aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorManolo Carrasco <manolo@apache.org>2012-09-10 15:08:42 +0000
committerManolo Carrasco <manolo@apache.org>2012-09-10 15:08:42 +0000
commit2b79b024b4f46d427b8d1adbdce36bdd8ca412a7 (patch)
treebf1fc8df3567c2c6437a7f28553247c68994cae3
parentfc46636a0db3e52928cb164b1928aff099a5f0ba (diff)
downloadgwtquery-2b79b024b4f46d427b8d1adbdce36bdd8ca412a7.tar.gz
gwtquery-2b79b024b4f46d427b8d1adbdce36bdd8ca412a7.zip
Use native JSON.stringify when available. Fix to store native js numbers in Properties instead of gwt types. Handle char and byte types
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/Properties.java67
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java26
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java86
-rw-r--r--gwtquery-core/src/main/java/com/google/gwt/query/rebind/JsonBuilderGenerator.java11
-rw-r--r--gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryAjaxTestGwt.java7
-rw-r--r--gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java23
6 files changed, 141 insertions, 79 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 52c257f7..d2ae415e 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
@@ -15,7 +15,6 @@
*/
package com.google.gwt.query.client;
-import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsArrayMixed;
import com.google.gwt.query.client.js.JsCache;
@@ -133,7 +132,15 @@ public class Properties extends JavaScriptObject {
c().delete(String.valueOf(name));
}
- public final <T> void set(T name, Object val) {
+ public final <T> void setNumber(T name, double val) {
+ c().putNumber(name, val);
+ }
+
+ public final <T> void setBoolean(T name, boolean val) {
+ c().putBoolean(name, val);
+ }
+
+ public final <T, O> void set(T name, O val) {
c().put(String.valueOf(name), val);
}
@@ -142,63 +149,11 @@ public class Properties extends JavaScriptObject {
}
public final String toJsonString() {
- String ret = "";
- for (String k : keys()){
- String ky = k.matches("\\d+") ? k : "\"" + k + "\"";
- JsCache o = getArray(k).cast();
- if (o != null) {
- ret += ky + ":[";
- for (int i = 0, l = o.length(); i < l ; i++) {
- Properties p = o.<JsCache>cast().getJavaScriptObject(i);
- if (p != null) {
- ret += p.toJsonString() + ",";
- } else {
- ret += "\"" + o.getString(i) + "\",";
- }
- }
- ret += "],";
- } else {
- Properties p = getJavaScriptObject(k);
- if (p != null) {
- ret += ky + ":" + p.toJsonString() + ",";
- } else {
- ret += ky + ":\"" + getStr(k) + "\",";
- }
- }
- }
- return "{" + ret.replaceAll(",\\s*([\\]}]|$)","$1")
- .replaceAll("([:,\\[])\"(-?[\\d\\.]+|null|false|true)\"", "$1$2")
- + "}";
+ return JsUtils.JSON2String(JsCache.checkNull(this));
}
public final String toQueryString() {
- String ret = "";
- for (String k : keys()) {
- ret += ret.isEmpty() ? "" : "&";
- JsCache o = getArray(k).cast();
- if (o != null) {
- for (int i = 0, l = o.length(); i < l ; i++) {
- ret += i > 0 ? "&" : "";
- Properties p = o.<JsCache>cast().getJavaScriptObject(i);
- if (p != null) {
- ret += k + "[]=" + p.toJsonString();
- } else {
- ret += k + "[]=" + o.getString(i) ;
- }
- }
- } else {
- Properties p = getJavaScriptObject(k);
- if (p != null) {
- ret += p.toQueryString();
- } else {
- String v = getStr(k);
- if (v != null && !v.isEmpty() && !"null".equalsIgnoreCase(v)) {
- ret += k + "=" + v;
- }
- }
- }
- }
- return ret;
+ return JsUtils.param(JsCache.checkNull(this));
}
public final boolean isEmpty(){
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
index ba7242a9..9de4ebc1 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsCache.java
@@ -114,6 +114,14 @@ public class JsCache extends JavaScriptObject {
public final native int indexOf(Object o) /*-{
return this.indexOf(o);
}-*/;
+
+ public final native <T> void putBoolean(T id, boolean b) /*-{
+ this[id] = b;
+ }-*/;
+
+ public final native <T> void putNumber(T id, double n) /*-{
+ this[id] = n;
+ }-*/;
public final native <T, O> void put(T id, O obj) /*-{
this[id] = obj;
@@ -171,11 +179,9 @@ public class JsCache extends JavaScriptObject {
return ret + "}";
}
- private void checkNull() {
- // In dev-mode a null object casted to JavascriptObject does not throw a NPE
- if (!GWT.isProdMode() && this == null) {
- throw new NullPointerException();
- }
+ // In dev-mode a null object casted to JavascriptObject does not throw a NPE
+ public final void checkNull() {
+ checkNull(this);
}
private final native JsArrayString keysImpl() /*-{
@@ -184,4 +190,14 @@ public class JsCache extends JavaScriptObject {
for(key in this) if (key != '__gwt_ObjectId') keys.push(String(key));
return keys;
}-*/;
+
+ /**
+ * Throw a NPE when a js is null
+ */
+ public static final <T extends JavaScriptObject> T checkNull(T js) {
+ if (!GWT.isProdMode() && js == null) {
+ throw new NullPointerException();
+ }
+ return js;
+ }
}
diff --git a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
index e3ad1586..a41d15e5 100644
--- a/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
+++ b/gwtquery-core/src/main/java/com/google/gwt/query/client/js/JsUtils.java
@@ -61,6 +61,10 @@ public class JsUtils {
public native Properties parseJSON(String json) /*-{
return $wnd.JSON.parse(json);
}-*/;
+
+ public native String JSON2String(JavaScriptObject o) /*-{
+ return $wnd.JSON.stringify(o);
+ }-*/;
public native Element parseXML(String xml) /*-{
return new DOMParser().parseFromString(xml, "text/xml").documentElement;
@@ -77,7 +81,7 @@ public class JsUtils {
Element e = a.get(i);
int id = e.hashCode();
if (!cache.exists(id)) {
- cache.put(id, 1);
+ cache.putNumber(id, 1);
ret.push(e);
}
}
@@ -100,6 +104,41 @@ public class JsUtils {
// a well-formed json string.
return evalImpl("(" + json + ")");
}
+
+ @Override
+ public String JSON2String(JavaScriptObject js) {
+ // This is a very basic implementation for IE6/IE7 of JSON.stringify
+ // If many people demand a better one we could consider to use json2.js
+ // @see https://github.com/douglascrockford/JSON-js/blob/master/json2.js
+ Properties prop = js.cast();
+ String ret = "";
+ for (String k : prop.keys()){
+ String ky = k.matches("\\d+") ? k : "\"" + k + "\"";
+ JsCache o = prop.getArray(k).cast();
+ if (o != null) {
+ ret += ky + ":[";
+ for (int i = 0, l = o.length(); i < l ; i++) {
+ Properties p = o.<JsCache>cast().getJavaScriptObject(i);
+ if (p != null) {
+ ret += p.toJsonString() + ",";
+ } else {
+ ret += "\"" + o.getString(i) + "\",";
+ }
+ }
+ ret += "],";
+ } else {
+ Properties p = prop.getJavaScriptObject(k);
+ if (p != null) {
+ ret += ky + ":" + p.toJsonString() + ",";
+ } else {
+ ret += ky + ":\"" + prop.getStr(k) + "\",";
+ }
+ }
+ }
+ return "{" + ret.replaceAll(",\\s*([\\]}]|$)","$1")
+ .replaceAll("([:,\\[])\"(-?[\\d\\.]+|null|false|true)\"", "$1$2")
+ + "}";
+ }
@Override
public native Element parseXML(String xml) /*-{
@@ -275,7 +314,7 @@ public class JsUtils {
? false
: !"HTML".equals(getOwnerDocument(o).getDocumentElement().getNodeName());
}
-
+
/**
* Load an external javascript library. The inserted script replaces the
* element with the given id in the document.
@@ -352,7 +391,46 @@ public class JsUtils {
return utilsImpl.unique(a);
}
- public static String XML2String(JavaScriptObject o) {
- return utilsImpl.XML2String(o);
+ public static String XML2String(JavaScriptObject js) {
+ return utilsImpl.XML2String(js);
+ }
+
+ public static String JSON2String(JavaScriptObject js) {
+ return utilsImpl.JSON2String(js);
+ }
+
+ /**
+ * Returns a QueryString representation of a JavascriptObject.
+ * TODO: jquery implementation accepts a second parameter (traditional)
+ */
+ public static String param(JavaScriptObject js) {
+ Properties prop = js.cast();
+ String ret = "";
+ for (String k : prop.keys()) {
+ ret += ret.isEmpty() ? "" : "&";
+ JsCache o = prop.getArray(k).cast();
+ if (o != null) {
+ for (int i = 0, l = o.length(); i < l ; i++) {
+ ret += i > 0 ? "&" : "";
+ Properties p = o.<JsCache>cast().getJavaScriptObject(i);
+ if (p != null) {
+ ret += k + "[]=" + p.toJsonString();
+ } else {
+ ret += k + "[]=" + o.getString(i) ;
+ }
+ }
+ } else {
+ Properties p = prop.getJavaScriptObject(k);
+ if (p != null) {
+ ret += p.toQueryString();
+ } else {
+ String v = prop.getStr(k);
+ if (v != null && !v.isEmpty() && !"null".equalsIgnoreCase(v)) {
+ ret += k + "=" + v;
+ }
+ }
+ }
+ }
+ return ret;
}
}
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 bbb7e80c..f61fd4e3 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
@@ -144,6 +144,10 @@ public class JsonBuilderGenerator extends Generator {
sw.println("return new Date(java.lang.Long.parseLong(p.getStr(\"" + name + "\")));");
} else if (method.getReturnType().isPrimitive() != null) {
sw.println("return (" + retType + ")p.getFloat(\"" + name + "\");");
+ } else if (retType.equals("java.lang.Character")) {
+ sw.println("return (char) p.getFloat(\"" + name + "\");");
+ } else if (retType.equals("java.lang.Byte")) {
+ sw.println("return (byte) p.getFloat(\"" + name + "\");");
} else if (retType.equals("java.lang.Integer")) {
sw.println("return (int) p.getFloat(\"" + name + "\");");
} else if (retType.equals("java.lang.Float")) {
@@ -154,7 +158,6 @@ public class JsonBuilderGenerator extends Generator {
sw.println("return (long) p.getFloat(\"" + name + "\");");
} else if (retType.equals("java.lang.Byte")) {
sw.println("return (byte) p.getFloat(\"" + name + "\");");
-
} else if (isTypeAssignableTo(method.getReturnType(), stringType)) {
sw.println("return p.getStr(\"" + name + "\");");
} else if (isTypeAssignableTo(method.getReturnType(), jsonBuilderType)) {
@@ -219,7 +222,11 @@ public class JsonBuilderGenerator extends Generator {
}
sw.println("setArrayBase(\"" + name + "\", " + a + ");");
} else if (type.getParameterizedQualifiedSourceName().matches("java.util.Date")) {
- sw.println("p.set(\"" + name + "\", a.getTime());");
+ sw.println("p.setNumber(\"" + name + "\", a.getTime());");
+ } else if (type.getParameterizedQualifiedSourceName().matches("(java.lang.(Character|Long|Double|Integer|Float|Byte)|(char|long|double|int|float|byte))")) {
+ sw.println("p.setNumber(\"" + name + "\", a);");
+ } else if (type.getParameterizedQualifiedSourceName().matches("(java.lang.Boolean|boolean)")) {
+ sw.println("p.setBoolean(\"" + name + "\", a);");
} else {
sw.println("p.set(\"" + name + "\", a);");
}
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 98a85094..03eddce8 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
@@ -147,11 +147,14 @@ public class GQueryAjaxTestGwt extends GWTTestCase {
public void testJsonValidService() {
delayTestFinish(5000);
- String testJsonpUrl = "http://services.digg.com/stories/top?appkey=http://mashup.com&type=javascript&callback=?";
+ // Use a public json service
+ String testJsonpUrl = "https://www.googleapis.com/blogger/v2/blogs/user_id/posts/post_id?callback=?&key=NO-KEY";
Ajax.getJSONP(testJsonpUrl, new Function(){
public void f() {
Properties p = getDataProperties();
- assertTrue(0 < p.getInt("count"));
+ // It should return error since we do not use a valid key
+ // {"error":{"errors":[{"domain":"usageLimits","reason":"keyInvalid","message":"Bad Request"}],"code":400,"message":"Bad Request"}}
+ assertEquals(400, p.getJavaScriptObject("error").<Properties>cast().getInt("code"));
finishTest();
}
}, null, 0);
diff --git a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java
index c0843612..b14533c9 100644
--- a/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java
+++ b/gwtquery-core/src/test/java/com/google/gwt/query/client/GQueryCoreTestGwt.java
@@ -19,6 +19,14 @@ import static com.google.gwt.query.client.GQuery.$;
import static com.google.gwt.query.client.GQuery.$$;
import static com.google.gwt.query.client.GQuery.document;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import junit.framework.Assert;
+
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.InputElement;
@@ -44,14 +52,6 @@ import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;
-import junit.framework.Assert;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
/**
* Test class for testing gwtquery-core api.
*/
@@ -539,7 +539,7 @@ public class GQueryCoreTestGwt extends GWTTestCase {
}
- public void aatestProperties() {
+ public void testProperties() {
Properties p = $$("border:'1px solid black'");
assertEquals(1, p.keys().length);
assertNotNull(p.getStr("border"));
@@ -549,7 +549,10 @@ public class GQueryCoreTestGwt extends GWTTestCase {
assertNotNull(p.getStr("border"));
try {
- // DevMode null casting return an object
+ // DevMode null casting returns an object
+ // @see:
+ // http://code.google.com/p/gwtquery/issues/detail?id=122
+ // http://code.google.com/p/google-web-toolkit/issues/detail?id=6625
((Properties)null).toJsonString();
fail("Executing methods of a null object should throw a NullPointerException");
} catch (NullPointerException e) {