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

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

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

import static com.google.common.base.Preconditions.checkNotNull;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.util.StdConverter;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * Allows serialization of {@link Multimap}s with non-{@link String} keys using Jackson. By default,
 * Jackson coerces all multimap 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 multimap field, add the following * annotations (assuming it is an {@link ImmutableListMultimap}: * *

{@code
 * @JsonSerialize(converter=MultimapEntries.FromMultimap}
 * @JsonDeserialize(converter=MapEntries.ToImmutableListMultimap}
 * private final ImmutableListMap myMultimap();
 *
 * }
* * There is also a converter to an {@link ImmutableSetMultimap}: {@link ToImmutableSetMultimap}. * *

Please do not use this class for any purpose other than that described above. */ public final class MultimapEntries { @JsonProperty("d") private List> entries; private MultimapEntries(@JsonProperty("d") List> entries) { // we do not make a defensive copy for speed and because Jackson seems to implicitly promise // it will not hold onto the reference this.entries = entries; } static MultimapEntries fromMap(Multimap multimap) { final List> entries = new ArrayList<>(); for (final Map.Entry> e : multimap.asMap().entrySet()) { // we do not defensively copy the key or the value since this should only be used in // Jackson converters, where it is not necessary entries.add(new MultimapEntry<>(e.getKey(), e.getValue())); } return new MultimapEntries<>(entries); } // exception on null desirable @SuppressWarnings("ConstantConditions") ImmutableListMultimap toImmutableListMultimap() { final ImmutableListMultimap.Builder ret = ImmutableListMultimap.builder(); for (final MultimapEntry entry : entries) { ret.putAll(entry.key, entry.values); } return ret.build(); } // exception on null desirable @SuppressWarnings("ConstantConditions") ImmutableSetMultimap toImmutableSetMultimap() { final ImmutableSetMultimap.Builder ret = ImmutableSetMultimap.builder(); for (final MultimapEntry entry : entries) { ret.putAll(entry.key, entry.values); } return ret.build(); } public static final class MultimapEntry { @JsonProperty("k") @Nullable private final K key; @JsonProperty("v") private final Collection values; @JsonCreator private MultimapEntry(@JsonProperty("k") K key, @JsonProperty("v") Collection values) { this.key = key; this.values = checkNotNull(values); } } public static class FromMultimap extends StdConverter, MultimapEntries> { @Override public MultimapEntries convert(final Multimap multimap) { return MultimapEntries.fromMap(multimap); } } public static class ToImmutableListMultimap extends StdConverter, ImmutableListMultimap> { @Override public ImmutableListMultimap convert( final MultimapEntries proxy) { return proxy.toImmutableListMultimap(); } } public static class ToImmutableSetMultimap extends StdConverter, ImmutableSetMultimap> { @Override public ImmutableSetMultimap convert( final MultimapEntries proxy) { return proxy.toImmutableSetMultimap(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy