aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGert Scholten <gscholt@gmail.com>2009-10-01 08:34:36 +0200
committerGert Scholten <gscholt@gmail.com>2009-10-01 08:34:36 +0200
commit488eb42b267f0abb55736f8b93fb972b33d15b55 (patch)
tree9b0bf002bc476daa6ee9ad515ae9c38794c0a4ae
parent30f8a7b840278dfa27b7cd30c12643856910d2f0 (diff)
downloadgwtjsonrpc-488eb42b267f0abb55736f8b93fb972b33d15b55.tar.gz
Add support for native JSON.parse parser.
Change-Id: If97e265d7487ec3cb7735a3a881be6a60a49c797 Signed-off-by: Gert Scholten <gscholt@gmail.com>
-rw-r--r--src/main/java/com/google/gwtjsonrpc/client/JsonCall.java51
1 files changed, 49 insertions, 2 deletions
diff --git a/src/main/java/com/google/gwtjsonrpc/client/JsonCall.java b/src/main/java/com/google/gwtjsonrpc/client/JsonCall.java
index f34a48d..4927fa5 100644
--- a/src/main/java/com/google/gwtjsonrpc/client/JsonCall.java
+++ b/src/main/java/com/google/gwtjsonrpc/client/JsonCall.java
@@ -27,6 +27,40 @@ import com.google.gwt.user.client.rpc.InvocationException;
import com.google.gwt.user.client.rpc.StatusCodeException;
class JsonCall<T> implements RequestCallback {
+ private static final JavaScriptObject jsonParser;
+
+ static {
+ jsonParser = selectJsonParser();
+ }
+
+ /**
+ * Select the most efficient available JSON parser.
+ *
+ * If we have a native JSON parser, present in modern browsers (FF 3.5 and
+ * IE8, at time of writing), it is returned. If no native parser is found, a
+ * parser function using <code>eval</code> is returned.
+ *
+ * This is done dynamically, not with a GWT user.agent check, because FF3.5
+ * does not have a specific user.agent associated with it. Introducing a new
+ * property for the presence of an ES3.1 parser is not worth it, since the
+ * check is only done once anyway, and will result in significantly longer
+ * compile times.
+ *
+ * As GWT will undoubtedly introduce support for the native JSON parser in the
+ * {@link com.google.gwt.json.client.JSONParser JSONParser} class, this code
+ * should be reevaluated to possibly use the GWT parser reference.
+ *
+ * @return a javascript function with the fastest available JSON parser
+ * @see "http://wiki.ecmascript.org/doku.php?id=es3.1:json_support"
+ */
+ private static native JavaScriptObject selectJsonParser()
+ /*-{
+ if ($wnd.JSON && typeof $wnd.JSON.parse === 'function')
+ return $wnd.JSON.parse;
+ else
+ return function(expr) { return eval('(' + expr + ')'); };
+ }-*/;
+
private final AbstractJsonProxy proxy;
private final String methodName;
private final String requestParams;
@@ -92,7 +126,7 @@ class JsonCall<T> implements RequestCallback {
if (isJsonBody(rsp)) {
final RpcResult r;
try {
- r = parse(rsp.getText());
+ r = parse(jsonParser, rsp.getText());
} catch (RuntimeException e) {
fireEvent(RpcCompleteEvent.e);
callback.onFailure(new InvocationException("Bad JSON response: " + e));
@@ -171,7 +205,20 @@ class JsonCall<T> implements RequestCallback {
return JsonUtil.JSON_TYPE.equals(type);
}
- private static final native RpcResult parse(String json)/*-{ return eval('('+json+')'); }-*/;
+ /**
+ * Call a JSON parser javascript function to parse an encoded JSON string.
+ *
+ * @param parser a javascript function
+ * @param json encoded JSON text
+ * @return the parsed data
+ * @see #jsonParser
+ */
+ private static final native RpcResult parse(JavaScriptObject parserFunction,
+ String json)
+ /*-{
+ return parserFunction(json);
+ }-*/;
+
private static class RpcResult extends JavaScriptObject {
protected RpcResult() {