diff options
author | Gert Scholten <gscholt@gmail.com> | 2009-05-11 14:59:41 +0200 |
---|---|---|
committer | Gert Scholten <gscholt@gmail.com> | 2009-05-15 09:13:16 +0200 |
commit | dce37e430c0fa2bbff9e2370249236e14e4064ca (patch) | |
tree | 8a0d8075dec5832d8c0d249029cb6aac39cd3c7b | |
parent | 1dc19c55e05918cf82d88493dafc21b29a3ee7c2 (diff) | |
download | gwtjsonrpc-dce37e430c0fa2bbff9e2370249236e14e4064ca.tar.gz |
Added serialisation of (boxed)primitive arrays in method parameters
and object fields.
Signed-off-by: Gert Scholten <gscholt@gmail.com>
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); } |