001package org.conqat.engine.commons.util; 002 003import java.io.IOException; 004import java.io.Serializable; 005import java.util.Arrays; 006import java.util.Collection; 007 008import org.conqat.lib.commons.collections.ListMap; 009import org.conqat.lib.commons.collections.UnmodifiableSet; 010 011import com.fasterxml.jackson.annotation.JsonCreator; 012import com.fasterxml.jackson.annotation.JsonProperty; 013import com.fasterxml.jackson.core.JsonGenerator; 014import com.fasterxml.jackson.core.JsonParser; 015import com.fasterxml.jackson.databind.DeserializationContext; 016import com.fasterxml.jackson.databind.JsonDeserializer; 017import com.fasterxml.jackson.databind.JsonSerializer; 018import com.fasterxml.jackson.databind.SerializerProvider; 019import com.fasterxml.jackson.databind.module.SimpleModule; 020 021/** 022 * Jackson module which supports serialization and deserialization of 023 * {@link ListMap} object and back. 024 */ 025public class ListMapSerializationModule extends SimpleModule { 026 027 ListMapSerializationModule() { 028 addSerializer(ListMap.class, new ListMapSerializer()); 029 addDeserializer(ListMap.class, new ListMapDeserializer()); 030 } 031 032 /** Serializer for {@link ListMap} objects. */ 033 private static class ListMapSerializer extends JsonSerializer<ListMap> { 034 035 @Override 036 public void serialize(ListMap value, JsonGenerator generator, SerializerProvider serializers) 037 throws IOException { 038 UnmodifiableSet keys = value.getKeys(); 039 SerializableListMapEntry[] entries = new SerializableListMapEntry[keys.size()]; 040 int i = 0; 041 for (Object key : keys) { 042 entries[i++] = new SerializableListMapEntry(key, value.getCollection(key)); 043 } 044 generator.writeObject(entries); 045 } 046 } 047 048 /** Deserializer for {@link ListMap} objects. */ 049 private static class ListMapDeserializer extends JsonDeserializer<ListMap> { 050 051 @Override 052 public ListMap deserialize(JsonParser parser, DeserializationContext ctx) throws IOException { 053 SerializableListMapEntry[] root = parser.getCodec().readValue(parser, SerializableListMapEntry[].class); 054 ListMap<Object, Serializable> listMap = new ListMap<>(); 055 for (SerializableListMapEntry serializableListMapEntry : root) { 056 listMap.addAll(serializableListMapEntry.key, Arrays.asList(serializableListMapEntry.values)); 057 } 058 return listMap; 059 } 060 } 061 062 private static class SerializableListMapEntry { 063 064 /** The name of the JSON property name for {@link #key}. */ 065 private static final String KEY_PROPERTY = "key"; 066 067 /** The name of the JSON property name for {@link #values}. */ 068 private static final String VALUES_PROPERTY = "values"; 069 070 @JsonProperty(KEY_PROPERTY) 071 private final Object key; 072 073 @JsonProperty(VALUES_PROPERTY) 074 private final Serializable[] values; 075 076 @JsonCreator 077 private SerializableListMapEntry(@JsonProperty(KEY_PROPERTY) Object key, 078 @JsonProperty(VALUES_PROPERTY) Collection<Serializable> values) { 079 this.key = key; 080 this.values = values.toArray(new Serializable[0]); 081 } 082 } 083 084}