tuscany-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jsdelf...@apache.org
Subject svn commit: r1517412 - in /tuscany/sca-cpp/trunk: components/cache/ components/sqldb/ hosting/server/ kernel/ modules/atom/ modules/js/htdocs/ modules/wsgi/
Date Mon, 26 Aug 2013 03:04:23 GMT
Author: jsdelfino
Date: Mon Aug 26 03:04:23 2013
New Revision: 1517412

URL: http://svn.apache.org/r1517412
Log:
Support sorting database search results by rank, and add a rank attribute to ATOM entries.

Modified:
    tuscany/sca-cpp/trunk/components/cache/partitioner.cpp
    tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp
    tuscany/sca-cpp/trunk/hosting/server/atomutil.py
    tuscany/sca-cpp/trunk/kernel/element.hpp
    tuscany/sca-cpp/trunk/kernel/kernel-test.cpp
    tuscany/sca-cpp/trunk/kernel/list.hpp
    tuscany/sca-cpp/trunk/kernel/tree.hpp
    tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp
    tuscany/sca-cpp/trunk/modules/atom/atom.hpp
    tuscany/sca-cpp/trunk/modules/js/htdocs/atomutil.js
    tuscany/sca-cpp/trunk/modules/js/htdocs/elemutil.js
    tuscany/sca-cpp/trunk/modules/wsgi/atomutil.py

Modified: tuscany/sca-cpp/trunk/components/cache/partitioner.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/partitioner.cpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/partitioner.cpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/partitioner.cpp Mon Aug 26 03:04:23 2013
@@ -31,6 +31,7 @@
 #include "string.hpp"
 #include "function.hpp"
 #include "list.hpp"
+#include "tree.hpp"
 #include "value.hpp"
 #include "monad.hpp"
 
@@ -78,9 +79,53 @@ const failable<list<value> > getlist(con
 }
 
 /**
+ * Return the rank of a result item if available.
+ */
+const value itemrank(const value& val) {
+    if (isList(val) && !isNull(val)) {
+        const value e = car<value>(val);
+        if (isList(e) && !isNull(e)) {
+            if (car<value>(e) == "entry") {
+                const list<value> ae = cdr<value>(e);
+                const list<value> li = assoc<value>("id", ae);
+                const list<value> lr = assoc<value>("rank", ae);
+                if (!isNull(li) && !isNull(lr))
+                    return mklist<value>(lr, li);
+            }
+        }
+    }
+    return val;
+}
+
+/**
+ * Compare the ranks of two result items.
+ */
+const int rankitems(const value& a, const value& b) {
+    const value ra = itemrank(a);
+    const value rb = itemrank(b);
+    if (ra == rb)
+        return 0;
+    if (ra < rb)
+        return -1;
+    return 1;
+}
+
+/**
+ * Convert a key to a (param name, value) assoc.
+ */
+const list<value> keyparams(const list<value>& key) {
+    if (isNull(key))
+        return nilListValue;
+    if (!isList(car(key)))
+        return keyparams(cdr(key));
+    return cons<value>(car(key), keyparams(cdr(key)));
+}
+
+/**
  * Get an item from a partition.
  */
 const failable<value> get(const value& key, const lvvlambda& selector, const
list<value>& partitions) {
+    debug(key, "partitioner::get::key");
 
     // Select partition
     const failable<list<value> > fp = partition(key, selector, partitions);
@@ -97,6 +142,7 @@ const failable<value> get(const value& k
             os << "Couldn't get entry from partition: " << key;
             return mkfailure<value>(str(os), 404, false);
         }
+        debug(val, "partitioner::get::val");
         return val;
     }
 
@@ -104,7 +150,17 @@ const failable<value> get(const value& k
     const failable<list<value> > val = getlist(key, p);
     if (!hasContent(val))
         return mkfailure<value>(val);
-    return (value)content(val);
+    const list<value> cval = content(val);
+    debug(cval, "partitioner::get::cval");
+
+    // Apply any ranking sort and result limit
+    const list<value> kparams = isList(key)? keyparams(key) : nilListValue;
+    const list<value> sval = (!isNull(assoc<value>("textsearch", kparams)) ||
!isNull(assoc<value>("rank", kparams)))? reverse<value>(sort<value>(cval,
rankitems)) : cval;
+    const list<value> limit = assoc<value>("limit", kparams);
+    const list<value> lval = !isNull(limit)? listHead(sval, (int)cadr(limit)) : sval;
+    debug(lval, "partitioner::get::lval");
+
+    return (value)lval;
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp Mon Aug 26 03:04:23 2013
@@ -339,13 +339,50 @@ const list<value> keyparams(const list<v
 }
 
 /**
- * Convert a get result to a list of items.
+ * Convert an SQL result row to a result item.
  */
-const list<value> getitems(PGresult* const r, const int i, const int n) {
+const value getitem(PGresult* const r, const int i, const int rk) {
+    const value val(content(scheme::readValue(string(PQgetvalue(r, i, 1)))));
+    if (rk > 0) {
+        // Add row tsrank and rank to result item if it's an ATOM entry
+        if (isList(val) && !isNull(val)) {
+            const value e = car<value>(val);
+            if (isList(e) && !isNull(e)) {
+                if (car<value>(e) == "entry") {
+                    const list<value> ae = cdr<value>(e);
+                    const list<value> lt = assoc<value>("title", ae);
+                    const list<value> li = assoc<value>("id", ae);
+                    const list<value> la = assoc<value>("author", ae);
+                    const list<value> lu = assoc<value>("updated", ae);
+                    const list<value> lc = assoc<value>("content", ae);
+
+                    ostringstream ros;
+                    ros << string(PQgetvalue(r, i, 2));
+                    if (rk > 1)
+                        ros << " " << string(PQgetvalue(r, i, 3));
+                    const list<value> lr = mklist<value>("rank", str(ros));
+
+                    const value rval = mklist<value>("entry") +
+                        (isNull(lt)? nilListValue : lt) + (isNull(li)? nilListValue : li)
+ (isNull(la)? nilListValue : la) +
+                        (isNull(lu)? nilListValue : lu) + lr + (isNull(lc)? nilListValue
: lc);
+                    debug(rval, "pgsql::getitem::rval");
+                    return mklist<value>(rval);
+                }
+            }
+        }
+    }
+
+    debug(val, "pgsql::getitem::val");
+    return val;
+}
+
+/**
+ * Convert an SQL result to a list of result items.
+ */
+const list<value> getitems(PGresult* const r, const int i, const int n, const int rk)
{
     if (i == n)
         return nilListValue;
-    const value val(content(scheme::readValue(string(PQgetvalue(r, i, 1)))));
-    return cons<value>(val, getitems(r, i + 1, n));
+    return cons<value>(getitem(r, i, rk), getitems(r, i + 1, n, rk));
 }
 
 /**
@@ -396,42 +433,51 @@ const failable<value> get(const value& k
     const char* sqlparams[6];
     int p = 0;
     int w = 0;
+    int rk = 0;
     ostringstream sqlos;
     sqlos << "select data." << kname << ", data." << vname;
     if (!isNull(textsearch)) {
         // Text search, setup text result ranking
         sqlos << ", ts_rank_cd(to_tsvector(data." << vname << "), tsquery,
32) as tsrank";
+        rk++;
     }
     if (!isNull(rank)) {
         // Ranking, setup rank expression
         const string rs = (string)cadr(rank);
-        sqlparams[p++] = c_str(rs);
-        sqlos << ", $" << p << " as rank";
+        sqlos << ", " << rs << " as rank";
+        rk++;
     }
     sqlos << " from " << table << " data";
     if (!isNull(textsearch)) {
         // Text search, define the query
         const string ts = tstranslate((string)cadr(textsearch));
+        debug(ts, "pgsql::get::sqlparam");
         sqlparams[p++] = c_str(ts);
         sqlos << ", plainto_tsquery($" << p << ") tsquery";
     }
     if (!lk || !isNull(id)) {
         // Query of the form key = id
-        sqlparams[p++] = c_str(write(content(scheme::writeValue(lk? (value)id : key))));
+        const string ks = write(content(scheme::writeValue(lk? (value)id : key)));
+        debug(ks, "pgsql::get::sqlparam");
+        sqlparams[p++] = c_str(ks);
         sqlos << (w == 0? " where" : " and");
         sqlos << " data." << kname << " = $" << p;
         w++;
     }
     if (!isNull(regex)) {
         // Query of the form key ~ param
-        sqlparams[p++] = c_str((string)cadr(regex));
+        const string rs = cadr(regex);
+        debug(rs, "pgsql::get::sqlparam");
+        sqlparams[p++] = c_str(rs);
         sqlos << (w == 0? " where" : " and");
         sqlos << " data." << kname << " ~ $" << p;
         w++;
     }
     if (!isNull(like)) {
         // Query of the form key like param
-        sqlparams[p++] = c_str((string)cadr(like));
+        const string ls = cadr(like);
+        debug(ls, "pgsql::get::sqlparam");
+        sqlparams[p++] = c_str(ls);
         sqlos << (w == 0? " where" : " and");
         sqlos << " data." << kname << " like $" << p;
         w++;
@@ -442,7 +488,7 @@ const failable<value> get(const value& k
         sqlos << " tsquery @@ to_tsvector(data." << vname << ")";
         w++;
     }
-    if (!isNull(textsearch) || !isNull(rank)) {
+    if (!isNull(rank) || !isNull(textsearch)) {
         // Result ordering
         sqlos << " order by" << (isNull(rank)? "" : " rank desc") << ((isNull(rank)
|| isNull(textsearch))? "" : ",") << (isNull(textsearch)? "" : " tsrank desc");
     }
@@ -473,14 +519,14 @@ const failable<value> get(const value& k
 
     // Return a collection of items
     if (l != 1) {
-        const list<value> lval = getitems(r, 0, n);
+        const list<value> lval = getitems(r, 0, n, rk);
         PQclear(r);
         debug(lval, "pgsql::get::result");
         return (value)lval;
     }
 
     // Return a single item
-    const value val(content(scheme::readValue(string(PQgetvalue(r, 0, 1)))));
+    const value val = getitem(r, 0, rk);
     PQclear(r);
     debug(val, "pgsql::get::result");
     return val;

Modified: tuscany/sca-cpp/trunk/hosting/server/atomutil.py
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/hosting/server/atomutil.py?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/hosting/server/atomutil.py (original)
+++ tuscany/sca-cpp/trunk/hosting/server/atomutil.py Mon Aug 26 03:04:23 2013
@@ -32,7 +32,7 @@ def title(e):
     if isNull(e):
         return ()
     t = assoc("'title", car(e))
-    return None if isNull(t) else cadr(t)
+    return None if isNull(t) or isNull(cdr(t)) else cadr(t)
 
 def entryid(e):
     if isNull(e):
@@ -52,6 +52,12 @@ def updated(e):
     u = assoc("'updated", car(e))
     return None if isNull(u) else cadr(u)
 
+def rank(e):
+    if isNull(e):
+        return ()
+    r = assoc("'rank", car(e))
+    return None if isNull(r) else cadr(r)
+
 def content(e):
     if isNull(e):
         return ()

Modified: tuscany/sca-cpp/trunk/kernel/element.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/element.hpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/element.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/element.hpp Mon Aug 26 03:04:23 2013
@@ -167,6 +167,8 @@ inline const bool elementToValueIsSymbol
 }
 
 inline const list<value> elementToValueGroupValues(const value& v, const list<value>&
l) {
+    debug(v, "elementToValueGroupValues::v");
+    debug(l, "elementToValueGroupValues::l");
     if (isNull(l) || !elementToValueIsSymbol(v) || !elementToValueIsSymbol(car(l)))
         return cons(v, l);
     if (car<value>(car(l)) != car<value>(v))
@@ -175,7 +177,8 @@ inline const list<value> elementToValueG
         const value g = mklist<value>(car<value>(v), mklist<value>(isList(cadr<value>(v))?
(value)cdr<value>(v) : cadr<value>(v), isList(cadr<value>(car(l)))? (value)cdr<value>(car(l))
: cadr<value>(car(l))));
         return elementToValueGroupValues(g, cdr(l));
     }
-    const value g = mklist<value>(car<value>(v), cons<value>(isList(cadr<value>(v))?
(value)cdr<value>(v) : cadr<value>(v), (list<value>)cadr<value>(car(l))));
+    const value g = isNull(cdr<value>(v))? mklist<value>(car<value>(v),
(list<value>)cadr<value>(car(l))) :
+        mklist<value>(car<value>(v), cons<value>(isList(cadr<value>(v))?
(value)cdr<value>(v) : cadr<value>(v), (list<value>)cadr<value>(car(l))));
     return elementToValueGroupValues(g, cdr(l));
 
 }

Modified: tuscany/sca-cpp/trunk/kernel/kernel-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/kernel-test.cpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/kernel-test.cpp (original)
+++ tuscany/sca-cpp/trunk/kernel/kernel-test.cpp Mon Aug 26 03:04:23 2013
@@ -477,6 +477,19 @@ const bool testAppend() {
     return true;
 }
 
+const bool testSublist() {
+    assert(listHead(mklist(1, 2), 0) == list<int>());
+    assert(listHead(mklist(1, 2), 1) == mklist(1));
+    assert(listHead(mklist(1, 2), 2) == mklist(1, 2));
+    assert(listHead(mklist(1, 2), 3) == mklist(1, 2));
+
+    assert(listTail(mklist(1, 2), 0) == mklist(1, 2));
+    assert(listTail(mklist(1, 2), 1) == mklist(2));
+    assert(listTail(mklist(1, 2), 2) == list<int>());
+    assert(listTail(mklist(1, 2), 3) == list<int>());
+    return true;
+}
+
 class Complex {
 public:
     Complex() : x(0), y(0) {
@@ -675,7 +688,7 @@ const double testSeqMap(const double x) 
     return x;
 }
 
-double testSeqReduce(unused const double v, const double accum) {
+double testSeqReduce(const double accum, unused const double v) {
     return accum + 1.0;
 }
 
@@ -956,6 +969,7 @@ int main() {
     tuscany::testEquals();
     tuscany::testLength();
     tuscany::testAppend();
+    tuscany::testSublist();
     tuscany::testComplex();
     tuscany::testMap();
     tuscany::testReduce();

Modified: tuscany/sca-cpp/trunk/kernel/list.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/list.hpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/list.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/list.hpp Mon Aug 26 03:04:23 2013
@@ -523,6 +523,17 @@ template<typename T> inline const T list
 }
 
 /**
+ * Returns a new list consisting of the first k elements of a list.
+ */
+template<typename T> inline const list<T> listHead(const list<T>& l,
const size_t k) noexcept {
+    if(k == 0)
+        return list<T>();
+    if(isNull(l))
+        return l;
+    return cons<T>(car(l), listHead(cdr(l), k - 1));
+}
+
+/**
  * Returns the tail of a list, ommiting the first k elements.
  */
 template<typename T> inline const list<T> listTail(const list<T>& l,
const size_t k) noexcept {

Modified: tuscany/sca-cpp/trunk/kernel/tree.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/tree.hpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/tree.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/tree.hpp Mon Aug 26 03:04:23 2013
@@ -174,25 +174,37 @@ template<typename T> inline const list<T
 }
 
 /**
+ * Default function used to compare two values while building a rooted binary tree.
+ */
+template<typename T> inline const int rbtreeComp(const T& a, const T& b) {
+    if (a == b)
+        return 0;
+    if (a < b)
+        return -1;
+    return 1;
+}
+
+/**
  * Construct a new rooted binary tree from a leaf and a tree.
  */
-template<typename T> inline const list<T> rbtreeCons(const T& e, const list<T>&
tree) {
+template<typename T> inline const list<T> rbtreeCons(const T& e, const list<T>&
tree, const lambda<int(const T&, const T&)>& comp = rbtreeComp<T>)
{
     if (isNull(tree))
         return mkrbtree(e, list<T>(), list<T>());
-    if (e == car(tree))
+    const int c = comp(e, car(tree));
+    if (c == 0)
         return tree;
-    if (e < car(tree))
-        return mkrbtree<T>(car(tree), rbtreeCons<T>(e, cadr(tree)), caddr(tree));
-    return mkrbtree<T>(car(tree), cadr(tree), rbtreeCons<T>(e, caddr(tree)));
+    if (c == -1)
+        return mkrbtree<T>(car(tree), rbtreeCons<T>(e, cadr(tree), comp), caddr(tree));
+    return mkrbtree<T>(car(tree), cadr(tree), rbtreeCons<T>(e, caddr(tree), comp));
 }
 
 /**
  * Make a rooted binary tree from an unordered list of leaves.
  */
-template<typename T> inline const list<T> mkrbtree(const list<T>& l)
{
+template<typename T> inline const list<T> mkrbtree(const list<T>& l,
const lambda<int(const T&, const T&)>& comp = rbtreeComp<T>) {
     if (isNull(l))
         return l;
-    return rbtreeCons(car(l), mkrbtree(cdr(l)));
+    return rbtreeCons(car(l), mkrbtree(cdr(l), comp), comp);
 }
 
 /**
@@ -207,8 +219,8 @@ template<typename T> inline const list<T
 /**
  * Sort a list, using a rooted binary tree.
  */
-template<typename T> inline const list<T> sort(const list<T>& l) {
-    return flatten(mkrbtree(l));
+template<typename T> inline const list<T> sort(const list<T>& l,  const
lambda<int(const T&, const T&)>& comp = rbtreeComp<T>) {
+    return flatten(mkrbtree(l, comp));
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp Mon Aug 26 03:04:23 2013
@@ -77,6 +77,17 @@ const string itemNoContentEntry("<?xml v
         "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
         "</entry>\n");
 
+const string itemEmptyTitleEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+        "<title type=\"text\"></title>"
+        "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>"
+        "<author>"
+        "<name>jane</name>"
+        "</author>"
+        "<updated>Fri Jan 01 08:11:36 PDT 2012</updated>"
+        "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
+        "</entry>\n");
+
 const string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">\n"
         "<title>item</title>"
         "<content type=\"text/xml\">"
@@ -155,6 +166,12 @@ const bool testEntry() {
         assert(str(os) == itemNoContentEntry);
     }
     {
+        const list<value> a = content(readATOMEntry(mklist(itemEmptyTitleEntry)));
+        ostringstream os;
+        writeATOMEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemEmptyTitleEntry);
+    }
+    {
         const list<value> a = content(readATOMEntry(mklist(incompleteEntry)));
         ostringstream os;
         writeATOMEntry<ostream*>(writer, &os, a);

Modified: tuscany/sca-cpp/trunk/modules/atom/atom.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/atom/atom.hpp?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/atom/atom.hpp Mon Aug 26 03:04:23 2013
@@ -46,7 +46,7 @@ const value entry("entry");
  */
 const list<value> entryElementValues(const list<value>& e) {
     const list<value> lt = elementChildren("title", e);
-    const list<value> t = nilListValue + element + value("title") + (isNull(lt)? value(emptyString)
: elementValue(car(lt)));
+    const list<value> t = nilListValue + element + value("title") + (isNull(lt) ||
!elementHasValue(car(lt))? value(emptyString) : elementValue(car(lt)));
 
     const list<value> li = elementChildren("id", e);
     const list<value> i = nilListValue + element + value("id") + (isNull(li)? value(emptyString)
: elementValue(car(li)));
@@ -60,11 +60,14 @@ const list<value> entryElementValues(con
     const list<value> lu = elementChildren("updated", e);
     const list<value> u = isNull(lu)? nilListValue : mklist<value>(nilListValue
+ element + value("updated") + elementValue(car(lu)));
 
+    const list<value> lr = elementChildren("rank", e);
+    const list<value> r = isNull(lr)? nilListValue : mklist<value>(nilListValue
+ element + value("rank") + elementValue(car(lr)));
+
     const list<value> lc = elementChildren("content", e);
     const list<value> c = isNull(lc)? nilListValue : isAttribute(elementValue(car(lc)))?
nilListValue :
         mklist<value>(nilListValue + element + value("content") + elementValue(car(lc)));
 
-    return append<value>(append<value>(append<value>(nilListValue + element
+ entry + value(t) + value(i), a), u), c);
+    return append<value>(append<value>(append<value>(append<value>(nilListValue
+ element + entry + value(t) + value(i), a), u), r), c);
 }
 
 /**
@@ -138,15 +141,17 @@ const list<value> entryElement(const lis
     const value author = elementChild("author", l);
     const bool email = isNull(author)? false : contains(elementValue(author), "@");
     const value updated = elementChild("updated", l);
+    const value rank = elementChild("rank", l);
     const value content = elementChild("content", l);
     const bool text = isNull(content)? false : elementHasValue(content);
     return nilListValue
         + element + entry + (nilListValue + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
-        + (nilListValue + element + "title" + (nilListValue + attribute + "type" + "text")
+ elementValue(title))
+        + (nilListValue + element + "title" + (nilListValue + attribute + "type" + "text")
+ (elementHasValue(title)? elementValue(title) : value("")))
         + (nilListValue + element + "id" + elementValue(id))
         + (isNull(author)? nilListValue : (nilListValue + element + "author" +
             (email? (nilListValue + element + "email" + elementValue(author)) : (nilListValue
+ element + "name" + elementValue(author)))))
         + (isNull(updated)? nilListValue : (nilListValue + element + "updated" + elementValue(updated)))
+        + (isNull(rank)? nilListValue : (nilListValue + element + "rank" + elementValue(rank)))
         + (isNull(content)?
             nilListValue :
             append<value>(nilListValue + element + "content" + (nilListValue + attribute
+ "type" + (text? "text" : "application/xml")),

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/atomutil.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/atomutil.js?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/atomutil.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/atomutil.js Mon Aug 26 03:04:23 2013
@@ -27,24 +27,27 @@ var atom = {};
  */
 atom.entryElementValues = function(e) {
     var lt = filter(selector(mklist(element, "'title")), e);
-    var t = mklist(element, "'title", isNull(lt)? '' : elementValue(car(lt)));
+    var t = mklist(element, "'title", isNull(lt) || !elementHasValue(car(lt))? '' : elementValue(car(lt)));
 
     var li = filter(selector(mklist(element, "'id")), e);
     var i = mklist(element, "'id", isNull(li)? '' : elementValue(car(li)));
 
     var la = filter(selector(mklist(element, "'author")), e);
-    var lan = isNull(la)? mklist() : filter(selector(mklist(element, "'name")), car(la));
-    var lae = isNull(la)? mklist() : filter(selector(mklist(element, "'email")), car(la));
+    var lan = isNull(la)? nil : filter(selector(mklist(element, "'name")), car(la));
+    var lae = isNull(la)? nil : filter(selector(mklist(element, "'email")), car(la));
     var laa = isNull(lan)? lae : lan;
-    var a = isNull(laa)? mklist() : mklist(mklist(element, "'author", elementValue(car(laa))));
+    var a = isNull(laa)? nil : mklist(mklist(element, "'author", elementValue(car(laa))));
 
     var lu = filter(selector(mklist(element, "'updated")), e);
-    var u = isNull(lu)? mklist() : mklist(mklist(element, "'updated", elementValue(car(lu))));
+    var u = isNull(lu)? nil : mklist(mklist(element, "'updated", elementValue(car(lu))));
+
+    var lr = filter(selector(mklist(element, "'rank")), e);
+    var r = isNull(lr)? nil : mklist(mklist(element, "'rank", elementValue(car(lr))));
 
     var lc = filter(selector(mklist(element, "'content")), e);
-    var c = isNull(lc)? mklist() : isAttribute(elementValue(car(lc)))? mklist() : mklist(mklist(element,
"'content", elementValue(car(lc))));
+    var c = isNull(lc)? nil : isAttribute(elementValue(car(lc)))? nil : mklist(mklist(element,
"'content", elementValue(car(lc))));
 
-    return append(append(append(mklist(element, "'entry", t, i), a), u), c);
+    return append(append(append(append(mklist(element, "'entry", t, i), a), u), r), c);
 };
 
 /**
@@ -71,7 +74,7 @@ atom.isATOMEntry = function(l) {
 atom.readATOMEntryDocument = function(doc) {
     var e = readXMLDocument(doc);
     if (isNull(e))
-        return mklist();
+        return nil;
     return mklist(atom.entryElementValues(car(e)));
 };
 
@@ -97,7 +100,7 @@ atom.isATOMFeed = function(l) {
 atom.readATOMFeedDocument = function(doc) {
     var f = readXMLDocument(doc);
     if (isNull(f))
-        return mklist();
+        return nil;
     var t = filter(selector(mklist(element, "'title")), car(f));
     var i = filter(selector(mklist(element, "'id")), car(f));
     var e = filter(selector(mklist(element, "'entry")), car(f));
@@ -117,20 +120,23 @@ atom.readATOMFeed = function(l) {
  * Convert a list of values representy an ATOM entry to a list of elements.
  */
 atom.entryElement = function(l) {
-    var title = elementValue(namedElementChild("'title", l));
+    var etitle = namedElementChild("'title", l);
+    var title = elementHasValue(etitle)? elementValue(etitle) : '';
     var id = elementValue(namedElementChild("'id", l));
     var author = namedElementChild("'author", l);
     var email = isNull(author)? false : (elementValue(author).indexOf('@') != -1);
     var updated = namedElementChild("'updated", l);
+    var rank = namedElementChild("'rank", l);
     var content = namedElementChild("'content", l);
     var text = isNull(content)? false : elementHasValue(content);
-    return append(append(append(append(
+    return append(append(append(append(append(
             mklist(element, "'entry", mklist(attribute, "'xmlns", "http://www.w3.org/2005/Atom"),
                 mklist(element, "'title", mklist(attribute, "'type", "text"), title), mklist(element,
"'id", id)),
-                isNull(author)? mklist() : mklist(mklist(element, "'author",
+                isNull(author)? nil : mklist(mklist(element, "'author",
                     (email? mklist(element, "'email", elementValue(author)) : mklist(element,
"'name", elementValue(author)))))),
-                isNull(updated)? mklist() : mklist(mklist(element, "'updated", elementValue(updated)))),
-                isNull(content)? mklist() :
+                isNull(updated)? nil : mklist(mklist(element, "'updated", elementValue(updated)))),
+                isNull(rank)? nil : mklist(mklist(element, "'rank", elementValue(rank)))),
+                isNull(content)? nil :
                     mklist(append(mklist(element, "'content", mklist(attribute, "'type",
text? "text" : "application/xml")),
                         text? mklist(elementValue(content)) : elementChildren(content)))),
                 mklist(mklist(element, "'link", mklist(attribute, "'href", id))));
@@ -182,3 +188,17 @@ atom.writeATOMFeed = function(ll) {
     return writeXML(mklist(fe), true);
 };
 
+/**
+ * Uncomment to test.
+ */
+/*
+(function testAtom() {
+    console.log('Testing...');
+    var entry = mklist("'entry", mklist("'title", 'test'), mklist("'id", 'test'), mklist("'content",
mklist("'rating", '1')));
+    var entryxml = car(atom.writeATOMEntry(valuesToElements(mklist(entry))));
+    assert(entryxml == '<?xml version="1.0" encoding="UTF-8"?>\n' +
+        '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">test</title><id>test</id><content
type="application/xml"><rating>1</rating></content><link href="test"/></entry>\n');
+    console.log('OK');
+})();
+*/
+

Modified: tuscany/sca-cpp/trunk/modules/js/htdocs/elemutil.js
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/js/htdocs/elemutil.js?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/js/htdocs/elemutil.js (original)
+++ tuscany/sca-cpp/trunk/modules/js/htdocs/elemutil.js Mon Aug 26 03:04:23 2013
@@ -42,45 +42,47 @@ function isAttribute(v) {
 /**
  * Return the name of an attribute.
  */
-attributeName = cadr;
+var attributeName = cadr;
 
 /**
  * Return the value of an attribute.
  */
-attributeValue = caddr;
+var attributeValue = caddr;
 
 /**
  * Return the name of an element.
  */
-elementName = cadr;
+var elementName = cadr;
 
 /**
  * Return true if an element has children.
  */
 function elementHasChildren(l) {
-    return !isNull(cddr(l));
+    return !isNull(l) && !isNull(cddr(l));
 }
 
 /**
  * Return the children of an element.
  */
-elementChildren = cddr;
+var elementChildren = cddr;
 
 /**
  * Return true if an element has a value.
  */
 function elementHasValue(l) {
-    var r = reverse(l);
-    if (isSymbol(car(r)))
+    if (isNull(l))
+        return false;
+    var v = last(l);
+    if (isSymbol(v))
         return false;
-    return (!(isList(car(r)) && !isNull(car(r)) && isSymbol(car(car(r)))))
+    return (!(isList(v) && !isNull(v) && isSymbol(car(v))))
 }
 
 /**
  * Return the value of an element.
  */
 function elementValue(l) {
-    return car(reverse(l));
+    return last(l);
 }
 
 /**
@@ -140,7 +142,7 @@ function elementsToValues(e) {
 function valueToElement(t) {
     if (isList(t) && !isNull(t) && isSymbol(car(t))) {
         var n = car(t);
-        var v = isNull(cdr(t))? mklist() : cadr(t);
+        var v = isNull(cdr(t))? nil : cadr(t);
         if (!isList(v)) {
             if (n.substring(0, 2) == atsign)
                 return mklist(attribute, "'" + n.substring(2), v);
@@ -171,7 +173,7 @@ function selector(s) {
     function evalSelect(s, v) {
         if (isNull(s))
             return true;
-        if (isNull(v))
+        if (!isList(v) || isNull(v))
             return false;
         if (car(s) != car(v))
             return false;
@@ -230,7 +232,7 @@ function namedElementChild(name, l) {
  * Set the contents of an element.
  */
 function setElement(l, e) {
-    setlist(l, e);
+    setList(l, e);
     l.memo = {};
 }
 

Modified: tuscany/sca-cpp/trunk/modules/wsgi/atomutil.py
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/wsgi/atomutil.py?rev=1517412&r1=1517411&r2=1517412&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/wsgi/atomutil.py (original)
+++ tuscany/sca-cpp/trunk/modules/wsgi/atomutil.py Mon Aug 26 03:04:23 2013
@@ -70,7 +70,8 @@ def readATOMFeed(l):
 
 # Convert a list of values representy an ATOM entry to a list of elements
 def entryElement(l):
-    title = elementValue(namedElementChild("'title", l))
+    etitle = namedElementChild("'title", l)
+    title = elementValue(etitle) if elementHasValue(etitle) else ''
     id = elementValue(namedElementChild("'id", l))
     content = namedElementChild("'content", l)
     text = False if isNull(content) else elementHasValue(content)



Mime
View raw message