aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert Scholten <gscholt@gmail.com>2009-05-11 14:59:41 +0200
committerGert Scholten <gscholt@gmail.com>2009-05-15 09:13:16 +0200
commitdce37e430c0fa2bbff9e2370249236e14e4064ca (patch)
tree8a0d8075dec5832d8c0d249029cb6aac39cd3c7b
parent1dc19c55e05918cf82d88493dafc21b29a3ee7c2 (diff)
downloadgwtjsonrpc-dce37e430c0fa2bbff9e2370249236e14e4064ca.tar.gz
Added serialisation of (boxed)primitive arrays in method parameters
and object fields. Signed-off-by: Gert Scholten <gscholt@gmail.com>
-rw-r--r--src/main/java/com/google/gwtjsonrpc/client/PrimitiveArraySerializer.java267
-rw-r--r--src/main/java/com/google/gwtjsonrpc/rebind/ProxyCreator.java5
-rw-r--r--src/main/java/com/google/gwtjsonrpc/rebind/SerializerCreator.java40
3 files changed, 301 insertions, 11 deletions
diff --git a/src/main/java/com/google/gwtjsonrpc/client/PrimitiveArraySerializer.java b/src/main/java/com/google/gwtjsonrpc/client/PrimitiveArraySerializer.java
new file mode 100644
index 0000000..5775094
--- /dev/null
+++ b/src/main/java/com/google/gwtjsonrpc/client/PrimitiveArraySerializer.java
@@ -0,0 +1,267 @@
+// Copyright 2009 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gwtjsonrpc.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+public class PrimitiveArraySerializer {
+ public static final PrimitiveArraySerializer INSTANCE =
+ new PrimitiveArraySerializer();
+
+ private void printJsonWithToString(final StringBuilder sb, final Object[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i] != null ? o[i].toString() : JsonSerializer.JS_NULL);
+ }
+ sb.append(']');
+ }
+
+ // Serialisation of Boxed Primitives
+ public void printJson(final StringBuilder sb, final Boolean[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ public void printJson(final StringBuilder sb, final Byte[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ public void printJson(final StringBuilder sb, final Character[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ if (o[i] != null) {
+ sb.append('"');
+ sb.append(JsonSerializer.escapeChar(o[i]));
+ sb.append('"');
+ } else
+ sb.append(JsonSerializer.JS_NULL);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final Double[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ public void printJson(final StringBuilder sb, final Float[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ public void printJson(final StringBuilder sb, final Integer[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ public void printJson(final StringBuilder sb, final Short[] o) {
+ printJsonWithToString(sb, o);
+ }
+
+ // Serialisation of Primitives
+ public void printJson(final StringBuilder sb, final boolean[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final byte[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final char[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final double[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final float[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final int[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ public void printJson(final StringBuilder sb, final short[] o) {
+ sb.append('[');
+ for (int i = 0, n = o.length; i < n; i++) {
+ if (i > 0) {
+ sb.append(',');
+ }
+ sb.append(o[i]);
+ }
+ sb.append(']');
+ }
+
+ // DeSerialisation native getters
+ private static final native boolean getBoolean(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native byte getByte(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native String getString(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native double getDouble(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native float getFloat(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native int getInteger(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ private static final native short getShort(JavaScriptObject jso, int pos) /*-{
+ return jso[pos];
+ }-*/;
+
+ // DeSerialisation of boxed primitive arrays
+ public void fromJson(final JavaScriptObject jso, final Boolean[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getBoolean(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Byte[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getByte(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Character[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = JsonSerializer.toChar(getString(jso, i));
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Double[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getDouble(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Float[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getFloat(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Integer[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getInteger(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final Short[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getShort(jso, i);
+ }
+ }
+
+ // DeSerialisation of primitive arrays
+ public void fromJson(final JavaScriptObject jso, final boolean[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getBoolean(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final byte[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getByte(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final char[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = JsonSerializer.toChar(getString(jso, i));
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final double[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getDouble(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final float[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getFloat(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final int[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getInteger(jso, i);
+ }
+ }
+
+ public void fromJson(final JavaScriptObject jso, final short[] r) {
+ for (int i = 0; i < r.length; i++) {
+ r[i] = getShort(jso, i);
+ }
+ }
+}
diff --git a/src/main/java/com/google/gwtjsonrpc/rebind/ProxyCreator.java b/src/main/java/com/google/gwtjsonrpc/rebind/ProxyCreator.java
index e6fbd51..16b1f23 100644
--- a/src/main/java/com/google/gwtjsonrpc/rebind/ProxyCreator.java
+++ b/src/main/java/com/google/gwtjsonrpc/rebind/ProxyCreator.java
@@ -215,7 +215,10 @@ class ProxyCreator {
if (SerializerCreator.needsTypeParameter(pType)) {
serializerFields[i] = "serializer_" + instanceField++;
w.print("private static final ");
- w.print(JsonSerializer.class.getName());
+ if (pType.isArray() != null)
+ w.print(serializerCreator.serializerFor(pType));
+ else
+ w.print(JsonSerializer.class.getName());
w.print(" ");
w.print(serializerFields[i]);
w.print(" = ");
diff --git a/src/main/java/com/google/gwtjsonrpc/rebind/SerializerCreator.java b/src/main/java/com/google/gwtjsonrpc/rebind/SerializerCreator.java
index bae1033..8e1360a 100644
--- a/src/main/java/com/google/gwtjsonrpc/rebind/SerializerCreator.java
+++ b/src/main/java/com/google/gwtjsonrpc/rebind/SerializerCreator.java
@@ -35,6 +35,7 @@ import com.google.gwtjsonrpc.client.ListSerializer;
import com.google.gwtjsonrpc.client.ObjectArraySerializer;
import com.google.gwtjsonrpc.client.ObjectMapSerializer;
import com.google.gwtjsonrpc.client.ObjectSerializer;
+import com.google.gwtjsonrpc.client.PrimitiveArraySerializer;
import com.google.gwtjsonrpc.client.SetSerializer;
import com.google.gwtjsonrpc.client.StringMapSerializer;
@@ -192,10 +193,16 @@ class SerializerCreator {
}
if (type.isArray() != null) {
- if (type.isArray().getComponentType().isPrimitive() != null) {
- logger.log(TreeLogger.ERROR,
- "Primitive array not supported in JSON encoding", null);
- throw new UnableToCompleteException();
+ final JType leafType = type.isArray().getLeafType();
+ if (leafType.isPrimitive() != null || isBoxedPrimitive(leafType)) {
+ if (type.isArray().getRank() != 1) {
+ logger.log(TreeLogger.ERROR, "gwtjsonrpc does not support "
+ + "(de)serializing of multi-dimensional arrays of primitves");
+ // To work around this, we would need to generate serializers for
+ // them, this can be considered a todo
+ throw new UnableToCompleteException();
+ } else // Rank 1 arrays work fine.
+ return;
}
checkCanSerialize(logger, type.isArray().getComponentType());
return;
@@ -240,8 +247,13 @@ class SerializerCreator {
String serializerFor(final JType t) {
if (t.isArray() != null) {
- return ObjectArraySerializer.class.getCanonicalName() + "<"
- + t.isArray().getComponentType().getQualifiedSourceName() + ">";
+ final JType componentType = t.isArray().getComponentType();
+ if (componentType.isPrimitive() != null
+ || isBoxedPrimitive(componentType))
+ return PrimitiveArraySerializer.class.getCanonicalName();
+ else
+ return ObjectArraySerializer.class.getCanonicalName() + "<"
+ + componentType.getQualifiedSourceName() + ">";
}
if (isStringMap(t)) {
@@ -298,9 +310,16 @@ class SerializerCreator {
void generateSerializerReference(final JType type, final SourceWriter w) {
if (type.isArray() != null) {
- w.print("new " + serializerFor(type) + "(");
- generateSerializerReference(type.isArray().getComponentType(), w);
- w.print(")");
+ final JType componentType = type.isArray().getComponentType();
+ if (componentType.isPrimitive() != null
+ || isBoxedPrimitive(componentType)) {
+ w.print(PrimitiveArraySerializer.class.getCanonicalName());
+ w.print(".INSTANCE");
+ } else {
+ w.print("new " + serializerFor(type) + "(");
+ generateSerializerReference(componentType, w);
+ w.print(")");
+ }
} else if (type.isParameterized() != null) {
w.print("new " + serializerFor(type) + "(");
@@ -666,7 +685,8 @@ class SerializerCreator {
cf.setSuperclass(getSerializerQualifiedName(targetType.getSuperclass()));
} else {
cf.addImport(ObjectSerializer.class.getCanonicalName());
- cf.setSuperclass(ObjectSerializer.class.getSimpleName());
+ cf.setSuperclass(ObjectSerializer.class.getSimpleName() + "<"
+ + targetType.getQualifiedSourceName() + ">");
}
return cf.createSourceWriter(ctx, pw);
}