001/*
002 * Licensed under the Apache License, Version 2.0 (the "License");
003 * you may not use this file except in compliance with the License.
004 * You may obtain a copy of the License at
005 *
006 *     http://www.apache.org/licenses/LICENSE-2.0
007 *
008 * Unless required by applicable law or agreed to in writing, software
009 * distributed under the License is distributed on an "AS IS" BASIS,
010 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011 * See the License for the specific language governing permissions and
012 * limitations under the License.
013 */
014package org.gbif.api.jackson;
015
016import org.gbif.api.vocabulary.License;
017
018import java.io.IOException;
019import java.util.Optional;
020
021import org.apache.commons.lang3.StringUtils;
022
023import com.fasterxml.jackson.core.JsonGenerator;
024import com.fasterxml.jackson.core.JsonParser;
025import com.fasterxml.jackson.core.JsonToken;
026import com.fasterxml.jackson.databind.DeserializationContext;
027import com.fasterxml.jackson.databind.JsonDeserializer;
028import com.fasterxml.jackson.databind.JsonMappingException;
029import com.fasterxml.jackson.databind.JsonSerializer;
030import com.fasterxml.jackson.databind.SerializerProvider;
031
032/**
033 * Jackson {@link JsonSerializer} and Jackson {@link JsonDeserializer} classes for {@link License}.
034 */
035public class LicenseSerde {
036
037  /**
038   * Jackson {@link JsonSerializer} for {@link License}.
039   */
040  public static class LicenseJsonSerializer extends JsonSerializer<License> {
041
042    @Override
043    public void serialize(License value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
044      if (value == null) {
045        jgen.writeNull();
046        return;
047      }
048
049      if (value.getLicenseUrl() != null) {
050        jgen.writeString(value.getLicenseUrl());
051        return;
052      }
053
054      //in last resort (UNSPECIFIED,UNSUPPORTED), we use the enum name
055      jgen.writeString(value.name().toLowerCase());
056    }
057  }
058
059  /**
060   * Jackson {@link JsonDeserializer} for {@link License}.
061   * If the value is empty, {@link License#UNSPECIFIED} will be returned.
062   * If the value can not be transformed into a License, {@link License#UNSUPPORTED} will be returned.
063   * This deserializer is a little lenient, names of licenses (in the License enum) also understood.
064   */
065  public static class LicenseJsonDeserializer extends JsonDeserializer<License> {
066    @Override
067    public License deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
068      if (jp.getCurrentToken() == JsonToken.VALUE_STRING) {
069        if (StringUtils.isEmpty(jp.getText())) {
070          return License.UNSPECIFIED;
071        }
072        // first, try by url
073        Optional<License> license = License.fromLicenseUrl(jp.getText());
074        if (license.isPresent()) {
075          return license.get();
076        }
077
078        // then, try by name
079        return License.fromString(jp.getText()).orElse(License.UNSUPPORTED);
080      }
081      throw JsonMappingException.from(jp, "Expected String");
082    }
083  }
084}