summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/modules')
-rw-r--r--sca-cpp/trunk/modules/http/curl.hpp8
-rw-r--r--sca-cpp/trunk/modules/http/httpd.hpp38
-rw-r--r--sca-cpp/trunk/modules/java/eval.hpp4
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.cpp47
-rw-r--r--sca-cpp/trunk/modules/java/mod-java.hpp21
-rw-r--r--sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java22
-rw-r--r--sca-cpp/trunk/modules/java/test/Client.java12
-rw-r--r--sca-cpp/trunk/modules/java/test/ClientImpl.java18
-rw-r--r--sca-cpp/trunk/modules/java/test/Server.java12
-rw-r--r--sca-cpp/trunk/modules/java/test/ServerImpl.java26
-rw-r--r--sca-cpp/trunk/modules/json/json.hpp2
-rw-r--r--sca-cpp/trunk/modules/python/client-test.py12
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp4
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.cpp31
-rw-r--r--sca-cpp/trunk/modules/python/mod-python.hpp10
-rw-r--r--sca-cpp/trunk/modules/python/server-test.py30
-rw-r--r--sca-cpp/trunk/modules/scheme/primitive.hpp6
-rw-r--r--sca-cpp/trunk/modules/server/client-test.scm12
-rw-r--r--sca-cpp/trunk/modules/server/impl-test.cpp2
-rw-r--r--sca-cpp/trunk/modules/server/mod-cpp.hpp7
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.cpp27
-rw-r--r--sca-cpp/trunk/modules/server/mod-eval.hpp228
-rw-r--r--sca-cpp/trunk/modules/server/mod-scheme.hpp10
-rw-r--r--sca-cpp/trunk/modules/server/mod-wiring.cpp104
-rw-r--r--sca-cpp/trunk/modules/server/server-test.scm24
25 files changed, 322 insertions, 395 deletions
diff --git a/sca-cpp/trunk/modules/http/curl.hpp b/sca-cpp/trunk/modules/http/curl.hpp
index 4e96411ec6..f2c9458f42 100644
--- a/sca-cpp/trunk/modules/http/curl.hpp
+++ b/sca-cpp/trunk/modules/http/curl.hpp
@@ -252,7 +252,7 @@ const failable<value> entryId(const failable<string> l) {
if (!hasContent(l))
return mkfailure<value>(reason(l));
const string ls(content(l));
- return value(string(substr(ls, find_last(ls, '/') + 1)));
+ return value(mklist<value>(string(substr(ls, find_last(ls, '/') + 1))));
}
/**
@@ -381,18 +381,18 @@ const failable<value, string> del(const string& url, const CURLSession& ch) {
* HTTP client proxy function.
*/
struct proxy {
- proxy(const string& url) : url(url) {
+ proxy(const string& uri) : uri(uri) {
}
const value operator()(const list<value>& args) const {
CURLSession cs;
- failable<value> val = evalExpr(args, url, cs);
+ failable<value> val = evalExpr(args, uri, cs);
if (!hasContent(val))
return value();
return content(val);
}
- const string url;
+ const string uri;
};
}
diff --git a/sca-cpp/trunk/modules/http/httpd.hpp b/sca-cpp/trunk/modules/http/httpd.hpp
index 6b08c3b838..bd0e23f76b 100644
--- a/sca-cpp/trunk/modules/http/httpd.hpp
+++ b/sca-cpp/trunk/modules/http/httpd.hpp
@@ -75,30 +75,6 @@ template<typename C> C& serverConf(const cmd_parms *cmd, const module* mod) {
/**
- * Convert a path string to a list of values.
- */
-const list<string> pathTokens(const char* p) {
- if (p == NULL || p[0] == '\0')
- return list<string>();
- if (p[0] == '/')
- return tokenize("/", p + 1);
- return tokenize("/", p);
-}
-
-const list<value> pathValues(const char* p) {
- return mkvalues(pathTokens(p));
-}
-
-/**
- * Convert a path represented as a list of values to a string.
- */
-const string path(const list<value>& p) {
- if (isNil(p))
- return "";
- return string("/") + car(p) + path(cdr(p));
-}
-
-/**
* Return the content type of a request.
*/
const char* optional(const char* s) {
@@ -219,10 +195,10 @@ const list<string> read(request_rec* r) {
}
/**
- * Convert a URI value to an absolute URL.
+ * Convert a URI represented as a list to an absolute URL.
*/
-const char* url(const value& v, request_rec* r) {
- const string u = string(r->uri) + "/" + v;
+const char* url(const list<value>& v, request_rec* r) {
+ const string u = string(r->uri) + path(v);
return ap_construct_url(r->pool, c_str(u), r);
}
@@ -400,7 +376,7 @@ const int internalRedirect(const string& uri, request_rec* r) {
/**
* Put a value in the process user data.
*/
-const bool putUserData(const string& k, const int v, const server_rec* s) {
+const bool putUserData(const string& k, const void* v, const server_rec* s) {
apr_pool_userdata_set((const void *)v, c_str(k), apr_pool_cleanup_null, s->process->pool);
return true;
}
@@ -408,10 +384,10 @@ const bool putUserData(const string& k, const int v, const server_rec* s) {
/**
* Return a user data value.
*/
-const int userData(const string& k, const server_rec* s) {
- void* v = (int)0;
+const void* userData(const string& k, const server_rec* s) {
+ void* v = NULL;
apr_pool_userdata_get(&v, c_str(k), s->process->pool);
- return (int)v;
+ return v;
}
}
diff --git a/sca-cpp/trunk/modules/java/eval.hpp b/sca-cpp/trunk/modules/java/eval.hpp
index 9140fe75b4..58a1ab5ff9 100644
--- a/sca-cpp/trunk/modules/java/eval.hpp
+++ b/sca-cpp/trunk/modules/java/eval.hpp
@@ -501,8 +501,8 @@ const failable<value> evalClass(const JavaRuntime& jr, const value& expr, const
// The start, stop, and restart functions are optional
const value fn = car<value>(expr);
- if (fn == "start" || fn == "stop" || fn == "restart")
- return value(false);
+ if (fn == "start" || fn == "restart" || "stop")
+ return value(lambda<value(const list<value>&)>());
return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastException(jr));
}
diff --git a/sca-cpp/trunk/modules/java/mod-java.cpp b/sca-cpp/trunk/modules/java/mod-java.cpp
index 4b8e7dca56..510f9574b0 100644
--- a/sca-cpp/trunk/modules/java/mod-java.cpp
+++ b/sca-cpp/trunk/modules/java/mod-java.cpp
@@ -37,40 +37,41 @@ namespace server {
namespace modeval {
/**
- * Start the module.
+ * Apply a lifecycle start or restart event.
*/
-const failable<bool> start(unused ServerConf& sc) {
- // Start a Java runtime
- sc.moduleConf = new (gc_new<java::JavaRuntime>()) java::JavaRuntime();
- return true;
-}
+struct javaLifecycle {
+ javaLifecycle(java::JavaRuntime& jr) : jr(jr) {
+ }
+ const value operator()(const list<value>& params) const {
+ const value func = car(params);
+ if (func == "javaRuntime")
+ return (gc_ptr<value>)(value*)(void*)&jr;
+ return lambda<value(const list<value>&)>();
+ }
+ java::JavaRuntime& jr;
+};
-/**
- * Stop the module.
- */
-const failable<bool> stop(unused ServerConf& sc) {
- return true;
-}
+const value applyLifecycle(unused const list<value>& params) {
-/**
- * Restart the module.
- */
-const failable<bool> restart(ServerConf& sc) {
- // Start a Java runtime
- sc.moduleConf = new (gc_new<java::JavaRuntime>()) java::JavaRuntime();
- return true;
+ // Create a Java runtime
+ java::JavaRuntime& jr = *(new (gc_new<java::JavaRuntime>()) java::JavaRuntime());
+
+ // Return the function to invoke on subsequent events
+ return failable<value>(lambda<value(const list<value>&)>(javaLifecycle(jr)));
}
/**
* Evaluate a Java component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle) {
const string itype(elementName(impl));
- if (contains(itype, ".java"))
- return modjava::evalImplementation(path, impl, px, sc);
+ if (contains(itype, ".java")) {
+ const void* p = (gc_ptr<value>)lifecycle(mklist<value>("javaRuntime"));
+ return modjava::evalImplementation(path, impl, px, *(java::JavaRuntime*)p);
+ }
if (contains(itype, ".cpp"))
- return modcpp::evalImplementation(path, impl, px, sc);
+ return modcpp::evalImplementation(path, impl, px);
return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
}
diff --git a/sca-cpp/trunk/modules/java/mod-java.hpp b/sca-cpp/trunk/modules/java/mod-java.hpp
index ccb6d9262b..e7da06e930 100644
--- a/sca-cpp/trunk/modules/java/mod-java.hpp
+++ b/sca-cpp/trunk/modules/java/mod-java.hpp
@@ -34,20 +34,12 @@
#include "value.hpp"
#include "monad.hpp"
#include "eval.hpp"
-#include "../server/mod-eval.hpp"
namespace tuscany {
namespace server {
namespace modjava {
/**
- * Return the Java runtime configured in a server.
- */
-java::JavaRuntime& javaRuntime(modeval::ServerConf sc) {
- return *(java::JavaRuntime*)sc.moduleConf;
-}
-
-/**
* Apply a Java component implementation function.
*/
struct applyImplementation {
@@ -59,11 +51,10 @@ struct applyImplementation {
const value operator()(const list<value>& params) const {
const value expr = append<value>(params, px);
debug(expr, "modeval::java::applyImplementation::input");
- const failable<value> val = java::evalClass(jr, expr, impl);
+ const failable<value> res = java::evalClass(jr, expr, impl);
+ const value val = !hasContent(res)? mklist<value>(value(), reason(res)) : mklist<value>(content(res));
debug(val, "modeval::java::applyImplementation::result");
- if (!hasContent(val))
- return mklist<value>(value(), reason(val));
- return mklist<value>(content(val));
+ return val;
}
};
@@ -71,12 +62,12 @@ struct applyImplementation {
* Evaluate a Java component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, java::JavaRuntime& jr) {
const string cn(attributeValue("class", impl));
- const failable<java::JavaClass> jc = java::readClass(javaRuntime(sc), path, cn);
+ const failable<java::JavaClass> jc = java::readClass(jr, path, cn);
if (!hasContent(jc))
return mkfailure<lambda<value(const list<value>&)> >(reason(jc));
- return lambda<value(const list<value>&)>(applyImplementation(content(jc), px, javaRuntime(sc)));
+ return lambda<value(const list<value>&)>(applyImplementation(content(jc), px, jr));
}
}
diff --git a/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java
index eedba5f46f..a00d5b1b53 100644
--- a/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java
+++ b/sca-cpp/trunk/modules/java/org/apache/tuscany/Service.java
@@ -26,34 +26,24 @@ package org.apache.tuscany;
public interface Service {
/**
- * Post a new item to a resource.
+ * Post a new item to a collection of items.
*/
- String post(Iterable<?> item);
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
/**
* Return an item.
*/
- Iterable<?> get(String id);
+ Iterable<?> get(Iterable<String> id);
/**
- * Return all items in the resource.
+ * Update an item.
*/
- Iterable<?> getall();
-
- /**
- * Update am item.
- */
- boolean put(String id, Iterable<?> item);
+ boolean put(Iterable<String> id, Iterable<?> item);
/**
* Delete an item.
*/
- boolean delete(String id);
-
- /**
- * Delete all items in the resource.
- */
- boolean deleteall();
+ boolean delete(Iterable<String> id);
/**
* Evaluate an expression.
diff --git a/sca-cpp/trunk/modules/java/test/Client.java b/sca-cpp/trunk/modules/java/test/Client.java
index ff2d3fee13..c3bd875fcc 100644
--- a/sca-cpp/trunk/modules/java/test/Client.java
+++ b/sca-cpp/trunk/modules/java/test/Client.java
@@ -23,16 +23,12 @@ public interface Client {
String echo(String x);
- Iterable<?> getall();
+ Iterable<?> get(Iterable<String> id);
- Iterable<?> get(String id);
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
- String post(Iterable<?> item);
+ Boolean put(Iterable<String> id, Iterable<?> item);
- Boolean put(String id, Iterable<?> entry);
-
- Boolean deleteall();
-
- Boolean delete(String id);
+ Boolean delete(Iterable<String> id);
}
diff --git a/sca-cpp/trunk/modules/java/test/ClientImpl.java b/sca-cpp/trunk/modules/java/test/ClientImpl.java
index 4bd3498dd5..ade2ba302e 100644
--- a/sca-cpp/trunk/modules/java/test/ClientImpl.java
+++ b/sca-cpp/trunk/modules/java/test/ClientImpl.java
@@ -25,27 +25,19 @@ public class ClientImpl {
return server.echo(x);
}
- public Iterable<?> getall(Server server) {
- return server.getall();
- }
-
- public Iterable<?> get(String id, Server server) {
+ public Iterable<?> get(Iterable<String> id, Server server) {
return server.get(id);
}
- public String post(Iterable<?> item, Server server) {
- return server.post(item);
+ public Iterable<String> post(Iterable<String> collection, Iterable<?> item, Server server) {
+ return server.post(collection, item);
}
- public Boolean put(String id, Iterable<?> item, Server server) {
+ public Boolean put(Iterable<String> id, Iterable<?> item, Server server) {
return server.put(id, item);
}
- public Boolean deleteall(Server server) {
- return server.deleteall();
- }
-
- public Boolean delete(String id, Server server) {
+ public Boolean delete(Iterable<String> id, Server server) {
return server.delete(id);
}
diff --git a/sca-cpp/trunk/modules/java/test/Server.java b/sca-cpp/trunk/modules/java/test/Server.java
index 917ccfd6b9..3dfe3c84ef 100644
--- a/sca-cpp/trunk/modules/java/test/Server.java
+++ b/sca-cpp/trunk/modules/java/test/Server.java
@@ -23,16 +23,12 @@ public interface Server {
String echo(String x);
- Iterable<?> getall();
+ Iterable<?> get(Iterable<String> id);
- Iterable<?> get(String id);
+ Iterable<String> post(Iterable<String> collection, Iterable<?> item);
- String post(Iterable<?> item);
+ Boolean put(Iterable<String> id, Iterable<?> item);
- Boolean put(String id, Iterable<?> entry);
-
- Boolean deleteall();
-
- Boolean delete(String id);
+ Boolean delete(Iterable<String> id);
}
diff --git a/sca-cpp/trunk/modules/java/test/ServerImpl.java b/sca-cpp/trunk/modules/java/test/ServerImpl.java
index dd4e227123..d979c20a15 100644
--- a/sca-cpp/trunk/modules/java/test/ServerImpl.java
+++ b/sca-cpp/trunk/modules/java/test/ServerImpl.java
@@ -27,31 +27,25 @@ public class ServerImpl {
return x;
}
- public Iterable<?> getall() {
- return list("Sample Feed", "123456789",
- list("Item", "111", list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99))),
- list("Item", "222", list(list("'javaClass", "services.Item"), list("'name", "Orange"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 3.55))),
- list("Item", "333", list(list("'javaClass", "services.Item"), list("'name", "Pear"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 1.55))));
- }
-
- public Iterable<?> get(String id) {
+ public Iterable<?> get(Iterable<String> id) {
+ if (isNil(id))
+ return list("Sample Feed", "123456789",
+ list("Item", "111", list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99))),
+ list("Item", "222", list(list("'javaClass", "services.Item"), list("'name", "Orange"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 3.55))),
+ list("Item", "333", list(list("'javaClass", "services.Item"), list("'name", "Pear"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 1.55))));
Iterable<?> entry = list(list("'javaClass", "services.Item"), list("'name", "Apple"), list("'currencyCode", "USD"), list("'currencySymbol", "$"), list("'price", 2.99));
return list("Item", id, entry);
}
- public String post(Iterable<?> item) {
- return "123456789";
+ public Iterable<String> post(Iterable<String> collection, Iterable<?> item) {
+ return list("123456789");
}
- public Boolean put(String id, Iterable<?> entry) {
- return true;
- }
-
- public Boolean deleteall() {
+ public Boolean put(Iterable<String> id, Iterable<?> item) {
return true;
}
- public Boolean delete(String id) {
+ public Boolean delete(Iterable<String> id) {
return true;
}
}
diff --git a/sca-cpp/trunk/modules/json/json.hpp b/sca-cpp/trunk/modules/json/json.hpp
index 4c36b8b477..1d966d3f67 100644
--- a/sca-cpp/trunk/modules/json/json.hpp
+++ b/sca-cpp/trunk/modules/json/json.hpp
@@ -140,7 +140,7 @@ const bool isJSArray(const list<value>& l) {
if (isSymbol(v))
return false;
if(isList(v)) {
- if(isSymbol(car<value>(v)))
+ if(!isNil((list<value>)v) && isSymbol(car<value>(v)))
return false;
}
return true;
diff --git a/sca-cpp/trunk/modules/python/client-test.py b/sca-cpp/trunk/modules/python/client-test.py
index 6e3723302a..47e6cf4bda 100644
--- a/sca-cpp/trunk/modules/python/client-test.py
+++ b/sca-cpp/trunk/modules/python/client-test.py
@@ -22,18 +22,14 @@ def echo(x, ref):
# ATOMPub test case
-def getall(ref):
- return ref("getall")
-
def get(id, ref):
return ref("get", id)
-def post(entry, ref):
- return ref("post", entry)
+def post(collection, item, ref):
+ return ref("post", collection, item)
-def put(id, entry, ref):
- return ref("put", id, entry)
+def put(id, item, ref):
+ return ref("put", id, item)
def delete(id, ref):
return ref("delete", id)
-
diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp
index 5231b0ef60..136ecf6499 100644
--- a/sca-cpp/trunk/modules/python/eval.hpp
+++ b/sca-cpp/trunk/modules/python/eval.hpp
@@ -241,9 +241,9 @@ const failable<value> evalScript(const value& expr, PyObject* script) {
// The start, stop, and restart functions are optional
const value fn = car<value>(expr);
- if (fn == "start" || fn == "stop" || fn == "restart") {
+ if (fn == "start" || fn == "restart" || fn == "stop") {
PyErr_Clear();
- return value(false);
+ return value(lambda<value(const list<value>&)>());
}
return mkfailure<value>(string("Couldn't find function: ") + car<value>(expr) + " : " + lastError());
diff --git a/sca-cpp/trunk/modules/python/mod-python.cpp b/sca-cpp/trunk/modules/python/mod-python.cpp
index df94f2e8a1..8561a1fbf4 100644
--- a/sca-cpp/trunk/modules/python/mod-python.cpp
+++ b/sca-cpp/trunk/modules/python/mod-python.cpp
@@ -37,40 +37,27 @@ namespace server {
namespace modeval {
/**
- * Start the module.
+ * Apply a lifecycle start or restart event.
*/
-const failable<bool> start(unused ServerConf& sc) {
- // Start a Python runtime
- sc.moduleConf = new (gc_new<python::PythonRuntime>()) python::PythonRuntime();
- return true;
-}
+const value applyLifecycle(unused const list<value>& params) {
-/**
- * Stop the module.
- */
-const failable<bool> stop(unused ServerConf& sc) {
- return true;
-}
+ // Create a Python runtime
+ new (gc_new<python::PythonRuntime>()) python::PythonRuntime();
-/**
- * Restart the module.
- */
-const failable<bool> restart(unused ServerConf& sc) {
- // Start a Python runtime
- sc.moduleConf = new (gc_new<python::PythonRuntime>()) python::PythonRuntime();
- return true;
+ // Return a nil function as we don't need to handle the stop event
+ return failable<value>(lambda<value(const list<value>&)>());
}
/**
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lambda<value(const list<value>&)>& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".python"))
- return modpython::evalImplementation(path, impl, px, sc);
+ return modpython::evalImplementation(path, impl, px);
if (contains(itype, ".cpp"))
- return modcpp::evalImplementation(path, impl, px, sc);
+ return modcpp::evalImplementation(path, impl, px);
return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
}
diff --git a/sca-cpp/trunk/modules/python/mod-python.hpp b/sca-cpp/trunk/modules/python/mod-python.hpp
index cbe2b6b97c..d13f2227ab 100644
--- a/sca-cpp/trunk/modules/python/mod-python.hpp
+++ b/sca-cpp/trunk/modules/python/mod-python.hpp
@@ -34,7 +34,6 @@
#include "value.hpp"
#include "monad.hpp"
#include "eval.hpp"
-#include "../server/mod-eval.hpp"
namespace tuscany {
namespace server {
@@ -51,11 +50,10 @@ struct applyImplementation {
const value operator()(const list<value>& params) const {
const value expr = append<value>(params, px);
debug(expr, "modeval::python::applyImplementation::input");
- const failable<value> val = python::evalScript(expr, impl);
+ const failable<value> res = python::evalScript(expr, impl);
+ const value val = !hasContent(res)? mklist<value>(value(), reason(res)) : mklist<value>(content(res));
debug(val, "modeval::python::applyImplementation::result");
- if (!hasContent(val))
- return mklist<value>(value(), reason(val));
- return mklist<value>(content(val));
+ return val;
}
};
@@ -63,7 +61,7 @@ struct applyImplementation {
* Evaluate a Python component implementation and convert it to an applicable
* lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
const string fpath(path + attributeValue("script", impl));
ifstream is(fpath);
if (fail(is))
diff --git a/sca-cpp/trunk/modules/python/server-test.py b/sca-cpp/trunk/modules/python/server-test.py
index ac2b6829c9..61e177d0aa 100644
--- a/sca-cpp/trunk/modules/python/server-test.py
+++ b/sca-cpp/trunk/modules/python/server-test.py
@@ -22,25 +22,21 @@ def echo(x):
# ATOMPub test case
-def getall():
- return ("Sample Feed", "123456789",
- ("Item", "111", (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))),
- ("Item", "222", (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 3.55))),
- ("Item", "333", (("'javaClass", "services.Item"), ("name", "Pear"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 1.55))))
-
def get(id):
- entry = (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))
- return ("Item", id, entry)
-
-def post(entry):
- return "123456789"
-
-def put(id, entry):
- return true
-
-def deleteall():
+ if id == ():
+ return ("Sample Feed", "123456789",
+ ("Item", "111", (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))),
+ ("Item", "222", (("'javaClass", "services.Item"), ("'name", "Orange"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 3.55))),
+ ("Item", "333", (("'javaClass", "services.Item"), ("name", "Pear"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 1.55))))
+
+ entry = (("'javaClass", "services.Item"), ("'name", "Apple"), ("'currencyCode", "USD"), ("'currencySymbol", "$"), ("'price", 2.99))
+ return ("Item", id, entry)
+
+def post(collection, item):
+ return ("123456789",)
+
+def put(id, item):
return true
def delete(id):
return true
-
diff --git a/sca-cpp/trunk/modules/scheme/primitive.hpp b/sca-cpp/trunk/modules/scheme/primitive.hpp
index 5a13725ffd..e911c76f6c 100644
--- a/sca-cpp/trunk/modules/scheme/primitive.hpp
+++ b/sca-cpp/trunk/modules/scheme/primitive.hpp
@@ -172,15 +172,15 @@ const value cdddrProc(unused const list<value>& args) {
}
const value startProc(unused const list<value>& args) {
- return false;
+ return lambda<value(const list<value>&)>();
}
const value stopProc(unused const list<value>& args) {
- return false;
+ return lambda<value(const list<value>&)>();
}
const value restartProc(unused const list<value>& args) {
- return false;
+ return lambda<value(const list<value>&)>();
}
const value applyPrimitiveProcedure(const value& proc, list<value>& args) {
diff --git a/sca-cpp/trunk/modules/server/client-test.scm b/sca-cpp/trunk/modules/server/client-test.scm
index 11c71cdfce..47b799d390 100644
--- a/sca-cpp/trunk/modules/server/client-test.scm
+++ b/sca-cpp/trunk/modules/server/client-test.scm
@@ -21,26 +21,18 @@
; ATOMPub test case
-(define (getall ref)
- (ref "getall")
-)
-
(define (get id ref)
(ref "get" id)
)
-(define (post entry ref)
- (ref "post" entry)
+(define (post coll entry ref)
+ (ref "post" coll entry)
)
(define (put id entry ref)
(ref "put" id entry)
)
-(define (deleteall ref)
- (ref deleteall)
-)
-
(define (delete id ref)
(ref "delete" id)
)
diff --git a/sca-cpp/trunk/modules/server/impl-test.cpp b/sca-cpp/trunk/modules/server/impl-test.cpp
index 51162d070d..3fa1d65323 100644
--- a/sca-cpp/trunk/modules/server/impl-test.cpp
+++ b/sca-cpp/trunk/modules/server/impl-test.cpp
@@ -38,7 +38,7 @@ const failable<value> get(unused const list<value>& params) {
}
const failable<value> post(unused const list<value>& params) {
- return value(string("123456789"));
+ return value(mklist<value>(string("123456789")));
}
const failable<value> put(unused const list<value>& params) {
diff --git a/sca-cpp/trunk/modules/server/mod-cpp.hpp b/sca-cpp/trunk/modules/server/mod-cpp.hpp
index 19ba938034..23b4941c26 100644
--- a/sca-cpp/trunk/modules/server/mod-cpp.hpp
+++ b/sca-cpp/trunk/modules/server/mod-cpp.hpp
@@ -37,7 +37,6 @@
#include "monad.hpp"
#include "dynlib.hpp"
#include "../scheme/driver.hpp"
-#include "mod-eval.hpp"
namespace tuscany {
namespace server {
@@ -54,8 +53,8 @@ const list<value> failableResult(const value& func, const list<value>& v) {
// Except for the start, stop, and restart functions, which are optional
const value reason = cadr(v);
if (length(reason) == 0) {
- if (func == "start" || func == "stop" || func == "restart")
- return mklist<value>(false);
+ if (func == "start" || func == "restart" || func == "stop")
+ return mklist<value>(lambda<value(const list<value>&)>());
return mklist<value>(value(), string("Function not supported: ") + func);
}
return v;
@@ -82,7 +81,7 @@ struct applyImplementation {
* Evaluate a C++ component implementation and convert it to
* an applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
// Configure the implementation's lambda function
const value ipath(attributeValue("path", impl));
diff --git a/sca-cpp/trunk/modules/server/mod-eval.cpp b/sca-cpp/trunk/modules/server/mod-eval.cpp
index 5a9b87ca2f..a94ccf5bbe 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.cpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.cpp
@@ -37,36 +37,23 @@ namespace server {
namespace modeval {
/**
- * Start the module.
+ * Apply a lifecycle start or restart event.
*/
-const failable<bool> start(unused ServerConf& sc) {
- return true;
-}
-
-/**
- * Stop the module.
- */
-const failable<bool> stop(unused ServerConf& sc) {
- return true;
-}
-
-/**
- * Restart the module.
- */
-const failable<bool> restart(unused ServerConf& sc) {
- return true;
+const value applyLifecycle(unused const list<value>& params) {
+ // Return a nil function as we don't need to handle any subsequent events
+ return failable<value>(lambda<value(const list<value>&)>());
}
/**
* Evaluate a Scheme or C++ component implementation and convert it to an
* applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused const lambda<value(const list<value>&)>& lifecycle) {
const string itype(elementName(impl));
if (contains(itype, ".scheme"))
- return modscheme::evalImplementation(path, impl, px, sc);
+ return modscheme::evalImplementation(path, impl, px);
if (contains(itype, ".cpp"))
- return modcpp::evalImplementation(path, impl, px, sc);
+ return modcpp::evalImplementation(path, impl, px);
return mkfailure<lambda<value(const list<value>&)> >(string("Unsupported implementation type: ") + itype);
}
diff --git a/sca-cpp/trunk/modules/server/mod-eval.hpp b/sca-cpp/trunk/modules/server/mod-eval.hpp
index 6ab1d68ad6..03cce5aeb4 100644
--- a/sca-cpp/trunk/modules/server/mod-eval.hpp
+++ b/sca-cpp/trunk/modules/server/mod-eval.hpp
@@ -53,16 +53,17 @@ namespace modeval {
*/
class ServerConf {
public:
- ServerConf(server_rec* s) : s(s), moduleConf(NULL), home(""), wiringServerName(""), contributionPath(""), compositeName("") {
+ ServerConf(server_rec* s) : s(s), home(""), wiringServerName(""), contributionPath(""), compositeName("") {
}
const server_rec* s;
- void* moduleConf;
+ lambda<value(const list<value>&)> lifecycle;
string home;
string wiringServerName;
string contributionPath;
string compositeName;
list<value> implementations;
+ list<value> implTree;
};
/**
@@ -103,20 +104,15 @@ const failable<int> get(request_rec* r, const lambda<value(const list<value>&)>&
return httpd::writeResult(json::jsonResult(id, content(val), cx), "application/json-rpc", r);
}
- // Evaluate an ATOM GET request and return an ATOM feed representing a collection of resources
- const list<value> path(httpd::pathValues(r->uri));
- if (isNil(cddr(path))) {
- const failable<value> val = failableResult(impl(cons<value>("getall", list<value>())));
- if (!hasContent(val))
- return mkfailure<int>(reason(val));
- return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(content(val))), "application/atom+xml;type=feed", r);
- }
-
- // Evaluate an ATOM GET and return an ATOM entry representing a resource
- const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(caddr(path)))));
+ // Evaluate the GET expression and return an ATOM entry or feed representing a resource
+ const list<value> path(pathValues(r->uri));
+ const failable<value> val = failableResult(impl(cons<value>("get", mklist<value>(cddr(path)))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
- return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(content(val))), "application/atom+xml;type=entry", r);
+ if (isNil(cddr(path)))
+ return httpd::writeResult(atom::writeATOMFeed(atom::feedValuesToElements(content(val))), "application/atom+xml;type=feed", r);
+ else
+ return httpd::writeResult(atom::writeATOMEntry(atom::entryValuesToElements(content(val))), "application/atom+xml;type=entry", r);
}
/**
@@ -157,6 +153,7 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>
if (contains(ct, "application/atom+xml")) {
// Read the ATOM entry
+ const list<value> path(pathValues(r->uri));
const int rc = httpd::setupReadPolicy(r);
if(rc != OK)
return rc;
@@ -164,12 +161,13 @@ const failable<int> post(request_rec* r, const lambda<value(const list<value>&)>
debug(ls, "modeval::post::input");
const value entry = atom::entryValue(content(atom::readEntry(ls)));
- // Evaluate the request expression
- const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(entry))));
+ // Evaluate the POST expression
+ const failable<value> val = failableResult(impl(cons<value>("post", mklist<value>(cddr(path), entry))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
// Return the created resource location
+ debug(content(val), "modeval::post::location");
apr_table_setn(r->headers_out, "Location", apr_pstrdup(r->pool, httpd::url(content(val), r)));
r->status = HTTP_CREATED;
return OK;
@@ -190,7 +188,7 @@ const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>&
debug(r->uri, "modeval::put::url");
// Read the ATOM entry
- const list<value> path(httpd::pathValues(r->uri));
+ const list<value> path(pathValues(r->uri));
const int rc = httpd::setupReadPolicy(r);
if(rc != OK)
return rc;
@@ -198,8 +196,8 @@ const failable<int> put(request_rec* r, const lambda<value(const list<value>&)>&
debug(ls, "modeval::put::input");
const value entry = atom::entryValue(content(atom::readEntry(ls)));
- // Evaluate the ATOM PUT request and update the corresponding resource
- const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(caddr(path), entry))));
+ // Evaluate the PUT expression and update the corresponding resource
+ const failable<value> val = failableResult(impl(cons<value>("put", mklist<value>(cddr(path), entry))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
if (val == value(false))
@@ -214,20 +212,8 @@ const failable<int> del(request_rec* r, const lambda<value(const list<value>&)>&
debug(r->uri, "modeval::delete::url");
// Evaluate an ATOM delete request
- const list<value> path(httpd::pathValues(r->uri));
- if (isNil(cddr(path))) {
-
- // Delete a collection of resources
- const failable<value> val = failableResult(impl(cons<value>("deleteall", list<value>())));
- if (!hasContent(val))
- return mkfailure<int>(reason(val));
- if (val == value(false))
- return HTTP_NOT_FOUND;
- return OK;
- }
-
- // Delete a resource
- const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(caddr(path)))));
+ const list<value> path(pathValues(r->uri));
+ const failable<value> val = failableResult(impl(cons<value>("delete", mklist<value>(cddr(path)))));
if (!hasContent(val))
return mkfailure<int>(reason(val));
if (val == value(false))
@@ -257,8 +243,8 @@ int handler(request_rec *r) {
// Get the component implementation lambda
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_eval);
- const list<value> path(httpd::pathValues(r->uri));
- const list<value> impl(assoctree<value>(cadr(path), sc.implementations));
+ const list<value> path(pathValues(r->uri));
+ const list<value> impl(assoctree<value>(cadr(path), sc.implTree));
if (isNil(impl))
return HTTP_NOT_FOUND;
@@ -317,7 +303,7 @@ const list<value> propProxies(const list<value>& props) {
* Evaluate a component and convert it to an applicable lambda function.
*/
const value evalComponent(ServerConf& sc, server_rec& server, const value& comp) {
- extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, ServerConf& sc);
+ extern const failable<lambda<value(const list<value>&)> > evalImplementation(const string& cpath, const value& impl, const list<value>& px, const lambda<value(const list<value>&)>& lifecycle);
const value impl = scdl::implementation(comp);
@@ -336,7 +322,7 @@ const value evalComponent(ServerConf& sc, server_rec& server, const value& comp)
const list<value> ppx(propProxies(scdl::properties(comp)));
// Evaluate the component implementation and convert it to an applicable lambda function
- const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(sc.contributionPath, impl, append(rpx, ppx), sc));
+ const failable<lambda<value(const list<value>&)> > cimpl(evalImplementation(sc.contributionPath, impl, append(rpx, ppx), sc.lifecycle));
if (!hasContent(cimpl))
return reason(cimpl);
return content(cimpl);
@@ -362,19 +348,28 @@ const failable<list<value> > readComponents(const string& path) {
}
/**
- * Apply a list of component implementations to a (start, stop or restart) lifecycle expression.
+ * Apply a list of component implementations to a start or restart lifecycle expression.
+ * Return the functions returned by the component implementations.
*/
-const failable<bool> applyLifecycleExpr(const list<value> impls, const list<value>& expr) {
+const failable<list<value> > applyLifecycleExpr(const list<value>& impls, const list<value>& expr) {
if (isNil(impls))
- return true;
+ return list<value>();
// Evaluate lifecycle expression against a component implementation lambda
- const lambda<value(const list<value>&)> l(cadr<value>(car(impls)));
+ const lambda<value(const list<value>&)> l = cadr<value>(car(impls));
const failable<value> r = failableResult(l(expr));
if (!hasContent(r))
- return mkfailure<bool>(reason(r));
+ return mkfailure<list<value> >(reason(r));
+ const lambda<value(const list<value>&)> rl = content(r);
+
+ // Use the returned lambda function, if any, from now on
+ const lambda<value(const list<value>&)> al = isNil(rl)? l : rl;
- return applyLifecycleExpr(cdr(impls), expr);
+ // Continue with the rest of the list
+ const failable<list<value> > nr = applyLifecycleExpr(cdr(impls), expr);
+ if (!hasContent(nr))
+ return nr;
+ return cons<value>(mklist<value>(car<value>(car(impls)), value(al)), content(nr));
}
/**
@@ -388,14 +383,106 @@ const failable<bool> confComponents(const string& lifecycle, ServerConf& sc, ser
const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName);
if (!hasContent(comps))
return mkfailure<bool>(reason(comps));
- const list<value> impls = componentToImplementationAssoc(sc, server, content(comps));
+ const list<value> starts = componentToImplementationAssoc(sc, server, content(comps));
- // Store the implementation lambda functions in a tree for fast retrieval
- sc.implementations = mkbtree(sort(impls));
+ // Start or restart the component implementations
+ // Record the returned lambda functions
+ debug(starts, "modeval::confComponents::start");
+ const failable<list<value> > impls = applyLifecycleExpr(starts, mklist<value>(c_str(lifecycle)));
+ if (!hasContent(impls))
+ return mkfailure<bool>(reason(impls));
+ sc.implementations = content(impls);
debug(sc.implementations, "modeval::confComponents::implementations");
- // Start or restart the component implementations
- return applyLifecycleExpr(impls, mklist<value>(c_str(lifecycle)));
+ // Store the implementation lambda functions in a tree for fast retrieval
+ sc.implTree = mkbtree(sort(sc.implementations));
+
+ return true;
+}
+
+/**
+ * Cleanup callback, called when the server is stopped or restarted.
+ */
+apr_status_t serverCleanup(void* v) {
+ gc_pool pool;
+ ServerConf& sc = *(ServerConf*)v;
+ debug("modeval::serverCleanup");
+
+ // Stop the component implementations
+ applyLifecycleExpr(sc.implementations, mklist<value>("stop"));
+
+ // Call the module lifecycle function
+ if (isNil(sc.lifecycle))
+ return APR_SUCCESS;
+ debug("modeval::serverCleanup::stop");
+ sc.lifecycle(mklist<value>("stop"));
+
+ return APR_SUCCESS;
+}
+
+/**
+ * Called after all the configuration commands have been run.
+ * Process the server configuration and configure the deployed components.
+ */
+int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
+ extern const value applyLifecycle(const list<value>&);
+
+ gc_scoped_pool pool(p);
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
+
+ // Count the calls to post config
+ const string k("tuscany::modeval::postConfig");
+ const int count = (int)httpd::userData(k, s);
+ httpd::putUserData(k, (void*)(count + 1), s);
+
+ // Count == 0, do nothing as post config is always called twice,
+ // count == 1 is the first start, count > 1 is a restart
+ if (count == 0)
+ return OK;
+ if (count == 1) {
+ debug("modeval::postConfig::start");
+ const failable<value> r = failableResult(applyLifecycle(mklist<value>("start")));
+ if (!hasContent(r))
+ return -1;
+ sc.lifecycle = content(r);
+ }
+ if (count > 1) {
+ debug("modeval::postConfig::restart");
+ const failable<value> r = failableResult(applyLifecycle(mklist<value>("restart")));
+ if (!hasContent(r))
+ return -1;
+ sc.lifecycle = content(r);
+ }
+
+ // Configure the deployed components
+ debug(sc.wiringServerName, "modeval::postConfig::wiringServerName");
+ debug(sc.contributionPath, "modeval::postConfig::contributionPath");
+ debug(sc.compositeName, "modeval::postConfig::compositeName");
+ const failable<bool> res = confComponents(count > 1? "restart" : "start", sc, *s);
+ if (!hasContent(res)) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
+ return -1;
+ }
+
+ // Register a cleanup callback, called when the server is stopped or restarted
+ apr_pool_pre_cleanup_register(p, (void*)&sc, serverCleanup);
+
+ return OK;
+}
+
+/**
+ * Child process initialization.
+ */
+void childInit(apr_pool_t* p, server_rec* s) {
+ gc_scoped_pool pool(p);
+ ServerConf* sc = (ServerConf*)ap_get_module_config(s->module_config, &mod_tuscany_eval);
+ if(sc == NULL) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
+ exit(APEXIT_CHILDFATAL);
+ }
+
+ // Register a cleanup callback, called when the child is stopped or restarted
+ apr_pool_pre_cleanup_register(p, (void*)sc, serverCleanup);
}
/**
@@ -444,51 +531,6 @@ const command_rec commands[] = {
{NULL, NULL, NULL, 0, NO_ARGS, NULL}
};
-int postConfig(apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
- extern const failable<bool> start(ServerConf& sc);
- extern const failable<bool> restart(ServerConf& sc);
- gc_scoped_pool pool(p);
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_eval);
-
- // Count the calls to post config
- const string k("tuscany::modeval::postConfig");
- const int count = httpd::userData(k, s);
- httpd::putUserData(k, count +1, s);
-
- // Count == 0, do nothing as post config is always called twice,
- // count == 1 is the first start, count > 1 is a restart
- if (count == 0)
- return OK;
- if (count == 1) {
- debug("modeval::postConfig::start");
- start(sc);
- }
- if (count > 1) {
- debug("modeval::postConfig::restart");
- restart(sc);
- }
-
- // Configure the components deployed to the server
- debug(sc.wiringServerName, "modeval::postConfig::wiringServerName");
- debug(sc.contributionPath, "modeval::postConfig::contributionPath");
- debug(sc.compositeName, "modeval::postConfig::compositeName");
- const failable<bool> res = confComponents(count > 1? "restart" : "start", sc, *s);
- if (!hasContent(res))
- return -1;
- return OK;
-}
-
-/**
- * Child process initialization.
- */
-void childInit(apr_pool_t* p, server_rec* svr_rec) {
- gc_scoped_pool pool(p);
- ServerConf* c = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_eval);
- if(c == NULL) {
- cerr << "[Tuscany] Due to one or more errors mod_tuscany_eval loading failed. Causing apache to stop loading." << endl;
- exit(APEXIT_CHILDFATAL);
- }
-}
void registerHooks(unused apr_pool_t *p) {
ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
diff --git a/sca-cpp/trunk/modules/server/mod-scheme.hpp b/sca-cpp/trunk/modules/server/mod-scheme.hpp
index e18eececf6..f5b9554c3f 100644
--- a/sca-cpp/trunk/modules/server/mod-scheme.hpp
+++ b/sca-cpp/trunk/modules/server/mod-scheme.hpp
@@ -34,7 +34,6 @@
#include "value.hpp"
#include "monad.hpp"
#include "../scheme/eval.hpp"
-#include "../server/mod-eval.hpp"
namespace tuscany {
namespace server {
@@ -61,11 +60,10 @@ struct applyImplementation {
const value expr = cons<value>(car(params), append(scheme::quotedParameters(cdr(params)), px));
debug(expr, "modeval::scheme::applyImplementation::input");
scheme::Env env = scheme::setupEnvironment();
- const value val = scheme::evalScript(expr, impl, env);
+ const value res = scheme::evalScript(expr, impl, env);
+ const value val = isNil(res)? mklist<value>(value(), string("Could not evaluate expression")) : mklist<value>(res);
debug(val, "modeval::scheme::applyImplementation::result");
- if (isNil(val))
- return mklist<value>(value(), string("Could not evaluate expression"));
- return mklist<value>(val);
+ return val;
}
};
@@ -73,7 +71,7 @@ struct applyImplementation {
* Evaluate a Scheme component implementation and convert it to an
* applicable lambda function.
*/
-const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px, unused modeval::ServerConf& sc) {
+const failable<lambda<value(const list<value>&)> > evalImplementation(const string& path, const value& impl, const list<value>& px) {
const string fpath(path + attributeValue("script", impl));
ifstream is(fpath);
if (fail(is))
diff --git a/sca-cpp/trunk/modules/server/mod-wiring.cpp b/sca-cpp/trunk/modules/server/mod-wiring.cpp
index e21f8be773..c21b0fe254 100644
--- a/sca-cpp/trunk/modules/server/mod-wiring.cpp
+++ b/sca-cpp/trunk/modules/server/mod-wiring.cpp
@@ -82,7 +82,7 @@ int translateReference(request_rec *r) {
// Find the requested component
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring);
- const list<value> rpath(httpd::pathValues(r->uri));
+ const list<value> rpath(pathValues(r->uri));
const list<value> comp(assoctree(cadr(rpath), sc.references));
if (isNil(comp))
return HTTP_NOT_FOUND;
@@ -147,20 +147,20 @@ int translateService(request_rec *r) {
// Find the requested component
const ServerConf& sc = httpd::serverConf<ServerConf>(r, &mod_tuscany_wiring);
- const list<value> path(httpd::pathValues(r->uri));
- const list<value> svc(assocPath(path, sc.services));
+ const list<value> p(pathValues(r->uri));
+ const list<value> svc(assocPath(p, sc.services));
if (isNil(svc))
return DECLINED;
debug(svc, "modwiring::translateService::service");
// Build a component-name + path-info URI
- const list<value> target(cons<value>(cadr(svc), httpd::pathInfo(path, car(svc))));
+ const list<value> target(cons<value>(cadr(svc), httpd::pathInfo(p, car(svc))));
debug(target, "modwiring::translateService::target");
// Dispatch to the target component using a local internal redirect
- const string p(httpd::path(target));
- debug(p, "modwiring::translateService::path");
- const string redir(string("/redirect:/components") + httpd::path(target));
+ const string tp(path(target));
+ debug(tp, "modwiring::translateService::path");
+ const string redir(string("/redirect:/components") + tp);
debug(redir, "modwiring::translateService::redirect");
r->filename = apr_pstrdup(r->pool, c_str(redir));
r->handler = "mod_tuscany_wiring";
@@ -216,7 +216,7 @@ const failable<list<value> > readComponents(const string& path) {
}
/**
- * Return a tree of component-name + references pairs. The references are
+ * Return a list of component-name + references pairs. The references are
* arranged in trees of reference-name + reference-target pairs.
*/
const list<value> componentReferenceToTargetTree(const value& c) {
@@ -229,12 +229,8 @@ const list<value> componentReferenceToTargetAssoc(const list<value>& c) {
return cons<value>(componentReferenceToTargetTree(car(c)), componentReferenceToTargetAssoc(cdr(c)));
}
-const list<value> componentReferenceToTargetTree(const list<value>& c) {
- return mkbtree(sort(componentReferenceToTargetAssoc(c)));
-}
-
/**
- * Return a tree of service-URI-path + component-name pairs. Service-URI-paths are
+ * Return a list of service-URI-path + component-name pairs. Service-URI-paths are
* represented as lists of URI path fragments.
*/
const list<value> defaultBindingURI(const string& cn, const string& sn) {
@@ -247,7 +243,7 @@ const list<value> bindingToComponentAssoc(const string& cn, const string& sn, co
const value uri(scdl::uri(car(b)));
if (isNil(uri))
return cons<value>(mklist<value>(defaultBindingURI(cn, sn), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
- return cons<value>(mklist<value>(httpd::pathValues(c_str(string(uri))), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
+ return cons<value>(mklist<value>(pathValues(c_str(string(uri))), cn), bindingToComponentAssoc(cn, sn, cdr(b)));
}
const list<value> serviceToComponentAssoc(const string& cn, const list<value>& s) {
@@ -266,10 +262,6 @@ const list<value> uriToComponentAssoc(const list<value>& c) {
return append<value>(serviceToComponentAssoc(scdl::name(car(c)), scdl::services(car(c))), uriToComponentAssoc(cdr(c)));
}
-const list<value> uriToComponentTree(const list<value>& c) {
- return mkbtree(sort(uriToComponentAssoc(c)));
-}
-
/**
* Configure the components declared in the server's deployment composite.
*/
@@ -277,19 +269,56 @@ const bool confComponents(ServerConf& sc) {
if (sc.contributionPath == "" || sc.compositeName == "")
return true;
- // Read the component configuration and store the references and service
- // URIs in trees for fast retrieval later
+ // Read the component configuration and store the references and service URIs
+ // in trees for fast retrieval later
const failable<list<value> > comps = readComponents(sc.contributionPath + sc.compositeName);
if (!hasContent(comps))
return true;
- sc.references = componentReferenceToTargetTree(content(comps));
- debug(sc.references, "modwiring::confComponents::references");
- sc.services = uriToComponentTree(content(comps));
- debug(sc.services, "modwiring::confComponents::services");
+ const list<value> refs = componentReferenceToTargetAssoc(content(comps));
+ debug(refs, "modwiring::confComponents::references");
+ sc.references = mkbtree(sort(refs));
+
+ const list<value> svcs = uriToComponentAssoc(content(comps));
+ debug(svcs, "modwiring::confComponents::services");
+ sc.services = mkbtree(sort(svcs));
return true;
}
/**
+ * Called after all the configuration commands have been run.
+ * Process the server configuration and configure the wiring for the deployed components.
+ */
+int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
+ // Count the calls to post config, skip the first one as
+ // postConfig is always called twice
+ const string k("tuscany::modwiring::postConfig");
+ const int count = (int)httpd::userData(k, s);
+ httpd::putUserData(k, (void*)(count + 1), s);
+ if (count == 0)
+ return OK;
+
+ // Configure the wiring for the deployed components
+ ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_wiring);
+ debug(sc.wiringServerName, "modwiring::postConfig::wiringServerName");
+ debug(sc.contributionPath, "modwiring::postConfig::contributionPath");
+ debug(sc.compositeName, "modwiring::postConfig::compositeName");
+ confComponents(sc);
+ return OK;
+}
+
+/**
+ * Child process initialization.
+ */
+void childInit(apr_pool_t* p, server_rec* svr_rec) {
+ gc_scoped_pool pool(p);
+ ServerConf *conf = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_wiring);
+ if(conf == NULL) {
+ cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << endl;
+ exit(APEXIT_CHILDFATAL);
+ }
+}
+
+/**
* Configuration commands.
*/
const char *confHome(cmd_parms *cmd, unused void *c, const char *arg) {
@@ -328,33 +357,6 @@ const command_rec commands[] = {
{NULL, NULL, NULL, 0, NO_ARGS, NULL}
};
-int postConfig(unused apr_pool_t *p, unused apr_pool_t *plog, unused apr_pool_t *ptemp, server_rec *s) {
- // Count the calls to post config, skip the first one as
- // postConfig is always called twice
- const string k("tuscany::modwiring::postConfig");
- const int count = httpd::userData(k, s);
- httpd::putUserData(k, count +1, s);
- if (count == 0)
- return OK;
-
- // Configure the wiring for the deployed components
- ServerConf& sc = httpd::serverConf<ServerConf>(s, &mod_tuscany_wiring);
- debug(sc.wiringServerName, "modwiring::postConfig::wiringServerName");
- debug(sc.contributionPath, "modwiring::postConfig::contributionPath");
- debug(sc.compositeName, "modwiring::postConfig::compositeName");
- confComponents(sc);
- return OK;
-}
-
-void childInit(apr_pool_t* p, server_rec* svr_rec) {
- gc_scoped_pool pool(p);
- ServerConf *conf = (ServerConf*)ap_get_module_config(svr_rec->module_config, &mod_tuscany_wiring);
- if(conf == NULL) {
- cerr << "[Tuscany] Due to one or more errors mod_tuscany_wiring loading failed. Causing apache to stop loading." << endl;
- exit(APEXIT_CHILDFATAL);
- }
-}
-
void registerHooks(unused apr_pool_t *p) {
ap_hook_post_config(postConfig, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_child_init(childInit, NULL, NULL, APR_HOOK_MIDDLE);
diff --git a/sca-cpp/trunk/modules/server/server-test.scm b/sca-cpp/trunk/modules/server/server-test.scm
index 8864f55cfd..490f168170 100644
--- a/sca-cpp/trunk/modules/server/server-test.scm
+++ b/sca-cpp/trunk/modules/server/server-test.scm
@@ -21,30 +21,24 @@
; ATOMPub test case
-(define (getall)
- '("Sample Feed" "123456789"
- ("Item" "111" ((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))
- ("Item" "222" ((javaClass "services.Item") (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55)))
- ("Item" "333" ((javaClass "services.Item") (name "Pear") (currencyCode "USD") (currencySymbol "$") (price 1.55))))
-)
-
(define (get id)
- (define entry '((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))
- (cons "Item" (list id entry))
+ (if (nul id)
+ '("Sample Feed" "123456789"
+ ("Item" "111" ((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99)))
+ ("Item" "222" ((javaClass "services.Item") (name "Orange") (currencyCode "USD") (currencySymbol "$") (price 3.55)))
+ ("Item" "333" ((javaClass "services.Item") (name "Pear") (currencyCode "USD") (currencySymbol "$") (price 1.55))))
+
+ '("Item" "111" ((javaClass "services.Item") (name "Apple") (currencyCode "USD") (currencySymbol "$") (price 2.99))))
)
-(define (post entry)
- "123456789"
+(define (post coll entry)
+ '("123456789")
)
(define (put id entry)
true
)
-(define (deleteall)
- true
-)
-
(define (delete id)
true
)