/** * Copyright Intellectual Reserve, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gedcomx.rt.json; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import java.io.IOException; import java.util.*; /** * @author Ryan Heaton */ public class KeyedListSerializer extends JsonSerializer<Collection<? extends HasJsonKey>> { public static final String JSON_DEFAULT_KEY = "$"; @Override public void serialize(Collection<? extends HasJsonKey> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { serializeGeneric(value, jgen, provider); } static void serializeGeneric(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { if (value == null) { jgen.writeNull(); } else { jgen.writeStartObject(); Map<String, List<Object>> bykey = new HashMap<String, List<Object>>(); for (Object keyed : value) { String jsonKey = ((HasJsonKey) keyed).getJsonKey(); if (jsonKey == null) { jsonKey = JSON_DEFAULT_KEY; } List<Object> keyedList = bykey.get(jsonKey); if (keyedList == null) { keyedList = new ArrayList<Object>(); bykey.put(jsonKey, keyedList); } keyedList.add(keyed); boolean unique = ((HasJsonKey) keyed).isHasUniqueKey(); if (unique && keyedList.size() > 1) { throw new JsonMappingException(jgen, "Attempt to serialize " + keyed + " failed because it's key '" + jsonKey + "' is not unique."); } } for (Map.Entry<String, List<Object>> keyedObjects : bykey.entrySet()) { String jsonKey = keyedObjects.getKey(); jgen.writeFieldName(jsonKey); boolean notUnique = keyedObjects.getValue().size() != 1 || !((HasJsonKey)keyedObjects.getValue().get(0)).isHasUniqueKey(); if (notUnique) { jgen.writeStartArray(); } for (Object keyed : keyedObjects.getValue()) { provider.findTypedValueSerializer(keyed.getClass(), true, null).serialize(keyed, jgen, provider); } if (notUnique) { jgen.writeEndArray(); } } jgen.writeEndObject(); } } }