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 2010/12/24 03:54:40 UTC

svn commit: r1052432 - in /tuscany/sca-cpp/trunk: etc/ kernel/ modules/atom/ modules/http/ modules/js/ modules/json/ modules/python/ modules/rss/ modules/scheme/ modules/server/

Author: jsdelfino
Date: Fri Dec 24 02:54:39 2010
New Revision: 1052432

URL: http://svn.apache.org/viewvc?rev=1052432&view=rev
Log:
Fix roundtripping of JSON arrays, booleans and numbers, ATOM / RSS feed detection, and support REST-style JSON and XML payloads in server handler and client proxy.

Added:
    tuscany/sca-cpp/trunk/modules/scheme/element-value.cpp
      - copied, changed from r1052431, tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
    tuscany/sca-cpp/trunk/modules/scheme/value-element.cpp
      - copied, changed from r1052431, tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
Modified:
    tuscany/sca-cpp/trunk/etc/git-exclude
    tuscany/sca-cpp/trunk/kernel/element.hpp
    tuscany/sca-cpp/trunk/kernel/stream.hpp
    tuscany/sca-cpp/trunk/modules/atom/atom.hpp
    tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
    tuscany/sca-cpp/trunk/modules/http/http.hpp
    tuscany/sca-cpp/trunk/modules/js/eval.hpp
    tuscany/sca-cpp/trunk/modules/json/json.hpp
    tuscany/sca-cpp/trunk/modules/python/eval.hpp
    tuscany/sca-cpp/trunk/modules/rss/rss.hpp
    tuscany/sca-cpp/trunk/modules/scheme/Makefile.am
    tuscany/sca-cpp/trunk/modules/scheme/io.hpp
    tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp

Modified: tuscany/sca-cpp/trunk/etc/git-exclude
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/etc/git-exclude?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/etc/git-exclude (original)
+++ tuscany/sca-cpp/trunk/etc/git-exclude Fri Dec 24 02:54:39 2010
@@ -110,4 +110,6 @@ xml-value
 value-xml
 json-value
 value-json
+element-value
+value-element
 

Modified: tuscany/sca-cpp/trunk/kernel/element.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/element.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/element.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/element.hpp Fri Dec 24 02:54:39 2010
@@ -100,7 +100,7 @@ const value elementHasValue(const list<v
     if (isSymbol(car(r)))
         return false;
     if(isList(car(r)) && !isNil((list<value>)car(r)) && isSymbol(car<value>(car(r))))
-            return false;
+        return false;
     return true;
 }
 
@@ -195,7 +195,7 @@ const value valueToElement(const value& 
     // Convert a name value pair
     if (isList(t) && !isNil((list<value>)t) && isSymbol(car<value>(t))) {
         const value n = car<value>(t);
-        const value v = cadr<value>(t);
+        const value v = isNil(cdr<value>(t))? value() : cadr<value>(t);
 
         // Convert a single value to an attribute or an element
         if (!isList(v)) {

Modified: tuscany/sca-cpp/trunk/kernel/stream.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/stream.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/stream.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/stream.hpp Fri Dec 24 02:54:39 2010
@@ -82,7 +82,7 @@ ostream& operator<<(ostream& os, const l
 }
 
 ostream& operator<<(ostream& os, const double v) {
-    return os.vprintf("%g", v);
+    return os.vprintf("%.10g", v);
 }
 
 ostream& operator<<(ostream& os, const void* v) {

Modified: tuscany/sca-cpp/trunk/modules/atom/atom.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/atom/atom.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/atom/atom.hpp Fri Dec 24 02:54:39 2010
@@ -57,12 +57,12 @@ const list<value> entriesElementsToValue
 }
 
 /**
- * Return true if a list of strings contains an RSS feed.
+ * Return true if a list of strings contains an ATOM feed.
  */
 const bool isATOMFeed(const list<string>& ls) {
     if (!isXML(ls))
         return false;
-    return contains(car(ls), "<feed");
+    return contains(car(ls), "<feed") && contains(car(ls), "=\"http://www.w3.org/2005/Atom\"");
 }
 
 /**
@@ -179,7 +179,9 @@ const failable<list<string> > writeATOMF
  * Convert an ATOM entry containing a value to an ATOM entry containing an item element.
  */
 const list<value> entryValuesToElements(const list<value> val) {
-    return cons(car(val), cons(cadr(val), valuesToElements(mklist<value>(cons<value>("item", (list<value>)caddr(val))))));
+    if (isList(caddr(val)))
+        return cons(car(val), cons(cadr(val), valuesToElements(mklist<value>(cons<value>("item", (list<value>)caddr(val))))));
+    return cons(car(val), cons(cadr(val), valuesToElements(mklist<value>(mklist<value>("item", caddr(val))))));
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/curl-get.cpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-get.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/curl-get.cpp Fri Dec 24 02:54:39 2010
@@ -36,7 +36,7 @@ const bool testGet(const string& url, co
     CURLSession ch(ca, cert, key);
     const failable<value> val = get(url, ch);
     assert(hasContent(val));
-    cout << val << endl;
+    cout << content(val) << endl;
     return true;
 }
 

Modified: tuscany/sca-cpp/trunk/modules/http/http.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/http.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/http.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/http.hpp Fri Dec 24 02:54:39 2010
@@ -399,10 +399,12 @@ const failable<value> get(const string& 
     const failable<list<list<string> > > res = get<list<string> >(rcons<string>, list<string>(), url, cs);
     if (!hasContent(res))
         return mkfailure<value>(reason(res));
-    const list<string> ls(reverse(cadr(content(res))));
-
     const string ct(content(contentType(car(content(res)))));
     debug(ct, "http::get::contentType");
+
+    const list<string> ls(reverse(cadr(content(res))));
+    debug(ls, "http::get::content");
+
     if (contains(ct, "application/atom+xml;type=entry")) {
         // Read an ATOM entry
         const value val(atom::entryValue(content(atom::readATOMEntry(ls))));
@@ -421,15 +423,22 @@ const failable<value> get(const string& 
         debug(val, "http::get::result");
         return val;
     }
-    if (contains(ct, "text/javascript") || contains(ct, "application/json")) {
+    if (contains(ct, "text/javascript") || contains(ct, "application/json") || json::isJSON(ls)) {
+        // Read a JSON document
         js::JSContext cx;
         const value val(json::jsonValues(content(json::readJSON(ls, cx))));
         debug(val, "http::get::result");
         return val;
     }
+    if (contains(ct, "text/xml") || contains(ct, "application/xml") || isXML(ls)) {
+        // Read an XML document
+        const value val(elementsToValues(readXML(ls)));
+        debug(val, "http::get::result");
+        return val;
+    }
 
-    // Return the content as a list of values
-    const value val(mkvalues(ls));
+    // Return the content type and a content list
+    const value val(mklist<value>(ct, mkvalues(ls)));
     debug(val, "http::get::result");
     return val;
 }
@@ -617,11 +626,26 @@ const failable<size_t> recv(char* c, con
 struct proxy {
     proxy(const string& uri, const string& ca, const string& cert, const string& key, const gc_pool& p) : p(p), uri(uri), ca(ca), cert(cert), key(key), cs(*(new (gc_new<CURLSession>(p)) CURLSession(ca, cert, key))) {
     }
-
+    
     const value operator()(const list<value>& args) const {
-        failable<value> val = evalExpr(args, uri, cs);
-        if (!hasContent(val))
-            return value();
+        const value fun = car(args);
+        if (fun == "get") {
+            const failable<value> val = get(uri + path(cadr(args)), cs);
+            return content(val);
+        }
+        if (fun == "post") {
+            const failable<value> val = post(caddr(args), uri + path(cadr(args)), cs);
+            return content(val);
+        }
+        if (fun == "put") {
+            const failable<value> val = put(caddr(args), uri + path(cadr(args)), cs);
+            return content(val);
+        }
+        if (fun == "delete") {
+            const failable<value> val = del(uri + path(cadr(args)), cs);
+            return content(val);
+        }
+        const failable<value> val = evalExpr(args, uri, cs);
         return content(val);
     }
 

Modified: tuscany/sca-cpp/trunk/modules/js/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/eval.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/js/eval.hpp Fri Dec 24 02:54:39 2010
@@ -229,7 +229,9 @@ const jsval valueToJSVal(const value& va
     JSObject* valuesToJSProperties(JSObject* o, const list<value>& l, const js::JSContext& cx);
 
     switch(type(val)) {
-    case value::String:
+    case value::String: {
+        return STRING_TO_JSVAL(JS_NewStringCopyZ(cx, c_str((string)val)));
+    }
     case value::Symbol: {
         return STRING_TO_JSVAL(JS_NewStringCopyZ(cx, c_str((string)val)));
     }

Modified: tuscany/sca-cpp/trunk/modules/json/json.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/json/json.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/json/json.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/json/json.hpp Fri Dec 24 02:54:39 2010
@@ -37,6 +37,16 @@ namespace tuscany {
 namespace json {
 
 /**
+ * Return true if a list of strings contains a JSON document.
+ */
+const bool isJSON(const list<string>& ls) {
+    if (isNil(ls))
+        return false;
+    const string s = substr(car(ls), 0, 1);
+    return s == "[" || s == "{";
+}
+
+/**
  * Consumes JSON strings and populates a JS object.
  */
 failable<bool> consume(JSONParser* parser, const list<string>& ilist, const js::JSContext& cx) {
@@ -93,7 +103,11 @@ template<typename R> JSBool writeCallbac
  * Convert a list of values to a JSON document.
  */
 template<typename R> const failable<R> writeJSON(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l, const js::JSContext& cx) {
-    jsval val = OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), l, cx));
+    jsval val;
+    if (js::isJSArray(l))
+        val = OBJECT_TO_JSVAL(valuesToJSElements(JS_NewArrayObject(cx, 0, NULL), l, 0, cx));
+    else
+        val = OBJECT_TO_JSVAL(valuesToJSProperties(JS_NewObject(cx, NULL, NULL, NULL), l, cx));
 
     WriteContext<R> wcx(reduce, initial, cx);
     if (!JS_Stringify(cx, &val, NULL, JSVAL_NULL, writeCallback<R>, &wcx))

Modified: tuscany/sca-cpp/trunk/modules/python/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/python/eval.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/python/eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/python/eval.hpp Fri Dec 24 02:54:39 2010
@@ -222,7 +222,6 @@ const list<value> pyTupleToValuesHelper(
 }
 
 const list<value> pyTupleToValues(PyObject* o) {
-    debug(pyRepr(o), "python::pyTupleToValues");
     return pyTupleToValuesHelper(o, 0, PyTuple_Size(o));
 }
 

Modified: tuscany/sca-cpp/trunk/modules/rss/rss.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/rss/rss.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/rss/rss.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/rss/rss.hpp Fri Dec 24 02:54:39 2010
@@ -62,7 +62,7 @@ const list<value> entriesElementsToValue
 const bool isRSSFeed(const list<string>& ls) {
     if (!isXML(ls))
         return false;
-    return contains(car(ls), "<rss");
+    return contains(car(ls), "<rss") && contains(car(ls), "");
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/modules/scheme/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/Makefile.am?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/Makefile.am Fri Dec 24 02:54:39 2010
@@ -22,11 +22,17 @@ eval_test_SOURCES = eval-test.cpp
 
 eval_shell_SOURCES = eval-shell.cpp
 
+value_element_SOURCES = value-element.cpp
+value_element_LDFLAGS = 
+
+element_value_SOURCES = element-value.cpp
+element_value_LDFLAGS = 
+
 xml_value_SOURCES = xml-value.cpp
-xml_value_LDFLAGS =  -lxml2
+xml_value_LDFLAGS = -lxml2
 
 value_xml_SOURCES = value-xml.cpp
-value_xml_LDFLAGS =  -lxml2
+value_xml_LDFLAGS = -lxml2
 
 json_value_SOURCES = json-value.cpp
 json_value_LDFLAGS = -lmozjs 
@@ -34,5 +40,5 @@ json_value_LDFLAGS = -lmozjs 
 value_json_SOURCES = value-json.cpp
 value_json_LDFLAGS = -lmozjs 
 
-noinst_PROGRAMS = eval-test eval-shell xml-value value-xml json-value value-json
+noinst_PROGRAMS = eval-test eval-shell element-value value-element xml-value value-xml json-value value-json
 TESTS = eval-test

Copied: tuscany/sca-cpp/trunk/modules/scheme/element-value.cpp (from r1052431, tuscany/sca-cpp/trunk/modules/http/curl-get.cpp)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/element-value.cpp?p2=tuscany/sca-cpp/trunk/modules/scheme/element-value.cpp&p1=tuscany/sca-cpp/trunk/modules/http/curl-get.cpp&r1=1052431&r2=1052432&rev=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-get.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/element-value.cpp Fri Dec 24 02:54:39 2010
@@ -20,34 +20,27 @@
 /* $Rev$ $Date$ */
 
 /**
- * HTTP GET command line test tool.
+ * Convert a scheme value representing an element to a value.
  */
 
-#include <assert.h>
-#include "stream.hpp"
+#include "fstream.hpp"
 #include "string.hpp"
-#include "perf.hpp"
-#include "http.hpp"
+#include "element.hpp"
+#include "eval.hpp"
 
 namespace tuscany {
-namespace http {
+namespace scheme {
 
-const bool testGet(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
-    CURLSession ch(ca, cert, key);
-    const failable<value> val = get(url, ch);
-    assert(hasContent(val));
-    cout << val << endl;
-    return true;
+int elementValue() {
+    const value v = elementsToValues(readValue(cin));
+    cout << writeValue(v);
+    return 0;
 }
 
 }
 }
 
-int main(unused const int argc, const char** argv) {
-    if (argc > 2)
-        tuscany::http::testGet(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
-    else
-        tuscany::http::testGet(tuscany::string(argv[1]));
-    return 0;
+int main() {
+    return tuscany::scheme::elementValue();
 }
 

Modified: tuscany/sca-cpp/trunk/modules/scheme/io.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/io.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/io.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/io.hpp Fri Dec 24 02:54:39 2010
@@ -154,7 +154,12 @@ const list<char> readIdentifierHelper(co
 }
 
 const value readIdentifier(const char chr, istream& in) {
-    return c_str(listToString(readIdentifierHelper(mklist(chr), in)));
+    const value val = c_str(listToString(readIdentifierHelper(mklist(chr), in)));
+    if (val == "false")
+        return value((bool)false);
+    if (val == "true")
+        return value((bool)true);
+    return val;
 }
 
 const list<char> readStringHelper(const list<char>& listSoFar, istream& in) {

Copied: tuscany/sca-cpp/trunk/modules/scheme/value-element.cpp (from r1052431, tuscany/sca-cpp/trunk/modules/http/curl-get.cpp)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/value-element.cpp?p2=tuscany/sca-cpp/trunk/modules/scheme/value-element.cpp&p1=tuscany/sca-cpp/trunk/modules/http/curl-get.cpp&r1=1052431&r2=1052432&rev=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-get.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/value-element.cpp Fri Dec 24 02:54:39 2010
@@ -20,34 +20,27 @@
 /* $Rev$ $Date$ */
 
 /**
- * HTTP GET command line test tool.
+ * Convert a scheme value to a value representing an element.
  */
 
-#include <assert.h>
-#include "stream.hpp"
+#include "fstream.hpp"
 #include "string.hpp"
-#include "perf.hpp"
-#include "http.hpp"
+#include "element.hpp"
+#include "eval.hpp"
 
 namespace tuscany {
-namespace http {
+namespace scheme {
 
-const bool testGet(const string& url, const string& ca = "", const string& cert = "", const string& key = "") {
-    CURLSession ch(ca, cert, key);
-    const failable<value> val = get(url, ch);
-    assert(hasContent(val));
-    cout << val << endl;
-    return true;
+int valueElement() {
+    const value v = valuesToElements(readValue(cin));
+    cout << writeValue(v);
+    return 0;
 }
 
 }
 }
 
-int main(unused const int argc, const char** argv) {
-    if (argc > 2)
-        tuscany::http::testGet(tuscany::string(argv[1]), tuscany::string(argv[2]), tuscany::string(argv[3]), tuscany::string(argv[4]));
-    else
-        tuscany::http::testGet(tuscany::string(argv[1]));
-    return 0;
+int main() {
+    return tuscany::scheme::valueElement();
 }
 

Modified: tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp?rev=1052432&r1=1052431&r2=1052432&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/server/mod-eval.hpp Fri Dec 24 02:54:39 2010
@@ -130,15 +130,21 @@ const failable<int> get(request_rec* r, 
         return mkfailure<int>(reason(val));
     const value c = content(val);
 
-    // Write returned content-type / content-list pair
-    if (isList(cadr<value>(c)))
+    // Write content-type / content-list pair
+    if (isString(car<value>(c)) && isList(cadr<value>(c)))
         return httpd::writeResult(convertValues<string>(cadr<value>(c)), car<value>(c), r);
 
-    // Write returned ATOM feed or entry
-    if (isNil(cddr(path)))
-        return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(c)), "application/atom+xml;type=feed", r);
-    else
-        return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(c)), "application/atom+xml;type=entry", r);
+    // Write ATOM feed or entry
+    if (isString(car<value>(c)) && isString(cadr<value>(c))) {
+        if (isNil(cddr(path)))
+            return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(c)), "application/atom+xml;type=feed", r);
+        else
+            return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(c)), "application/atom+xml;type=entry", r);
+    }
+
+    // Write JSON value
+    js::JSContext cx;
+    return httpd::writeResult(json::writeJSON(valuesToElements(c), cx), "application/json", r);
 }
 
 /**