001/* 002 * Copyright 2020 Global Biodiversity Information Facility (GBIF) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.gbif.api.jackson; 017 018import org.gbif.api.vocabulary.Rank; 019 020import java.io.IOException; 021import java.util.HashMap; 022import java.util.Map; 023 024import com.fasterxml.jackson.core.JsonGenerator; 025import com.fasterxml.jackson.core.JsonParser; 026import com.fasterxml.jackson.core.JsonToken; 027import com.fasterxml.jackson.databind.DeserializationContext; 028import com.fasterxml.jackson.databind.JsonDeserializer; 029import com.fasterxml.jackson.databind.JsonMappingException; 030import com.fasterxml.jackson.databind.JsonSerializer; 031import com.fasterxml.jackson.databind.SerializerProvider; 032 033/** 034 * Jackson {@link JsonSerializer} and Jackson {@link JsonDeserializer} classes for {@link Rank} that uses the common rank markers instead of enum names. 035 */ 036public class RankSerde { 037 038 /** 039 * Jackson {@link JsonSerializer} for {@link Rank}. 040 */ 041 public static class RankJsonSerializer extends JsonSerializer<Rank> { 042 043 @Override 044 public void serialize(Rank value, JsonGenerator jgen, SerializerProvider provider) throws IOException { 045 if (value == null) { 046 jgen.writeNull(); 047 return; 048 } 049 if (value.getMarker() == null) { 050 jgen.writeString(value.name().toLowerCase().replaceAll("_", " ")); 051 } else { 052 jgen.writeString(value.getMarker()); 053 } 054 } 055 } 056 057 /** 058 * Jackson {@link JsonDeserializer} for {@link Rank}. 059 */ 060 public static class RankJsonDeserializer extends JsonDeserializer<Rank> { 061 private static final Map<String, Rank> RANKS = new HashMap<>(); 062 static { 063 for (Rank r : Rank.values()) { 064 if (r.getMarker() != null) { 065 RANKS.put(r.getMarker(), r); 066 } 067 } 068 } 069 070 @Override 071 public Rank deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException { 072 if (jp.getCurrentToken() == JsonToken.VALUE_STRING) { 073 if (RANKS.containsKey(jp.getText())) { 074 return RANKS.get(jp.getText()); 075 076 } else { 077 // try enum name as last resort 078 try { 079 return Rank.valueOf(jp.getText().toUpperCase().replace(" ", "_")); 080 } catch (IllegalArgumentException e) { 081 // swallow 082 } 083 } 084 return null; 085 } 086 throw JsonMappingException.from(jp, "Expected String"); 087 } 088 } 089}