All Downloads are FREE. Search and download functionalities are using the official Maven repository.

edu.isi.nlp.serialization.jackson.MapEntries Maven / Gradle / Ivy

The newest version!
package edu.isi.nlp.serialization.jackson;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.util.StdConverter;
import com.google.common.collect.ImmutableBiMap;
import com.google.common.collect.ImmutableMap;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * Allows serialization of {@link Map}s with non-{@link String} keys using Jackson. By default,
 * Jackson coerces all map keys to be {@code String}s when serializing, breaking round-tripping when
 * there are non-{@code String} keys.
 *
 * 

This class can be used with Jackson's converter mechanism to work around this problem by * supplying a substitute object for serialization which does not trigger the special key behavior * (at some cost to performance/memory...). On the problematic map field, add the following * annotations (assuming it is an {@link ImmutableMap}: * *

{@code
 * @JsonSerialize(converter=MapEntries.FromMap}
 * @JsonDeserialize(converter=MapEntries.ToImmutableMap}
 * private final ImmutableMap myMap();
 *
 * }
* * There is also a converter to an {@link ImmutableBiMap}: {@link ToImmutableBiMap}. * *

Please do not use this class for any purpose other than that described above. */ public final class MapEntries { @JsonProperty("d") private List> entries; private MapEntries(@JsonProperty("d") List> entries) { // no defensive copy for speed. We trust Jackson not to hold on to this reference, // which seems to be implicitly promised this.entries = entries; } private static MapEntries fromMap(Map map) { final List> entries = new ArrayList<>(); for (final Map.Entry e : map.entrySet()) { // we do not make any defensive copy here because this is assumed not to be used // outside our converters entries.add(new MapEntry<>(e.getKey(), e.getValue())); } return new MapEntries<>(entries); } // warning below suppressed because we want ImmutableBiMap to throw its exception // if any element is null @SuppressWarnings("ConstantConditions") private ImmutableMap toRegularImmutableMap() { final ImmutableMap.Builder ret = ImmutableMap.builder(); for (final MapEntry entry : entries) { ret.put(entry.key, entry.value); } return ret.build(); } // warning below suppressed because we want ImmutableBiMap to throw its exception // if any element is null @SuppressWarnings("ConstantConditions") private ImmutableBiMap toImmutableBiMap() { final ImmutableBiMap.Builder ret = ImmutableBiMap.builder(); for (final MapEntry entry : entries) { ret.put(entry.key, entry.value); } return ret.build(); } public static final class MapEntry { // nullable in case we ever want to support non-Immutable maps @JsonProperty("k") @Nullable private final K key; // nullable in case we ever want to support non-Immutable maps @JsonProperty("v") @Nullable private final V value; @JsonCreator private MapEntry(@JsonProperty("k") K key, @JsonProperty("v") V value) { this.key = key; this.value = value; } } public static class FromMap extends StdConverter, MapEntries> { @Override public MapEntries convert(final Map map) { return MapEntries.fromMap(map); } } public static class ToImmutableMap extends StdConverter, ImmutableMap> { @Override public ImmutableMap convert(final MapEntries proxy) { return proxy.toRegularImmutableMap(); } } public static class ToImmutableBiMap extends StdConverter, ImmutableBiMap> { @Override public ImmutableBiMap convert(final MapEntries proxy) { return proxy.toImmutableBiMap(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy