diff options
author | Leif Åstrand <leif@vaadin.com> | 2015-01-10 12:56:52 +0200 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-01-12 08:46:08 +0000 |
commit | 35d91245de3218283c8f4c733a3aa72ea395fb1c (patch) | |
tree | 7b4fb520d6a733403ed9a335d0442a64cf646be6 | |
parent | 28dbd0c0dad3491d1f4d405e753075df983ecacc (diff) | |
download | vaadin-framework-35d91245de3218283c8f4c733a3aa72ea395fb1c.tar.gz vaadin-framework-35d91245de3218283c8f4c733a3aa72ea395fb1c.zip |
Support JsonValue types as declared types in state and RPC (#15560)
Change-Id: I2779a533811bb1b60c4e74789f6378574bc6ac61
8 files changed, 104 insertions, 6 deletions
diff --git a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java index 13bd7051f6..f946d87638 100644 --- a/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java +++ b/client-compiler/src/com/vaadin/server/widgetsetutils/ConnectorBundleLoaderFactory.java @@ -47,6 +47,7 @@ import com.google.gwt.user.rebind.SourceWriter; import com.vaadin.client.JsArrayObject; import com.vaadin.client.ServerConnector; import com.vaadin.client.annotations.OnStateChange; +import com.vaadin.client.communication.JsonDecoder; import com.vaadin.client.metadata.ConnectorBundleLoader; import com.vaadin.client.metadata.ConnectorBundleLoader.CValUiInfo; import com.vaadin.client.metadata.InvokationHandler; @@ -1011,7 +1012,16 @@ public class ConnectorBundleLoaderFactory extends Generator { w.print(", "); } String parameterTypeName = getBoxedTypeName(parameterType); - w.print("(" + parameterTypeName + ") params[" + i + "]"); + + if (parameterTypeName.startsWith("elemental.json.Json")) { + // Need to pass through native method to allow casting Object to + // JSO if the value is a string + w.print("%s.<%s>obj2jso(params[%d])", + JsonDecoder.class.getCanonicalName(), + parameterTypeName, i); + } else { + w.print("(" + parameterTypeName + ") params[" + i + "]"); + } } w.println(");"); diff --git a/client/src/com/vaadin/client/communication/JsonDecoder.java b/client/src/com/vaadin/client/communication/JsonDecoder.java index a8adbac0c6..0ce89c873e 100644 --- a/client/src/com/vaadin/client/communication/JsonDecoder.java +++ b/client/src/com/vaadin/client/communication/JsonDecoder.java @@ -82,13 +82,16 @@ public class JsonDecoder { */ public static Object decodeValue(Type type, JsonValue jsonValue, Object target, ApplicationConnection connection) { + String baseTypeName = type.getBaseTypeName(); + if (baseTypeName.startsWith("elemental.json.Json")) { + return jsonValue; + } - // Null is null, regardless of type + // Null is null, regardless of type (except JSON) if (jsonValue.getType() == JsonType.NULL) { return null; } - String baseTypeName = type.getBaseTypeName(); if (Map.class.getName().equals(baseTypeName) || HashMap.class.getName().equals(baseTypeName)) { return decodeMap(type, jsonValue, connection); @@ -293,4 +296,14 @@ public class JsonDecoder { tokens.add(decodeValue(childType, entryValue, null, connection)); } } + + /** + * Called by generated deserialization code to treat a generic object as a + * JsonValue. This is needed because GWT refuses to directly cast String + * typed as Object into a JSO. + */ + public static native <T extends JsonValue> T obj2jso(Object object) + /*-{ + return object; + }-*/; } diff --git a/server/src/com/vaadin/server/JsonCodec.java b/server/src/com/vaadin/server/JsonCodec.java index 1f7b4ead43..ec1ea10f2b 100644 --- a/server/src/com/vaadin/server/JsonCodec.java +++ b/server/src/com/vaadin/server/JsonCodec.java @@ -300,7 +300,9 @@ public class JsonCodec implements Serializable { } // Try to decode object using fields - if (value.getType() == JsonType.NULL) { + if (isJsonType(targetType)) { + return value; + } else if (value.getType() == JsonType.NULL) { return null; } else if (targetType == byte.class || targetType == Byte.class) { return Byte.valueOf((byte) value.asNumber()); @@ -334,6 +336,11 @@ public class JsonCodec implements Serializable { } } + private static boolean isJsonType(Type type) { + return type instanceof Class<?> + && JsonValue.class.isAssignableFrom((Class<?>) type); + } + private static Object decodeArray(Type componentType, JsonArray value, ConnectorTracker connectorTracker) { Class<?> componentClass = getClassForType(componentType); diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java index 333964e9bf..df37601f23 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTest.java @@ -42,10 +42,14 @@ import com.vaadin.tests.widgetset.client.SerializerTestState; import com.vaadin.tests.widgetset.client.SimpleTestBean; import com.vaadin.tests.widgetset.server.SerializerTestExtension; +import elemental.json.Json; +import elemental.json.JsonString; +import elemental.json.JsonValue; + @Widgetset("com.vaadin.tests.widgetset.TestingWidgetSet") public class SerializerTest extends AbstractTestUI { - private Log log = new Log(40); + private Log log = new Log(45); @Override protected void setup(VaadinRequest request) { @@ -256,6 +260,12 @@ public class SerializerTest extends AbstractTestUI { rpc.sendDate(new Date(1)); rpc.sendDate(new Date(2013 - 1900, 5 - 1, 31, 11, 12, 13)); + + state.jsonNull = Json.createNull(); + state.jsonString = Json.create("a string"); + state.jsonBoolean = Json.create(false); + rpc.sendJson(Json.create(true), Json.createNull(), Json.create("JSON")); + state.date1 = new Date(1); state.date2 = new Date(2013 - 1900, 5 - 1, 31, 11, 12, 13); @@ -448,6 +458,13 @@ public class SerializerTest extends AbstractTestUI { } @Override + public void sendJson(JsonValue value1, JsonValue value2, + JsonString string) { + log.log("sendJson: " + value1.toJson() + ", " + value2.toJson() + + ", " + string.toJson()); + } + + @Override public void log(String string) { log.log(string); @@ -458,7 +475,7 @@ public class SerializerTest extends AbstractTestUI { @Override protected String getTestDescription() { - return "Test for lots of different cases of encoding and decoding variuos data types"; + return "Test for lots of different cases of encoding and decoding various data types"; } @Override diff --git a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java index dcba561599..a5216546b3 100644 --- a/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java +++ b/uitest/src/com/vaadin/tests/serialization/SerializerTestTest.java @@ -27,6 +27,9 @@ public class SerializerTestTest extends MultiBrowserTest { openTestURL(); int logRow = 0; + Assert.assertEquals( + "sendJson: {\"b\":false,\"s\":\"JSON\"}, null, \"value\"", + getLogRow(logRow++)); Assert.assertEquals("sendDate: May 31, 2013 8:12:13 AM UTC", getLogRow(logRow++)); Assert.assertEquals("sendDate: January 1, 1970 12:00:00 AM UTC", @@ -77,6 +80,9 @@ public class SerializerTestTest extends MultiBrowserTest { "sendBoolean: false, false, [false, false, true, false, true, true]", getLogRow(logRow++)); Assert.assertEquals("sendBeanSubclass: 43", getLogRow(logRow++)); + Assert.assertEquals("state.jsonBoolean: false", getLogRow(logRow++)); + Assert.assertEquals("state.jsonString: a string", getLogRow(logRow++)); + Assert.assertEquals("state.jsonNull: NULL", getLogRow(logRow++)); Assert.assertEquals( "state.doubleArray: [1.7976931348623157e+308, 5e-324]", getLogRow(logRow++)); diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java index 7758cdc2ac..07acd3d021 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestConnector.java @@ -35,6 +35,13 @@ import com.vaadin.shared.ui.Connect; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.tests.widgetset.server.SerializerTestExtension; +import elemental.json.Json; +import elemental.json.JsonBoolean; +import elemental.json.JsonObject; +import elemental.json.JsonString; +import elemental.json.JsonType; +import elemental.json.JsonValue; + @Connect(SerializerTestExtension.class) public class SerializerTestConnector extends AbstractExtensionConnector { @@ -259,6 +266,27 @@ public class SerializerTestConnector extends AbstractExtensionConnector { } @Override + public void sendJson(JsonValue value1, JsonValue value2, + JsonString string) { + if (value1.getType() != JsonType.BOOLEAN) { + throw new RuntimeException("Expected boolean, got " + + value1.toJson()); + } + + if (value2.getType() != JsonType.NULL) { + throw new RuntimeException("Expected null, got " + + value2.toJson()); + } + + JsonObject returnObject = Json.createObject(); + returnObject.put("b", !((JsonBoolean) value1).asBoolean()); + returnObject.put("s", string); + + rpc.sendJson(returnObject, Json.createNull(), + Json.create("value")); + } + + @Override public void log(String message) { // Do nothing, used only in the other direction } @@ -311,6 +339,11 @@ public class SerializerTestConnector extends AbstractExtensionConnector { rpc.log("state.doubleObjectValue: " + getState().doubleObjectValue); rpc.log("state.doubleArray: " + Arrays.toString(getState().doubleArray)); + rpc.log("state.jsonNull: " + getState().jsonNull.getType().name()); + rpc.log("state.jsonString: " + + ((JsonString) getState().jsonString).getString()); + rpc.log("state.jsonBoolean: " + getState().jsonBoolean.getBoolean()); + /* * TODO public double doubleValue; public Double DoubleValue; public * double[] doubleArray; ; diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java index 6b4c4e7ac1..4baebc819e 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestRpc.java @@ -26,6 +26,9 @@ import com.vaadin.shared.communication.ClientRpc; import com.vaadin.shared.communication.ServerRpc; import com.vaadin.shared.ui.label.ContentMode; +import elemental.json.JsonString; +import elemental.json.JsonValue; + @SuppressWarnings("javadoc") public interface SerializerTestRpc extends ServerRpc, ClientRpc { public void sendBoolean(boolean value, Boolean boxedValue, boolean[] array); @@ -82,5 +85,7 @@ public interface SerializerTestRpc extends ServerRpc, ClientRpc { public void sendDate(Date date); + public void sendJson(JsonValue value1, JsonValue value2, JsonString string); + public void log(String string); } diff --git a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java index faf41fbf88..31ff58971f 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/SerializerTestState.java @@ -24,6 +24,9 @@ import com.vaadin.shared.AbstractComponentState; import com.vaadin.shared.Connector; import com.vaadin.shared.ui.label.ContentMode; +import elemental.json.JsonBoolean; +import elemental.json.JsonValue; + public class SerializerTestState extends AbstractComponentState { public boolean booleanValue; @@ -99,4 +102,8 @@ public class SerializerTestState extends AbstractComponentState { public BeanWithAbstractSuperclass beanWithAbstractSuperclass; + public JsonValue jsonNull = null; + public JsonValue jsonString = null; + public JsonBoolean jsonBoolean = null; + } |