You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2011/03/13 20:24:08 UTC

svn commit: r1081204 - in /tuscany/sca-cpp/trunk/modules: js/Makefile.am js/htdocs/component.js js/htdocs/jsonutil.js js/htdocs/util.js js/js-eval.cpp js/json-test.js js/util-test server/server-conf

Author: jsdelfino
Date: Sun Mar 13 19:24:08 2011
New Revision: 1081204

URL: http://svn.apache.org/viewvc?rev=1081204&view=rev
Log:
Add Javascript functions and test cases to help work with JSON.

Added:
    tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
    tuscany/sca-cpp/trunk/modules/js/js-eval.cpp
    tuscany/sca-cpp/trunk/modules/js/json-test.js
    tuscany/sca-cpp/trunk/modules/js/util-test   (contents, props changed)
      - copied, changed from r1081203, tuscany/sca-cpp/trunk/modules/js/Makefile.am
Modified:
    tuscany/sca-cpp/trunk/modules/js/Makefile.am
    tuscany/sca-cpp/trunk/modules/js/htdocs/component.js
    tuscany/sca-cpp/trunk/modules/js/htdocs/util.js
    tuscany/sca-cpp/trunk/modules/server/server-conf

Modified: tuscany/sca-cpp/trunk/modules/js/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/Makefile.am?rev=1081204&r1=1081203&r2=1081204&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/js/Makefile.am Sun Mar 13 19:24:08 2011
@@ -25,5 +25,9 @@ EXTRA_DIST = htdocs/*.js htdocs/*.css
 js_test_SOURCES = js-test.cpp
 js_test_LDFLAGS = -lmozjs 
 
-noinst_PROGRAMS = js-test
-TESTS = js-test
+js_eval_SOURCES = js-eval.cpp
+js_eval_LDFLAGS = -lmozjs 
+
+noinst_PROGRAMS = js-test js-eval
+dist_noinst_SCRIPTS = util-test
+TESTS = js-test util-test

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/component.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/component.js?rev=1081204&r1=1081203&r2=1081204&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/component.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/component.js Sun Mar 13 19:24:08 2011
@@ -31,11 +31,11 @@
  * Client component wiring API, supporting JSON and ATOM bindings.
  */
 
+var JSONClient = {};
+
 /**
  * Escape a character.
  */
-var JSONClient = {};
-
 JSONClient.escapeJSONChar = function(c) {
     if(c == "\"" || c == "\\") return "\\" + c;
     if (c == "\b") return "\\b";

Added: tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js?rev=1081204&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js (added)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/jsonutil.js Sun Mar 13 19:24:08 2011
@@ -0,0 +1,259 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+/**
+ * JSON data conversion functions.
+ */
+var json = {};
+
+/**
+ * JSON exceptions.
+ */
+json.Exception = function(code, message) {
+    this.name = "JSONException";
+    this.code = code;
+    this.message = message;
+};
+
+json.Exception.prototype = new Error();
+
+json.Exception.prototype.toString = function() {
+    return this.name + ": " + this.message;
+};
+
+/**
+ * Return true if a list represents a JS array.
+ */
+json.isJSArray = function(l) {
+    if (isNil(l))
+        return true;
+    var v = car(l);
+    if (isSymbol(v))
+        return false;
+    if (isList(v))
+        if (!isNil(v) && isSymbol(car(v)))
+            return false;
+    return true;
+};
+
+/**
+ * Converts JSON properties to values.
+ */
+json.jsPropertiesToValues = function(propertiesSoFar, o, i) {
+    if (isNil(i))
+        return propertiesSoFar;
+    var p = car(i);
+    var jsv = o[p];
+    var v = json.jsValToValue(jsv);
+
+    if (typeof p == 'string') {
+        var n = '' + p;
+        if (n.slice(0, 1) == '@')
+            return json.jsPropertiesToValues(cons(mklist(attribute, "'" + n.slice(1), v), propertiesSoFar), o, cdr(i));
+        if (isList(v) && !json.isJSArray(v))
+            return json.jsPropertiesToValues(cons(cons(element, cons("'" + n, v)), propertiesSoFar), o, cdr(i));
+        return json.jsPropertiesToValues(cons(mklist(element, "'" + n, v), propertiesSoFar), o, cdr(i));
+    }
+    return json.jsPropertiesToValues(cons(v, propertiesSoFar), o, cdr(i));
+};
+
+/**
+ * Converts a JSON val to a value.
+ */
+json.jsValToValue = function(jsv) {
+    if (isList(jsv))
+        return json.jsPropertiesToValues(mklist(), jsv, reverse(range(0, jsv.length)));
+    if (typeof jsv == 'object')
+        return json.jsPropertiesToValues(mklist(), jsv, properties(jsv));
+    if (typeof jsv == 'string')
+        return '' + jsv;
+    return jsv;
+}
+
+/**
+ * Return true if a list of strings contains a JSON document.
+ */
+json.isJSON = function(l) {
+    if (isNil(l))
+        return false;
+    var s = car(l).slice(0, 1);
+    return s == "[" || s == "{";
+};
+
+/**
+ * Convert a list of strings representing a JSON document to a list of values.
+ */
+json.readJSON = function(l) {
+    var s = writeStrings(l);
+    var obj;
+    eval('obj = { \"val\": ' + s + " }");
+    return json.jsValToValue(obj.val);
+};
+
+/**
+ * Convert a list of values to JSON array elements.
+ */
+json.valuesToJSElements = function(a, l, i) {
+    if (isNil(l))
+        return a;
+    var pv = json.valueToJSVal(car(l));
+    a[i] = pv
+    return json.valuesToJSElements(a, cdr(l), i + 1);
+};
+    
+/**
+ * Convert a value to a JSON value.
+ */
+json.valueToJSVal = function(v) {
+    if (!isList(v))
+        return v;
+    if (json.isJSArray(v))
+        return json.valuesToJSElements(range(0, v.length), v, 0);
+    return json.valuesToJSProperties({}, v);
+};
+
+/**
+ * Convert a list of values to JSON properties.
+ */
+json.valuesToJSProperties = function(o, l) {
+    if (isNil(l))
+        return o;
+    var token = car(l);
+    if (isTaggedList(token, attribute)) {
+        var pv = json.valueToJSVal(attributeValue(token));
+        o['@' + attributeName(token).slice(1)] = pv;
+    } else if (isTaggedList(token, element)) {
+        if (elementHasValue(token)) {
+            var pv = json.valueToJSVal(elementValue(token));
+            o[elementName(token).slice(1)] = pv;
+        } else {
+            var child = {};
+            o[elementName(token).slice(1)] = child;
+            json.valuesToJSProperties(child, elementChildren(token));
+        }
+    }
+    return json.valuesToJSProperties(o, cdr(l));
+};
+
+/**
+ * Convert a list of values to a list of strings representing a JSON document.
+ */
+json.writeJSON = function(l) {
+    var jsv;
+    if (json.isJSArray(l))
+        jsv = json.valuesToJSElements(range(0, l.length), l, 0);
+    else
+        jsv = json.valuesToJSProperties({}, l);
+    var s = json.toJSON(jsv);
+    return mklist(s);
+}
+
+/**
+ * Convert a list + params to a JSON-RPC request.
+ */
+json.jsonRequest = function(id, func, params) {
+    var r = mklist(mklist("'id", id), mklist("'method", func), mklist("'params", params));
+    return json.writeJSON(valuesToElements(r));
+};
+
+/**
+ * Convert a value to a JSON-RPC result.
+ */
+json.jsonResult = function(id, val) {
+    return json.writeJSON(valuesToElements(mklist(mklist("'id", id), mklist("'result", val))));
+};
+
+/**
+ * Convert a JSON-RPC result to a value.
+ */
+json.jsonResultValue = function(s) {
+    var jsres = json.readJSON(s);
+    var res = elementsToValues(jsres);
+    var val = cadr(assoc("'result", res));
+    if (isList(val) && !json.isJSArray(val))
+        return mklist(val);
+    return val;
+};
+
+/**
+ * Escape a character.
+ */
+json.escapeJSONChar = function(c) {
+    if(c == "\"" || c == "\\") return "\\" + c;
+    if (c == "\b") return "\\b";
+    if (c == "\f") return "\\f";
+    if (c == "\n") return "\\n";
+    if (c == "\r") return "\\r";
+    if (c == "\t") return "\\t";
+    var hex = c.charCodeAt(0).toString(16);
+    if(hex.length == 1) return "\\u000" + hex;
+    if(hex.length == 2) return "\\u00" + hex;
+    if(hex.length == 3) return "\\u0" + hex;
+    return "\\u" + hex;
+};
+
+/**
+ * Encode a string into JSON format.
+ */
+json.escapeJSONString = function(s) {
+    // The following should suffice but Safari's regex is broken (doesn't support callback substitutions)
+    // return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g, json.escapeJSONChar) + "\"";
+
+    // Rather inefficient way to do it
+    var parts = s.split("");
+    for(var i = 0; i < parts.length; i++) {
+        var c = parts[i];
+        if(c == '"' || c == '\\' || c.charCodeAt(0) < 32 || c.charCodeAt(0) >= 128)
+            parts[i] = json.escapeJSONChar(parts[i]);
+    }
+    return "\"" + parts.join("") + "\"";
+};
+
+/**
+ * Marshall objects to JSON format.
+ */
+json.toJSON = function(o) {
+    if(o == null)
+        return "null";
+    if(o.constructor == String)
+        return json.escapeJSONString(o);
+    if(o.constructor == Number)
+        return o.toString();
+    if(o.constructor == Boolean)
+        return o.toString();
+    if(o.constructor == Date)
+        return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
+    if(o.constructor == Array) {
+        var v = [];
+        for(var i = 0; i < o.length; i++)
+            v.push(json.toJSON(o[i]));
+        return "[" + v.join(", ") + "]";
+    }
+    var v = [];
+    for(attr in o) {
+        if(o[attr] == null)
+            v.push("\"" + attr + "\": null");
+        else if(typeof o[attr] == "function")
+            ; // Skip
+        else
+            v.push(json.escapeJSONString(attr) + ": " + json.toJSON(o[attr]));
+    }
+    return "{" + v.join(", ") + "}";
+};
+

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/util.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/util.js?rev=1081204&r1=1081203&r2=1081204&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/util.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/util.js Sun Mar 13 19:24:08 2011
@@ -72,6 +72,13 @@ function reverse(l) {
     return l.slice(0).reverse();
 }
 
+function range(a, b) {
+    var l = new Array();
+    for (var x = a; x < b; x++)
+        l.push(x);
+    return l;
+}
+
 function isNil(v) {
     if (v == null || typeof v == 'undefined' || (v.constructor == Array && v.length == 0))
         return true;
@@ -85,7 +92,7 @@ function isSymbol(v) {
 }
 
 function isString(v) {
-    if (typeof v == 'string')
+    if (typeof v == 'string' && v.slice(0, 1) != "'")
         return true;
     return false;
 }
@@ -199,6 +206,21 @@ function debug(o) {
 }
 
 /**
+ * Simple assert function.
+ */
+function AssertException() {
+}
+
+AssertException.prototype.toString = function () {
+    return 'AssertException';
+};
+
+function assert(exp) {
+    if (!exp)
+        throw new AssertException();
+}
+
+/**
  * Write a list of strings.
  */
 function writeStrings(l) {
@@ -252,6 +274,16 @@ function unmemo(obj) {
 }
 
 /**
+ * Returns a list of the properties of an object.
+ */
+function properties(o) {
+    var a = new Array();
+    for (p in o)
+        a.push(p);
+    return a;
+}
+
+/**
  * Functions with side effects. Use with moderation.
  */
 

Added: tuscany/sca-cpp/trunk/modules/js/js-eval.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/js-eval.cpp?rev=1081204&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/js-eval.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/js/js-eval.cpp Sun Mar 13 19:24:08 2011
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+/**
+ * Evaluate a JavaScript script.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "fstream.hpp"
+#include "string.hpp"
+#include "eval.hpp"
+
+namespace tuscany {
+namespace js {
+
+bool eval() {
+    ostringstream os;
+    for(;;) {
+        int c = cin.get();
+        if (c == -1)
+            break;
+        os << (char)c;
+    }
+    failable<value> v = evalScript(str(os));
+    assert(hasContent(v));
+    cout << v;
+    return true;
+}
+
+}
+}
+
+int main() {
+    tuscany::js::eval();
+    return 0;
+}

Added: tuscany/sca-cpp/trunk/modules/js/json-test.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/json-test.js?rev=1081204&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/json-test.js (added)
+++ tuscany/sca-cpp/trunk/modules/js/json-test.js Sun Mar 13 19:24:08 2011
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.    
+ */
+
+/**
+ * Test JSON data encoding functions.
+ */
+function testJSON() {
+    var ad = mklist(mklist(attribute, "'city", "san francisco"), mklist(attribute, "'state", "ca"));
+    var ac = mklist(mklist(element, "'id", "1234"), mklist(attribute, "'balance", 1000));
+    var cr = mklist(mklist(attribute, "'name", "jdoe"), cons(element, cons("'address", ad)), cons(element, cons("'account", ac)));
+    var c = mklist(cons(element, cons("'customer", cr)));
+    var s = json.writeJSON(c);
+    assert(car(s) == "{\"customer\": {\"@name\": \"jdoe\", \"address\": {\"@city\": \"san francisco\", \"@state\": \"ca\"}, \"account\": {\"id\": \"1234\", \"@balance\": 1000}}}");
+
+    var phones = mklist("408-1234", "650-1234");
+    var l = mklist(mklist(element, "'phones", phones), mklist(element, "'lastName", "test\ttab"), mklist(attribute, "'firstName", "test1"));
+    var s2 = json.writeJSON(l);
+    assert(car(s2) == "{\"phones\": [\"408-1234\", \"650-1234\"], \"lastName\": \"test\\ttab\", \"@firstName\": \"test1\"}");
+
+    var r = json.readJSON(s2);
+    var w = json.writeJSON(r);
+    assert(car(w) == "{\"@firstName\": \"test1\", \"lastName\": \"test\\ttab\", \"phones\": [\"408-1234\", \"650-1234\"]}");
+
+    var l4 = mklist(mklist("'ns1:echoString", mklist("'@xmlns:ns1", "http://ws.apache.org/axis2/services/echo"), mklist("'text", "Hello World!")));
+    var s4 = json.writeJSON(valuesToElements(l4));
+    assert(car(s4) == "{\"ns1:echoString\": {\"@xmlns:ns1\": \"http://ws.apache.org/axis2/services/echo\", \"text\": \"Hello World!\"}}");
+
+    var r5 = elementsToValues(json.readJSON(s4));
+    var s5 = json.writeJSON(valuesToElements(r5));
+    assert(car(s5) == "{\"ns1:echoString\": {\"text\": \"Hello World!\", \"@xmlns:ns1\": \"http://ws.apache.org/axis2/services/echo\"}}");
+    return true;
+}
+
+testJSON();
+

Copied: tuscany/sca-cpp/trunk/modules/js/util-test (from r1081203, tuscany/sca-cpp/trunk/modules/js/Makefile.am)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/util-test?p2=tuscany/sca-cpp/trunk/modules/js/util-test&p1=tuscany/sca-cpp/trunk/modules/js/Makefile.am&r1=1081203&r2=1081204&rev=1081204&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/js/util-test Sun Mar 13 19:24:08 2011
@@ -1,3 +1,5 @@
+#!/bin/sh
+
 #  Licensed to the Apache Software Foundation (ASF) under one
 #  or more contributor license agreements.  See the NOTICE file
 #  distributed with this work for additional information
@@ -15,15 +17,14 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-incl_HEADERS = *.hpp
-incldir = $(prefix)/include/modules/js
-
-moddir = $(prefix)/modules/js
-nobase_dist_mod_DATA = htdocs/*.js htdocs/*.css
-EXTRA_DIST = htdocs/*.js htdocs/*.css
+# Run Javascript util test cases
+here=`readlink -f $0`; here=`dirname $here`
 
-js_test_SOURCES = js-test.cpp
-js_test_LDFLAGS = -lmozjs 
+echo "Testing..."
+cat htdocs/util.js htdocs/elemutil.js htdocs/jsonutil.js json-test.js | ./js-eval 2>/dev/null 1>&2
+rc=$?
+if [ "$rc" = "0" ]; then
+    echo "OK"
+fi
 
-noinst_PROGRAMS = js-test
-TESTS = js-test
+return $rc

Propchange: tuscany/sca-cpp/trunk/modules/js/util-test
------------------------------------------------------------------------------
    svn:executable = *

Modified: tuscany/sca-cpp/trunk/modules/server/server-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/server-conf?rev=1081204&r1=1081203&r2=1081204&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/server-conf (original)
+++ tuscany/sca-cpp/trunk/modules/server/server-conf Sun Mar 13 19:24:08 2011
@@ -61,6 +61,7 @@ Alias /util.js $jsprefix/htdocs/util.js
 Alias /elemutil.js $jsprefix/htdocs/elemutil.js
 Alias /xmlutil.js $jsprefix/htdocs/xmlutil.js
 Alias /atomutil.js $jsprefix/htdocs/atomutil.js
+Alias /jsonutil.js $jsprefix/htdocs/jsonutil.js
 Alias /ui.js $jsprefix/htdocs/ui.js
 Alias /ui.css $jsprefix/htdocs/ui.css
 Alias /scdl.js $jsprefix/htdocs/scdl.js
@@ -85,6 +86,10 @@ Require all granted
 AuthType None
 Require all granted
 </Location>
+<Location /jsonutil.js>
+AuthType None
+Require all granted
+</Location>
 <Location /ui.js>
 AuthType None
 Require all granted