mirror of https://github.com/apache/jclouds.git
make it possible to deserialize into ctors that have immutable collection parameters
This commit is contained in:
parent
7596205774
commit
ef2718629f
|
@ -26,6 +26,7 @@ import javax.inject.Inject;
|
|||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapter;
|
||||
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.IterableTypeAdapterFactory;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
|
@ -84,10 +85,10 @@ public class CloudStackParserModule extends AbstractModule {
|
|||
|
||||
public static final class Adapter<E> extends TypeAdapter<Iterable<E>> {
|
||||
|
||||
private final IterableTypeAdapterFactory.IterableTypeAdapter<E> delegate;
|
||||
private final IterableTypeAdapter<E> delegate;
|
||||
|
||||
public Adapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapterFactory.IterableTypeAdapter<E>(elementAdapter);
|
||||
this.delegate = new IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Set;
|
|||
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapter;
|
||||
import org.jclouds.json.internal.NullFilteringTypeAdapterFactories.SetTypeAdapterFactory;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
|
@ -63,10 +64,10 @@ public class KeystoneParserModule extends AbstractModule {
|
|||
|
||||
public static final class Adapter<E> extends TypeAdapter<Set<E>> {
|
||||
|
||||
private final SetTypeAdapterFactory.SetTypeAdapter<E> delegate;
|
||||
private final SetTypeAdapter<E> delegate;
|
||||
|
||||
public Adapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new SetTypeAdapterFactory.SetTypeAdapter<E>(elementAdapter);
|
||||
this.delegate = new SetTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,10 @@ 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;
|
||||
|
@ -88,9 +91,10 @@ public class GsonModule extends AbstractModule {
|
|||
@Singleton
|
||||
Gson provideGson(TypeAdapter<JsonBall> jsonAdapter, DateAdapter adapter, ByteListAdapter byteListAdapter,
|
||||
ByteArrayAdapter byteArrayAdapter, PropertiesAdapter propertiesAdapter, JsonAdapterBindings bindings,
|
||||
OptionalTypeAdapterFactory optional, SetTypeAdapterFactory set, MapTypeAdapterFactory map,
|
||||
MultimapTypeAdapterFactory multimap, IterableTypeAdapterFactory iterable,
|
||||
CollectionTypeAdapterFactory collection, FluentIterableTypeAdapterFactory fluentIterable,
|
||||
OptionalTypeAdapterFactory optional, SetTypeAdapterFactory set, ImmutableSetTypeAdapterFactory immutableSet,
|
||||
MapTypeAdapterFactory map, MultimapTypeAdapterFactory multimap, IterableTypeAdapterFactory iterable,
|
||||
CollectionTypeAdapterFactory collection, ListTypeAdapterFactory list,
|
||||
ImmutableListTypeAdapterFactory immutableList, FluentIterableTypeAdapterFactory fluentIterable,
|
||||
DefaultExclusionStrategy exclusionStrategy) {
|
||||
|
||||
FieldNamingStrategy serializationPolicy = new AnnotationOrNameFieldNamingStrategy(ImmutableSet.of(
|
||||
|
@ -109,7 +113,10 @@ public class GsonModule extends AbstractModule {
|
|||
builder.registerTypeAdapterFactory(optional);
|
||||
builder.registerTypeAdapterFactory(iterable);
|
||||
builder.registerTypeAdapterFactory(collection);
|
||||
builder.registerTypeAdapterFactory(list);
|
||||
builder.registerTypeAdapterFactory(immutableList);
|
||||
builder.registerTypeAdapterFactory(set);
|
||||
builder.registerTypeAdapterFactory(immutableSet);
|
||||
builder.registerTypeAdapterFactory(map);
|
||||
builder.registerTypeAdapterFactory(multimap);
|
||||
builder.registerTypeAdapterFactory(fluentIterable);
|
||||
|
|
|
@ -25,6 +25,7 @@ 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;
|
||||
|
@ -61,15 +62,73 @@ public class NullFilteringTypeAdapterFactories {
|
|||
param));
|
||||
}
|
||||
|
||||
public static class IterableTypeAdapterFactory implements TypeAdapterFactory {
|
||||
public static final class IterableTypeAdapter<E> extends TypeAdapter<Iterable<E>> {
|
||||
|
||||
private final TypeAdapter<E> elementAdapter;
|
||||
|
||||
public IterableTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.elementAdapter = elementAdapter;
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Iterable<E> value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
for (E element : value)
|
||||
elementAdapter.write(out, element);
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
public Iterable<E> read(JsonReader in) throws IOException {
|
||||
return readAndBuild(in, ImmutableList.<E> builder());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <C extends Iterable<E>, B extends ImmutableCollection.Builder<E>> C readAndBuild(JsonReader in,
|
||||
B builder) throws IOException {
|
||||
in.beginArray();
|
||||
while (in.hasNext()) {
|
||||
E element = elementAdapter.read(in);
|
||||
if (element != null)
|
||||
builder.add(element);
|
||||
}
|
||||
in.endArray();
|
||||
return (C) builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return elementAdapter.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
IterableTypeAdapter<?> that = IterableTypeAdapter.class.cast(obj);
|
||||
return equal(this.elementAdapter, that.elementAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", elementAdapter).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ImmutableListTypeAdapterFactory implements TypeAdapterFactory {
|
||||
|
||||
protected final Class<?> declaring;
|
||||
|
||||
public IterableTypeAdapterFactory() {
|
||||
this(Iterable.class);
|
||||
public ImmutableListTypeAdapterFactory() {
|
||||
this(ImmutableList.class);
|
||||
}
|
||||
|
||||
protected IterableTypeAdapterFactory(Class<?> declaring) {
|
||||
protected ImmutableListTypeAdapterFactory(Class<?> declaring) {
|
||||
this.declaring = declaring;
|
||||
}
|
||||
|
||||
|
@ -88,164 +147,124 @@ public class NullFilteringTypeAdapterFactories {
|
|||
return (TypeAdapter<I>) new IterableTypeAdapter<E>(elementAdapter);
|
||||
}
|
||||
|
||||
public static final class IterableTypeAdapter<E> extends TypeAdapter<Iterable<E>> {
|
||||
|
||||
private final TypeAdapter<E> elementAdapter;
|
||||
|
||||
public IterableTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.elementAdapter = elementAdapter;
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Iterable<E> value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginArray();
|
||||
for (E element : value)
|
||||
elementAdapter.write(out, element);
|
||||
out.endArray();
|
||||
}
|
||||
|
||||
public Iterable<E> read(JsonReader in) throws IOException {
|
||||
return readAndBuild(in, ImmutableList.<E> builder());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <C extends Iterable<E>, B extends ImmutableCollection.Builder<E>> C readAndBuild(JsonReader in,
|
||||
B builder) throws IOException {
|
||||
in.beginArray();
|
||||
while (in.hasNext()) {
|
||||
E element = elementAdapter.read(in);
|
||||
if (element != null)
|
||||
builder.add(element);
|
||||
}
|
||||
in.endArray();
|
||||
return (C) builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return elementAdapter.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
IterableTypeAdapter<?> that = IterableTypeAdapter.class.cast(obj);
|
||||
return equal(this.elementAdapter, that.elementAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", elementAdapter).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionTypeAdapterFactory extends IterableTypeAdapterFactory {
|
||||
public static class IterableTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
|
||||
public IterableTypeAdapterFactory() {
|
||||
super(Iterable.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CollectionTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
|
||||
public CollectionTypeAdapterFactory() {
|
||||
super(Collection.class);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <E, I> TypeAdapter<I> newAdapter(TypeAdapter<E> elementAdapter) {
|
||||
return (TypeAdapter<I>) new CollectionTypeAdapter<E>(elementAdapter);
|
||||
}
|
||||
|
||||
public static final class CollectionTypeAdapter<E> extends TypeAdapter<Collection<E>> {
|
||||
|
||||
private final IterableTypeAdapterFactory.IterableTypeAdapter<E> delegate;
|
||||
|
||||
public CollectionTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapterFactory.IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Collection<E> value) throws IOException {
|
||||
this.delegate.write(out, value);
|
||||
}
|
||||
|
||||
public Collection<E> read(JsonReader in) throws IOException {
|
||||
return delegate.readAndBuild(in, ImmutableList.<E> builder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
CollectionTypeAdapter<?> that = CollectionTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", delegate.elementAdapter).toString();
|
||||
}
|
||||
public static class ListTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
|
||||
public ListTypeAdapterFactory() {
|
||||
super(List.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SetTypeAdapterFactory extends IterableTypeAdapterFactory {
|
||||
public SetTypeAdapterFactory() {
|
||||
super(Set.class);
|
||||
public static final class SetTypeAdapter<E> extends TypeAdapter<Set<E>> {
|
||||
|
||||
private final IterableTypeAdapter<E> delegate;
|
||||
|
||||
public SetTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Set<E> value) throws IOException {
|
||||
this.delegate.write(out, value);
|
||||
}
|
||||
|
||||
public Set<E> read(JsonReader in) throws IOException {
|
||||
return delegate.readAndBuild(in, ImmutableSet.<E> builder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
SetTypeAdapter<?> that = SetTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", delegate.elementAdapter).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ImmutableSetTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
|
||||
public ImmutableSetTypeAdapterFactory() {
|
||||
this(ImmutableSet.class);
|
||||
}
|
||||
|
||||
protected ImmutableSetTypeAdapterFactory(Class<?> declaring) {
|
||||
super(declaring);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <E, I> TypeAdapter<I> newAdapter(TypeAdapter<E> elementAdapter) {
|
||||
return (TypeAdapter<I>) new SetTypeAdapter<E>(elementAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class SetTypeAdapter<E> extends TypeAdapter<Set<E>> {
|
||||
|
||||
private final IterableTypeAdapterFactory.IterableTypeAdapter<E> delegate;
|
||||
|
||||
public SetTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapterFactory.IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Set<E> value) throws IOException {
|
||||
this.delegate.write(out, value);
|
||||
}
|
||||
|
||||
public Set<E> read(JsonReader in) throws IOException {
|
||||
return delegate.readAndBuild(in, ImmutableSet.<E> builder());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
SetTypeAdapter<?> that = SetTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", delegate.elementAdapter).toString();
|
||||
}
|
||||
public static class SetTypeAdapterFactory extends ImmutableSetTypeAdapterFactory {
|
||||
public SetTypeAdapterFactory() {
|
||||
super(Set.class);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FluentIterableTypeAdapterFactory extends IterableTypeAdapterFactory {
|
||||
private static final class FluentIterableTypeAdapter<E> extends TypeAdapter<FluentIterable<E>> {
|
||||
|
||||
private final IterableTypeAdapter<E> delegate;
|
||||
|
||||
public FluentIterableTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, FluentIterable<E> value) throws IOException {
|
||||
this.delegate.write(out, value.toList());
|
||||
}
|
||||
|
||||
public FluentIterable<E> read(JsonReader in) throws IOException {
|
||||
return FluentIterable.from(delegate.read(in));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
FluentIterableTypeAdapter<?> that = FluentIterableTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", delegate.elementAdapter).toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static class FluentIterableTypeAdapterFactory extends ImmutableListTypeAdapterFactory {
|
||||
public FluentIterableTypeAdapterFactory() {
|
||||
super(FluentIterable.class);
|
||||
}
|
||||
|
@ -254,43 +273,64 @@ public class NullFilteringTypeAdapterFactories {
|
|||
protected <E, I> TypeAdapter<I> newAdapter(TypeAdapter<E> elementAdapter) {
|
||||
return (TypeAdapter<I>) new FluentIterableTypeAdapter<E>(elementAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class FluentIterableTypeAdapter<E> extends TypeAdapter<FluentIterable<E>> {
|
||||
private static final class MapTypeAdapter<K, V> extends TypeAdapter<Map<K, V>> {
|
||||
|
||||
private final IterableTypeAdapterFactory.IterableTypeAdapter<E> delegate;
|
||||
protected final TypeAdapter<K> keyAdapter;
|
||||
protected final TypeAdapter<V> valueAdapter;
|
||||
|
||||
public FluentIterableTypeAdapter(TypeAdapter<E> elementAdapter) {
|
||||
this.delegate = new IterableTypeAdapterFactory.IterableTypeAdapter<E>(elementAdapter);
|
||||
nullSafe();
|
||||
protected MapTypeAdapter(TypeAdapter<K> keyAdapter, TypeAdapter<V> valueAdapter) {
|
||||
this.keyAdapter = keyAdapter;
|
||||
this.valueAdapter = valueAdapter;
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Map<K, V> value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, FluentIterable<E> value) throws IOException {
|
||||
this.delegate.write(out, value.toList());
|
||||
out.beginObject();
|
||||
for (Map.Entry<K, V> element : value.entrySet()) {
|
||||
out.name(String.valueOf(element.getKey()));
|
||||
valueAdapter.write(out, element.getValue());
|
||||
}
|
||||
out.endObject();
|
||||
}
|
||||
|
||||
public FluentIterable<E> read(JsonReader in) throws IOException {
|
||||
return FluentIterable.from(delegate.read(in));
|
||||
public Map<K, V> read(JsonReader in) throws IOException {
|
||||
ImmutableMap.Builder<K, V> result = ImmutableMap.builder();
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
|
||||
K name = keyAdapter.read(in);
|
||||
V value = valueAdapter.read(in);
|
||||
if (value != null)
|
||||
result.put(name, value);
|
||||
}
|
||||
in.endObject();
|
||||
return result.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(keyAdapter, valueAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
FluentIterableTypeAdapter<?> that = FluentIterableTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
MapTypeAdapter<?, ?> that = MapTypeAdapter.class.cast(obj);
|
||||
return equal(this.keyAdapter, that.keyAdapter) && equal(this.valueAdapter, that.valueAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("elementAdapter", delegate.elementAdapter).toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("keyAdapter", keyAdapter).add("valueAdapter", valueAdapter).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -321,64 +361,49 @@ public class NullFilteringTypeAdapterFactories {
|
|||
protected <K, V, T> TypeAdapter<T> newAdapter(TypeAdapter<K> keyAdapter, TypeAdapter<V> valueAdapter) {
|
||||
return (TypeAdapter<T>) new MapTypeAdapter<K, V>(keyAdapter, valueAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
public static final class MapTypeAdapter<K, V> extends TypeAdapter<Map<K, V>> {
|
||||
private static final class MultimapTypeAdapter<K, V> extends TypeAdapter<Multimap<K, V>> {
|
||||
|
||||
protected final TypeAdapter<K> keyAdapter;
|
||||
protected final TypeAdapter<V> valueAdapter;
|
||||
private final MapTypeAdapter<K, Iterable<V>> delegate;
|
||||
|
||||
protected MapTypeAdapter(TypeAdapter<K> keyAdapter, TypeAdapter<V> valueAdapter) {
|
||||
this.keyAdapter = keyAdapter;
|
||||
this.valueAdapter = valueAdapter;
|
||||
nullSafe();
|
||||
}
|
||||
public MultimapTypeAdapter(TypeAdapter<K> keyAdapter, TypeAdapter<V> valueAdapter) {
|
||||
this.delegate = new MapTypeAdapter<K, Iterable<V>>(keyAdapter,
|
||||
new IterableTypeAdapter<V>(valueAdapter));
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Map<K, V> value) throws IOException {
|
||||
if (value == null) {
|
||||
out.nullValue();
|
||||
return;
|
||||
}
|
||||
out.beginObject();
|
||||
for (Map.Entry<K, V> element : value.entrySet()) {
|
||||
out.name(String.valueOf(element.getKey()));
|
||||
valueAdapter.write(out, element.getValue());
|
||||
}
|
||||
out.endObject();
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
public void write(JsonWriter out, Multimap<K, V> value) throws IOException {
|
||||
this.delegate.write(out, Map.class.cast(value.asMap()));
|
||||
}
|
||||
|
||||
public Map<K, V> read(JsonReader in) throws IOException {
|
||||
ImmutableMap.Builder<K, V> result = ImmutableMap.builder();
|
||||
in.beginObject();
|
||||
while (in.hasNext()) {
|
||||
JsonReaderInternalAccess.INSTANCE.promoteNameToValue(in);
|
||||
K name = keyAdapter.read(in);
|
||||
V value = valueAdapter.read(in);
|
||||
if (value != null)
|
||||
result.put(name, value);
|
||||
}
|
||||
in.endObject();
|
||||
return result.build();
|
||||
}
|
||||
public Multimap<K, V> read(JsonReader in) throws IOException {
|
||||
ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.<K, V> builder();
|
||||
for (Entry<K, Iterable<V>> entry : delegate.read(in).entrySet())
|
||||
builder.putAll(entry.getKey(), entry.getValue());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(keyAdapter, valueAdapter);
|
||||
}
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
MapTypeAdapter<?, ?> that = MapTypeAdapter.class.cast(obj);
|
||||
return equal(this.keyAdapter, that.keyAdapter) && equal(this.valueAdapter, that.valueAdapter);
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
MultimapTypeAdapter<?, ?> that = MultimapTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("keyAdapter", keyAdapter).add("valueAdapter", valueAdapter).toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("keyAdapter", delegate.keyAdapter)
|
||||
.add("valueAdapter", delegate.valueAdapter).toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,47 +419,5 @@ public class NullFilteringTypeAdapterFactories {
|
|||
return (TypeAdapter<T>) new MultimapTypeAdapter<K, V>(keyAdapter, valueAdapter);
|
||||
}
|
||||
|
||||
public static final class MultimapTypeAdapter<K, V> extends TypeAdapter<Multimap<K, V>> {
|
||||
|
||||
private final MapTypeAdapterFactory.MapTypeAdapter<K, Collection<V>> delegate;
|
||||
|
||||
public MultimapTypeAdapter(TypeAdapter<K> keyAdapter, TypeAdapter<V> valueAdapter) {
|
||||
this.delegate = new MapTypeAdapterFactory.MapTypeAdapter<K, Collection<V>>(keyAdapter,
|
||||
new CollectionTypeAdapterFactory.CollectionTypeAdapter<V>(valueAdapter));
|
||||
nullSafe();
|
||||
}
|
||||
|
||||
public void write(JsonWriter out, Multimap<K, V> value) throws IOException {
|
||||
this.delegate.write(out, value.asMap());
|
||||
}
|
||||
|
||||
public Multimap<K, V> read(JsonReader in) throws IOException {
|
||||
ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.<K, V> builder();
|
||||
for (Entry<K, Collection<V>> entry : delegate.read(in).entrySet())
|
||||
builder.putAll(entry.getKey(), entry.getValue());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return delegate.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null || getClass() != obj.getClass())
|
||||
return false;
|
||||
MultimapTypeAdapter<?, ?> that = MultimapTypeAdapter.class.cast(obj);
|
||||
return equal(this.delegate, that.delegate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper(this).add("keyAdapter", delegate.keyAdapter)
|
||||
.add("valueAdapter", delegate.valueAdapter).toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,12 +23,16 @@ 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;
|
||||
|
@ -149,6 +153,46 @@ public class NullFilteringTypeAdapterFactoriesTest {
|
|||
ImmutableList.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
|
||||
}
|
||||
|
||||
private Gson list = new GsonBuilder().registerTypeAdapterFactory(new ListTypeAdapterFactory()).create();
|
||||
private Type listType = new TypeToken<List<String>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
private Type listResourceType = new TypeToken<List<Resource>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
|
||||
public void testList() {
|
||||
Iterable<String> noNulls = list.fromJson("[\"value\",\"a test string!\"]", listType);
|
||||
assertEquals(noNulls, ImmutableList.of("value", "a test string!"));
|
||||
Iterable<String> withNull = list.fromJson("[null,\"a test string!\"]", listType);
|
||||
assertEquals(withNull, ImmutableList.of("a test string!"));
|
||||
Iterable<String> withDupes = list.fromJson("[\"value\",\"value\"]", listType);
|
||||
assertEquals(withDupes, ImmutableList.of("value", "value"));
|
||||
Iterable<Resource> resources = list.fromJson(
|
||||
"[{\"id\":\"i-foo\",\"name\":\"foo\"},{\"id\":\"i-bar\",\"name\":\"bar\"}]", listResourceType);
|
||||
assertEquals(resources, ImmutableList.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
|
||||
}
|
||||
|
||||
private Gson immutableList = new GsonBuilder().registerTypeAdapterFactory(new ImmutableListTypeAdapterFactory()).create();
|
||||
private Type immutableListType = new TypeToken<ImmutableList<String>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
private Type immutableListResourceType = new TypeToken<ImmutableList<Resource>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
|
||||
public void testImmutableList() {
|
||||
Iterable<String> noNulls = immutableList.fromJson("[\"value\",\"a test string!\"]", immutableListType);
|
||||
assertEquals(noNulls, ImmutableList.of("value", "a test string!"));
|
||||
Iterable<String> withNull = immutableList.fromJson("[null,\"a test string!\"]", immutableListType);
|
||||
assertEquals(withNull, ImmutableList.of("a test string!"));
|
||||
Iterable<String> withDupes = immutableList.fromJson("[\"value\",\"value\"]", immutableListType);
|
||||
assertEquals(withDupes, ImmutableList.of("value", "value"));
|
||||
Iterable<Resource> resources = immutableList.fromJson(
|
||||
"[{\"id\":\"i-foo\",\"name\":\"foo\"},{\"id\":\"i-bar\",\"name\":\"bar\"}]", immutableListResourceType);
|
||||
assertEquals(resources, ImmutableList.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
|
||||
}
|
||||
|
||||
private Gson set = new GsonBuilder().registerTypeAdapterFactory(new SetTypeAdapterFactory()).create();
|
||||
private Type setType = new TypeToken<Set<String>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@ -169,6 +213,26 @@ public class NullFilteringTypeAdapterFactoriesTest {
|
|||
assertEquals(resources, ImmutableSet.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
|
||||
}
|
||||
|
||||
private Gson immutableSet = new GsonBuilder().registerTypeAdapterFactory(new ImmutableSetTypeAdapterFactory()).create();
|
||||
private Type immutableSetType = new TypeToken<ImmutableSet<String>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
private Type immutableSetResourceType = new TypeToken<ImmutableSet<Resource>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
}.getType();
|
||||
|
||||
public void testImmutableSet() {
|
||||
Iterable<String> noNulls = immutableSet.fromJson("[\"value\",\"a test string!\"]", immutableSetType);
|
||||
assertEquals(noNulls, ImmutableSet.of("value", "a test string!"));
|
||||
Iterable<String> withNull = immutableSet.fromJson("[null,\"a test string!\"]", immutableSetType);
|
||||
assertEquals(withNull, ImmutableSet.of("a test string!"));
|
||||
Iterable<String> withDupes = immutableSet.fromJson("[\"value\",\"value\"]", immutableSetType);
|
||||
assertEquals(withDupes, ImmutableSet.of("value", "value"));
|
||||
Iterable<Resource> resources = immutableSet.fromJson(
|
||||
"[{\"id\":\"i-foo\",\"name\":\"foo\"},{\"id\":\"i-bar\",\"name\":\"bar\"}]", immutableSetResourceType);
|
||||
assertEquals(resources, ImmutableSet.of(new Resource("i-foo", "foo"), new Resource("i-bar", "bar")));
|
||||
}
|
||||
|
||||
private Gson map = new GsonBuilder().registerTypeAdapterFactory(new MapTypeAdapterFactory()).create();
|
||||
private Type mapType = new TypeToken<Map<String, String>>() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
|
Loading…
Reference in New Issue