Adds support for ImmutableMap in jclouds gson

This commit is contained in:
Zack Shoylev 2014-07-25 12:53:36 -05:00
parent 8cb2cb449b
commit 231a60675e
3 changed files with 100 additions and 73 deletions

View File

@ -16,44 +16,6 @@
*/ */
package org.jclouds.json.config; package org.jclouds.json.config;
import static com.google.common.io.BaseEncoding.base16;
import java.beans.ConstructorProperties;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import org.jclouds.date.DateService;
import org.jclouds.domain.JsonBall;
import org.jclouds.json.Json;
import org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory;
import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.json.internal.NamingStrategies.AnnotationConstructorNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.AnnotationOrNameFieldNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.ExtractNamed;
import org.jclouds.json.internal.NamingStrategies.ExtractSerializedName;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.CollectionTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.FluentIterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableSetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MultimapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
import org.jclouds.json.internal.NullHackJsonLiteralAdapter;
import org.jclouds.json.internal.OptionalTypeAdapterFactory;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMap.Builder; import com.google.common.collect.ImmutableMap.Builder;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -77,6 +39,43 @@ import com.google.gson.stream.JsonWriter;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.ImplementedBy; import com.google.inject.ImplementedBy;
import com.google.inject.Provides; import com.google.inject.Provides;
import org.jclouds.date.DateService;
import org.jclouds.domain.JsonBall;
import org.jclouds.json.Json;
import org.jclouds.json.internal.DeserializationConstructorAndReflectiveTypeAdapterFactory;
import org.jclouds.json.internal.EnumTypeAdapterThatReturnsFromValue;
import org.jclouds.json.internal.GsonWrapper;
import org.jclouds.json.internal.NamingStrategies.AnnotationConstructorNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.AnnotationOrNameFieldNamingStrategy;
import org.jclouds.json.internal.NamingStrategies.ExtractNamed;
import org.jclouds.json.internal.NamingStrategies.ExtractSerializedName;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableMapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.CollectionTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.FluentIterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableSetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MultimapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
import org.jclouds.json.internal.NullHackJsonLiteralAdapter;
import org.jclouds.json.internal.OptionalTypeAdapterFactory;
import javax.inject.Inject;
import javax.inject.Provider;
import javax.inject.Singleton;
import java.beans.ConstructorProperties;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import static com.google.common.io.BaseEncoding.base16;
/** /**
* Contains logic for parsing objects from Strings. * Contains logic for parsing objects from Strings.
@ -92,7 +91,7 @@ public class GsonModule extends AbstractModule {
MapTypeAdapterFactory map, MultimapTypeAdapterFactory multimap, IterableTypeAdapterFactory iterable, MapTypeAdapterFactory map, MultimapTypeAdapterFactory multimap, IterableTypeAdapterFactory iterable,
CollectionTypeAdapterFactory collection, ListTypeAdapterFactory list, CollectionTypeAdapterFactory collection, ListTypeAdapterFactory list,
ImmutableListTypeAdapterFactory immutableList, FluentIterableTypeAdapterFactory fluentIterable, ImmutableListTypeAdapterFactory immutableList, FluentIterableTypeAdapterFactory fluentIterable,
DefaultExclusionStrategy exclusionStrategy) { ImmutableMapTypeAdapterFactory immutableMap, DefaultExclusionStrategy exclusionStrategy) {
FieldNamingStrategy serializationPolicy = new AnnotationOrNameFieldNamingStrategy(ImmutableSet.of( FieldNamingStrategy serializationPolicy = new AnnotationOrNameFieldNamingStrategy(ImmutableSet.of(
new ExtractSerializedName(), new ExtractNamed())); new ExtractSerializedName(), new ExtractNamed()));
@ -117,6 +116,7 @@ public class GsonModule extends AbstractModule {
builder.registerTypeAdapterFactory(map); builder.registerTypeAdapterFactory(map);
builder.registerTypeAdapterFactory(multimap); builder.registerTypeAdapterFactory(multimap);
builder.registerTypeAdapterFactory(fluentIterable); builder.registerTypeAdapterFactory(fluentIterable);
builder.registerTypeAdapterFactory(immutableMap);
AnnotationConstructorNamingStrategy deserializationPolicy = new AnnotationConstructorNamingStrategy( AnnotationConstructorNamingStrategy deserializationPolicy = new AnnotationConstructorNamingStrategy(
ImmutableSet.of(ConstructorProperties.class, Inject.class), ImmutableSet.of(new ExtractNamed())); ImmutableSet.of(ConstructorProperties.class, Inject.class), ImmutableSet.of(new ExtractNamed()));
@ -151,7 +151,7 @@ public class GsonModule extends AbstractModule {
return false; return false;
} }
} }
@ImplementedBy(CDateAdapter.class) @ImplementedBy(CDateAdapter.class)
public abstract static class DateAdapter extends TypeAdapter<Date> { public abstract static class DateAdapter extends TypeAdapter<Date> {

View File

@ -16,18 +16,6 @@
*/ */
package org.jclouds.json.internal; package org.jclouds.json.internal;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableCollection; import com.google.common.collect.ImmutableCollection;
@ -44,6 +32,18 @@ import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader; import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import static com.google.common.base.Objects.equal;
import static com.google.common.base.Objects.toStringHelper;
/** /**
* Eliminates null values when deserializing Collections, Maps, and Multimaps * Eliminates null values when deserializing Collections, Maps, and Multimaps
* <p/> * <p/>
@ -150,7 +150,7 @@ public class NullFilteringTypeAdapterFactories {
super(Iterable.class); super(Iterable.class);
} }
} }
public static class CollectionTypeAdapterFactory extends ImmutableListTypeAdapterFactory { public static class CollectionTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
public CollectionTypeAdapterFactory() { public CollectionTypeAdapterFactory() {
super(Collection.class); super(Collection.class);
@ -271,6 +271,13 @@ public class NullFilteringTypeAdapterFactories {
} }
} }
public static class ImmutableMapTypeAdapterFactory extends MapTypeAdapterFactory {
public ImmutableMapTypeAdapterFactory() {
super(ImmutableMap.class);
}
}
private static final class MapTypeAdapter<K, V> extends TypeAdapter<Map<K, V>> { private static final class MapTypeAdapter<K, V> extends TypeAdapter<Map<K, V>> {
protected final TypeAdapter<K> keyAdapter; protected final TypeAdapter<K> keyAdapter;

View File

@ -16,26 +16,6 @@
*/ */
package org.jclouds.json.internal; package org.jclouds.json.internal;
import static com.google.common.base.Objects.equal;
import static org.testng.Assert.assertEquals;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.CollectionTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.FluentIterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableSetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MultimapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
import org.testng.annotations.Test;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.FluentIterable; import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -46,6 +26,26 @@ import com.google.common.collect.Multimap;
import com.google.common.reflect.TypeToken; import com.google.common.reflect.TypeToken;
import com.google.gson.Gson; import com.google.gson.Gson;
import com.google.gson.GsonBuilder; import com.google.gson.GsonBuilder;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.CollectionTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.FluentIterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableSetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ListTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.MultimapTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.ImmutableMapTypeAdapterFactory;
import org.testng.annotations.Test;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Objects.equal;
import static org.testng.Assert.assertEquals;
@Test(testName = "NullFilteringTypeAdapterFactoriesTest") @Test(testName = "NullFilteringTypeAdapterFactoriesTest")
public class NullFilteringTypeAdapterFactoriesTest { public class NullFilteringTypeAdapterFactoriesTest {
@ -227,6 +227,26 @@ public class NullFilteringTypeAdapterFactoriesTest {
assertEquals(resources, ImmutableSet.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar"))); assertEquals(resources, ImmutableSet.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
} }
private Gson immutableMap = new GsonBuilder().registerTypeAdapterFactory(new ImmutableMapTypeAdapterFactory()).create();
private Type immutableMapType = new TypeToken<ImmutableMap<String, String>>() {
private static final long serialVersionUID = 1L;
}.getType();
private Type immutableMapResourceType = new TypeToken<ImmutableMap<String, Resource>>() {
private static final long serialVersionUID = 1L;
}.getType();
public void testImmutableMap() {
ImmutableMap<String, String> noNulls = immutableMap.fromJson("{\"value\":\"a test string!\"}", immutableMapType);
assertEquals(noNulls, ImmutableMap.of("value", "a test string!"));
ImmutableMap<String, String> withNull = immutableMap.fromJson("{\"key\":null}", immutableMapType);
assertEquals(withNull, ImmutableMap.of());
ImmutableMap<String, String> withEmpty = map.fromJson("{\"value\":\"\"}", mapType);
assertEquals(withEmpty, ImmutableMap.of("value", ""));
ImmutableMap<String, Resource> resources = immutableMap.fromJson(
"{\"key1\":{\"id\":\"i-foo\",\"name\":\"foo\"},\"key2\":{\"id\":\"i-bar\",\"name\":\"bar\"}}", immutableMapResourceType);
assertEquals(resources, ImmutableMap.of("key1", new Resource("i-foo", "foo"), "key2", new Resource("i-bar", "bar")));
}
private Gson map = new GsonBuilder().registerTypeAdapterFactory(new MapTypeAdapterFactory()).create(); private Gson map = new GsonBuilder().registerTypeAdapterFactory(new MapTypeAdapterFactory()).create();
private Type mapType = new TypeToken<Map<String, String>>() { private Type mapType = new TypeToken<Map<String, String>>() {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;