001package org.gbif.api.jackson;
002
003import org.gbif.api.vocabulary.License;
004
005import java.io.IOException;
006
007import com.google.common.base.Optional;
008import com.google.common.base.Strings;
009import org.codehaus.jackson.JsonGenerator;
010import org.codehaus.jackson.JsonParser;
011import org.codehaus.jackson.JsonToken;
012import org.codehaus.jackson.map.DeserializationContext;
013import org.codehaus.jackson.map.JsonDeserializer;
014import org.codehaus.jackson.map.JsonSerializer;
015import org.codehaus.jackson.map.SerializerProvider;
016
017/**
018 * Jackson {@link JsonSerializer} and Jackson {@link JsonDeserializer} classes for {@link License}.
019 */
020public class LicenseSerde {
021
022  /**
023   * Jackson {@link JsonSerializer} for {@link License}.
024   */
025  public static class LicenseJsonSerializer extends JsonSerializer<License> {
026
027    @Override
028    public void serialize(License value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
029      if(value == null){
030        jgen.writeNull();
031        return;
032      }
033
034      if(value.getLicenseUrl() != null){
035        jgen.writeString(value.getLicenseUrl());
036        return;
037      }
038
039      //in last resort (UNSPECIFIED,UNSUPPORTED), we use the enum name
040      jgen.writeString(value.name().toLowerCase());
041
042    }
043  }
044
045  /**
046   * Jackson {@link JsonDeserializer} for {@link License}.
047   * If the value is empty, License.UNSPECIFIED will be returned.
048   * If the value can not be transformed into a License, License.UNSUPPORTED will be returned.
049   * This deserializer a little bit lenient, names of licenses (in the License enum) also understood.
050   */
051  public static class LicenseJsonDeserializer extends JsonDeserializer<License> {
052    @Override
053    public License deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
054      if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
055        if(Strings.isNullOrEmpty(jp.getText())){
056          return License.UNSPECIFIED;
057        }
058        //first, try by url
059        Optional<License> license = License.fromLicenseUrl(jp.getText());
060        if(license.isPresent()){
061          return license.get();
062        }
063        //then, try by name
064        license = License.fromString(jp.getText());
065        return license.or(License.UNSUPPORTED);
066      }
067      throw ctxt.mappingException("Expected String");
068    }
069  }
070
071}