]> source.dussan.org Git - gwtquery.git/commitdiff
Replace org.json by elemental.json
authorManolo Carrasco <manolo@apache.org>
Sun, 26 Oct 2014 18:35:56 +0000 (19:35 +0100)
committerManolo Carrasco <manolo@apache.org>
Sun, 26 Oct 2014 22:50:35 +0000 (23:50 +0100)
Include only the elemental.json stuff for JVM needed to run
GQuery JsonBuilders in server side without depending on anything but
gwtquery.jar.

gwtquery-core/pom.xml
gwtquery-core/src/main/java/com/google/gwt/query/vm/JsonFactoryJre.java
gwtquery-core/src/test/java/com/google/gwt/query/client/ajax/AjaxTestJre.java
gwtquery-core/src/test/java/com/google/gwt/query/client/dbinding/DataBindingTestJre.java

index 04286df6538765809608ba34280eb41e28618042..111662cf3bb5f09b1106e040038f91ae8e0902dc 100644 (file)
             <version>${gwtversion}</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>com.google.gwt</groupId>
+            <artifactId>gwt-elemental</artifactId>
+            <version>${gwtversion}</version>
+        </dependency>
         <dependency>
           <groupId>javax.validation</groupId>
           <artifactId>validation-api</artifactId>
           <classifier>sources</classifier>
           <scope>provided</scope>
         </dependency>
-        <!-- needed in server side if we don't include gwt-servlet
-             we will remove this when using elemental.json or android.json -->
-        <dependency>
-          <groupId>org.json</groupId>
-          <artifactId>json</artifactId>
-          <version>20140107</version>
-        </dependency>
     </dependencies>
     <build>
         <resources>
@@ -58,6 +56,9 @@
             <resource>
                 <directory>${basedir}/src/main/super</directory>
             </resource>
+            <resource>
+                <directory>${project.build.directory}/generated-resources</directory>
+            </resource>
         </resources>
         <testResources>
             <testResource>
                   <includes>**/GQueryGwtSuiteTest.java</includes>
               </configuration>
             </plugin>
+            <!-- We include elemental json implementation for JVM so as people
+                 using GQuery json builders and ajax in server side don't have
+                 to include that dependency -->
+            <plugin>
+              <artifactId>maven-dependency-plugin</artifactId>
+              <executions>
+                <execution>
+                  <goals>
+                    <goal>unpack-dependencies</goal>
+                  </goals>
+                  <phase>generate-resources</phase>
+                  <configuration>
+                    <includeGroupIds>com.google.gwt</includeGroupIds>
+                    <includeArtifactIds>gwt-elemental</includeArtifactIds>
+                    <excludeTransitive>true</excludeTransitive>
+                    <includes>elemental/json/**/*</includes>
+                    <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
+                  </configuration>
+                </execution>
+              </executions>
+            </plugin>
 
         </plugins>
     </build>
-
 </project>
index 775a789f8754e89c29083f0f75122063e9fbe3da..7bd8c792bd95462ff00a3f3eff3706c70fe24b95 100644 (file)
@@ -1,5 +1,13 @@
 package com.google.gwt.query.vm;
 
+import com.google.gwt.query.client.Function;
+import com.google.gwt.query.client.IsProperties;
+import com.google.gwt.query.client.Properties;
+import com.google.gwt.query.client.builders.JsonBuilder;
+import com.google.gwt.query.client.builders.JsonFactory;
+import com.google.gwt.query.client.builders.Name;
+import com.google.gwt.query.rebind.JsonBuilderGenerator;
+
 import java.lang.reflect.Array;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -10,39 +18,63 @@ import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import com.google.gwt.query.client.IsProperties;
-import com.google.gwt.query.client.Function;
-import com.google.gwt.query.client.Properties;
-import com.google.gwt.query.client.builders.JsonBuilder;
-import com.google.gwt.query.client.builders.JsonFactory;
-import com.google.gwt.query.client.builders.Name;
-import com.google.gwt.query.rebind.JsonBuilderGenerator;
+import elemental.json.Json;
+import elemental.json.JsonArray;
+import elemental.json.JsonBoolean;
+import elemental.json.JsonNull;
+import elemental.json.JsonNumber;
+import elemental.json.JsonObject;
+import elemental.json.JsonString;
+import elemental.json.JsonValue;
+import elemental.json.impl.JreJsonNull;
 
+/**
+ * Factory class to create JsonBuilders in the JVM.
+ *
+ * It uses java.util.reflect.Proxy to implement JsonBuilders
+ * and elemental light weight json to handle json data.
+ */
 public class JsonFactoryJre implements JsonFactory  {
 
   static JsonFactoryJre jsonFactory = new JsonFactoryJre();
 
+  /**
+   * Although functions cannot be serialized to json we use JsonBuilders
+   * or IsProperties objects which can be used as settings in Ajax.
+   * Since Ajax and Promises are server side compatible, we need to handle
+   * Functions in JVM.
+   */
+  static class JreJsonFunction extends JreJsonNull {
+    final private Function function;
+    public JreJsonFunction(Function f) {
+      function = f;
+    }
+    @Override
+    public String toJson() {
+      return function.toString();
+    }
+    public Function getFunction() {
+      return function;
+    }
+  }
+
   public static class JsonBuilderHandler implements InvocationHandler {
-    private JSONObject jsonObject;
+    private JsonObject jsonObject;
 
     public JsonBuilderHandler() {
-      jsonObject = new JSONObject();
+      jsonObject = Json.createObject();
     }
 
-    public JsonBuilderHandler(JSONObject j) {
+    public JsonBuilderHandler(JsonObject j) {
        jsonObject = j;
     }
 
     public JsonBuilderHandler(String payload) throws Throwable {
-      jsonObject = new JSONObject(payload);
+      jsonObject = Json.parse(payload);
     }
 
     @SuppressWarnings("unchecked")
-    private <T> Object jsonArrayToList(JSONArray j, Class<T> ctype, boolean isArray) {
+    private <T> Object jsonArrayToList(JsonArray j, Class<T> ctype, boolean isArray) {
       List<T> l = new ArrayList<T>();
       for (int i = 0; j != null && i < j.length() ; i++) {
         l.add((T)getValue(j, i, null, null, ctype, null));
@@ -50,109 +82,110 @@ public class JsonFactoryJre implements JsonFactory  {
       return l.isEmpty() ? null : isArray ? l.toArray((T[])Array.newInstance(ctype, l.size())) : l;
     }
 
-    private Object getValue(JSONArray arr, int idx, JSONObject obj, String attr, Class<?> clz, Method method) {
-      Object ret = null;
+    private Double toDouble(String attr, JsonArray arr, int idx, JsonObject obj) {
       try {
-        if (clz.isArray() || clz.equals(List.class)) {
-          Class<?> ctype = Object.class;
-          if (clz.isArray()) {
-            ctype = clz.getComponentType();
-          } else {
-            Type returnType = method.getGenericReturnType();
-            if (returnType instanceof ParameterizedType) {
-              ctype = (Class<?>)((ParameterizedType) returnType).getActualTypeArguments()[0];
-            }
-          }
-          ret = jsonArrayToList(obj.getJSONArray(attr), ctype, clz.isArray());
-        } else if (clz.equals(Date.class)) {
-          ret = new Date(obj != null ? obj.getLong(attr): arr.getLong(idx));
-        } else if (clz.equals(Boolean.class) || clz.isPrimitive() && clz == Boolean.TYPE) {
-          try {
-            ret = obj != null ? obj.getBoolean(attr): arr.getBoolean(idx);
-          } catch (Exception e) {
-            return Boolean.FALSE;
-          }
-        } else if (clz.equals(Byte.class) || clz.equals(Short.class) || clz.equals(Integer.class)
-            || clz.isPrimitive() && (clz == Byte.TYPE || clz == Short.TYPE || clz == Integer.TYPE)) {
-          try {
-            ret = obj != null ? obj.getInt(attr): arr.getInt(idx);
-          } catch (Exception e) {
-            return 0;
-          }
-        } else if (clz.equals(Double.class) || clz.equals(Float.class)
-            || clz.isPrimitive() && (clz == Double.TYPE || clz == Float.TYPE)) {
-          try {
-            ret = obj != null ? obj.getDouble(attr): arr.getDouble(idx);
-          } catch (Exception e) {
-            return .0;
-          }
-        } else if (clz.equals(Long.class)
-            || clz.isPrimitive() && clz == Long.TYPE) {
-          try {
-            ret = obj != null ? obj.getLong(attr): arr.getLong(idx);
-          } catch (Exception e) {
-            return 0l;
-          }
+        return obj != null ? obj.getNumber(attr) : arr.getNumber(idx);
+      } catch (Exception e) {
+        return Double.valueOf(0d);
+      }
+    }
+
+    private Object getValue(JsonArray arr, int idx, JsonObject obj, String attr, Class<?> clz, Method method) {
+     if (clz.equals(Boolean.class) || clz == Boolean.TYPE) {
+        try {
+          return obj != null ? obj.getBoolean(attr): arr.getBoolean(idx);
+        } catch (Exception e) {
+          return Boolean.FALSE;
+        }
+      } else if (clz.equals(Date.class)) {
+        return new Date((long)(obj != null ? obj.getNumber(attr): arr.getNumber(idx)));
+      } else if (clz.equals(Byte.class) || clz == Byte.TYPE) {
+        return toDouble(attr, arr, idx, obj).byteValue();
+      } else if (clz.equals(Short.class) || clz == Short.TYPE) {
+        return toDouble(attr, arr, idx, obj).shortValue();
+      } else if (clz.equals(Integer.class) || clz == Integer.TYPE) {
+        return toDouble(attr, arr, idx, obj).intValue();
+      } else if (clz.equals(Double.class) || clz == Double.TYPE) {
+        return toDouble(attr, arr, idx, obj);
+      } else if (clz.equals(Float.class) || clz == Float.TYPE) {
+        return toDouble(attr, arr, idx, obj).floatValue();
+      } else if (clz.equals(Long.class) || clz == Long.TYPE) {
+        return toDouble(attr, arr, idx, obj).longValue();
+      }
+
+      Object ret = obj != null ? obj.get(attr): arr.get(idx);
+      if (ret instanceof JreJsonFunction || clz.equals(Function.class)) {
+        return ret != null && ret instanceof JreJsonFunction ? ((JreJsonFunction)ret).getFunction() : null;
+      } else if (ret instanceof JsonNull) {
+        return null;
+      } else if (ret instanceof JsonString) {
+        return ((JsonString)ret).asString();
+      } else if (ret instanceof JsonBoolean) {
+        return ((JsonBoolean)ret).asBoolean();
+      } else if (ret instanceof JsonNumber) {
+        return toDouble(attr, arr, idx, obj);
+      } else if (ret instanceof JsonArray || clz.isArray() || clz.equals(List.class)) {
+        Class<?> ctype = Object.class;
+        if (clz.isArray()) {
+          ctype = clz.getComponentType();
         } else {
-          ret = obj != null ? obj.get(attr): arr.get(idx);
-          if (ret == JSONObject.NULL ) {
-            // org.json returns an Null object instead of null when parsing.
-            ret = null;
-          } else if (clz.equals(String.class)) {
-            ret = String.valueOf(ret);
-          } else if (ret instanceof JSONObject) {
-            if (clz == Object.class) {
-              ret = jsonFactory.createBinder((JSONObject)ret);
-            } else if (IsProperties.class.isAssignableFrom(clz) && !clz.isAssignableFrom(ret.getClass())) {
-              ret = jsonFactory.create(clz, (JSONObject)ret);
-            }
-          } else if (ret instanceof Number) {
-            // Javascript always returns a double
-            ret = Double.valueOf(((Number) ret).doubleValue());
+          Type returnType = method.getGenericReturnType();
+          if (returnType instanceof ParameterizedType) {
+            ctype = (Class<?>)((ParameterizedType) returnType).getActualTypeArguments()[0];
           }
         }
-      } catch (JSONException e) {
+        return jsonArrayToList(obj.getArray(attr), ctype, clz.isArray());
+      } else if (ret instanceof JsonObject) {
+        if (clz == Object.class) {
+          return jsonFactory.createBinder((JsonObject)ret);
+        } else if (IsProperties.class.isAssignableFrom(clz) && !clz.isAssignableFrom(ret.getClass())) {
+          return jsonFactory.create(clz, (JsonObject)ret);
+        }
       }
       return ret;
     }
 
-    private <T> JSONArray listToJsonArray(Object...l) throws Throwable {
-      JSONArray ret = new JSONArray();
+    private <T> JsonArray listToJsonArray(Object...l) throws Throwable {
+      JsonArray ret = Json.createArray();
       for (Object o: l) {
-        setValue(ret, null, null, o, null);
+        setValue(ret, null, null, o);
       }
       return ret;
     }
 
-    private Object setValue(JSONArray arr, JSONObject obj, String attr, Object o, Method method) {
+    private Object setValue(JsonArray jsArr, JsonObject jsObj, String attr, Object val) {
+      if (val == null) {
+        return Json.createNull();
+      }
+
       try {
-        if (o == null) {
-          return o;
+        Class<?> valClaz = JsonValue.class;
+        if (val instanceof Number) {
+          val = ((Number)val).doubleValue();
+          valClaz = Double.TYPE;
+        } else if (val instanceof Boolean) {
+          valClaz = Boolean.TYPE;
+        } else if (val instanceof Date) {
+          val = ((Date)val).getTime();
+          valClaz = Double.TYPE;
+        } else if (val instanceof String) {
+          valClaz = String.class;
+        } else if (val instanceof IsProperties) {
+          val = ((IsProperties)val).getDataImpl();
+        } else if (val.getClass().isArray() || val instanceof List) {
+          val  = listToJsonArray(val.getClass().isArray() ? (Object[])val : ((List<?>)val).toArray());
+        } else if (val instanceof Function) {
+          val = new JreJsonFunction((Function)val);
         }
-        if (o instanceof String) {
-          return obj != null ? obj.put(attr, o) : arr.put(o);
-        } else if (o instanceof Boolean) {
-          return obj != null ? obj.put(attr, o) : arr.put(o);
-        } else if (o instanceof Number) {
-          return obj != null ? obj.put(attr, o) : arr.put(o);
-        } else if (o instanceof Date) {
-          return obj != null ? obj.put(attr, ((Date) o).getTime()) : arr.put(((Date) o).getTime());
-        } else if (o instanceof IsProperties) {
-          return obj != null ? obj.put(attr, ((IsProperties) o).getDataImpl()) : arr.put(((IsProperties) o).getDataImpl());
-        } else if (o.getClass().isArray() || o instanceof List) {
-          Object[] arg;
-          if (o.getClass().isArray()) {
-            arg = (Object[])o;
-          } else {
-            arg = ((List<?>)o).toArray();
-          }
-          JSONArray a = listToJsonArray(arg);
-          return obj != null ? obj.put(attr, a) : arr.put(a);
+
+        if (jsObj != null) {
+          Method mth = jsObj.getClass().getMethod("put", String.class, valClaz);
+          mth.invoke(jsObj, new Object[]{attr, val});
+          return jsObj;
         } else {
-          if (!(o instanceof Function) && !(o instanceof JSONObject)) {
-            System.out.println("Unkown setter object " + attr + " " + o.getClass().getName() + " " + o);
-          }
-          return obj != null ? obj.put(attr, o) : arr.put(o);
+          Method mth = jsArr.getClass().getMethod("set", Integer.TYPE, valClaz);
+          mth.invoke(jsArr, new Object[]{new Integer(jsArr.length()), val});
+          return jsArr;
         }
       } catch (Throwable e) {
         e.printStackTrace();
@@ -170,8 +203,9 @@ public class JsonFactoryJre implements JsonFactory  {
       String attr = name != null ? name.value() : deCapitalize(mname.replaceFirst("^[gs]et", ""));
 
       if ("getFieldNames".equals(mname)) {
-        return JSONObject.getNames(jsonObject);
+        return jsonObject.keys();
       } else if ("as".equals(mname)) {
+        @SuppressWarnings("unchecked")
         Class<? extends JsonBuilder> clz = (Class<? extends JsonBuilder>)args[0];
         return jsonFactory.create(clz, jsonObject);
       } else if ("getJsonName".equals(mname)) {
@@ -180,10 +214,10 @@ public class JsonFactoryJre implements JsonFactory  {
         return jsonObject;
       } else if (largs > 0 && ("parse".equals(mname) || "load".equals(mname))) {
         String json = String.valueOf(args[0]);
-        if (largs > 1 && Boolean.TRUE.equals(args[0])) {
+        if (largs > 1 && Boolean.TRUE.equals(args[1])) {
           json = Properties.wrapPropertiesString(json);
         }
-        jsonObject = new JSONObject(json);
+        jsonObject = Json.parse(json);
       } else if (mname.matches("toString")) {
         return jsonObject.toString();
       } else if (mname.matches("toJsonWithName")) {
@@ -201,15 +235,15 @@ public class JsonFactoryJre implements JsonFactory  {
         Class<?> ret = method.getReturnType();
         return getValue(null, 0, jsonObject, attr, ret, method);
       } else if (largs == 2 && mname.equals("set")) {
-        setValue(null, jsonObject, String.valueOf(args[0]), args[1], method);
+        setValue(null, jsonObject, String.valueOf(args[0]), args[1]);
         return proxy;
       } else if (largs == 1 || mname.startsWith("set")) {
-        setValue(null, jsonObject, attr, args[0], method);
+        setValue(null, jsonObject, attr, args[0]);
         return proxy;
       }
       return null;
     }
-    
+
     private String deCapitalize(String s) {
       return s != null && s.length() > 0 ? s.substring(0, 1).toLowerCase() + s.substring(1) : s;
     }
@@ -224,50 +258,21 @@ public class JsonFactoryJre implements JsonFactory  {
       }
       return null;
     }
-    
-    private String param(JSONObject o) {
+
+    private String param(JsonObject o) {
       String ret = "";
-      for (String k : JSONObject.getNames(o)) {
+      for (String k : o.keys()) {
         ret += ret.isEmpty() ? "" : "&";
-        JSONObject p = null;
-        JSONArray a = null;
-        String s = null;
-        try {
-          a = o.getJSONArray(k);
-        } catch (Exception e) {
-        }
-        if (a != null) {
-          for (int i = 0, l = a.length(); i < l ; i++) {
+        JsonValue v = o.get(k);
+        if (v instanceof JsonArray) {
+          for (int i = 0, l = ((JsonArray)v).length(); i < l ; i++) {
             ret += i > 0 ? "&" : "";
-            try {
-              p = a.getJSONObject(i);
-            } catch (Exception e) {
-              try {
-                s = String.valueOf(a.get(i));
-              } catch (Exception d) {
-              }
-            }
-            if (p != null) {
-              ret += k + "[]=" + p.toString();
-            } else if (s != null){
-              ret += k + "[]=" + s;
-            }
+            JsonValue e = ((JsonArray)v).get(i);
+            ret += k + "[]=" + e.toJson();
           }
         } else {
-          try {
-            p = o.getJSONObject(k);
-          } catch (Exception e) {
-            try {
-              s = String.valueOf(o.get(k));
-            } catch (Exception d) {
-            }
-          }
-          if (p != null) {
-            ret += k + "=" + p.toString();
-          } else if (s != null) {
-            if (!"null".equalsIgnoreCase(s)) {
-              ret += k + "=" + s;
-            }
+          if (v != null && !(v instanceof JsonNull)) {
+            ret += k + "=" + v.toJson();
           }
         }
       }
@@ -276,7 +281,7 @@ public class JsonFactoryJre implements JsonFactory  {
   }
 
   @SuppressWarnings("unchecked")
-  public <T> T create(Class<T> clz, JSONObject jso) {
+  public <T> T create(Class<T> clz, JsonObject jso) {
     InvocationHandler handler = new JsonBuilderHandler(jso);
     return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] {clz}, handler);
   }
@@ -286,13 +291,13 @@ public class JsonFactoryJre implements JsonFactory  {
     InvocationHandler handler = new JsonBuilderHandler();
     return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] {clz}, handler);
   }
-  
+
   public IsProperties createBinder() {
     InvocationHandler handler = new JsonBuilderHandler();
     return (IsProperties)Proxy.newProxyInstance(IsProperties.class.getClassLoader(), new Class[] {IsProperties.class}, handler);
   }
-  
-  public IsProperties createBinder(JSONObject jso) {
+
+  public IsProperties createBinder(JsonObject jso) {
     InvocationHandler handler = new JsonBuilderHandler(jso);
     return (IsProperties)Proxy.newProxyInstance(IsProperties.class.getClassLoader(), new Class[] {IsProperties.class}, handler);
   }
index 1167651d6ee0cd67b86c614661f612b07dd7325f..cf98d8b95321028ae0e031b58c11fbabf9616974 100644 (file)
  */
 package com.google.gwt.query.client.ajax;
 
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Random;
-
-import javax.servlet.Servlet;
+import com.google.gwt.core.shared.GWT;
+import com.google.gwt.query.servlet.GQAjaxTestServlet;
+import com.google.gwt.query.vm.AjaxTransportJre;
 
 import org.mortbay.jetty.Server;
 import org.mortbay.jetty.handler.HandlerWrapper;
@@ -27,32 +25,41 @@ import org.mortbay.jetty.servlet.DefaultServlet;
 import org.mortbay.jetty.webapp.WebAppClassLoader;
 import org.mortbay.jetty.webapp.WebAppContext;
 
-import com.google.gwt.query.servlet.GQAjaxTestServlet;
-import com.google.gwt.query.vm.AjaxTransportJre;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Random;
+
+import javax.servlet.Servlet;
 
 /**
  * Tests for Data Binders and Ajax run in the JVM
  */
 public class AjaxTestJre extends AjaxTests {
-  
+
   static Server server;
   static int port = new Random().nextInt(1000) + 2000;
 
   public String getModuleName() {
     return null;
   }
-  
+
   public AjaxTestJre() throws Exception {
+    // Disable stderr, so as stack traces of expected failures do not
+    // mess the output.
+    System.setErr(new PrintStream(new ByteArrayOutputStream()));
+
     String localDomain = "http://127.0.0.1:" + port;
     AjaxTransportJre.enableCORS(localDomain);
     String corsDomain = "http://localhost:" + port;
-    
+
     echoUrl = localDomain + "/" + servletPath;
     echoUrlCORS = corsDomain + "/" + servletPath + "?cors=true";
 
     startWebServer(port);
   }
-  
+
   protected void startWebServer(int port) throws Exception {
     if (server == null) {
       final Map<String, Class<? extends Servlet>> servlets = new HashMap<String, Class<? extends Servlet>>();
@@ -63,7 +70,7 @@ public class AjaxTestJre extends AjaxTests {
 
   public static Server createWebServer(final int port, final String resourceBase, final String[] classpath,
       final Map<String, Class<? extends Servlet>> servlets, final HandlerWrapper handler) throws Exception {
-    
+
     final Server server = new Server(port);
 
     final WebAppContext context = new WebAppContext();
index 965bf1614e0673de33af74c1cedc023437a66b61..7158fe8daa4a87dd554b6b58b2ae1e0669a75ea0 100644 (file)
  */
 package com.google.gwt.query.client.dbinding;
 
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
-
+import com.google.gwt.core.shared.GWT;
 import com.google.gwt.junit.client.GWTTestCase;
 import com.google.gwt.query.client.Function;
 import com.google.gwt.query.client.GQ;
@@ -26,6 +23,12 @@ import com.google.gwt.query.client.IsProperties;
 import com.google.gwt.query.client.builders.JsonBuilder;
 import com.google.gwt.query.client.builders.Name;
 
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
 /**
  * Tests for Deferred which can run either in JVM and GWT
  */
@@ -41,11 +44,13 @@ public class DataBindingTestJre extends GWTTestCase {
     p1.set("b", 1);
     p1.set("c", "null");
     p1.set("d", null);
+    p1.set("e", true);
 
     assertEquals("1", p1.get("a"));
     assertEquals(Double.valueOf(1), p1.get("b"));
     assertEquals("null", p1.get("c"));
     assertNull(p1.get("d"));
+    assertTrue((Boolean)p1.get("e"));
 
     p1 = GQ.create(p1.toJson());
 
@@ -57,7 +62,7 @@ public class DataBindingTestJre extends GWTTestCase {
 
   public interface Item extends JsonBuilder {
     public static enum Type {BIG, SMALL}
-    
+
     Date getDate();
     void setDate(Date d);
     Type getType();
@@ -79,6 +84,8 @@ public class DataBindingTestJre extends GWTTestCase {
     JsonExample setD(long l);
     List<Item> getItems();
     void setItems(List<Item> a);
+    Item getI();
+    void setI(Item i);
     String y();
     void y(String s);
     Function getF();
@@ -124,21 +131,25 @@ public class DataBindingTestJre extends GWTTestCase {
     assertTrue(functionRun);
 
     Item i1 = GQ.create(Item.class);
-    Item i2 = GQ.create(Item.class);
     i1.setDate(new Date(2000));
+    c.setI(i1);
+    assertEquals(2000l, c.getI().getDate().getTime());
+
+    Item i2 = GQ.create(Item.class);
     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());
 
+
     assertFalse(c.toJson().startsWith("{\"jsonExample\":"));
     assertTrue(c.toJsonWithName().startsWith("{\"jsonExample\":"));
     assertTrue(c.toJson().contains("\"items\":[{\"date\":"));
-    assertTrue(c.toQueryString().contains("t[]=bar"));
+    assertTrue(c.toQueryString().replace("\"bar\"", "bar").contains("t[]=bar"));
     assertTrue(c.toQueryString().contains("a=1"));
     assertTrue(c.toQueryString().contains("\"a\":2"));
-    
+
     assertEquals(1, c.<Number>get("a").intValue());
   }
 }
\ No newline at end of file