From 74a16805c66e349aaff0960a4e7fdae7deb693f2 Mon Sep 17 00:00:00 2001 From: Manolo Carrasco Date: Sun, 18 Dec 2011 12:57:36 +0000 Subject: [PATCH] JsonBuilder: Support of java.util.List and java.util.Date types. Fix arrays of JsonBuilder objects, Fixes issue 117. Fix Properties toString methods when there are arrays of objects --- .../google/gwt/query/client/Properties.java | 19 ++++- .../client/builders/JsonBuilderBase.java | 17 +++- .../query/rebind/JsonBuilderGenerator.java | 77 +++++++++++++++---- .../gwt/query/client/GQueryAjaxTestGwt.java | 23 +++++- 4 files changed, 111 insertions(+), 25 deletions(-) diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java index f89a0128..d7f4d90b 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java @@ -141,11 +141,16 @@ public class Properties extends JavaScriptObject { for (String k : keys()){ String ky = k.matches("\\d+") ? k : "\"" + k + "\""; - JsArrayMixed o = getArray(k); + JsCache o = getArray(k).cast(); if (o != null) { ret += ky + ":["; for (int i = 0, l = o.length(); i < l ; i++) { - ret += "\"" + o.getString(i) + "\","; + Properties p = o.cast().getJavaScriptObject(i); + if (p != null) { + ret += p.toJsonString() + ","; + } else { + ret += "\"" + o.getString(i) + "\","; + } } ret += "],"; } else { @@ -166,10 +171,16 @@ public class Properties extends JavaScriptObject { String ret = ""; for (String k : keys()) { ret += ret.isEmpty() ? "" : "&"; - JsArrayMixed o = getArray(k); + JsCache o = getArray(k).cast(); if (o != null) { for (int i = 0, l = o.length(); i < l ; i++) { - ret += (i > 0 ? "&" : "") + k + "[]=" + o.getString(i) ; + ret += i > 0 ? "&" : ""; + Properties p = o.cast().getJavaScriptObject(i); + if (p != null) { + ret += k + "[]=" + p.toJsonString(); + } else { + ret += k + "[]=" + o.getString(i) ; + } } } else { Properties p = getJavaScriptObject(k); diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/builders/JsonBuilderBase.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/builders/JsonBuilderBase.java index ecd8e042..e8f23d4b 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/client/builders/JsonBuilderBase.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/builders/JsonBuilderBase.java @@ -16,6 +16,7 @@ package com.google.gwt.query.client.builders; import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; import com.google.gwt.query.client.Properties; import com.google.gwt.query.client.js.JsObjectArray; import com.google.gwt.query.client.js.JsUtils; @@ -44,11 +45,19 @@ public abstract class JsonBuilderBase> implements J } return (J)this; } - + protected void setArrayBase(String n, T[] r) { - JsObjectArray a = JsObjectArray.create(); - a.add(r); - p.set(n, a); + if (r.length > 0 && r[0] instanceof JsonBuilder) { + JsArray a = JavaScriptObject.createArray().cast(); + for (T o : r) { + a.push(((JsonBuilder)o).getProperties()); + } + p.set(n, a); + } else { + JsObjectArray a = JsObjectArray.create(); + a.add(r); + p.set(n, a); + } } @SuppressWarnings("unchecked") diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/JsonBuilderGenerator.java b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/JsonBuilderGenerator.java index 5b69a292..25a6899c 100644 --- a/gwtquery-core/src/main/java/com/google/gwt/query/rebind/JsonBuilderGenerator.java +++ b/gwtquery-core/src/main/java/com/google/gwt/query/rebind/JsonBuilderGenerator.java @@ -16,6 +16,7 @@ package com.google.gwt.query.rebind; import java.io.PrintWriter; +import java.util.List; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.ext.Generator; @@ -26,6 +27,7 @@ import com.google.gwt.core.ext.typeinfo.JArrayType; import com.google.gwt.core.ext.typeinfo.JClassType; import com.google.gwt.core.ext.typeinfo.JMethod; import com.google.gwt.core.ext.typeinfo.JParameter; +import com.google.gwt.core.ext.typeinfo.JParameterizedType; import com.google.gwt.core.ext.typeinfo.JType; import com.google.gwt.core.ext.typeinfo.TypeOracle; import com.google.gwt.query.client.Properties; @@ -41,6 +43,7 @@ public class JsonBuilderGenerator extends Generator { static JClassType jsonBuilderType; static JClassType stringType; static JClassType jsType; + static JClassType listType; public String generate(TreeLogger treeLogger, GeneratorContext generatorContext, String requestedClass) @@ -50,11 +53,12 @@ public class JsonBuilderGenerator extends Generator { jsonBuilderType = oracle.findType(JsonBuilder.class.getName()); stringType = oracle.findType(String.class.getName()); jsType = oracle.findType(JavaScriptObject.class.getName()); + listType = oracle.findType(List.class.getName()); String t[] = generateClassName(clazz); - SourceWriter sw = getSourceWriter(treeLogger, generatorContext, t[0], - t[1], requestedClass); + SourceWriter sw = getSourceWriter(treeLogger, generatorContext, t[0], t[1], + requestedClass); if (sw != null) { for (JMethod method : clazz.getMethods()) { generateMethod(sw, method, treeLogger); @@ -78,41 +82,71 @@ public class JsonBuilderGenerator extends Generator { return (c != null && c.isAssignableTo(o)); } + public static String capitalize(String s) { + if (s.length() == 0) + return s; + return s.substring(0, 1).toUpperCase() + s.substring(1).toLowerCase(); + } + public void generateMethod(SourceWriter sw, JMethod method, TreeLogger logger) throws UnableToCompleteException { Name nameAnnotation = method.getAnnotation(Name.class); String name = nameAnnotation != null ? nameAnnotation.value() - : method.getName().replaceFirst("^(get|set)", "").toLowerCase(); + : method.getName().replaceFirst("^(get|set)", ""); + name = name.substring(0, 1).toLowerCase() + name.substring(1); String retType = method.getReturnType().getParameterizedQualifiedSourceName(); - sw.print("public final " + retType + " " + method.getName()); JParameter[] params = method.getParameters(); if (params.length == 0) { JArrayType arr = method.getReturnType().isArray(); + JParameterizedType list = method.getReturnType().isParameterized(); + sw.println("() {"); sw.indent(); if (retType.matches("(java.lang.Boolean|boolean)")) { sw.println("return p.getBoolean(\"" + name + "\");"); + } else if (retType.matches("java.util.Date")) { + sw.println("return new Date((long)p.getFloat(\"" + name + "\"));"); } else if (method.getReturnType().isPrimitive() != null) { sw.println("return (" + retType + ")p.getFloat(\"" + name + "\");"); } else if (isTypeAssignableTo(method.getReturnType(), stringType)) { sw.println("return p.getStr(\"" + name + "\");"); } else if (isTypeAssignableTo(method.getReturnType(), jsonBuilderType)) { String q = method.getReturnType().getQualifiedSourceName(); - sw.println("return " + - "((" + q + ")GWT.create(" + q + ".class))" + - ".load(p.getJavaScriptObject(\"" + name + "\"));"); - } else if (retType.equals(Properties.class.getName())){ + sw.println("return " + "((" + q + ")GWT.create(" + q + ".class))" + + ".load(p.getJavaScriptObject(\"" + name + "\"));"); + } else if (retType.equals(Properties.class.getName())) { sw.println("return getPropertiesBase(\"" + name + "\");"); } else if (isTypeAssignableTo(method.getReturnType(), jsType)) { sw.println("return p.getJavaScriptObject(\"" + name + "\");"); - } else if (arr != null) { - String t = arr.getComponentType().getQualifiedSourceName(); + } else if (arr != null || list != null) { + JType type = arr != null ? arr.getComponentType() + : list.getTypeArgs()[0]; + boolean buildType = isTypeAssignableTo(type, jsonBuilderType); + String t = type.getQualifiedSourceName(); sw.println("JsArrayMixed a = p.getArray(\"" + name + "\");"); sw.println("int l = a == null ? 0 : a.length();"); - sw.println("return getArrayBase(\"" + name + "\", new " + t + "[l], " - + t + ".class);"); + String ret; + if (buildType) { + sw.println(t + "[] r = new " + t + "[l];"); + sw.println("JsObjectArray a1 = p.getArray(\"" + name + + "\").cast();"); + sw.println("int l1 = r.length;"); + sw.println("for (int i = 0 ; i < l1 ; i++) {"); + sw.println(" Object w = a1.get(i);"); + sw.println(" " + t + " instance = GWT.create(" + t + ".class);"); + sw.println(" r[i] = instance.load(w);"); + sw.println("}"); + ret = "r"; + } else { + ret = "getArrayBase(\"" + name + "\", new " + t + "[l], " + t+ ".class)"; + } + if (arr != null) { + sw.println("return " + ret + ";"); + } else { + sw.println("return Arrays.asList(" + ret + ");"); + } } else { sw.println("return null; // Unsupported return type: " + retType); } @@ -121,16 +155,25 @@ public class JsonBuilderGenerator extends Generator { } else if (params.length == 1) { JType type = params[0].getType(); JArrayType arr = type.isArray(); + JParameterizedType list = type.isParameterized(); sw.print("(" + type.getParameterizedQualifiedSourceName() + " a)"); sw.println("{"); sw.indent(); - if (arr != null) { - sw.println("setArrayBase(\"" + name + "\", a);"); + if (arr != null || list != null) { + String a = "a"; + if (list != null) { + a = "a.toArray(new " + list.getTypeArgs()[0].getQualifiedSourceName() + + "[0])"; + } + sw.println("setArrayBase(\"" + name + "\", " + a + ");"); + } else if (type.getParameterizedQualifiedSourceName().matches("java.util.Date")) { + sw.println("p.set(\"" + name + "\", a.getTime());"); } else { sw.println("p.set(\"" + name + "\", a);"); } - if (!"void".equals(retType)){ - if (isTypeAssignableTo(method.getReturnType(), method.getEnclosingType())) { + if (!"void".equals(retType)) { + if (isTypeAssignableTo(method.getReturnType(), + method.getEnclosingType())) { sw.println("return this;"); } else { sw.println("return null;"); @@ -156,6 +199,8 @@ public class JsonBuilderGenerator extends Generator { composerFactory.addImport("com.google.gwt.query.client.*"); composerFactory.addImport("com.google.gwt.core.client.*"); composerFactory.addImport("com.google.gwt.dom.client.*"); + composerFactory.addImport("java.util.*"); + for (String interfaceName : interfaceNames) { composerFactory.addImplementedInterface(interfaceName); } diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java index 231db889..5d3e8d68 100644 --- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java +++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java @@ -18,6 +18,10 @@ package com.google.gwt.query.client; import static com.google.gwt.query.client.GQuery.$; +import java.util.Arrays; +import java.util.Date; +import java.util.List; + import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Element; import com.google.gwt.junit.client.GWTTestCase; @@ -56,6 +60,11 @@ public class GQueryAjaxTestGwt extends GWTTestCase { } } + interface Item extends JsonBuilder { + Date getDate(); + void setDate(Date d); + } + interface JsonExample extends JsonBuilder { int getA(); JsonExample getB(); @@ -67,6 +76,8 @@ public class GQueryAjaxTestGwt extends GWTTestCase { JsonExample setT(String[] strings); JsonExample setZ(Boolean b); JsonExample setD(long l); + List getItems(); + void setItems(List a); } public void testJsonBuilder() { @@ -88,7 +99,17 @@ public class GQueryAjaxTestGwt extends GWTTestCase { assertEquals("foo", c.getT()[0]); assertEquals("bar", c.getT()[1]); assertEquals(1234l, c.getD()); - + + Item i1 = GWT.create(Item.class); + Item i2 = GWT.create(Item.class); + i1.setDate(new Date(2000)); + i2.setDate(new Date(3000)); + Item[] items = new Item[]{i1, i2}; + c.setItems(Arrays.asList(items)); + assertEquals(2000l, c.getItems().get(0).getDate().getTime()); + assertEquals(3000l, c.getItems().get(1).getDate().getTime()); + String s = "{\"a\":1,\"b\":{\"a\":2,\"b\":{\"a\":3}},\"u\":\"url\",\"d\":1234,\"t\":[\"foo\",\"bar\"],\"z\":false,\"items\":[{\"date\":2000},{\"date\":3000}]}"; + assertEquals(s, c.toString()); } interface XmlExample extends XmlBuilder { -- 2.39.5