I realize this post is coming at the end of the day on friday, but hopefully it will get a look =)
Going through the different JSON parsing implementations available for GWT out there, almost all of them rely on a straight eval and note that they should only be used for trusted code. The old JSONValue code seems kind of quaint in light of JavaScriptObjects, and looking through the trunk it looks like there's just a TODO in JsonUtils for safe parsing. Anyway, I don't have that much experience writing JSNI code, so I wanted to run this small class past you all and see if this aligns with GWT best practices, if I'm doing anything monumentally stupid, or if I'm just plain missing something. The following is a pretty basic adaptation of Douglas Crockford's json2.js. When parse() is called, it checks to see if there is a native JSON defined (which exists in the latest IE, Firefox, Chrome and Safari) and simply uses that. If not, it defines a $wnd.JSON.parse in javascript using the json2 code, which is then indistinguishable from the native functionality in future calls (this tactic comes straight from json2.js). It lazily initializes the JSON object, as defining an entry point doesn't seem like a big win, and adds a lot of support necessary to make it happen. It also defines it on the $wnd object...scope still occasionally confuses me in javascript, but it seemed to make more sense to define it there than on window. Any thoughts? Even drive by comments are useful if it gives me enough to google. Thanks! The code: /** * Evaluates a JSON string safely * * @param <T> The type of JavaScriptObject that should be returned * @param jsonString The source JSON text * @return The evaluated object * @throws NullPointerException if <code>jsonString</code> is <code>null</code> * @throws IllegalArgumentException if <code>jsonString</code> is empty * @throws JavaScriptException if <code>jsonString</code> is non- parseable */ public static final <T extends JavaScriptObject> T parse(String jsonString) { if (jsonString == null) { throw new NullPointerException(); } if (jsonString.length() == 0) { throw new IllegalArgumentException("empty argument"); } // check if JSON variable is defined, if not, call init code if (isJsonUndefined()) { defineJSON(); } return nativeParse(jsonString); } private static native <T extends JavaScriptObject> T nativeParse (String jsonString) /*-{ return $wnd.JSON.parse(jsonString); }-*/; /** * simple check to see if JSON object is defined * will be defined in browsers with native implementation * otherwise, will need to init manually * * @return true if JSON object is undefined */ protected static final native boolean isJsonUndefined() /*-{ return !$wnd.JSON; }-*/; /** * naive way to define the JSON object *if* not already * natively defined by browser. straight copy from json2.js. */ private static final native void defineJSON() /*-{ //http://www.JSON.org/json2.js //2009-09-29 //Public Domain. //NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. //See http://www.JSON.org/js.html // Create a JSON object only if one does not already exist. if (!$wnd.JSON) { $wnd.JSON = {}; } (function () { var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f \u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; // create parse method if one does not exist // The parse method takes a text and returns // a JavaScript value if the text is a valid JSON text. if (typeof $wnd.JSON.parse !== 'function') { $wnd.JSON.parse = function (text) { var j; // first stage, escape sequences cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } // second stage, remove non-JSON patterns if (/^[\],:{}\s]*$/. test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]? \d+)?/g, ']'). replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { // third stage, eval j = eval('(' + text + ')'); return j; } // If the text is not JSON parseable, then a SyntaxError is thrown. throw new SyntaxError('JSON.parse'); }; } }()); }-*/; --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To post to this group, send email to google-web-toolkit@googlegroups.com To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en -~----------~----~----~----~------~----~------~--~---