Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,8 @@
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.function.Supplier;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Expand Down Expand Up @@ -191,12 +187,12 @@ public Entity read(JsonReader in) throws IOException {
// we're an adapter for. So if we have SoftLayer_Something and a newer release of the
// API has a type extending it but we don't have a generated class for it, it will get
// properly serialized to a SoftLayer_Something.
// If the API returns a type that isn't the same or a subtype of the type class,
// try as best we can to fit the data within the type class.
Class<? extends Entity> clazz = typeClasses.get(apiTypeName);
Entity result;
if (clazz == null) {
if (clazz == null || !typeClass.isAssignableFrom(clazz)) {
result = readForThisType(in);
} else if (!typeClass.isAssignableFrom(clazz)) {
throw new RuntimeException("Expecting " + typeClass + " to be super type of " + clazz);
} else {
result = ((EntityTypeAdapter) gson.getAdapter(clazz)).readForThisType(in);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.google.gson.reflect.TypeToken;
import com.softlayer.api.service.Entity;
import com.softlayer.api.service.TestEntity;
import com.softlayer.api.service.TestThing;

public class GsonJsonMarshallerFactoryTest {

Expand Down Expand Up @@ -51,21 +52,22 @@ private String toJson(Object obj) throws Exception {
public void testRead() throws Exception {
Entity entity = fromJson(Entity.class,
"{"
+ "\"complexType\": \"SoftLayer_TestEntity\","
+ "\"bar\": \"some string\","
+ "\"foo\": \"another string\","
+ "\"baz\": null,"
+ "\"date\": \"1984-02-25T20:15:25-06:00\","
+ "\"notApiProperty\": \"bad value\","
+ "\"child\": {"
+ " \"complexType\": \"SoftLayer_TestEntity\","
+ " \"bar\": \"child string\""
+ "},"
+ "\"moreChildren\": ["
+ " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 1\" },"
+ " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 2\" }"
+ "]"
+ "}");
+ "\"complexType\": \"SoftLayer_TestEntity\","
+ "\"bar\": \"some string\","
+ "\"foo\": \"another string\","
+ "\"baz\": null,"
+ "\"date\": \"1984-02-25T20:15:25-06:00\","
+ "\"notApiProperty\": \"bad value\","
+ "\"child\": {"
+ " \"complexType\": \"SoftLayer_TestEntity\","
+ " \"bar\": \"child string\""
+ "},"
+ "\"moreChildren\": ["
+ " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 1\" },"
+ " { \"complexType\": \"SoftLayer_TestEntity\", \"bar\": \"child 2\" }"
+ "],"
+ "\"testThing\": {\"complexType\": \"SoftLayer_TestThing\", \"id\": 123}"
+ "}");
assertEquals(TestEntity.class, entity.getClass());
TestEntity obj = (TestEntity) entity;
assertEquals("some string", obj.getFoo());
Expand All @@ -85,6 +87,69 @@ public void testRead() throws Exception {
assertEquals(2, obj.getMoreChildren().size());
assertEquals("child 1", obj.getMoreChildren().get(0).getFoo());
assertEquals("child 2", obj.getMoreChildren().get(1).getFoo());
assertEquals(TestThing.class, obj.getTestThing().getClass());
assertEquals(123, obj.getTestThing().getId().intValue());
}

@Test
public void testReadPropertyWithIncorrectComplexTypeCoercesTheType() throws Exception {
Entity entity = fromJson(Entity.class,
"{"
+ "\"complexType\": \"SoftLayer_TestEntity\","
+ "\"testThing\": {\"complexType\": \"SoftLayer_TestEntity\", \"id\": 123, \"foo\": \"unknown!\"}"
+ "}");
assertEquals(TestEntity.class, entity.getClass());
TestEntity obj = (TestEntity) entity;
assertEquals(0, obj.getUnknownProperties().size());
assertEquals(TestThing.class, obj.getTestThing().getClass());
assertEquals(123, obj.getTestThing().getId().intValue());
assertEquals(1, obj.getTestThing().getUnknownProperties().size());
assertEquals("unknown!", obj.getTestThing().getUnknownProperties().get("foo"));
}


@Test
public void testReadPropertyWithUnknownComplexTypeCoercesTheType() throws Exception {
Entity entity = fromJson(Entity.class,
"{"
+ "\"complexType\": \"SoftLayer_TestEntity\","
+ "\"testThing\": {\"complexType\": \"WhoKnows\", \"id\": 123, \"foo\": \"unknown!\"}"
+ "}");
assertEquals(TestEntity.class, entity.getClass());
TestEntity obj = (TestEntity) entity;
assertEquals(0, obj.getUnknownProperties().size());
assertEquals(TestThing.class, obj.getTestThing().getClass());
assertEquals(123, obj.getTestThing().getId().intValue());
assertEquals(1, obj.getTestThing().getUnknownProperties().size());
assertEquals("unknown!", obj.getTestThing().getUnknownProperties().get("foo"));
}

@Test
public void testReadPropertyThrowsExceptionWithoutComplexType() {

Exception e = assertThrows(RuntimeException.class, () -> {
Entity entity = fromJson(Entity.class,
"{"
+ "\"complexType\": \"SoftLayer_TestEntity\","
+ "\"testThing\": {\"id\": 123}"
+ "}");
});

assertEquals("Expected 'complexType' as first property", e.getMessage());
}

@Test
public void testReadPropertyThrowsExceptioWithComplexTypeNotFirst() {

Exception e = assertThrows(RuntimeException.class, () -> {
Entity entity = fromJson(Entity.class,
"{"
+ "\"testThing\": {\"id\": 123},"
+ "\"complexType\": \"SoftLayer_TestEntity\""
+ "}");
});

assertEquals("Expected 'complexType' as first property", e.getMessage());
}

@Test
Expand Down
1 change: 0 additions & 1 deletion src/test/java/com/softlayer/api/service/TestEntity.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import com.softlayer.api.annotation.ApiType;
import com.softlayer.api.ApiClient;
import com.softlayer.api.ResponseHandler;
import com.softlayer.api.ResultLimit;

@ApiType("SoftLayer_TestEntity")
public class TestEntity extends Entity {
Expand Down
2 changes: 2 additions & 0 deletions src/test/java/com/softlayer/api/service/TestThing.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import com.softlayer.api.annotation.ApiMethod;
import com.softlayer.api.annotation.ApiProperty;
import com.softlayer.api.annotation.ApiService;
import com.softlayer.api.annotation.ApiType;

@ApiType("SoftLayer_TestThing")
public class TestThing extends Entity {

@ApiProperty(canBeNullOrNotSet = true)
Expand Down