diff options
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) { |