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/05/31 04:29:46 UTC

svn commit: r949652 - in /tuscany/sca-cpp/trunk: ./ etc/ kernel/ modules/ modules/atom/ modules/http/ modules/rss/

Author: jsdelfino
Date: Mon May 31 02:29:45 2010
New Revision: 949652

URL: http://svn.apache.org/viewvc?rev=949652&view=rev
Log:
Add support for RSS feeds and minor fixes to ATOM support.

Added:
    tuscany/sca-cpp/trunk/modules/http/curl-get.cpp
    tuscany/sca-cpp/trunk/modules/rss/
    tuscany/sca-cpp/trunk/modules/rss/Makefile.am
      - copied, changed from r949466, tuscany/sca-cpp/trunk/modules/Makefile.am
    tuscany/sca-cpp/trunk/modules/rss/rss-test.cpp
    tuscany/sca-cpp/trunk/modules/rss/rss.hpp
      - copied, changed from r949466, tuscany/sca-cpp/trunk/modules/atom/atom.hpp
Modified:
    tuscany/sca-cpp/trunk/configure.ac
    tuscany/sca-cpp/trunk/etc/git-exclude
    tuscany/sca-cpp/trunk/kernel/xml.hpp
    tuscany/sca-cpp/trunk/modules/Makefile.am
    tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp
    tuscany/sca-cpp/trunk/modules/atom/atom.hpp
    tuscany/sca-cpp/trunk/modules/http/Makefile.am
    tuscany/sca-cpp/trunk/modules/http/curl.hpp

Modified: tuscany/sca-cpp/trunk/configure.ac
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/configure.ac?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/configure.ac (original)
+++ tuscany/sca-cpp/trunk/configure.ac Mon May 31 02:29:45 2010
@@ -770,6 +770,7 @@ AC_CONFIG_FILES([Makefile
                  modules/http/Makefile
                  modules/python/Makefile
                  modules/java/Makefile
+                 modules/rss/Makefile
                  modules/server/Makefile
                  modules/wsgi/Makefile
                  components/Makefile

Modified: tuscany/sca-cpp/trunk/etc/git-exclude
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/etc/git-exclude?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/etc/git-exclude (original)
+++ tuscany/sca-cpp/trunk/etc/git-exclude Mon May 31 02:29:45 2010
@@ -99,4 +99,6 @@ qpid-test
 xmpp-test
 pgsql-test
 tinycdb-test
+curl-get
+rss-test
 

Modified: tuscany/sca-cpp/trunk/kernel/xml.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/xml.hpp?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/xml.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/xml.hpp Mon May 31 02:29:45 2010
@@ -200,6 +200,15 @@ int readCallback(void *context, char* bu
 }
 
 /**
+ * Return true if a list of strings contains an XML document.
+ */
+const bool isXML(const list<string>& ls) {
+    if (isNil(ls))
+        return false;
+    return substr(car(ls), 0, 5) == "<?xml";
+}
+
+/**
  * Read a list of values from a list of strings representing an XML document.
  */
 const list<value> readXML(const list<string>& ilist) {

Modified: tuscany/sca-cpp/trunk/modules/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/Makefile.am?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/Makefile.am Mon May 31 02:29:45 2010
@@ -15,7 +15,7 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-SUBDIRS = scheme atom json scdl http server python wsgi java
+SUBDIRS = scheme atom rss json scdl http rss server python wsgi java
 
 includedir = $(prefix)/include/modules
 nobase_include_HEADERS = */*.hpp

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=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp (original)
+++ tuscany/sca-cpp/trunk/modules/atom/atom-test.cpp Mon May 31 02:29:45 2010
@@ -48,6 +48,14 @@ string itemEntry("<?xml version=\"1.0\" 
         "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
         "</entry>\n");
 
+string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<entry xmlns=\"http://www.w3.org/2005/Atom\">"
+        "<title type=\"text\">item</title>"
+        "<id>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</id>"
+        "<content type=\"text\">Apple</content>"
+        "<link href=\"cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b\"/>"
+        "</entry>\n");
+
 string incompleteEntry("<entry xmlns=\"http://www.w3.org/2005/Atom\">"
         "<title>item</title><content type=\"text/xml\">"
         "<Item xmlns=\"http://services/\">"
@@ -80,12 +88,24 @@ bool testEntry() {
         assert(str(os) == itemEntry);
     }
     {
+        const list<value> a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), string("Apple"));
+        ostringstream os;
+        writeATOMEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemTextEntry);
+    }
+    {
         const list<value> a = content(readATOMEntry(mklist(itemEntry)));
         ostringstream os;
         writeATOMEntry<ostream*>(writer, &os, a);
         assert(str(os) == itemEntry);
     }
     {
+        const list<value> a = content(readATOMEntry(mklist(itemTextEntry)));
+        ostringstream os;
+        writeATOMEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemTextEntry);
+    }
+    {
         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=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/atom/atom.hpp Mon May 31 02:29:45 2010
@@ -44,7 +44,7 @@ const list<value> entryElementsToValues(
     const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
     const value i = isNil(li)? value(emptyString) : elementValue(car(li));
     const list<value> lc = filter<value>(selector(mklist<value>(element, "content")), e);
-    return mklist<value>(t, i, cadr(elementChildren(car(lc))));
+    return mklist<value>(t, i, elementValue(car(lc)));
 }
 
 /**
@@ -57,6 +57,15 @@ const list<value> entriesElementsToValue
 }
 
 /**
+ * Return true if a list of strings contains an RSS feed.
+ */
+const bool isATOMFeed(const list<string>& ls) {
+    if (!isXML(ls))
+        return false;
+    return contains(car(ls), "<feed");
+}
+
+/**
  * Convert a list of strings to a list of values representing an ATOM entry.
  */
 const failable<list<value> > readATOMEntry(const list<string>& ilist) {
@@ -71,7 +80,7 @@ const failable<list<value> > readATOMEnt
  */
 const value entryValue(const list<value>& e) {
     const list<value> v = elementsToValues(mklist<value>(caddr(e)));
-    return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v))));
+    return cons(car(e), mklist<value>(cadr(e), isList(car(v))? (value)cdr<value>(car(v)) : car(v)));
 }
 
 /**
@@ -90,6 +99,19 @@ const failable<list<value> > readATOMFee
 }
 
 /**
+ * Convert an ATOM feed containing elements to an ATOM feed containing values.
+ */
+const list<value> feedValuesLoop(const list<value> e) {
+    if (isNil(e))
+        return e;
+    return cons<value>(entryValue(car(e)), feedValuesLoop(cdr(e)));
+}
+
+const list<value> feedValues(const list<value>& e) {
+    return cons(car<value>(e), cons<value>(cadr<value>(e), feedValuesLoop(cddr<value>(e))));
+}
+
+/**
  * Convert a list of values representing an ATOM entry to a list of elements.
  * The first two values in the list are the entry title and id.
  */
@@ -98,7 +120,8 @@ const list<value> entryElement(const lis
         + element + "entry" + (list<value>() + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
         + (list<value>() + element + "title" + (list<value>() + attribute + "type" + "text") + car(l))
         + (list<value>() + element + "id" + cadr(l))
-        + (list<value>() + element + "content" + (list<value>() + attribute + "type" + "application/xml") + caddr(l))
+        + (list<value>() + element + "content"
+        + (list<value>() + attribute + "type" + (isList(caddr(l))? "application/xml" : "text")) + caddr(l))
         + (list<value>() + element + "link" + (list<value>() + attribute + "href" + cadr(l)));
 }
 

Modified: tuscany/sca-cpp/trunk/modules/http/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/Makefile.am?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/http/Makefile.am Mon May 31 02:29:45 2010
@@ -23,6 +23,9 @@ moddir=$(prefix)/modules/http
 curl_test_SOURCES = curl-test.cpp
 curl_test_LDFLAGS = -lxml2 -lcurl -lmozjs
 
+curl_get_SOURCES = curl-get.cpp
+curl_get_LDFLAGS = -lxml2 -lcurl -lmozjs
+
 mod_DATA = httpd.prefix curl.prefix
 nobase_dist_mod_DATA = conf/*
 
@@ -34,5 +37,5 @@ curl.prefix: $(top_builddir)/config.stat
 	echo ${CURL_PREFIX} >curl.prefix
 
 dist_noinst_SCRIPTS = httpd-test http-test
-noinst_PROGRAMS = curl-test
+noinst_PROGRAMS = curl-test curl-get
 TESTS = httpd-test http-test

Added: 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=949652&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl-get.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/http/curl-get.cpp Mon May 31 02:29:45 2010
@@ -0,0 +1,50 @@
+/*
+ * 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$ */
+
+/**
+ * HTTP client command line test tool.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "perf.hpp"
+#include "curl.hpp"
+
+namespace tuscany {
+namespace http {
+
+const bool testGet(const string& url) {
+    CURLSession ch;
+    const failable<value> val = get(url, ch);
+    assert(hasContent(val));
+    cout << val << endl;
+    return true;
+}
+
+}
+}
+
+int main(unused const int argc, const char** argv) {
+    tuscany::http::testGet(tuscany::string(argv[1]));
+    return 0;
+}
+

Modified: tuscany/sca-cpp/trunk/modules/http/curl.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/curl.hpp?rev=949652&r1=949651&r2=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/curl.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/http/curl.hpp Mon May 31 02:29:45 2010
@@ -37,6 +37,7 @@
 #include "monad.hpp"
 #include "parallel.hpp"
 #include "../atom/atom.hpp"
+#include "../rss/rss.hpp"
 #include "../json/json.hpp"
 
 namespace tuscany {
@@ -330,10 +331,23 @@ const failable<value> get(const string& 
 
     const string ct(content(contentType(car(content(res)))));
     if (ct == "application/atom+xml;type=entry") {
+        // Read an ATOM entry
         const value val(atom::entryValue(content(atom::readATOMEntry(ls))));
         debug(val, "http::get::result");
         return val;
     }
+    if (ct == "application/atom+xml;type=feed" || atom::isATOMFeed(ls)) {
+        // Read an ATOM feed
+        const value val(atom::feedValues(content(atom::readATOMFeed(ls))));
+        debug(val, "http::get::result");
+        return val;
+    }
+    if (ct == "application/rss+xml" || rss::isRSSFeed(ls)) {
+        // Read an RSS feed
+        const value val(rss::feedValues(content(rss::readRSSFeed(ls))));
+        debug(val, "http::get::result");
+        return val;
+    }
 
     // Return the content as a list of values
     const value val(mkvalues(ls));

Copied: tuscany/sca-cpp/trunk/modules/rss/Makefile.am (from r949466, tuscany/sca-cpp/trunk/modules/Makefile.am)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/rss/Makefile.am?p2=tuscany/sca-cpp/trunk/modules/rss/Makefile.am&p1=tuscany/sca-cpp/trunk/modules/Makefile.am&r1=949466&r2=949652&rev=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/modules/rss/Makefile.am Mon May 31 02:29:45 2010
@@ -15,8 +15,8 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-SUBDIRS = scheme atom json scdl http server python wsgi java
-
-includedir = $(prefix)/include/modules
-nobase_include_HEADERS = */*.hpp
+rss_test_SOURCES = rss-test.cpp
+rss_test_LDFLAGS = -lxml2
 
+noinst_PROGRAMS = rss-test
+TESTS = rss-test

Added: tuscany/sca-cpp/trunk/modules/rss/rss-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/rss/rss-test.cpp?rev=949652&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/modules/rss/rss-test.cpp (added)
+++ tuscany/sca-cpp/trunk/modules/rss/rss-test.cpp Mon May 31 02:29:45 2010
@@ -0,0 +1,214 @@
+/*
+ * 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$ */
+
+/**
+ * Test RSS data conversion functions.
+ */
+
+#include <assert.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "rss.hpp"
+
+namespace tuscany {
+namespace rss {
+
+ostream* writer(const string& s, ostream* os) {
+    (*os) << s;
+    return os;
+}
+
+string itemEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<item>"
+        "<title>fruit</title>"
+        "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>"
+        "<description>"
+        "<fruit>"
+        "<name>Apple</name><price>$2.99</price>"
+        "</fruit>"
+        "</description>"
+        "</item>\n");
+
+string itemTextEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<item>"
+        "<title>fruit</title>"
+        "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>"
+        "<description>Apple</description>"
+        "</item>\n");
+
+string incompleteEntry("<item>"
+        "<title>fruit</title><description>"
+        "<fruit xmlns=\"http://services/\">"
+        "<name xmlns=\"\">Orange</name>"
+        "<price xmlns=\"\">3.55</price>"
+        "</fruit>"
+        "</description>"
+        "</item>");
+
+string completedEntry("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<item>"
+        "<title>fruit</title>"
+        "<link></link>"
+        "<description>"
+        "<fruit xmlns=\"http://services/\">"
+        "<name xmlns=\"\">Orange</name>"
+        "<price xmlns=\"\">3.55</price>"
+        "</fruit>"
+        "</description>"
+        "</item>\n");
+
+bool testEntry() {
+    {
+        const list<value> i = list<value>() + element + value("fruit")
+                + value(list<value>() + element + value("name") + value(string("Apple")))
+                + value(list<value>() + element + value("price") + value(string("$2.99")));
+        const list<value> a = mklist<value>(string("fruit"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
+        ostringstream os;
+        writeRSSEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemEntry);
+    }
+    {
+        const list<value> a = mklist<value>(string("fruit"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), "Apple");
+        ostringstream os;
+        writeRSSEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemTextEntry);
+    }
+    {
+        const list<value> a = content(readRSSEntry(mklist(itemEntry)));
+        ostringstream os;
+        writeRSSEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemEntry);
+    }
+    {
+        const list<value> a = content(readRSSEntry(mklist(itemTextEntry)));
+        ostringstream os;
+        writeRSSEntry<ostream*>(writer, &os, a);
+        assert(str(os) == itemTextEntry);
+    }
+    {
+        const list<value> a = content(readRSSEntry(mklist(incompleteEntry)));
+        ostringstream os;
+        writeRSSEntry<ostream*>(writer, &os, a);
+        assert(str(os) == completedEntry);
+    }
+    return true;
+}
+
+string emptyFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<rss version=\"2.0\">"
+        "<channel>"
+        "<title>Feed</title>"
+        "<link>1234</link>"
+        "<description>Feed</description>"
+        "</channel>"
+        "</rss>\n");
+
+string itemFeed("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+        "<rss version=\"2.0\">"
+        "<channel>"
+        "<title>Feed</title>"
+        "<link>1234</link>"
+        "<description>Feed</description>"
+        "<item>"
+        "<title>fruit</title>"
+        "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b</link>"
+        "<description>"
+        "<fruit>"
+        "<name>Apple</name><price>$2.99</price>"
+        "</fruit>"
+        "</description>"
+        "</item>"
+        "<item>"
+        "<title>fruit</title>"
+        "<link>cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c</link>"
+        "<description>"
+        "<fruit>"
+        "<name>Orange</name><price>$3.55</price>"
+        "</fruit>"
+        "</description>"
+        "</item>"
+        "</channel>"
+        "</rss>\n");
+
+bool testFeed() {
+    {
+        ostringstream os;
+        writeRSSFeed<ostream*>(writer, &os, mklist<value>("Feed", "1234"));
+        assert(str(os) == emptyFeed);
+    }
+    {
+        const list<value> a = content(readRSSFeed(mklist(emptyFeed)));
+        ostringstream os;
+        writeRSSFeed<ostream*>(writer, &os, a);
+        assert(str(os) == emptyFeed);
+    }
+    {
+        const list<value> i = list<value>()
+                + (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+                    + (list<value>() + element + "fruit"
+                        + (list<value>() + element + "name" + "Apple")
+                        + (list<value>() + element + "price" + "$2.99")))
+                + (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+                    + (list<value>() + element + "fruit"
+                        + (list<value>() + element + "name" + "Orange")
+                        + (list<value>() + element + "price" + "$3.55")));
+        const list<value> a = cons<value>("Feed", cons<value>("1234", i));
+        ostringstream os;
+        writeRSSFeed<ostream*>(writer, &os, a);
+        assert(str(os) == itemFeed);
+    }
+    {
+        const list<value> i = list<value>()
+                + (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"
+                    + valueToElement(list<value>() + "fruit"
+                        + (list<value>() + "name" + "Apple")
+                        + (list<value>() + "price" + "$2.99")))
+                + (list<value>() + "fruit" + "cart-53d67a61-aa5e-4e5e-8401-39edeba8b83c"
+                    + valueToElement(list<value>() + "fruit"
+                        + (list<value>() + "name" + "Orange")
+                        + (list<value>() + "price" + "$3.55")));
+        const list<value> a = cons<value>("Feed", cons<value>("1234", i));
+        ostringstream os;
+        writeRSSFeed<ostream*>(writer, &os, a);
+        assert(str(os) == itemFeed);
+    }
+    {
+        const list<value> a = content(readRSSFeed(mklist(itemFeed)));
+        ostringstream os;
+        writeRSSFeed<ostream*>(writer, &os, a);
+        assert(str(os) == itemFeed);
+    }
+    return true;
+}
+
+}
+}
+
+int main() {
+    tuscany::cout << "Testing..." << tuscany::endl;
+
+    tuscany::rss::testEntry();
+    tuscany::rss::testFeed();
+
+    tuscany::cout << "OK" << tuscany::endl;
+
+    return 0;
+}

Copied: tuscany/sca-cpp/trunk/modules/rss/rss.hpp (from r949466, tuscany/sca-cpp/trunk/modules/atom/atom.hpp)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/rss/rss.hpp?p2=tuscany/sca-cpp/trunk/modules/rss/rss.hpp&p1=tuscany/sca-cpp/trunk/modules/atom/atom.hpp&r1=949466&r2=949652&rev=949652&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/atom/atom.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/rss/rss.hpp Mon May 31 02:29:45 2010
@@ -19,11 +19,11 @@
 
 /* $Rev$ $Date$ */
 
-#ifndef tuscany_atom_hpp
-#define tuscany_atom_hpp
+#ifndef tuscany_rss_hpp
+#define tuscany_rss_hpp
 
 /**
- * ATOM data conversion functions.
+ * RSS data conversion functions.
  */
 
 #include "string.hpp"
@@ -33,22 +33,22 @@
 #include "xml.hpp"
 
 namespace tuscany {
-namespace atom {
+namespace rss {
 
 /**
- * Convert a list of elements to a list of values representing an ATOM entry.
+ * Convert a list of elements to a list of values representing an RSS entry.
  */
 const list<value> entryElementsToValues(const list<value>& e) {
     const list<value> lt = filter<value>(selector(mklist<value>(element, "title")), e);
     const value t = isNil(lt)? value(emptyString) : elementValue(car(lt));
-    const list<value> li = filter<value>(selector(mklist<value>(element, "id")), e);
+    const list<value> li = filter<value>(selector(mklist<value>(element, "link")), e);
     const value i = isNil(li)? value(emptyString) : elementValue(car(li));
-    const list<value> lc = filter<value>(selector(mklist<value>(element, "content")), e);
-    return mklist<value>(t, i, cadr(elementChildren(car(lc))));
+    const list<value> ld = filter<value>(selector(mklist<value>(element, "description")), e);
+    return mklist<value>(t, i, elementValue(car(ld)));
 }
 
 /**
- * Convert a list of elements to a list of values representing ATOM entries.
+ * Convert a list of elements to a list of values representing RSS entries.
  */
 const list<value> entriesElementsToValues(const list<value>& e) {
     if (isNil(e))
@@ -57,9 +57,18 @@ const list<value> entriesElementsToValue
 }
 
 /**
- * Convert a list of strings to a list of values representing an ATOM entry.
+ * Return true if a list of strings contains an RSS feed.
  */
-const failable<list<value> > readATOMEntry(const list<string>& ilist) {
+const bool isRSSFeed(const list<string>& ls) {
+    if (!isXML(ls))
+        return false;
+    return contains(car(ls), "<rss");
+}
+
+/**
+ * Convert a list of strings to a list of values representing an RSS entry.
+ */
+const failable<list<value> > readRSSEntry(const list<string>& ilist) {
     const list<value> e = readXML(ilist);
     if (isNil(e))
         return mkfailure<list<value> >("Empty entry");
@@ -67,43 +76,56 @@ const failable<list<value> > readATOMEnt
 }
 
 /**
- * Convert a list of values representing an ATOM entry to a value.
+ * Convert a list of values representing an RSS entry to a value.
  */
 const value entryValue(const list<value>& e) {
     const list<value> v = elementsToValues(mklist<value>(caddr(e)));
-    return cons(car(e), mklist<value>(cadr(e), cdr<value>(car(v))));
+    return cons(car(e), mklist<value>(cadr(e), isList(car(v))? (value)cdr<value>(car(v)) : car(v)));
 }
 
 /**
- * Convert a list of strings to a list of values representing an ATOM feed.
+ * Convert a list of strings to a list of values representing an RSS feed.
  */
-const failable<list<value> > readATOMFeed(const list<string>& ilist) {
+const failable<list<value> > readRSSFeed(const list<string>& ilist) {
     const list<value> f = readXML(ilist);
     if (isNil(f))
         return mkfailure<list<value> >("Empty feed");
-    const list<value> t = filter<value>(selector(mklist<value>(element, "title")), car(f));
-    const list<value> i = filter<value>(selector(mklist<value>(element, "id")), car(f));
-    const list<value> e = filter<value>(selector(mklist<value>(element, "entry")), car(f));
+    const list<value> c = filter<value>(selector(mklist<value>(element, "channel")), car(f));
+    const list<value> t = filter<value>(selector(mklist<value>(element, "title")), car(c));
+    const list<value> i = filter<value>(selector(mklist<value>(element, "link")), car(c));
+    const list<value> e = filter<value>(selector(mklist<value>(element, "item")), car(c));
     if (isNil(e))
         return mklist<value>(elementValue(car(t)), elementValue(car(i)));
     return cons<value>(elementValue(car(t)), cons(elementValue(car(i)), entriesElementsToValues(e)));
 }
 
 /**
- * Convert a list of values representing an ATOM entry to a list of elements.
+ * Convert an RSS feed containing elements to an RSS feed containing values.
+ */
+const list<value> feedValuesLoop(const list<value> e) {
+    if (isNil(e))
+        return e;
+    return cons<value>(entryValue(car(e)), feedValuesLoop(cdr(e)));
+}
+
+const list<value> feedValues(const list<value>& e) {
+    return cons(car<value>(e), cons<value>(cadr<value>(e), feedValuesLoop(cddr<value>(e))));
+}
+
+/**
+ * Convert a list of values representing an RSS entry to a list of elements.
  * The first two values in the list are the entry title and id.
  */
 const list<value> entryElement(const list<value>& l) {
     return list<value>()
-        + element + "entry" + (list<value>() + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
-        + (list<value>() + element + "title" + (list<value>() + attribute + "type" + "text") + car(l))
-        + (list<value>() + element + "id" + cadr(l))
-        + (list<value>() + element + "content" + (list<value>() + attribute + "type" + "application/xml") + caddr(l))
-        + (list<value>() + element + "link" + (list<value>() + attribute + "href" + cadr(l)));
+        + element + "item"
+        + (list<value>() + element + "title" + car(l))
+        + (list<value>() + element + "link" + cadr(l))
+        + (list<value>() + element + "description" + caddr(l));
 }
 
 /**
- * Convert a list of values representing ATOM entries to a list of elements.
+ * Convert a list of values representing RSS entries to a list of elements.
  */
 const list<value> entriesElements(const list<value>& l) {
     if (isNil(l))
@@ -112,55 +134,56 @@ const list<value> entriesElements(const 
 }
 
 /**
- * Convert a list of values representing an ATOM entry to an ATOM entry.
+ * Convert a list of values representing an RSS entry to an RSS entry.
  * The first two values in the list are the entry id and title.
  */
-template<typename R> const failable<R> writeATOMEntry(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
+template<typename R> const failable<R> writeRSSEntry(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
     return writeXML<R>(reduce, initial, mklist<value>(entryElement(l)));
 }
 
-const failable<list<string> > writeATOMEntry(const list<value>& l) {
-    const failable<list<string> > ls = writeATOMEntry<list<string> >(rcons<string>, list<string>(), l);
+const failable<list<string> > writeRSSEntry(const list<value>& l) {
+    const failable<list<string> > ls = writeRSSEntry<list<string> >(rcons<string>, list<string>(), l);
     if (!hasContent(ls))
         return ls;
     return reverse(list<string>(content(ls)));
 }
 
 /**
- * Convert a list of values representing an ATOM feed to an ATOM feed.
+ * Convert a list of values representing an RSS feed to an RSS feed.
  * The first two values in the list are the feed id and title.
  */
-template<typename R> const failable<R> writeATOMFeed(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
-    const list<value> f = list<value>()
-        + element + "feed" + (list<value>() + attribute + "xmlns" + "http://www.w3.org/2005/Atom")
-        + (list<value>() + element + "title" + (list<value>() + attribute + "type" + "text") + car(l))
-        + (list<value>() + element + "id" + cadr(l));
-    if (isNil(cddr(l)))
-        return writeXML<R>(reduce, initial, mklist<value>(f));
-    const list<value> fe = append(f, entriesElements(cddr(l)));
+template<typename R> const failable<R> writeRSSFeed(const lambda<R(const string&, const R)>& reduce, const R& initial, const list<value>& l) {
+    const list<value> c = list<value>()
+        + (list<value>() + element + "title" + car(l))
+        + (list<value>() + element + "link" + cadr(l))
+        + (list<value>() + element + "description" + car(l));
+    const list<value> ce = isNil(cddr(l))? c : append(c, entriesElements(cddr(l)));
+    const list<value> fe = list<value>()
+        + element + "rss" + (list<value>() + attribute + "version" + "2.0")
+        + append(list<value>() + element + "channel", ce);
     return writeXML<R>(reduce, initial, mklist<value>(fe));
 }
 
 /**
- * Convert a list of values representing an ATOM feed to a list of strings.
+ * Convert a list of values representing an RSS feed to a list of strings.
  * The first two values in the list are the feed id and title.
  */
-const failable<list<string> > writeATOMFeed(const list<value>& l) {
-    const failable<list<string> > ls = writeATOMFeed<list<string>>(rcons<string>, list<string>(), l);
+const failable<list<string> > writeRSSFeed(const list<value>& l) {
+    const failable<list<string> > ls = writeRSSFeed<list<string>>(rcons<string>, list<string>(), l);
     if (!hasContent(ls))
         return ls;
     return reverse(list<string>(content(ls)));
 }
 
 /**
- * Convert an ATOM entry containing a value to an ATOM entry containing an item element.
+ * Convert an RSS entry containing a value to an RSS 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))))));
 }
 
 /**
- * Convert an ATOM feed containing values to an ATOM feed containing elements.
+ * Convert an RSS feed containing values to an RSS feed containing elements.
  */
 const list<value> feedValuesToElementsLoop(const list<value> val) {
     if (isNil(val))
@@ -175,4 +198,4 @@ const list<value> feedValuesToElements(c
 }
 }
 
-#endif /* tuscany_atom_hpp */
+#endif /* tuscany_rss_hpp */