mirror of https://github.com/apache/jclouds.git
Fixed bug found in docker provider where deserialization constructors don't handle json null.
This commit is contained in:
parent
5b6f1e929e
commit
c0e6a2c51c
|
@ -166,7 +166,7 @@ public final class DeserializationConstructorAndReflectiveTypeAdapterFactory imp
|
|||
empty = false;
|
||||
String name = in.nextName();
|
||||
ParameterReader<?> parameter = parameterReaders.get(name);
|
||||
if (parameter == null) {
|
||||
if (parameter == null || in.peek() == JsonToken.NULL) {
|
||||
in.skipValue();
|
||||
} else {
|
||||
Object value = parameter.read(in);
|
||||
|
|
|
@ -128,8 +128,8 @@ public class Reflection2 {
|
|||
}
|
||||
|
||||
/**
|
||||
* This gets all declared constructors, not just public ones. makes them accessible, as well.
|
||||
* This also includes factory methods on abstract types, defined static methods returning the same type.
|
||||
* This gets all declared constructors or factory methods on abstract types, not just public ones, and makes them
|
||||
* accessible.
|
||||
*/
|
||||
private static LoadingCache<TypeToken<?>, Set<Invokable<?, ?>>> constructorsForTypeToken = CacheBuilder
|
||||
.newBuilder().build(new CacheLoader<TypeToken<?>, Set<Invokable<?, ?>>>() {
|
||||
|
@ -143,6 +143,7 @@ public class Reflection2 {
|
|||
if (Modifier.isAbstract(key.getRawType().getModifiers())) {
|
||||
for (Invokable<?, Object> method : methods(key.getRawType())){
|
||||
if (method.isStatic() && method.getReturnType().equals(key)) {
|
||||
method.setAccessible(true);
|
||||
builder.add(method);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,17 @@ import static com.google.common.io.BaseEncoding.base16;
|
|||
import static com.google.common.primitives.Bytes.asList;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.json.config.GsonModule.DefaultExclusionStrategy;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.gson.FieldAttributes;
|
||||
|
@ -210,67 +213,73 @@ public class JsonTest {
|
|||
EnumInsideWithParser.Test.UNRECOGNIZED);
|
||||
}
|
||||
|
||||
private abstract static class SpinalCasedType {
|
||||
private abstract static class UpperCamelCasedType {
|
||||
abstract String id();
|
||||
|
||||
abstract String contentType();
|
||||
@Nullable abstract Map<String, String> volumes();
|
||||
|
||||
// Currently, this only works for deserialization. Need to set a naming policy for serialization!
|
||||
@SerializedNames({ "id", "content-type" })
|
||||
private static SpinalCasedType create(String id, String contentType) {
|
||||
return new SpinalCasedTypeImpl(id, contentType);
|
||||
@SerializedNames({ "Id", "Volumes" })
|
||||
private static UpperCamelCasedType create(String id, Map<String, String> volumes) {
|
||||
return new UpperCamelCasedTypeImpl(id, volumes);
|
||||
}
|
||||
}
|
||||
|
||||
public void spinalCaseWithSerializedNames() {
|
||||
public void upperCamelCaseWithSerializedNames() {
|
||||
Json json = Guice.createInjector(new GsonModule(), new AbstractModule() {
|
||||
@Override protected void configure() {
|
||||
bind(FieldNamingPolicy.class).toInstance(FieldNamingPolicy.LOWER_CASE_WITH_DASHES);
|
||||
bind(FieldNamingPolicy.class).toInstance(FieldNamingPolicy.UPPER_CAMEL_CASE);
|
||||
}
|
||||
}).getInstance(Json.class);
|
||||
|
||||
SpinalCasedType resource = SpinalCasedType.create("1234", "application/json");
|
||||
String spinalJson = "{\"id\":\"1234\",\"content-type\":\"application/json\"}";
|
||||
UpperCamelCasedType resource = UpperCamelCasedType.create("1234", Collections.<String, String>emptyMap());
|
||||
String spinalJson = "{\"Id\":\"1234\",\"Volumes\":{}}";
|
||||
|
||||
assertEquals(json.toJson(resource), spinalJson);
|
||||
assertEquals(spinalJson, json.toJson(resource));
|
||||
assertEquals(json.fromJson(spinalJson, UpperCamelCasedType.class), resource);
|
||||
}
|
||||
|
||||
private static class SpinalCasedTypeImpl extends SpinalCasedType {
|
||||
private final String id;
|
||||
private final String contentType;
|
||||
public void upperCamelCaseWithSerializedNamesNullJsonValue() {
|
||||
Json json = Guice.createInjector(new GsonModule(), new AbstractModule() {
|
||||
@Override protected void configure() {
|
||||
bind(FieldNamingPolicy.class).toInstance(FieldNamingPolicy.UPPER_CAMEL_CASE);
|
||||
}
|
||||
}).getInstance(Json.class);
|
||||
|
||||
private SpinalCasedTypeImpl(String id, String contentType) {
|
||||
assertEquals(json.fromJson("{\"Id\":\"1234\",\"Volumes\":null}", UpperCamelCasedType.class),
|
||||
UpperCamelCasedType.create("1234", null));
|
||||
}
|
||||
|
||||
private static class UpperCamelCasedTypeImpl extends UpperCamelCasedType {
|
||||
private final String id;
|
||||
private final Map<String, String> volumes;
|
||||
|
||||
private UpperCamelCasedTypeImpl(String id, Map<String, String> volumes) {
|
||||
this.id = id;
|
||||
this.contentType = contentType;
|
||||
this.volumes = volumes;
|
||||
}
|
||||
|
||||
@Override String id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override String contentType() {
|
||||
return contentType;
|
||||
@Override @Nullable Map<String, String> volumes() {
|
||||
return volumes;
|
||||
}
|
||||
|
||||
@Override public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof SpinalCasedType) {
|
||||
SpinalCasedType that = (SpinalCasedType) o;
|
||||
return (this.id.equals(that.id())) && (this.contentType.equals(that.contentType()));
|
||||
if (o instanceof UpperCamelCasedType) {
|
||||
UpperCamelCasedType that = (UpperCamelCasedType) o;
|
||||
return Objects.equal(this.id, that.id()) && Objects.equal(this.volumes, that.volumes());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override public int hashCode() {
|
||||
int h = 1;
|
||||
h *= 1000003;
|
||||
h ^= id.hashCode();
|
||||
h *= 1000003;
|
||||
h ^= contentType.hashCode();
|
||||
return h;
|
||||
return Objects.hashCode(id, volumes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue