summaryrefslogtreecommitdiffstats
path: root/sandbox/sebastien/cpp/apr-2/samples
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/sebastien/cpp/apr-2/samples')
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/Makefile.am22
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/README3
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/Makefile.am28
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/htdocs/index.html156
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/loan-approval.py77
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.composite46
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.py45
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/loan-python/server-test58
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/loan-python/start31
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/loan-python/stop21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/loan-python/util.py145
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/Makefile.am25
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/index.html31
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/test/index.html21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/html.py22
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/json.py24
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/relay.composite75
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/rss.py25
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/relay-python/start30
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/relay-python/stop20
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/relay-python/xml.py24
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/Makefile.am36
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/shopping-cart.py76
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.composite64
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.py40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/shopping-cart.py76
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.composite64
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.py40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/login/index.html194
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/logout/index.html33
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/login/index.html194
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/logout/index.html33
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/index.html34
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/login/index.html194
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/logout/index.html33
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-conf35
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-ssl-conf40
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/server-conf45
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/server-ssl-conf63
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/server-test61
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cluster/shared/shared.composite62
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-master-conf47
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-standby-conf40
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-start121
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-stop44
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/start79
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/stop42
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cluster/tunnel-ssl-conf32
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/Makefile.am40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/currency-converter.cpp67
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/fruits-catalog.cpp76
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-request.txt1
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-result.txt1
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/shopping-cart-entry.xml1
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cpp/server-test58
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/shopping-cart.cpp135
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cpp/ssl-start36
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cpp/start31
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-cpp/stop21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-cpp/store.composite70
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/Makefile.am44
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/app.yaml54
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-backend.composite32
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-frontend.composite66
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-single.composite71
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/domain.composite71
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/gmemcache.py45
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/index.html169
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/test/items-result.txt1
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/htpasswd.py21
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-gae/server-test59
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/shopping-cart.py82
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-gae/start21
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-gae/stop21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-gae/store.py40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/Makefile.am34
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/htdocs/index.html150
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-java/server-test58
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-java/ssl-start38
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-java/start33
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-java/stop23
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/store.composite70
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverter.java28
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverterImpl.java45
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/store/FruitsCatalogImpl.java51
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-java/store/ShoppingCartImpl.java112
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/Makefile.am25
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/currency-converter.scm27
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/fruits-catalog.scm30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/htdocs/index.html150
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-nosql/server-test58
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/shopping-cart.scm82
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-nosql/ssl-start36
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-nosql/start31
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-nosql/stop20
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.composite70
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.scm47
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/Makefile.am28
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/login/index.html40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/logout/index.html33
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/test/items-result.txt1
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-python/server-test58
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/shopping-cart.py75
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-python/ssl-start36
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-python/start31
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-python/stop21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/store.composite70
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-python/store.py40
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-python/uec2-start46
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/Makefile.am30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/currency-converter.scm27
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/fruits-catalog.scm30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/htdocs/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.cpp96
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.scm140
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-scheme/server-test58
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/shopping-cart.scm82
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-scheme/ssl-start36
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-scheme/start31
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-scheme/stop21
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.composite70
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.scm47
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/Makefile.am28
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/currency-converter.scm27
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/fruits-catalog.scm30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/htdocs/index.html150
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-sql/server-test58
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/shopping-cart.scm82
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-sql/ssl-start39
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-sql/start34
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-sql/stop22
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/store.composite90
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-sql/store.scm47
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/Makefile.am28
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/shopping-cart.py75
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.composite62
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.py40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/currency-converter.py29
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/fruits-catalog.py30
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/shopping-cart.py75
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.composite62
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.py40
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/jane/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/joe/index.html150
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/index.html34
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-vhost/server-test61
-rw-r--r--sandbox/sebastien/cpp/apr-2/samples/store-vhost/shared/shared.composite33
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-vhost/ssl-start46
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-vhost/start36
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-vhost/stop21
-rwxr-xr-xsandbox/sebastien/cpp/apr-2/samples/store-vhost/uec2-start50
165 files changed, 9124 insertions, 0 deletions
diff --git a/sandbox/sebastien/cpp/apr-2/samples/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/Makefile.am
new file mode 100644
index 0000000000..bd161fec30
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/Makefile.am
@@ -0,0 +1,22 @@
+# 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.
+
+SUBDIRS = store-scheme store-cpp store-python store-java store-gae store-sql store-nosql store-vhost store-cluster relay-python
+
+sample_DATA = README
+sampledir=$(prefix)/samples
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/README b/sandbox/sebastien/cpp/apr-2/samples/README
new file mode 100644
index 0000000000..818a2faaf8
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/README
@@ -0,0 +1,3 @@
+Apache Tuscany SCA Samples
+==========================
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/loan-python/Makefile.am
new file mode 100644
index 0000000000..0d0027ce6b
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/Makefile.am
@@ -0,0 +1,28 @@
+# 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.
+
+if WANT_PYTHON
+
+dist_sample_SCRIPTS = start stop
+sampledir = $(prefix)/samples/loan-python
+
+nobase_dist_sample_DATA = loan.py loan-approval.py util.py loan.composite htdocs/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/loan-python/htdocs/index.html
new file mode 100644
index 0000000000..f972af9555
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/htdocs/index.html
@@ -0,0 +1,156 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var component = new tuscany.sca.Component("Store");
+
+//@Reference
+var catalog = new tuscany.sca.Reference("catalog");
+
+//@Reference
+var shoppingCart = new tuscany.sca.Reference("shoppingCart");
+
+//@Reference
+var shoppingTotal = new tuscany.sca.Reference("shoppingTotal");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.apply("total", shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.apply("items", catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan-approval.py b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan-approval.py
new file mode 100644
index 0000000000..3951f16eeb
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan-approval.py
@@ -0,0 +1,77 @@
+# 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.
+
+# Loan approval service implementation
+import uuid
+import sys
+from util import *
+from loan import *
+
+loansId = ("loans", "1234")
+
+# Return the list of loans
+def loans(cache):
+ l = cache("get", loansId)
+ if l is None:
+ return ()
+ return l
+
+# Post a new loan request
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ loans = cons(cons(id, cdr(item)), loans(cache))
+ cache("put", loansId, loans)
+ return (id,)
+
+# Return the person currently processing a loan request
+def processor(l):
+ if approver(l) is not None:
+ return approver(l)
+ return assessor(l)
+
+# Return a list of loans that match a given criteria
+def get(r, cache):
+ # All the loans
+ if r == ():
+ return loans(cache)
+ # Loans that need approval
+ if car(r) == "needApproval":
+ return filter(lambda l: (amount(l) >= 10000 or risk(l) == "high") and approval(l) is None, loans(cache))
+ # Loans that need a risk assessment
+ if car(r) == "needAssessment":
+ return filter(lambda : amount(l) < 10000 and risk(l) is None, loans(cache))
+ # Loans currently under approval
+ if car(r) == "underApproval":
+ return filter(lambda l: approver(l) is not None, loans(cache))
+ # Loans currently under assessment
+ if car(r) == "underAssessment":
+ return filter(lambda l: assessor(l) is not None, loans(cache))
+ # Loan requests that are unassigned
+ if car(r) == "unassigned":
+ return filter(lambda l: processor(l) is None, loans(cache))
+ # Loan requests that are assigned and getting processed
+ if car(r) == "assigned":
+ return filter(lambda l: processor(l) == cadr(r), loans(cache))
+ # Approved loans
+ if car(r) == "approved":
+ return filter(lambda l: approval(l) == true, loans(cache))
+ # Denied loans
+ if car(r) == "denied":
+ return filter(lambda l: approval(l) == false, loans(cache))
+ # A particular loan
+ return filter(lambda l: id(l) == r, loans(cache))
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.composite b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.composite
new file mode 100644
index 0000000000..0e64b5bf44
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.composite
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="LoanApprovalUI">
+ <t:implementation.widget/>
+ <reference name="loanApproval" target="LoanApproval"/>
+ </component>
+
+ <component name="LoanApproval">
+ <t:implementation.python script="loan-approval.py"/>
+ <service name="LoanApproval">
+ <t:binding.atom uri="loan-approval"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.py b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.py
new file mode 100644
index 0000000000..9e345cd1f6
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/loan.py
@@ -0,0 +1,45 @@
+# 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.
+
+from util import *
+
+# Loan data type
+
+def firstName(loan):
+ return assoc("'firstName", loan)
+
+def lastName(loan):
+ return assoc("'lastName", loan)
+
+def ssn(loan):
+ return assoc("'ssn", loan)
+
+def amount(loan):
+ return assoc("'amount", loan)
+
+def approver(loan):
+ return assoc("'approver", loan)
+
+def approval(loan):
+ return assoc("'approval", loan)
+
+def assessor(loan):
+ return assoc("'assessor", loan)
+
+def risk(loan):
+ return assoc("'risk", loan)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/server-test b/sandbox/sebastien/cpp/apr-2/samples/loan-python/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/start b/sandbox/sebastien/cpp/apr-2/samples/loan-python/start
new file mode 100755
index 0000000000..e7aa7d86ca
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite loan.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/stop b/sandbox/sebastien/cpp/apr-2/samples/loan-python/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/loan-python/util.py b/sandbox/sebastien/cpp/apr-2/samples/loan-python/util.py
new file mode 100644
index 0000000000..560101e32d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/loan-python/util.py
@@ -0,0 +1,145 @@
+# 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.
+
+# Simple utility functions
+from sys import maxint
+
+# Scheme-like lists
+def cons(a, b):
+ return (a,) + b
+
+def car(l):
+ return l[0]
+
+def first(l):
+ return car(l)
+
+def cdr(l):
+ return l[1:]
+
+def rest(l):
+ return cdr(l)
+
+def cadr(l):
+ return car(cdr(l))
+
+def cddr(l):
+ return cdr(cdr(l))
+
+def caddr(l):
+ return car(cddr(l))
+
+def append(a, b):
+ return a + b
+
+def reverse(l):
+ r = list(l)
+ r.reverse()
+ return tuple(r)
+
+def isNil(l):
+ if isinstance(l, streampair):
+ return l.isNil()
+ return l == ()
+
+def isSymbol(v):
+ return isinstance(v, basestring) and v[0:1] == "'"
+
+def isList(v):
+ if getattr(v, '__iter__', False) == False:
+ return False
+ if isinstance(v, basestring) or isinstance(v, dict):
+ return False
+ return True
+
+def isTaggedList(v, t):
+ return isList(v) and not isNil(v) and car(v) == t
+
+
+# Scheme-like streams
+class streampair(object):
+ def __init__(self, car, cdr):
+ self.car = car
+ self.cdr = cdr
+
+ def __repr__(self):
+ return repr(self[0:len(self)])
+
+ def isNil(self):
+ return self.cdr == ()
+
+ def __len__(self):
+ if self.cdr == ():
+ return 0
+ return 1 + len(self.cdr())
+
+ def __getitem__(self, i):
+ if i == 0:
+ return self.car
+ return self.cdr()[i - 1]
+
+ def __getslice__(self, i, j):
+ if isNil(self):
+ return ()
+ if i > 0:
+ if j == maxint:
+ return self.cdr()[i - 1: j]
+ return self.cdr()[i - 1: j - 1]
+ if j == maxint:
+ return self
+ if j == 0:
+ return (self.car,)
+ return (self.car,) + self.cdr()[: j - 1]
+
+ def __eq__(self, other):
+ sl = len(self)
+ ol = len(other)
+ if sl != ol:
+ return False
+ return self[0: sl] == other[0: ol]
+
+ def __ne__(self, other):
+ return not self.__eq__(other)
+
+def cons_stream(car, cdr):
+ return streampair(car, cdr)
+
+
+# Scheme-like associations
+def assoc(k, l):
+ if l == ():
+ return None
+
+ if k == car(car(l)):
+ return car(l)
+ return assoc(k, cdr(l))
+
+# Currying / partial function application
+def curry(f, *args):
+ return lambda *a: f(*(args + a))
+
+# Split a path into a list of segments
+def tokens(path):
+ return tuple(filter(lambda s: len(s) != 0, path.split("/")))
+
+# Write a list of strings to a stream
+def writeStrings(l, os):
+ if l == ():
+ return os
+ os.write(car(l))
+ return writeStrings(cdr(l), os)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/relay-python/Makefile.am
new file mode 100644
index 0000000000..4e357eb330
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/Makefile.am
@@ -0,0 +1,25 @@
+# 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.
+
+if WANT_PYTHON
+
+dist_sample_SCRIPTS = start stop
+sampledir = $(prefix)/samples/relay-python
+
+nobase_dist_sample_DATA = html.py json.py xml.py rss.py relay.composite htdocs/*.html htdocs/test/*.html
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/index.html
new file mode 100644
index 0000000000..2025a5851d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/index.html
@@ -0,0 +1,31 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Relay</title>
+<body>
+
+<p><a href="/html">Sample HTML request</a></p>
+<p><a href="/jsontwit">Sample Twitter JSON request</a></p>
+<p><a href="/xmltwit">Sample Twitter XML request</a></p>
+<p><a href="/rsstwit">Sample Twitter RSS request</a></p>
+<p><a href="/jsonfb">Sample Facebook JSON request</a></p>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/test/index.html b/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/test/index.html
new file mode 100644
index 0000000000..1bfb3e30c2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/htdocs/test/index.html
@@ -0,0 +1,21 @@
+<!--
+ 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.
+-->
+
+<html><body><h1>It works!</h1></body></html>
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/html.py b/sandbox/sebastien/cpp/apr-2/samples/relay-python/html.py
new file mode 100644
index 0000000000..87a94a35ba
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/html.py
@@ -0,0 +1,22 @@
+# 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.
+
+# Content relay implementation
+def get(id, target):
+ #return ("text/plain", ("It works!",))
+ return target.get(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/json.py b/sandbox/sebastien/cpp/apr-2/samples/relay-python/json.py
new file mode 100644
index 0000000000..24f969d419
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/json.py
@@ -0,0 +1,24 @@
+# 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.
+
+# Relay implementation
+import uuid
+import sys
+
+def get(id, target):
+ return target.get(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/relay.composite b/sandbox/sebastien/cpp/apr-2/samples/relay-python/relay.composite
new file mode 100644
index 0000000000..2f5b92dee0
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/relay.composite
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://relay"
+ name="relay">
+
+ <component name="JSONTwit">
+ <t:implementation.python script="json.py"/>
+ <service name="Relay">
+ <t:binding.http uri="jsontwit"/>
+ </service>
+ <reference name="target">
+ <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.json?screen_name=jsdelfino"/>
+ </reference>
+ </component>
+
+ <component name="XMLTwit">
+ <t:implementation.python script="xml.py"/>
+ <service name="Relay">
+ <t:binding.http uri="xmltwit"/>
+ </service>
+ <reference name="target">
+ <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=jsdelfino"/>
+ </reference>
+ </component>
+
+ <component name="RSSTwit">
+ <t:implementation.python script="rss.py"/>
+ <service name="Relay">
+ <t:binding.http uri="rsstwit"/>
+ </service>
+ <reference name="target">
+ <t:binding.http uri="http://api.twitter.com/1/statuses/user_timeline.rss?screen_name=jsdelfino"/>
+ </reference>
+ </component>
+
+ <component name="HTML">
+ <t:implementation.python script="html.py"/>
+ <service name="Relay">
+ <t:binding.http uri="html"/>
+ </service>
+ <reference name="target">
+ <t:binding.http uri="http://localhost:8090/test"/>
+ </reference>
+ </component>
+
+ <component name="JSONFB">
+ <t:implementation.python script="json.py"/>
+ <service name="Relay">
+ <t:binding.http uri="jsonfb"/>
+ </service>
+ <reference name="target">
+ <t:binding.http uri="https://graph.facebook.com/100001053301307"/>
+ </reference>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/rss.py b/sandbox/sebastien/cpp/apr-2/samples/relay-python/rss.py
new file mode 100644
index 0000000000..96e4491c1a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/rss.py
@@ -0,0 +1,25 @@
+# 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.
+
+import sys
+
+# Feed relay implementation
+def get(id, target):
+ v = target.get(id)
+ print >> sys.stderr, v
+ return v
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/start b/sandbox/sebastien/cpp/apr-2/samples/relay-python/start
new file mode 100755
index 0000000000..c156e43a52
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/start
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite relay.composite
+
+EOF
+
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/stop b/sandbox/sebastien/cpp/apr-2/samples/relay-python/stop
new file mode 100755
index 0000000000..3b4f46694d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/stop
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/relay-python/xml.py b/sandbox/sebastien/cpp/apr-2/samples/relay-python/xml.py
new file mode 100644
index 0000000000..24f969d419
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/relay-python/xml.py
@@ -0,0 +1,24 @@
+# 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.
+
+# Relay implementation
+import uuid
+import sys
+
+def get(id, target):
+ return target.get(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/Makefile.am
new file mode 100644
index 0000000000..e9aab86f10
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/Makefile.am
@@ -0,0 +1,36 @@
+# 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.
+
+if WANT_PYTHON
+if WANT_SQLDB
+if WANT_OPENID
+if WANT_LOG
+if WANT_QUEUE
+
+dist_sample_SCRIPTS = start stop ssl-start ssl-stop proxy-conf proxy-ssl-conf server-conf server-ssl-conf tunnel-ssl-conf sqldb-master-conf sqldb-standby-conf
+sampledir = $(prefix)/samples/store-cluster
+
+nobase_dist_sample_DATA = htdocs/*.html htdocs/*/*.html htdocs/domains/*/*.html htdocs/domains/*/*/*.html domains/*/*.py domains/*/*.composite shared/*.composite
+
+dist_noinst_SCRIPTS = server-test
+#TESTS = server-test
+
+endif
+endif
+endif
+endif
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/fruits-catalog.py
new file mode 100644
index 0000000000..fb20b4ff27
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Passion"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Mango"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Pineapple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/shopping-cart.py
new file mode 100644
index 0000000000..44484ea5d2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/shopping-cart.py
@@ -0,0 +1,76 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+# Convert a particular host and user email to a cart id
+def cartid(host, email):
+ return ("cart", host.eval(), email.eval())
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get(id)
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache, host, email):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartid(host, email), cache)
+ cache.put(cartid(host, email), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache, host, email):
+ if id == ():
+ return ("Your Cart", email.eval()) + getcart(cartid(host, email), cache)
+ return find(id[0], getcart(cartid(host, email), cache))
+
+# Delete items from the cart
+def delete(id, cache, host, email):
+ if id == ():
+ return cache.delete(cartid(host, email))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache, host, email):
+ return sum(getcart(cartid(host, email), cache))
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.composite
new file mode 100644
index 0000000000..137027a50c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.composite
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <property name="host">localhost</property>
+ <property name="email">anonymous@localhost</property>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.py
new file mode 100644
index 0000000000..ff82f1d327
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/jane/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.total()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deleteall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/fruits-catalog.py
new file mode 100644
index 0000000000..6644421683
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Apple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Orange"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Pear"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/shopping-cart.py
new file mode 100644
index 0000000000..44484ea5d2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/shopping-cart.py
@@ -0,0 +1,76 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+# Convert a particular host and user email to a cart id
+def cartid(host, email):
+ return ("cart", host.eval(), email.eval())
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get(id)
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache, host, email):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartid(host, email), cache)
+ cache.put(cartid(host, email), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache, host, email):
+ if id == ():
+ return ("Your Cart", email.eval()) + getcart(cartid(host, email), cache)
+ return find(id[0], getcart(cartid(host, email), cache))
+
+# Delete items from the cart
+def delete(id, cache, host, email):
+ if id == ():
+ return cache.delete(cartid(host, email))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache, host, email):
+ return sum(getcart(cartid(host, email), cache))
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.composite
new file mode 100644
index 0000000000..137027a50c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.composite
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <property name="host">localhost</property>
+ <property name="email">anonymous@localhost</property>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.py
new file mode 100644
index 0000000000..811b05c580
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/domains/joe/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.total()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deletall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/index.html
new file mode 100644
index 0000000000..238ed701f0
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Jane's Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/login/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/login/index.html
new file mode 100644
index 0000000000..2eecc74b92
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/login/index.html
@@ -0,0 +1,194 @@
+<!--
+ 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.
+-->
+
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
+
+<script type="text/javascript">
+function queryParams() {
+ qp = new Array();
+ qs = window.location.search.substring(1).split('&');
+ for (i = 0; i < qs.length; i++) {
+ e = qs[i].indexOf('=');
+ if (e > 0)
+ qp[qs[i].substring(0, e)] = unescape(qs[i].substring(e + 1));
+ }
+ return qp;
+}
+
+function openauthReferrer() {
+ r = queryParams()['openauth_referrer'];
+ if (typeof(r) == 'undefined')
+ return r;
+ q = r.indexOf('?');
+ if (q > 0)
+ return r.substring(0, q);
+ return r;
+}
+
+if (typeof(openauthReferrer()) == 'undefined') {
+ document.location = '/';
+}
+
+function submitOpenIDSignin(w) {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.openIDSignin.openid_identifier.value = w();
+ document.openIDSignin.action = openauthReferrer();
+ document.openIDSignin.submit();
+}
+
+function withGoogle() {
+ return 'https://www.google.com/accounts/o8/id';
+}
+
+function withYahoo() {
+ return 'https://me.yahoo.com/';
+}
+
+function withMyOpenID() {
+ return 'http://www.myopenid.com/xrds';
+}
+
+function withVerisign() {
+ return 'https://pip.verisignlabs.com/';
+}
+
+function withMySpace() {
+ return 'https://api.myspace.com/openid';
+}
+
+function withGoogleApps() {
+ return 'https://www.google.com/accounts/o8/site-xrds?ns=2&hd=' + document.fields.domain.value;
+}
+
+function withLivejournal() {
+ return 'http://' + document.fields.ljuser.value + '.livejournal.com';
+}
+
+function withBlogspot() {
+ return 'http://' + document.fields.bsuser.value + '.blogspot.com';
+}
+
+function withBlogger() {
+ return 'http://' + document.fields.bguser.value + '.blogger.com';
+}
+
+function withXRDSEndpoint() {
+ return document.fields.endpoint.value;
+}
+
+function submitOAuth2Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth2Signin.mod_oauth2_authorize.value = parms[0];
+ document.oauth2Signin.mod_oauth2_access_token.value = parms[1];
+ document.oauth2Signin.mod_oauth2_client_id.value = parms[2];
+ document.oauth2Signin.mod_oauth2_info.value = parms[3];
+ document.oauth2Signin.action = openauthReferrer();
+ document.oauth2Signin.submit();
+}
+
+function withFacebook() {
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ return parms;
+}
+
+function withGithub() {
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth1Signin.mod_oauth1_request_token.value = parms[0];
+ document.oauth1Signin.mod_oauth1_authorize.value = parms[1];
+ document.oauth1Signin.mod_oauth1_access_token.value = parms[2];
+ document.oauth1Signin.mod_oauth1_client_id.value = parms[3];
+ document.oauth1Signin.mod_oauth1_info.value = parms[4];
+ document.oauth1Signin.action = openauthReferrer();
+ document.oauth1Signin.submit();
+}
+
+function withLinkedin() {
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ return parms;
+}
+
+function withTwitter() {
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ return parms;
+}
+</script>
+
+<form name="fields">
+<p>Sign in with your Google account<br/><input type="button" onclick="submitOpenIDSignin(withGoogle)" value="Sign in"/></p>
+<p>Sign in with your Yahoo account<br/><input type="button" onclick="submitOpenIDSignin(withYahoo)" value="Sign in"/></p>
+<p>Sign in with your MyOpenID account<br/><input type="button" onclick="submitOpenIDSignin(withMyOpenID)" value="Sign in"/></p>
+<p>Sign in with your Verisign account<br/><input type="button" onclick="submitOpenIDSignin(withVerisign)" value="Sign in"/></p>
+<p>Sign in with your MySpace account<br/><input type="button" onclick="submitOpenIDSignin(withMySpace)" value="Sign in"/></p>
+
+<p>Sign in with a Google apps domain<br/>
+<input type="text" size="20" name="domain" value="example.com"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withGoogleApps)" value="Sign in"/></p>
+
+<p>Sign in with your Livejournal account<br/>
+<input type="text" size="10" name="ljuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withLivejournal)" value="Sign in"/></p>
+
+<p>Sign in with your Blogspot account<br/>
+<input type="text" size="10" name="bsuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogspot)" value="Sign in"/></p>
+
+<p>Sign in with your Blogger account<br/>
+<input type="text" size="10" name="bguser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogger)" value="Sign in"/></p>
+
+<p>Sign in with an OpenID endpoint<br/>
+<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
+
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
+</form>
+
+<form name="openIDSignin" action="/" method="GET">
+<input type="hidden" name="openid_identifier" value=""/>
+</form>
+
+<form name="oauth2Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth2_authorize" value=""/>
+<input type="hidden" name="mod_oauth2_access_token" value=""/>
+<input type="hidden" name="mod_oauth2_client_id" value=""/>
+<input type="hidden" name="mod_oauth2_info" value=""/>
+<input type="hidden" name="mod_oauth2_step" value="authorize"/>
+</form>
+
+<form name="oauth1Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth1_request_token" value=""/>
+<input type="hidden" name="mod_oauth1_authorize" value=""/>
+<input type="hidden" name="mod_oauth1_access_token" value=""/>
+<input type="hidden" name="mod_oauth1_client_id" value=""/>
+<input type="hidden" name="mod_oauth1_info" value=""/>
+<input type="hidden" name="mod_oauth1_step" value="authorize"/>
+</form>
+
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/logout/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/logout/index.html
new file mode 100644
index 0000000000..02a92d1b31
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/jane/logout/index.html
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<html><body>
+<h1>Sign out</h1>
+
+<form name="signout" action="/login" method="GET">
+<script type="text/javascript">
+function submitSignout() {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.signout.submit();
+ return true;
+}
+</script>
+<input type="button" onclick="submitSignout()" value="Sign out"/>
+</form>
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/index.html
new file mode 100644
index 0000000000..c1cfc59aa7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Joe's Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/login/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/login/index.html
new file mode 100644
index 0000000000..2eecc74b92
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/login/index.html
@@ -0,0 +1,194 @@
+<!--
+ 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.
+-->
+
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
+
+<script type="text/javascript">
+function queryParams() {
+ qp = new Array();
+ qs = window.location.search.substring(1).split('&');
+ for (i = 0; i < qs.length; i++) {
+ e = qs[i].indexOf('=');
+ if (e > 0)
+ qp[qs[i].substring(0, e)] = unescape(qs[i].substring(e + 1));
+ }
+ return qp;
+}
+
+function openauthReferrer() {
+ r = queryParams()['openauth_referrer'];
+ if (typeof(r) == 'undefined')
+ return r;
+ q = r.indexOf('?');
+ if (q > 0)
+ return r.substring(0, q);
+ return r;
+}
+
+if (typeof(openauthReferrer()) == 'undefined') {
+ document.location = '/';
+}
+
+function submitOpenIDSignin(w) {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.openIDSignin.openid_identifier.value = w();
+ document.openIDSignin.action = openauthReferrer();
+ document.openIDSignin.submit();
+}
+
+function withGoogle() {
+ return 'https://www.google.com/accounts/o8/id';
+}
+
+function withYahoo() {
+ return 'https://me.yahoo.com/';
+}
+
+function withMyOpenID() {
+ return 'http://www.myopenid.com/xrds';
+}
+
+function withVerisign() {
+ return 'https://pip.verisignlabs.com/';
+}
+
+function withMySpace() {
+ return 'https://api.myspace.com/openid';
+}
+
+function withGoogleApps() {
+ return 'https://www.google.com/accounts/o8/site-xrds?ns=2&hd=' + document.fields.domain.value;
+}
+
+function withLivejournal() {
+ return 'http://' + document.fields.ljuser.value + '.livejournal.com';
+}
+
+function withBlogspot() {
+ return 'http://' + document.fields.bsuser.value + '.blogspot.com';
+}
+
+function withBlogger() {
+ return 'http://' + document.fields.bguser.value + '.blogger.com';
+}
+
+function withXRDSEndpoint() {
+ return document.fields.endpoint.value;
+}
+
+function submitOAuth2Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth2Signin.mod_oauth2_authorize.value = parms[0];
+ document.oauth2Signin.mod_oauth2_access_token.value = parms[1];
+ document.oauth2Signin.mod_oauth2_client_id.value = parms[2];
+ document.oauth2Signin.mod_oauth2_info.value = parms[3];
+ document.oauth2Signin.action = openauthReferrer();
+ document.oauth2Signin.submit();
+}
+
+function withFacebook() {
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ return parms;
+}
+
+function withGithub() {
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth1Signin.mod_oauth1_request_token.value = parms[0];
+ document.oauth1Signin.mod_oauth1_authorize.value = parms[1];
+ document.oauth1Signin.mod_oauth1_access_token.value = parms[2];
+ document.oauth1Signin.mod_oauth1_client_id.value = parms[3];
+ document.oauth1Signin.mod_oauth1_info.value = parms[4];
+ document.oauth1Signin.action = openauthReferrer();
+ document.oauth1Signin.submit();
+}
+
+function withLinkedin() {
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ return parms;
+}
+
+function withTwitter() {
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ return parms;
+}
+</script>
+
+<form name="fields">
+<p>Sign in with your Google account<br/><input type="button" onclick="submitOpenIDSignin(withGoogle)" value="Sign in"/></p>
+<p>Sign in with your Yahoo account<br/><input type="button" onclick="submitOpenIDSignin(withYahoo)" value="Sign in"/></p>
+<p>Sign in with your MyOpenID account<br/><input type="button" onclick="submitOpenIDSignin(withMyOpenID)" value="Sign in"/></p>
+<p>Sign in with your Verisign account<br/><input type="button" onclick="submitOpenIDSignin(withVerisign)" value="Sign in"/></p>
+<p>Sign in with your MySpace account<br/><input type="button" onclick="submitOpenIDSignin(withMySpace)" value="Sign in"/></p>
+
+<p>Sign in with a Google apps domain<br/>
+<input type="text" size="20" name="domain" value="example.com"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withGoogleApps)" value="Sign in"/></p>
+
+<p>Sign in with your Livejournal account<br/>
+<input type="text" size="10" name="ljuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withLivejournal)" value="Sign in"/></p>
+
+<p>Sign in with your Blogspot account<br/>
+<input type="text" size="10" name="bsuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogspot)" value="Sign in"/></p>
+
+<p>Sign in with your Blogger account<br/>
+<input type="text" size="10" name="bguser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogger)" value="Sign in"/></p>
+
+<p>Sign in with an OpenID endpoint<br/>
+<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
+
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
+</form>
+
+<form name="openIDSignin" action="/" method="GET">
+<input type="hidden" name="openid_identifier" value=""/>
+</form>
+
+<form name="oauth2Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth2_authorize" value=""/>
+<input type="hidden" name="mod_oauth2_access_token" value=""/>
+<input type="hidden" name="mod_oauth2_client_id" value=""/>
+<input type="hidden" name="mod_oauth2_info" value=""/>
+<input type="hidden" name="mod_oauth2_step" value="authorize"/>
+</form>
+
+<form name="oauth1Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth1_request_token" value=""/>
+<input type="hidden" name="mod_oauth1_authorize" value=""/>
+<input type="hidden" name="mod_oauth1_access_token" value=""/>
+<input type="hidden" name="mod_oauth1_client_id" value=""/>
+<input type="hidden" name="mod_oauth1_info" value=""/>
+<input type="hidden" name="mod_oauth1_step" value="authorize"/>
+</form>
+
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/logout/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/logout/index.html
new file mode 100644
index 0000000000..02a92d1b31
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/domains/joe/logout/index.html
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<html><body>
+<h1>Sign out</h1>
+
+<form name="signout" action="/login" method="GET">
+<script type="text/javascript">
+function submitSignout() {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.signout.submit();
+ return true;
+}
+</script>
+<input type="button" onclick="submitSignout()" value="Sign out"/>
+</form>
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/index.html
new file mode 100644
index 0000000000..21e32d7efc
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/index.html
@@ -0,0 +1,34 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+</head>
+
+<body>
+<h1>Store</h1>
+<p>For this sample to work, add the sample domain to your /etc/hosts as follows:<br/>
+127.0.0.1 sca-store.com jane.sca-store.com joe.sca-store.com</p>
+
+<p/>
+<p>Jane's store at <a href="http://jane.sca-store.com/">jane.sca-store.com</a>
+<br/>Joe's store at <a href="http://joe.sca-store.com/">joe.sca-store.com</a></p>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/login/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/login/index.html
new file mode 100644
index 0000000000..2eecc74b92
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/login/index.html
@@ -0,0 +1,194 @@
+<!--
+ 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.
+-->
+
+<html><body><h1>Sign in with an OpenID or OAuth provider</h1>
+
+<script type="text/javascript">
+function queryParams() {
+ qp = new Array();
+ qs = window.location.search.substring(1).split('&');
+ for (i = 0; i < qs.length; i++) {
+ e = qs[i].indexOf('=');
+ if (e > 0)
+ qp[qs[i].substring(0, e)] = unescape(qs[i].substring(e + 1));
+ }
+ return qp;
+}
+
+function openauthReferrer() {
+ r = queryParams()['openauth_referrer'];
+ if (typeof(r) == 'undefined')
+ return r;
+ q = r.indexOf('?');
+ if (q > 0)
+ return r.substring(0, q);
+ return r;
+}
+
+if (typeof(openauthReferrer()) == 'undefined') {
+ document.location = '/';
+}
+
+function submitOpenIDSignin(w) {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.openIDSignin.openid_identifier.value = w();
+ document.openIDSignin.action = openauthReferrer();
+ document.openIDSignin.submit();
+}
+
+function withGoogle() {
+ return 'https://www.google.com/accounts/o8/id';
+}
+
+function withYahoo() {
+ return 'https://me.yahoo.com/';
+}
+
+function withMyOpenID() {
+ return 'http://www.myopenid.com/xrds';
+}
+
+function withVerisign() {
+ return 'https://pip.verisignlabs.com/';
+}
+
+function withMySpace() {
+ return 'https://api.myspace.com/openid';
+}
+
+function withGoogleApps() {
+ return 'https://www.google.com/accounts/o8/site-xrds?ns=2&hd=' + document.fields.domain.value;
+}
+
+function withLivejournal() {
+ return 'http://' + document.fields.ljuser.value + '.livejournal.com';
+}
+
+function withBlogspot() {
+ return 'http://' + document.fields.bsuser.value + '.blogspot.com';
+}
+
+function withBlogger() {
+ return 'http://' + document.fields.bguser.value + '.blogger.com';
+}
+
+function withXRDSEndpoint() {
+ return document.fields.endpoint.value;
+}
+
+function submitOAuth2Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth2Signin.mod_oauth2_authorize.value = parms[0];
+ document.oauth2Signin.mod_oauth2_access_token.value = parms[1];
+ document.oauth2Signin.mod_oauth2_client_id.value = parms[2];
+ document.oauth2Signin.mod_oauth2_info.value = parms[3];
+ document.oauth2Signin.action = openauthReferrer();
+ document.oauth2Signin.submit();
+}
+
+function withFacebook() {
+ var parms = ['https://graph.facebook.com/oauth/authorize', 'https://graph.facebook.com/oauth/access_token', 'testfacebookapp', 'https://graph.facebook.com/me'];
+ return parms;
+}
+
+function withGithub() {
+ var parms = ['https://github.com/login/oauth/authorize', 'https://github.com/login/oauth/access_token', 'testgithubapp', 'https://github.com/api/v2/json/user/show'];
+ return parms;
+}
+
+function submitOAuth1Signin(w) {
+ parms = w();
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.oauth1Signin.mod_oauth1_request_token.value = parms[0];
+ document.oauth1Signin.mod_oauth1_authorize.value = parms[1];
+ document.oauth1Signin.mod_oauth1_access_token.value = parms[2];
+ document.oauth1Signin.mod_oauth1_client_id.value = parms[3];
+ document.oauth1Signin.mod_oauth1_info.value = parms[4];
+ document.oauth1Signin.action = openauthReferrer();
+ document.oauth1Signin.submit();
+}
+
+function withLinkedin() {
+ var parms = ['https://api.linkedin.com/uas/oauth/requestToken', 'https://www.linkedin.com/uas/oauth/authorize', 'https://api.linkedin.com/uas/oauth/accessToken', 'testlinkedinapp', 'https://api.linkedin.com/v1/people/~:(id,first-name,last-name,public-profile-url)'];
+ return parms;
+}
+
+function withTwitter() {
+ var parms = ['https://api.twitter.com/oauth/request_token', 'https://api.twitter.com/oauth/authorize', 'https://api.twitter.com/oauth/access_token', 'testtwitterapp', 'https://api.twitter.com/1/statuses/user_timeline.json'];
+ return parms;
+}
+</script>
+
+<form name="fields">
+<p>Sign in with your Google account<br/><input type="button" onclick="submitOpenIDSignin(withGoogle)" value="Sign in"/></p>
+<p>Sign in with your Yahoo account<br/><input type="button" onclick="submitOpenIDSignin(withYahoo)" value="Sign in"/></p>
+<p>Sign in with your MyOpenID account<br/><input type="button" onclick="submitOpenIDSignin(withMyOpenID)" value="Sign in"/></p>
+<p>Sign in with your Verisign account<br/><input type="button" onclick="submitOpenIDSignin(withVerisign)" value="Sign in"/></p>
+<p>Sign in with your MySpace account<br/><input type="button" onclick="submitOpenIDSignin(withMySpace)" value="Sign in"/></p>
+
+<p>Sign in with a Google apps domain<br/>
+<input type="text" size="20" name="domain" value="example.com"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withGoogleApps)" value="Sign in"/></p>
+
+<p>Sign in with your Livejournal account<br/>
+<input type="text" size="10" name="ljuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withLivejournal)" value="Sign in"/></p>
+
+<p>Sign in with your Blogspot account<br/>
+<input type="text" size="10" name="bsuser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogspot)" value="Sign in"/></p>
+
+<p>Sign in with your Blogger account<br/>
+<input type="text" size="10" name="bguser" value=""/><br/>
+<input type="button" onclick="submitOpenIDSignin(withBlogger)" value="Sign in"/></p>
+
+<p>Sign in with an OpenID endpoint<br/>
+<input type="text" size="50" name="endpoint" value="https://www.google.com/accounts/o8/id"/><br/>
+<input type="button" onclick="submitOpenIDSignin(withXRDSEndpoint)" value="Sign in"/></p>
+
+<p>Sign in with your Facebook account<br/><input type="button" onclick="submitOAuth2Signin(withFacebook)" value="Sign in"/></p>
+<p>Sign in with your Github account<br/><input type="button" onclick="submitOAuth2Signin(withGithub)" value="Sign in"/></p>
+
+<p>Sign in with your Linkedin account<br/><input type="button" onclick="submitOAuth1Signin(withLinkedin)" value="Sign in"/></p>
+<p>Sign in with your Twitter account<br/><input type="button" onclick="submitOAuth1Signin(withTwitter)" value="Sign in"/></p>
+</form>
+
+<form name="openIDSignin" action="/" method="GET">
+<input type="hidden" name="openid_identifier" value=""/>
+</form>
+
+<form name="oauth2Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth2_authorize" value=""/>
+<input type="hidden" name="mod_oauth2_access_token" value=""/>
+<input type="hidden" name="mod_oauth2_client_id" value=""/>
+<input type="hidden" name="mod_oauth2_info" value=""/>
+<input type="hidden" name="mod_oauth2_step" value="authorize"/>
+</form>
+
+<form name="oauth1Signin" action="/" method="GET">
+<input type="hidden" name="mod_oauth1_request_token" value=""/>
+<input type="hidden" name="mod_oauth1_authorize" value=""/>
+<input type="hidden" name="mod_oauth1_access_token" value=""/>
+<input type="hidden" name="mod_oauth1_client_id" value=""/>
+<input type="hidden" name="mod_oauth1_info" value=""/>
+<input type="hidden" name="mod_oauth1_step" value="authorize"/>
+</form>
+
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/logout/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/logout/index.html
new file mode 100644
index 0000000000..02a92d1b31
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/htdocs/logout/index.html
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<html><body>
+<h1>Sign out</h1>
+
+<form name="signout" action="/login" method="GET">
+<script type="text/javascript">
+function submitSignout() {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.signout.submit();
+ return true;
+}
+</script>
+<input type="button" onclick="submitSignout()" value="Sign out"/>
+</form>
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-conf
new file mode 100755
index 0000000000..b60e7ba7f9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-conf
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+
+set -x
+
+# Configure a proxy balancer
+../../modules/http/httpd-conf $root sca-store.com $port/80 $root/htdocs
+../../modules/http/vhost-conf $root
+../../modules/http/proxy-conf $root
+../../modules/http/httpd-event-conf $root
+
+# Aggregate proxy balancer logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-ssl-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-ssl-conf
new file mode 100755
index 0000000000..fc329f0d18
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/proxy-ssl-conf
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+sslport=$3
+
+set -x
+
+# Configure an SSL-enabled proxy balancer
+../../modules/http/httpd-conf $root sca-store.com $port $root/htdocs
+../../modules/http/vhost-conf $root
+../../modules/http/proxy-conf $root
+../../modules/http/httpd-event-conf $root
+tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C $root -x
+../../modules/http/httpd-ssl-conf $root $sslport
+../../modules/http/vhost-ssl-conf $root
+../../modules/http/proxy-ssl-conf $root
+
+# Aggregate proxy balancer logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-conf
new file mode 100755
index 0000000000..d274dd3d17
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-conf
@@ -0,0 +1,45 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+
+set -x
+
+# Configure an app server
+../../modules/http/httpd-conf $root sca-store.com $port/80 htdocs
+../../modules/http/vhost-conf $root
+../../modules/server/server-conf $root
+../../modules/python/python-conf $root
+cat >>$root/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/shared/
+SCAComposite shared.composite
+
+# Configure SCA Composite for mass dynamic virtual hosting
+SCAVirtualContribution `pwd`/domains/
+SCAVirtualComposite store.composite
+
+EOF
+
+# Aggregate app server logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-ssl-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-ssl-conf
new file mode 100755
index 0000000000..612dc6be47
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-ssl-conf
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+sslport=$3
+
+set -x
+
+# Configure an SSL-enabled app server
+../../modules/http/httpd-conf $root sca-store.com $port htdocs
+../../modules/http/vhost-conf $root
+
+tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C $root -x
+../../modules/http/httpd-ssl-conf $root $sslport
+../../modules/http/vhost-ssl-conf $root
+
+../../modules/oauth/oauth-conf $root
+../../modules/oauth/oauth-memcached-conf $root localhost 11211
+../../modules/oauth/oauth-memcached-conf $root localhost 11212
+../../modules/oauth/oauth-memcached-conf $root localhost 11213
+../../modules/openid/openid-conf $root
+../../modules/openid/openid-step2-conf $root
+../../modules/openid/openid-memcached-conf $root localhost 11211
+../../modules/openid/openid-memcached-conf $root localhost 11212
+../../modules/openid/openid-memcached-conf $root localhost 11213
+../../modules/http/open-auth-conf $root
+../../modules/http/passwd-auth-conf $root foo foo
+
+../../modules/server/server-conf $root
+../../modules/python/python-conf $root
+cat >>$root/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/shared/
+SCAComposite shared.composite
+
+# Configure SCA Composite for mass dynamic virtual hosting
+SCAVirtualContribution `pwd`/domains/
+SCAVirtualComposite store.composite
+
+EOF
+
+# Aggregate app server logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-test
new file mode 100755
index 0000000000..68856f530e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/server-test
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+# For this test to work, add the test domain to your etc/hosts as follows:
+# 127.0.0.1 sca-store.com joe.sca-store.com joe.sca-store.com
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://joe.sca-store.com/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/domains/joe/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/shared/shared.composite b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/shared/shared.composite
new file mode 100644
index 0000000000..b7eae5f78a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/shared/shared.composite
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://shared"
+ name="shared">
+
+ <component name="Cache">
+ <implementation.cpp path="../../../components/cache" library="libdatacache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <reference name="l1reader" target="Memcache"/>
+ <reference name="l1writer" target="Memcache"/>
+ <reference name="l2reader" target="Standbydb"/>
+ <reference name="l2writer" target="Masterdb"/>
+ </component>
+
+ <component name="Memcache">
+ <implementation.cpp path="../../../components/cache" library="libmemcache"/>
+ <service name="Memcache">
+ <t:binding.atom uri="memcache"/>
+ </service>
+ <property name="servers">localhost:11211,localhost:11212,localhost:11213</property>
+ </component>
+
+ <component name="Masterdb">
+ <implementation.cpp path="../../../components/sqldb" library="libsqldb"/>
+ <property name="conninfo">host=localhost port=5432 dbname=db</property>
+ <property name="table">store</property>
+ <service name="Masterdb">
+ <t:binding.atom uri="masterdb"/>
+ </service>
+ </component>
+
+ <component name="Standbydb">
+ <implementation.cpp path="../../../components/sqldb" library="libsqldb"/>
+ <property name="conninfo">host=localhost port=5433 dbname=db</property>
+ <property name="table">store</property>
+ <service name="Standbydb">
+ <t:binding.atom uri="standbydb"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-master-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-master-conf
new file mode 100755
index 0000000000..83f78be999
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-master-conf
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+httpport=$3
+
+set -x
+
+# Aggregate database server logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category "sqldb" $root/logs/postgresql
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
+# Configure a database backup HTTP server
+../../modules/http/httpd-conf $root localhost $httpport $root/htdocs
+
+# Configure a database server
+if [ ! -f $root/sqldb/data/postgresql.conf ]; then
+ create="true"
+else
+ create="false"
+fi
+../../components/sqldb/pgsql-conf $root $port
+if [ "$create" = "true" ]; then
+ ../../components/sqldb/pgsql-start $root
+ ../../components/sqldb/pgsql localhost $port "create table store(key text, value text);" 1>>$root/logs/postgresql 2>&1
+ ../../components/sqldb/pgsql-stop $root
+fi
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-standby-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-standby-conf
new file mode 100755
index 0000000000..4998ead4b4
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/sqldb-standby-conf
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+httpport=$3
+mhost=$4
+mport=$5
+mhttpport=$6
+
+set -x
+
+# Aggregate database server logs
+category=`basename $root`
+../../components/log/scribe-tail-start $category "sqldb" $root/logs/postgresql
+../../components/log/scribe-tail-start $category $root/logs/error_log
+../../components/log/scribe-tail-start $category $root/logs/access_log
+
+# Configure a database backup HTTP server
+../../modules/http/httpd-conf $root localhost $httpport $root/htdocs
+
+# Configure a standby database server
+../../components/sqldb/pgsql-standby-conf $root $port $mhost $mport $mhttpport
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-start
new file mode 100755
index 0000000000..f80bb075d6
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-start
@@ -0,0 +1,121 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+set -x
+
+# Redirect traffic from ports 80, 443 and 444 to proxy1
+sudo ../../ubuntu/ip-redirect-all 80 8090
+sudo ../../ubuntu/ip-redirect-all 443 8091
+sudo ../../ubuntu/ip-redirect-all 444 8092
+
+# Redirect traffic from ports 80, 443 and 444 to proxy2
+#sudo ../../ubuntu/ip-redirect-all 80 8093
+#sudo ../../ubuntu/ip-redirect-all 443 8094
+#sudo ../../ubuntu/ip-redirect-all 444 8095
+
+# Redirect traffic from ports 119 and 563 to tunnel
+sudo ../../ubuntu/ip-redirect-all 119 8119
+sudo ../../ubuntu/ip-redirect-all 563 8563
+
+# Generate SSL certificates
+../../modules/http/ssl-ca-conf tmp/ssl sca-store.com
+../../modules/http/ssl-cert-conf tmp/ssl localhost server
+../../modules/http/ssl-cert-conf tmp/ssl *.sca-store.com vhost
+../../modules/http/ssl-cert-conf tmp/ssl sca-store.com proxy
+../../modules/http/ssl-cert-conf tmp/ssl localhost tunnel
+
+# Start an SSL tunnel
+./tunnel-ssl-conf tmp/tunnel 8119/119 8563/563
+../../modules/http/httpd-start tmp/tunnel
+sleep 1
+
+# Start scribe logging
+../../modules/http/tunnel-ssl-conf tmp/tunnel 1465 localhost 563 1463
+../../modules/http/httpd-restart tmp/tunnel
+../../components/log/scribed-central-conf tmp/monitor
+../../components/log/scribed-client-conf tmp/monitor localhost 1465
+../../components/log/scribed-central-start tmp/monitor
+../../components/log/scribed-client-start tmp/monitor
+sleep 1
+
+# Start three memcached servers
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11211 localhost 563 11411
+../../components/cache/memcached-start 127.0.0.1:11411
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11212 localhost 563 11412
+../../components/cache/memcached-start 127.0.0.1:11412
+../../modules/http/tunnel-ssl-conf tmp/tunnel 11213 localhost 563 11413
+../../components/cache/memcached-start 127.0.0.1:11413
+../../modules/http/httpd-restart tmp/tunnel
+sleep 1
+
+# Start a master and two hot standby databases
+../../modules/http/tunnel-ssl-conf tmp/tunnel 5432 localhost 563 5532
+../../modules/http/tunnel-ssl-conf tmp/tunnel 8502 localhost 563 8602
+../../modules/http/httpd-restart tmp/tunnel
+./sqldb-master-conf tmp/sqldb1 127.0.0.1:5532 127.0.0.1:8602
+../../components/sqldb/pgsql-start tmp/sqldb1
+../../modules/http/httpd-start tmp/sqldb1
+sleep 1
+
+../../modules/http/tunnel-ssl-conf tmp/tunnel 5433 localhost 563 5533
+../../modules/http/tunnel-ssl-conf tmp/tunnel 8503 localhost 563 8603
+../../modules/http/httpd-restart tmp/tunnel
+./sqldb-standby-conf tmp/sqldb2 127.0.0.1:5533 127.0.0.1:8603 localhost 5432 8502
+../../components/sqldb/pgsql-start tmp/sqldb2
+../../modules/http/httpd-start tmp/sqldb2
+
+../../modules/http/tunnel-ssl-conf tmp/tunnel 5434 localhost 563 5534
+../../modules/http/tunnel-ssl-conf tmp/tunnel 8504 localhost 563 8604
+../../modules/http/httpd-restart tmp/tunnel
+./sqldb-standby-conf tmp/sqldb3 127.0.0.1:5534 127.0.0.1:8604 localhost 5432 8502
+../../components/sqldb/pgsql-start tmp/sqldb3
+../../modules/http/httpd-start tmp/sqldb3
+
+# Start three app servers
+./server-ssl-conf tmp/server1 8101/80 8441/443
+../../modules/http/httpd-start tmp/server1
+sleep 1
+
+./server-ssl-conf tmp/server2 8102/80 8442/443
+../../modules/http/httpd-start tmp/server2
+sleep 1
+
+./server-ssl-conf tmp/server3 8103/80 8443/443
+../../modules/http/httpd-start tmp/server3
+sleep 1
+
+# Start two proxy balancers
+./proxy-ssl-conf tmp/proxy1 8090/80 8091/443
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8101
+../../modules/http/proxy-ssl-member-conf tmp/proxy1 localhost 8441
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8102
+../../modules/http/proxy-ssl-member-conf tmp/proxy1 localhost 8442
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8103
+../../modules/http/proxy-ssl-member-conf tmp/proxy1 localhost 8443
+../../modules/http/httpd-start tmp/proxy1
+
+./proxy-ssl-conf tmp/proxy2 8093/80 8094/443
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8101
+../../modules/http/proxy-ssl-member-conf tmp/proxy2 localhost 8441
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8102
+../../modules/http/proxy-ssl-member-conf tmp/proxy2 localhost 8442
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8103
+../../modules/http/proxy-ssl-member-conf tmp/proxy2 localhost 8443
+../../modules/http/httpd-start tmp/proxy2
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-stop b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-stop
new file mode 100755
index 0000000000..ff36721315
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/ssl-stop
@@ -0,0 +1,44 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+set -x
+
+../../modules/http/httpd-stop tmp/server1
+../../modules/http/httpd-stop tmp/server2
+../../modules/http/httpd-stop tmp/server3
+
+../../modules/http/httpd-stop tmp/proxy1
+../../modules/http/httpd-stop tmp/proxy2
+
+../../components/cache/memcached-stop 127.0.0.1:11411
+../../components/cache/memcached-stop 127.0.0.1:11412
+../../components/cache/memcached-stop 127.0.0.1:11413
+
+../../components/sqldb/pgsql-stop tmp/sqldb3
+../../modules/http/httpd-stop tmp/sqldb3
+../../components/sqldb/pgsql-stop tmp/sqldb2
+../../modules/http/httpd-stop tmp/sqldb2
+../../components/sqldb/pgsql-stop tmp/sqldb1
+../../modules/http/httpd-stop tmp/sqldb1
+
+../../modules/http/httpd-stop tmp/tunnel
+
+../../components/log/scribed-client-stop tmp/monitor
+../../components/log/scribed-central-stop tmp/monitor
+../../components/log/scribe-tail-stop tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/start b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/start
new file mode 100755
index 0000000000..67434d6a0e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/start
@@ -0,0 +1,79 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+set -x
+
+# Redirect traffic from port 80 to proxy1
+sudo ../../ubuntu/ip-redirect-all 80 8090
+
+# Redirect traffic from port 80 to proxy2
+#sudo ../../ubuntu/ip-redirect-all 80 8091
+
+# Start scribe logging
+../../components/log/scribed-central-conf tmp/monitor
+../../components/log/scribed-client-conf tmp/monitor localhost
+../../components/log/scribed-central-start tmp/monitor
+../../components/log/scribed-client-start tmp/monitor
+sleep 1
+
+# Start three memcached servers
+../../components/cache/memcached-start 11211
+../../components/cache/memcached-start 11212
+../../components/cache/memcached-start 11213
+
+# Start a master and two hot standby databases
+./sqldb-master-conf tmp/sqldb1 5432 8502
+../../components/sqldb/pgsql-start tmp/sqldb1
+../../modules/http/httpd-start tmp/sqldb1
+sleep 1
+
+./sqldb-standby-conf tmp/sqldb2 5433 8503 localhost 5432 8502
+../../components/sqldb/pgsql-start tmp/sqldb2
+../../modules/http/httpd-start tmp/sqldb2
+
+./sqldb-standby-conf tmp/sqldb3 5434 8504 localhost 5432 8502
+../../components/sqldb/pgsql-start tmp/sqldb3
+../../modules/http/httpd-start tmp/sqldb3
+
+# Start three app servers
+./server-conf tmp/server1 8101
+../../modules/http/httpd-start tmp/server1
+sleep 1
+
+./server-conf tmp/server2 8102
+../../modules/http/httpd-start tmp/server2
+sleep 1
+
+./server-conf tmp/server3 8103
+../../modules/http/httpd-start tmp/server3
+sleep 1
+
+# Start two proxy balancers
+./proxy-conf tmp/proxy1 8090
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8101
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8102
+../../modules/http/proxy-member-conf tmp/proxy1 localhost 8103
+../../modules/http/httpd-start tmp/proxy1
+
+./proxy-conf tmp/proxy2 8091
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8101
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8102
+../../modules/http/proxy-member-conf tmp/proxy2 localhost 8103
+../../modules/http/httpd-start tmp/proxy2
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/stop b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/stop
new file mode 100755
index 0000000000..b2fa11b7c4
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/stop
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+set -x
+
+../../modules/http/httpd-stop tmp/server1
+../../modules/http/httpd-stop tmp/server2
+../../modules/http/httpd-stop tmp/server3
+
+../../modules/http/httpd-stop tmp/proxy1
+../../modules/http/httpd-stop tmp/proxy2
+
+../../components/cache/memcached-stop 11211
+../../components/cache/memcached-stop 11212
+../../components/cache/memcached-stop 11213
+
+../../components/sqldb/pgsql-stop tmp/sqldb3
+../../modules/http/httpd-stop tmp/sqldb3
+../../components/sqldb/pgsql-stop tmp/sqldb2
+../../modules/http/httpd-stop tmp/sqldb2
+../../components/sqldb/pgsql-stop tmp/sqldb1
+../../modules/http/httpd-stop tmp/sqldb1
+
+../../components/log/scribed-client-stop tmp/monitor
+../../components/log/scribed-central-stop tmp/monitor
+../../components/log/scribe-tail-stop tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cluster/tunnel-ssl-conf b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/tunnel-ssl-conf
new file mode 100755
index 0000000000..7a9a8ad305
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cluster/tunnel-ssl-conf
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+root=$1
+port=$2
+sslport=$3
+
+set -x
+
+# Configure an SSL-enabled tunnel server
+../../modules/http/httpd-conf $root sca-store.com $port $root/htdocs
+../../modules/http/httpd-event-conf $root
+tar -C tmp/ssl -c `../../modules/http/ssl-cert-find tmp/ssl` | tar -C $root -x
+../../modules/http/httpd-ssl-conf $root $sslport
+../../modules/http/cert-auth-conf $root
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/Makefile.am
new file mode 100644
index 0000000000..1a642e583c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/Makefile.am
@@ -0,0 +1,40 @@
+# 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.
+
+
+dist_sample_SCRIPTS = start stop ssl-start
+sampledir = $(prefix)/samples/store-cpp
+
+nobase_dist_sample_DATA = currency-converter.cpp fruits-catalog.cpp shopping-cart.cpp store.composite htdocs/*.html
+
+sample_LTLIBRARIES = libcurrency-converter.la libfruits-catalog.la libshopping-cart.la
+noinst_DATA = libcurrency-converter.so libfruits-catalog.so libshopping-cart.so
+
+libcurrency_converter_la_SOURCES = currency-converter.cpp
+libcurrency-converter.so:
+ ln -s .libs/libcurrency-converter.so
+
+libfruits_catalog_la_SOURCES = fruits-catalog.cpp
+libfruits-catalog.so:
+ ln -s .libs/libfruits-catalog.so
+
+libshopping_cart_la_SOURCES = shopping-cart.cpp
+libshopping-cart.so:
+ ln -s .libs/libshopping-cart.so
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/currency-converter.cpp b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/currency-converter.cpp
new file mode 100644
index 0000000000..5f0702490a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/currency-converter.cpp
@@ -0,0 +1,67 @@
+/*
+ * 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$ */
+
+/**
+ * Currency converter component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+/**
+ * Convert an amount from USD to a currency.
+ */
+const failable<value> convert(unused const value& from, const value& to, const value& amount) {
+ if (to == string("EUR"))
+ return value(0.70 * (double)amount);
+ return amount;
+}
+
+/**
+ * Return a currency symbol.
+ */
+const failable<value> symbol(const value& currency) {
+ if (currency == string("EUR"))
+ return value(string("E"));
+ return value(string("$"));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "convert")
+ return tuscany::store::convert(cadr(params), caddr(params), cadddr(params));
+ if (func == "symbol")
+ return tuscany::store::symbol(cadr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/fruits-catalog.cpp b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/fruits-catalog.cpp
new file mode 100644
index 0000000000..ce5ebfec6f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/fruits-catalog.cpp
@@ -0,0 +1,76 @@
+/*
+ * 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$ */
+
+/**
+ * Catalog component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+/**
+ * Returns the catalog.
+ */
+struct convert {
+ const lambda<value(const list<value>&)> converter;
+ const string currency;
+ convert(const lambda<value(const list<value>&)>& converter, const string& currency) : converter(converter), currency(currency) {
+ }
+ const value operator()(const value& price) const {
+ return converter(mklist<value>("convert", string("USD"), currency, price));
+ }
+};
+
+const list<value> mkfruit(const string& name, const string& code, const string& symbol, const double price) {
+ return list<value>() +
+ mklist<value>("name", name) + mklist<value>("currencyCode", code) + mklist<value>("currencySymbol", symbol) + mklist<value>("price", price);
+}
+
+const failable<value> items(const lambda<value(const list<value>&)> converter, const lambda<value(const list<value>&)> currencyCode) {
+ const string currency(currencyCode(list<value>()));
+ const string symbol(converter(mklist<value>("symbol", currency)));
+ const lambda<value(const value&)> conv(convert(converter, currency));
+
+ return value(list<value>() +
+ mkfruit("Apple", currency, symbol, conv(2.99)) +
+ mkfruit("Orange", currency, symbol, conv(3.55)) +
+ mkfruit("Pear", currency, symbol, conv(1.55)));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "items")
+ return tuscany::store::items(cadr(params), caddr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-request.txt b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-request.txt
new file mode 100644
index 0000000000..ecf564cb98
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-request.txt
@@ -0,0 +1 @@
+{"id": 1, "method": "items", "params": []}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-result.txt b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-result.txt
new file mode 100644
index 0000000000..56f87d2778
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/items-result.txt
@@ -0,0 +1 @@
+{"id":1,"result":[{"name":"Apple","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Orange","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Pear","currencyCode":"USD","currencySymbol":"$","price":1.55}]} \ No newline at end of file
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/shopping-cart-entry.xml b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/shopping-cart-entry.xml
new file mode 100644
index 0000000000..25a284294c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/htdocs/test/shopping-cart-entry.xml
@@ -0,0 +1 @@
+<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml"><item><name>Orange</name><currencyCode>USD</currencyCode><currencySymbol>$</currencySymbol><price>3.55</price></item></content></entry>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/server-test
new file mode 100755
index 0000000000..e0d8716449
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/shopping-cart.cpp b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/shopping-cart.cpp
new file mode 100644
index 0000000000..738ab2f4c7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/shopping-cart.cpp
@@ -0,0 +1,135 @@
+/*
+ * 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$ */
+
+/**
+ * Shopping cart component implementation.
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace store {
+
+const string cartId("1234");
+
+/**
+ * Get the shopping cart from the cache. Return an empty
+ * cart if not found.
+ */
+const list<value> getcart(const value& id, const lambda<value(const list<value>&)> cache) {
+ const value cart = cache(mklist<value>("get", mklist<value>(id)));
+ cerr << "cart value: " << cart << "\n";
+ const failable<value> fcart = cart;
+ cerr << "cart fvalue: " << fcart << "\n";
+ cerr << "cart content: " << content(fcart) << "\n";
+ cerr << "cart reason: " << reason(fcart) << "\n";
+ if (isNil(cart))
+ return value(list<value>());
+ return (list<value>)cart;
+}
+
+/**
+ * Post a new item to the cart. Create a new cart if necessary.
+ */
+const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)> cache) {
+ const value id(mkuuid());
+ const list<value> newItem(mklist<value>(car<value>(item), id, caddr<value>(item)));
+ const list<value> cart(cons<value>(newItem, getcart(cartId, cache)));
+ cache(mklist<value>("put", mklist<value>(cartId), cart));
+ return value(mklist<value>(id));
+}
+
+/**
+ * Find an item in the cart.
+ */
+const value find(const value& id, const list<value>& cart) {
+ if (isNil(cart))
+ return cons<value>(string("Item"), mklist<value>("0", list<value>()));
+ if (id == cadr<value>(car(cart)))
+ return car(cart);
+ return find(id, cdr(cart));
+}
+
+/**
+ * Return items from the cart.
+ */
+const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)> cache) {
+ if (isNil(id))
+ return value(append(mklist<value>(string("Your Cart"), cartId), getcart(cartId, cache)));
+ return find(car(id), getcart(cartId, cache));
+}
+
+/**
+ * Delete items from the cart.
+ */
+const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)> cache) {
+ if (isNil(id))
+ return cache(mklist<value>("delete", mklist<value>(cartId)));
+ return value(true);
+}
+
+/**
+ * Return the price of an item.
+ */
+const double price(const list<value>& item) {
+ return cadr<value>(assoc<value>("price", caddr(item)));
+}
+
+/**
+ * Sum the prices of a list of items.
+ */
+const double sum(const list<value>& items) {
+ if (isNil(items))
+ return 0;
+ return price(car(items)) + sum(cdr(items));
+}
+
+/**
+ * Return the total price of the items in the cart.
+ */
+const failable<value> total(const lambda<value(const list<value>&)> cache) {
+ const list<value> cart(getcart(cartId, cache));
+ return value(sum(cart));
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+ const tuscany::value func(car(params));
+ if (func == "post")
+ return tuscany::store::post(cadr(params), caddr(params), cadddr(params));
+ if (func == "get")
+ return tuscany::store::get(cadr(params), caddr(params));
+ if (func == "delete")
+ return tuscany::store::del(cadr(params), caddr(params));
+ if (func == "total")
+ return tuscany::store::total(cadr(params));
+ return tuscany::mkfailure<tuscany::value>();
+}
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/ssl-start
new file mode 100755
index 0000000000..01ee0eb76c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/ssl-start
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/server/cpp-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/start b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/start
new file mode 100755
index 0000000000..7b9c0d6379
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/cpp-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/stop b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-cpp/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/store.composite
new file mode 100644
index 0000000000..8b5edede99
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-cpp/store.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.widget location="store.html"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <implementation.cpp path="." library="libfruits-catalog"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.cpp path="." library="libshopping-cart"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <implementation.cpp path="." library="libcurrency-converter"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-gae/Makefile.am
new file mode 100644
index 0000000000..09d5b516cf
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/Makefile.am
@@ -0,0 +1,44 @@
+# 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.
+
+if WANT_PYTHON
+if WANT_GAE
+
+dist_sample_SCRIPTS = start stop
+sampledir = $(prefix)/samples/store-gae
+
+BUILT_SOURCES = target.stamp
+target.stamp: app.yaml *.py *.composite $(top_builddir)/modules/wsgi/*.py htdocs/* $(top_builddir)/modules/js/htdocs/*
+ mkdir -p target
+ cp app.yaml *.py *.composite `ls $(top_builddir)/modules/wsgi/*.py | grep -v "\-test"` target
+ mkdir -p target/htdocs
+ cp -R htdocs/* target/htdocs
+ cp -R $(top_builddir)/modules/js/htdocs/* target/htdocs
+ touch target.stamp
+
+clean-local:
+ rm -rf target.stamp target
+
+nobase_sample_DATA = target/app.yaml target/*.py target/*.composite target/htdocs/*.html target/htdocs/*.js
+
+EXTRA_DIST = app.yaml *.composite *.py htdocs/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/app.yaml b/sandbox/sebastien/cpp/apr-2/samples/store-gae/app.yaml
new file mode 100644
index 0000000000..6a4e6a2fab
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/app.yaml
@@ -0,0 +1,54 @@
+# 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.
+
+application: sca-store
+version: 1
+runtime: python
+api_version: 1
+skip_files:
+- ^(.*/)?app\.yaml
+- ^(.*/)?app\.yml
+- ^(.*/)?index\.yaml
+- ^(.*/)?index\.yml
+- ^(.*/)?#.*#
+- ^(.*/)?.*~
+- ^(.*/)?.*\.py[co]
+- ^(.*/)?.*/RCS/.*
+- ^(.*/)?\..*
+- ^(.*/)?.*-test$
+- ^(.*/)?.*\.cpp$
+- ^(.*/)?.*\.o$
+- ^(.*/)?core$
+- ^(.*/)?.*\.out$
+- ^(.*/)?.*\.log$
+- ^(.*/)?Makefile.*
+- ^(.*/)?tmp/.*
+- ^(.*/)?wsgi-start
+- ^(.*/)?wsgi-stop
+
+handlers:
+- url: /(.*\.(html|png))
+ static_files: htdocs/\1
+ upload: htdocs/(.*\.(html|png))
+ secure: always
+ login: required
+
+- url: /.*
+ script: composite.py
+ secure: always
+ login: required
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-backend.composite b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-backend.composite
new file mode 100644
index 0000000000..a543b9a6b5
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-backend.composite
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store-backend">
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-frontend.composite b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-frontend.composite
new file mode 100644
index 0000000000..e7e10e2de1
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-frontend.composite
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store-frontend">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache">
+ <t:binding.http uri="https://sca-store-backend.appspot.com/cache"/>
+ </reference>
+ <property name="host">localhost</property>
+ <property name="email">anonymous@example.com</property>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-single.composite b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-single.composite
new file mode 100644
index 0000000000..4a5d53e695
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain-single.composite
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ <property name="host">localhost</property>
+ <property name="email">anonymous@example.com</property>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain.composite b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain.composite
new file mode 100644
index 0000000000..4a5d53e695
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/domain.composite
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ <property name="host">localhost</property>
+ <property name="email">anonymous@example.com</property>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.python script="gmemcache.py"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/fruits-catalog.py
new file mode 100644
index 0000000000..4b2baca2ff
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Platano"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Banana"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Guanabana"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/gmemcache.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/gmemcache.py
new file mode 100644
index 0000000000..61f1dc3486
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/gmemcache.py
@@ -0,0 +1,45 @@
+# 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.
+
+# Google AppEngine Memcached based cache implementation
+import uuid
+from google.appengine.api import memcache
+
+# Post a new item to the cache
+def post(collection, item):
+ id = collection + (str(uuid.uuid1()),)
+ r = memcache.add(repr(id), item, 600)
+ if r == False:
+ return None
+ return id
+
+# Get items from the cache
+def get(id):
+ item = memcache.get(repr(id))
+ return item
+
+# Update an item in the cache
+def put(id, item):
+ return memcache.set(repr(id), item, 600)
+
+# Delete items from the cache
+def delete(id):
+ r = memcache.delete(repr(id))
+ if r != 2:
+ return False
+ return True
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/index.html
new file mode 100644
index 0000000000..a38a8a0e4f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/index.html
@@ -0,0 +1,169 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.defun(sca.reference(store, "shoppingCart"), "email", "host");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+}
+
+function shoppingCart_hostResponse(host, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('host').innerHTML = host;
+}
+
+function shoppingCart_emailResponse(email, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('email').innerHTML = email;
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total,exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.email(shoppingCart_emailResponse);
+ shoppingCart.host(shoppingCart_hostResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<p>Welcome to: <span id="host"></span>, you're signed in as: <span id="email"></span><br/><a href="/logout">Sign out</a></p>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/test/items-result.txt b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/test/items-result.txt
new file mode 100644
index 0000000000..bbc07e8917
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htdocs/test/items-result.txt
@@ -0,0 +1 @@
+{"id":1,"result":[{"price":2.9900000000000002,"currencyCode":"USD","name":"Platano","currencySymbol":"$"},{"price":3.5499999999999998,"currencyCode":"USD","name":"Banana","currencySymbol":"$"},{"price":1.55,"currencyCode":"USD","name":"Guanabana","currencySymbol":"$"}]} \ No newline at end of file
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/htpasswd.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htpasswd.py
new file mode 100644
index 0000000000..75d94f58b6
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/htpasswd.py
@@ -0,0 +1,21 @@
+# 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.
+
+# Configure the user and password used for HTTP basic authentication
+user = "foo"
+passwd = "foo"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-gae/server-test
new file mode 100755
index 0000000000..4d42e9a5f5
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/server-test
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start 2>/dev/null
+sleep 2
+
+# Test HTTP GET (with authentication)
+mkdir -p tmp
+$curl_prefix/bin/curl -L -c tmp/cookies.txt -b tmp/cookies.txt "http://localhost:8090/_ah/login?email=test@example.com&action=Login&continue=http://localhost:8090/" 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl -b tmp/cookies.txt http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl -b tmp/cookies.txt http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl -b tmp/cookies.txt http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/shopping-cart.py
new file mode 100644
index 0000000000..3c3168d77b
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/shopping-cart.py
@@ -0,0 +1,82 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get((id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache, host, email):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache.put((cartId,), cart)
+ return (id,)
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache, host, email):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache, host, email):
+ if id == ():
+ return cache.delete((cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache, host, email):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
+# Return the email of the cart owner
+def email(cache, host, email_):
+ return email_.eval()
+
+# Return the host that the app is running on
+def host(cache, host_, email):
+ return host_.eval()
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/start b/sandbox/sebastien/cpp/apr-2/samples/store-gae/start
new file mode 100755
index 0000000000..3c9644e656
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/start
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/wsgi/gae-start target 8090
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/stop b/sandbox/sebastien/cpp/apr-2/samples/store-gae/stop
new file mode 100755
index 0000000000..7c8a7e5551
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/wsgi/gae-stop target 8090
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-gae/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-gae/store.py
new file mode 100644
index 0000000000..ff82f1d327
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-gae/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.total()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deleteall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-java/Makefile.am
new file mode 100644
index 0000000000..f32ae72812
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/Makefile.am
@@ -0,0 +1,34 @@
+# 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.
+
+JAVAROOT = ${top_builddir}/samples/store-java
+
+if WANT_JAVA
+
+dist_sample_SCRIPTS = start stop ssl-start
+sampledir=$(prefix)/samples/store-java
+
+AM_JAVACFLAGS = -cp ${top_builddir}/modules/java/libmod-tuscany-java-${PACKAGE_VERSION}.jar:${JAVAROOT}
+dist_sample_JAVA = store/*.java
+CLEANFILES = *.stamp store/*.class
+
+nobase_dist_sample_DATA = store.composite htdocs/*.html store/*.*
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-java/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-java/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-java/ssl-start
new file mode 100755
index 0000000000..3d4642dea6
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/ssl-start
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/java/java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/start b/sandbox/sebastien/cpp/apr-2/samples/store-java/start
new file mode 100755
index 0000000000..c8146e9e46
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/start
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/java/java-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/stop b/sandbox/sebastien/cpp/apr-2/samples/store-java/stop
new file mode 100755
index 0000000000..79d914e937
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/stop
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+export CLASSPATH=`pwd`/../../modules/java/libmod-tuscany-java-1.0.jar:`pwd`
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-java/store.composite
new file mode 100644
index 0000000000..4b0db9d05c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/store.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.widget location="store.html"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <implementation.java class="store.FruitsCatalogImpl"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.java class="store.ShoppingCartImpl"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <implementation.java class="store.CurrencyConverterImpl"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverter.java b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverter.java
new file mode 100644
index 0000000000..1ed15a670a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverter.java
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package store;
+
+public interface CurrencyConverter {
+
+ Double convert(String from, String to, Double amount);
+
+ String symbol(String currency);
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverterImpl.java b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverterImpl.java
new file mode 100644
index 0000000000..a6d0fd00b3
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/CurrencyConverterImpl.java
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+package store;
+
+/**
+ * Currency converter component implementation.
+ */
+public class CurrencyConverterImpl {
+
+ /**
+ * Convert an amount from USD to a currency.
+ */
+ public Double convert(String from, String to, Double amount) {
+ if ("EUR".equals(to))
+ return amount * 0.70;
+ return amount;
+ }
+
+ /**
+ * Return a currency symbol.
+ */
+ public String symbol(String currency) {
+ if ("EUR".equals(currency))
+ return "E";
+ return "$";
+ }
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/store/FruitsCatalogImpl.java b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/FruitsCatalogImpl.java
new file mode 100644
index 0000000000..8881543103
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/FruitsCatalogImpl.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package store;
+
+import static org.apache.tuscany.IterableUtil.*;
+
+import org.apache.tuscany.Service;
+
+/**
+ * Catalog component implementation.
+ */
+public class FruitsCatalogImpl {
+
+ /**
+ * Returns the catalog.
+ */
+ public Iterable<?> items(final CurrencyConverter converter, final Service currencyCode) {
+ final String code = currencyCode.eval();
+
+ class Converter {
+ Double convert(final Double price) {
+ return converter.convert(code, "USD", price);
+ }
+ }
+
+ final Converter c = new Converter();
+ final String symbol = converter.symbol(code);
+
+ return list(list(list("'name", "Apple"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(2.99))),
+ list(list("'name", "Orange"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(3.55))),
+ list(list("'name", "Pear"), list("'currencyCode", code), list("'currencySymbol", symbol), list("'price", c.convert(1.55))));
+ }
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-java/store/ShoppingCartImpl.java b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/ShoppingCartImpl.java
new file mode 100644
index 0000000000..e51beacc20
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-java/store/ShoppingCartImpl.java
@@ -0,0 +1,112 @@
+/*
+ * 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.
+ */
+
+package store;
+
+import static org.apache.tuscany.IterableUtil.*;
+import static org.apache.tuscany.UUIDUtil.*;
+
+import org.apache.tuscany.Service;
+
+/**
+ * Shopping cart component implementation.
+ */
+public class ShoppingCartImpl {
+
+ static String cartId = "1234";
+
+ /**
+ * Get the shopping cart from the cache. Return an empty cart if not found.
+ */
+ public Iterable<?> getcart(final String id, final Service cache) {
+ final Iterable<String> iid = list(id);
+ final Iterable<?> cart = cache.get(iid);
+ if(cart == null)
+ return list();
+ return cart;
+ }
+
+ /**
+ * Post a new item to the cart. Create a new cart if necessary.
+ */
+ public Iterable<String> post(final Iterable<String> collection, final Iterable<?> item, final Service cache) {
+ final String id = uuid();
+ final Iterable<?> newItem = list(car(item), id, caddr(item));
+ final Iterable<?> cart = cons(newItem, this.getcart(cartId, cache));
+ final Iterable<String> iid = list(cartId);
+ cache.put(iid, cart);
+ return list(id);
+ }
+
+ /**
+ * Find an item in the cart.
+ */
+ Iterable<?> find(final String id, final Iterable<?> cart) {
+ if(isNil(cart))
+ return cons("Item", list("0", list()));
+ if(id.equals(cadr(car(cart))))
+ return car(cart);
+ return this.find(id, cdr(cart));
+ }
+
+ /**
+ * Return items from the cart.
+ */
+ public Iterable<?> get(final Iterable<String> id, final Service cache) {
+ if(isNil(id))
+ return cons("Your Cart", cons(cartId, this.getcart(cartId, cache)));
+ return this.find((String)car(id), this.getcart(cartId, cache));
+ }
+
+ /**
+ * Delete items from the cart.
+ */
+ public Boolean delete(final Iterable<String> id, final Service cache) {
+ if(isNil(id)) {
+ final Iterable<String> iid = list(cartId);
+ return cache.delete(iid);
+ }
+ return true;
+ }
+
+ /**
+ * Return the price of an item.
+ */
+ Double price(final Iterable<?> item) {
+ return Double.valueOf((String)cadr(assoc("'price", caddr(item))));
+ }
+
+ /**
+ * Sum the prices of a list of items.
+ */
+ Double sum(final Iterable<?> items) {
+ if(isNil(items))
+ return 0.0;
+ return this.price((Iterable<?>)car(items)) + this.sum(cdr(items));
+ }
+
+ /**
+ * Return the total price of the items in the cart.
+ */
+ public Double total(final Service cache) {
+ final Iterable<?> cart = this.getcart(cartId, cache);
+ return this.sum(cart);
+ }
+
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/Makefile.am
new file mode 100644
index 0000000000..e69d8a164f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/Makefile.am
@@ -0,0 +1,25 @@
+# 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.
+
+dist_sample_SCRIPTS = start stop ssl-start
+sampledir = $(prefix)/samples/store-nosql
+
+nobase_dist_sample_DATA = currency-converter.scm fruits-catalog.scm shopping-cart.scm store.scm store.composite htdocs/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/currency-converter.scm b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/currency-converter.scm
new file mode 100644
index 0000000000..fc506c3d73
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/currency-converter.scm
@@ -0,0 +1,27 @@
+; 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.
+
+; Currency converter implementation
+
+(define (convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/fruits-catalog.scm b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/fruits-catalog.scm
new file mode 100644
index 0000000000..d55394b96a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/fruits-catalog.scm
@@ -0,0 +1,30 @@
+; 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.
+
+; Catalog implementation
+
+(define (items converter currencyCode)
+ (define code (currencyCode))
+ (define (convert price) (converter "convert" "USD" code price))
+ (define symbol (converter "symbol" code))
+ (list
+ (list (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 2.99)))
+ (list (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 3.55)))
+ (list (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 1.55)))
+ )
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/shopping-cart.scm b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/shopping-cart.scm
new file mode 100644
index 0000000000..61b169426f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/shopping-cart.scm
@@ -0,0 +1,82 @@
+; 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.
+
+; Shopping cart implementation
+
+(define cartId "1234")
+
+; Get the shopping cart from the cache
+; Return an empty cart if not found
+(define (getcart id cache)
+ (define cart (cache "get" (list id)))
+ (if (nul cart)
+ (list)
+ cart)
+)
+
+; Post a new item to the cart, create a new cart if necessary
+(define (post collection item cache)
+ (define id (uuid))
+ (define newItem (list (car item) id (caddr item)))
+ (define cart (cons newItem (getcart cartId cache)))
+ (cache "put" (list cartId) cart)
+ (list id)
+)
+
+; Find an item in the cart
+(define (find id cart)
+ (if (nul cart)
+ (cons "Item" (list "0" (list)))
+ (if (= id (cadr (car cart)))
+ (car cart)
+ (find id (cdr cart))))
+)
+
+; Get items from the cart
+(define (get id cache)
+ (if (nul id)
+ (cons "Your Cart" (cons cartId (getcart cartId cache)))
+ (find (car id) (getcart cartId cache))
+ )
+)
+
+; Delete items from the cart
+(define (delete id cache)
+ (if (nul id)
+ (cache "delete" (list cartId))
+ true
+ )
+)
+
+; Return the price of an item
+(define (price item)
+ (cadr (assoc 'price (caddr item)))
+)
+
+; Sum the prices of a list of items
+(define (sum items)
+ (if (nul items)
+ 0
+ (+ (price (car items)) (sum (cdr items))))
+)
+
+; Return the total price of the items in the cart
+(define (total cache)
+ (define cart (getcart cartId cache))
+ (sum cart)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/ssl-start
new file mode 100755
index 0000000000..c536e9b3f2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/ssl-start
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/nosqldb/tinycdb -c -m tmp/store.cdb </dev/null
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/start b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/start
new file mode 100755
index 0000000000..79da4682b2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/nosqldb/tinycdb -c -m tmp/store.cdb </dev/null
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/stop b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/stop
new file mode 100755
index 0000000000..3b4f46694d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/stop
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.composite
new file mode 100644
index 0000000000..90e4323318
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="NoSqldb"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="NoSqldb">
+ <implementation.cpp path="../../components/nosqldb" library="libnosqldb"/>
+ <property name="dbname">tmp/store.cdb</property>
+ <service name="NoSqldb">
+ <t:binding.atom uri="nosqldb"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.scm b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.scm
new file mode 100644
index 0000000000..f54257343e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-nosql/store.scm
@@ -0,0 +1,47 @@
+; 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.
+
+; Store implementation
+
+(define (post item catalog shoppingCart shoppingTotal)
+ (shoppingCart "post" item)
+)
+
+(define (getall catalog shoppingCart shoppingTotal)
+ (shoppingCart "getall")
+)
+
+(define (get id catalog shoppingCart shoppingTotal)
+ (shoppingCart "get" id)
+)
+
+(define (items catalog shoppingCart shoppingTotal)
+ (catalog "items")
+)
+
+(define (total catalog shoppingCart shoppingTotal)
+ (shoppingCart "total")
+)
+
+(define (deleteall catalog shoppingCart shoppingTotal)
+ (shoppingCart "deleteall")
+)
+
+(define (delete id catalog shoppingCart shoppingTotal)
+ (shoppingCart "delete" id)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-python/Makefile.am
new file mode 100644
index 0000000000..8db150cc0e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/Makefile.am
@@ -0,0 +1,28 @@
+# 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.
+
+if WANT_PYTHON
+
+dist_sample_SCRIPTS = start stop ssl-start uec2-start
+sampledir = $(prefix)/samples/store-python
+
+nobase_dist_sample_DATA = currency-converter.py fruits-catalog.py shopping-cart.py store.py store.composite htdocs/*.html htdocs/login/*.html htdocs/logout/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-python/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-python/fruits-catalog.py
new file mode 100644
index 0000000000..8289afcac5
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Mango"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Passion"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Kiwi"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/login/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/login/index.html
new file mode 100644
index 0000000000..3f312e4ca4
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/login/index.html
@@ -0,0 +1,40 @@
+<!--
+ 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.
+-->
+
+<html><body><h1>Sign in</h1>
+
+<script type="text/javascript">
+function submitFormSignin() {
+ document.cookie = 'TuscanyOpenAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.formSignin.httpd_location.value = '/';
+ document.formSignin.submit();
+}
+</script>
+
+<form name="formSignin" method="POST" action="/login/dologin">
+<table border="0">
+<tr><td>Username:</td><td><input type="text" name="httpd_username" value=""/></td></tr>
+<tr><td>Password:</td><td><input type="password" name="httpd_password" value=""/></td></tr>
+<tr><td><input type="button" onclick="submitFormSignin()" value="Sign in"/></td><td></td></tr>
+</table>
+<input type="hidden" name="httpd_location" value="/"/>
+</form>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/logout/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/logout/index.html
new file mode 100644
index 0000000000..1ac6e39a1c
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/logout/index.html
@@ -0,0 +1,33 @@
+<!--
+ 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.
+-->
+
+<html><body>
+<h1>Sign out</h1>
+
+<form name="signout" action="/login" method="GET">
+<script type="text/javascript">
+function submitSignout() {
+ document.cookie = 'TuscanyFormAuth=;expires=' + new Date(1970,01,01).toGMTString() + ';path=/;secure=TRUE';
+ document.signout.submit();
+ return true;
+}
+</script>
+<input type="button" onclick="submitSignout()" value="Sign out"/>
+</form>
+</body></html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/test/items-result.txt b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/test/items-result.txt
new file mode 100644
index 0000000000..788b7cdf89
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/htdocs/test/items-result.txt
@@ -0,0 +1 @@
+{"id":1,"result":[{"name":"Mango","currencyCode":"USD","currencySymbol":"$","price":2.99},{"name":"Passion","currencyCode":"USD","currencySymbol":"$","price":3.55},{"name":"Kiwi","currencyCode":"USD","currencySymbol":"$","price":1.55}]} \ No newline at end of file
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-python/server-test
new file mode 100755
index 0000000000..27490c580b
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-python/shopping-cart.py
new file mode 100644
index 0000000000..feb7398ed9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/shopping-cart.py
@@ -0,0 +1,75 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get((id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache.put((cartId,), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache):
+ if id == ():
+ return cache.delete((cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-python/ssl-start
new file mode 100755
index 0000000000..60b9bb5ace
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/ssl-start
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/open-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/start b/sandbox/sebastien/cpp/apr-2/samples/store-python/start
new file mode 100755
index 0000000000..8df7875634
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/stop b/sandbox/sebastien/cpp/apr-2/samples/store-python/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-python/store.composite
new file mode 100644
index 0000000000..912898123b
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/store.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-python/store.py
new file mode 100644
index 0000000000..b71f505dd1
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.gettotal()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deleteall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-python/uec2-start b/sandbox/sebastien/cpp/apr-2/samples/store-python/uec2-start
new file mode 100755
index 0000000000..84c170e596
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-python/uec2-start
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+# Pass your EC2 public host name
+if [ "$1" != "" ]; then
+ host=$1
+else
+ host="localhost"
+fi
+
+# Ports 80, 443, 444, 8090, 8453, 8454 need to be open
+sudo ../../ubuntu/ip-redirect-all 80 8090
+sudo ../../ubuntu/ip-redirect-all 443 8453
+
+../../modules/http/ssl-ca-conf tmp $host
+../../modules/http/ssl-cert-conf tmp $host
+../../modules/http/httpd-conf tmp $host 8090/80 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453/443
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/Makefile.am
new file mode 100644
index 0000000000..2330d45422
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/Makefile.am
@@ -0,0 +1,30 @@
+# 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.
+
+dist_sample_SCRIPTS = start stop ssl-start
+sampledir = $(prefix)/samples/store-scheme
+
+nobase_dist_sample_DATA = currency-converter.scm fruits-catalog.scm shopping-cart.scm store.scm store.composite htdocs/*.html
+
+EXTRA_DIST = script-test.scm
+
+dist_noinst_SCRIPTS = server-test
+noinst_PROGRAMS = script-test
+script_test_SOURCES = script-test.cpp
+script_test_LDFLAGS = -lxml2 -lmozjs
+
+TESTS = script-test server-test
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/currency-converter.scm b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/currency-converter.scm
new file mode 100644
index 0000000000..fc506c3d73
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/currency-converter.scm
@@ -0,0 +1,27 @@
+; 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.
+
+; Currency converter implementation
+
+(define (convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/fruits-catalog.scm b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/fruits-catalog.scm
new file mode 100644
index 0000000000..d55394b96a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/fruits-catalog.scm
@@ -0,0 +1,30 @@
+; 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.
+
+; Catalog implementation
+
+(define (items converter currencyCode)
+ (define code (currencyCode))
+ (define (convert price) (converter "convert" "USD" code price))
+ (define symbol (converter "symbol" code))
+ (list
+ (list (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 2.99)))
+ (list (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 3.55)))
+ (list (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 1.55)))
+ )
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.cpp b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.cpp
new file mode 100644
index 0000000000..0d5a9ccf9d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.cpp
@@ -0,0 +1,96 @@
+/*
+ * 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$ */
+
+/**
+ * Store Test case.
+ */
+
+#include <assert.h>
+#include <regex.h>
+#include "stream.hpp"
+#include "string.hpp"
+#include "list.hpp"
+#include "xml.hpp"
+#include "../../modules/scheme/driver.hpp"
+#include "../../modules/json/json.hpp"
+
+namespace store {
+
+using namespace tuscany;
+
+bool testScript() {
+ gc_scoped_pool pool;
+
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::evalDriverRun(is, os);
+ assert(contains(str(os), "(\"Sample Feed\" \""));
+ assert(contains(str(os), "\" (\"Item\" \""));
+ assert(contains(str(os), "\" ((name \"Orange\") (currencyCode \"USD\") (currencySymbol \"$\") (price 3.55))) (\"Item\" \""));
+ assert(contains(str(os), "\" ((name \"Apple\") (currencyCode \"USD\") (currencySymbol \"$\") (price 2.99))))"));
+ return true;
+}
+
+bool testEval() {
+ {
+ gc_scoped_pool pool;
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::setupDisplay(os);
+ scheme::Env globalEnv = scheme::setupEnvironment();
+ const value exp(mklist<value>("storeui_service", string("items")));
+ const value val = scheme::evalScript(exp, is, globalEnv);
+
+ ostringstream vs;
+ vs << val;
+ assert(contains(str(vs), "(((name \"Apple\") (currencyCode \"USD\") (currencySymbol \"$\") (price 2.99)) ((name \"Orange\") (currencyCode \"USD\") (currencySymbol \"$\") (price 3.55)) ((name \"Pear\") (currencyCode \"USD\") (currencySymbol \"$\") (price 1.55)))"));
+ }
+
+ {
+ gc_scoped_pool pool;
+ ifstream is("script-test.scm");
+ ostringstream os;
+ scheme::setupDisplay(os);
+
+ scheme::Env globalEnv = scheme::setupEnvironment();
+ const value exp(mklist<value>("storeui_service", string("total")));
+ const value res = scheme::evalScript(exp, is, globalEnv);
+
+ ostringstream rs;
+ rs << res;
+ assert(contains(str(rs), "10"));
+ }
+ return true;
+}
+
+}
+
+int main() {
+
+ tuscany::cout << "Testing..." << tuscany::endl;
+
+ store::testScript();
+ store::testEval();
+
+ tuscany::cout << "OK" << tuscany::endl;
+
+ return 0;
+}
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.scm b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.scm
new file mode 100644
index 0000000000..50b587b8f1
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/script-test.scm
@@ -0,0 +1,140 @@
+; 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.
+
+; Currency implementation
+
+(define (currency_convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (currency_symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
+(define (currency_impl op args)
+ (cond
+ ((equal? op "convert") (apply currency_convert args))
+ ((equal? op "symbol") (apply currency_symbol args))
+ )
+)
+
+; Currency composite
+
+(define (currency_service op . args) (currency_impl op args))
+
+; Catalog implementation
+
+(define (catalog_get converter)
+ (define (convert price) (converter "convert" "USD" "USD" price))
+
+ (define code "USD")
+ (define symbol (converter "symbol" code))
+
+ (list
+ (list (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 2.99))
+ (list (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 3.55))
+ (list (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price 1.55))
+ )
+)
+
+(define (catalog_impl converter op args)
+ (cond
+ ((equal? op "items") (apply catalog_get (cons converter args)))
+ )
+)
+
+; Catalog composite
+
+(define (catalog_service op . args) (catalog_impl currency_service op args))
+
+; Cart implementation
+
+(define (cart_post content item)
+ (cons (cons "Item" (list (uuid) item)) content)
+)
+
+(define (cart_getall content)
+ (cons "Sample Feed" (cons (uuid) content))
+)
+
+(define (cart_getentry id)
+ (define entry (list (list 'name "Apple") (list 'currencyCode "USD") (list 'currencySymbol "$") (list 'price 2.99)))
+ (cons "Item" (list id entry))
+)
+
+(define (cart_total)
+ 10.0
+)
+
+(define (cart_impl op args)
+ (cond
+ ((equal? op "post") (apply cart_post args))
+ ((equal? op "getall") (apply cart_getall args))
+ ((equal? op "getentry") (apply cart_getentry args))
+ ((equal? op "total") (apply cart_total args))
+ )
+)
+
+; Store UI implementation
+
+(define (storeui_post cart content item)
+ (cart "post" content item)
+)
+
+(define (storeui_getcart cart content)
+ (cart "getall" content)
+)
+
+(define (storeui_getentry cart id)
+ (cart "getentry" id)
+)
+
+(define (storeui_items catalog)
+ (catalog "items")
+)
+
+(define (storeui_total cart)
+ (cart "total")
+)
+
+(define (storeui_impl cart catalog op args)
+ (cond
+ ((equal? op "post") (apply storeui_post (cons cart args)))
+ ((equal? op "getall") (apply storeui_getcart (cons cart args)))
+ ((equal? op "getentry") (apply storeui_getentry (cons cart args)))
+ ((equal? op "items") (apply storeui_items (cons catalog args)))
+ ((equal? op "total") (apply storeui_total (cons cart args)))
+ )
+)
+
+; Store UI composite
+
+(define (cart_service op . args) (cart_impl op args))
+
+(define (storeui_service op . args) (storeui_impl cart_service catalog_service op args))
+
+; Store UI test case
+
+(define catalog (storeui_service "items"))
+(define empty (list))
+(define apple (car catalog))
+(define orange (car (cdr catalog)))
+(define added1 (storeui_service "post" empty apple))
+(define added2 (storeui_service "post" added1 orange))
+(display (storeui_service "getall" added2))
+(display (storeui_service "total"))
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/shopping-cart.scm b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/shopping-cart.scm
new file mode 100644
index 0000000000..61b169426f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/shopping-cart.scm
@@ -0,0 +1,82 @@
+; 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.
+
+; Shopping cart implementation
+
+(define cartId "1234")
+
+; Get the shopping cart from the cache
+; Return an empty cart if not found
+(define (getcart id cache)
+ (define cart (cache "get" (list id)))
+ (if (nul cart)
+ (list)
+ cart)
+)
+
+; Post a new item to the cart, create a new cart if necessary
+(define (post collection item cache)
+ (define id (uuid))
+ (define newItem (list (car item) id (caddr item)))
+ (define cart (cons newItem (getcart cartId cache)))
+ (cache "put" (list cartId) cart)
+ (list id)
+)
+
+; Find an item in the cart
+(define (find id cart)
+ (if (nul cart)
+ (cons "Item" (list "0" (list)))
+ (if (= id (cadr (car cart)))
+ (car cart)
+ (find id (cdr cart))))
+)
+
+; Get items from the cart
+(define (get id cache)
+ (if (nul id)
+ (cons "Your Cart" (cons cartId (getcart cartId cache)))
+ (find (car id) (getcart cartId cache))
+ )
+)
+
+; Delete items from the cart
+(define (delete id cache)
+ (if (nul id)
+ (cache "delete" (list cartId))
+ true
+ )
+)
+
+; Return the price of an item
+(define (price item)
+ (cadr (assoc 'price (caddr item)))
+)
+
+; Sum the prices of a list of items
+(define (sum items)
+ (if (nul items)
+ 0
+ (+ (price (car items)) (sum (cdr items))))
+)
+
+; Return the total price of the items in the cart
+(define (total cache)
+ (define cart (getcart cartId cache))
+ (sum cart)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/ssl-start
new file mode 100755
index 0000000000..70e62f1f04
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/ssl-start
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/start b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/start
new file mode 100755
index 0000000000..ffd7173ee2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/start
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/stop b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.composite
new file mode 100644
index 0000000000..fd58ae6c9d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.composite
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.scm b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.scm
new file mode 100644
index 0000000000..f54257343e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-scheme/store.scm
@@ -0,0 +1,47 @@
+; 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.
+
+; Store implementation
+
+(define (post item catalog shoppingCart shoppingTotal)
+ (shoppingCart "post" item)
+)
+
+(define (getall catalog shoppingCart shoppingTotal)
+ (shoppingCart "getall")
+)
+
+(define (get id catalog shoppingCart shoppingTotal)
+ (shoppingCart "get" id)
+)
+
+(define (items catalog shoppingCart shoppingTotal)
+ (catalog "items")
+)
+
+(define (total catalog shoppingCart shoppingTotal)
+ (shoppingCart "total")
+)
+
+(define (deleteall catalog shoppingCart shoppingTotal)
+ (shoppingCart "deleteall")
+)
+
+(define (delete id catalog shoppingCart shoppingTotal)
+ (shoppingCart "delete" id)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-sql/Makefile.am
new file mode 100644
index 0000000000..3b738e3972
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/Makefile.am
@@ -0,0 +1,28 @@
+# 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.
+
+if WANT_SQLDB
+
+dist_sample_SCRIPTS = start stop ssl-start
+sampledir = $(prefix)/samples/store-sql
+
+nobase_dist_sample_DATA = currency-converter.scm fruits-catalog.scm shopping-cart.scm store.scm store.composite htdocs/*.html
+
+dist_noinst_SCRIPTS = server-test
+TESTS = server-test
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/currency-converter.scm b/sandbox/sebastien/cpp/apr-2/samples/store-sql/currency-converter.scm
new file mode 100644
index 0000000000..fc506c3d73
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/currency-converter.scm
@@ -0,0 +1,27 @@
+; 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.
+
+; Currency converter implementation
+
+(define (convert from to amount)
+ (if (equal? to "EUR") (* amount 0.70) amount)
+)
+
+(define (symbol currency)
+ (if (equal? currency "EUR") "E" "$")
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/fruits-catalog.scm b/sandbox/sebastien/cpp/apr-2/samples/store-sql/fruits-catalog.scm
new file mode 100644
index 0000000000..d55394b96a
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/fruits-catalog.scm
@@ -0,0 +1,30 @@
+; 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.
+
+; Catalog implementation
+
+(define (items converter currencyCode)
+ (define code (currencyCode))
+ (define (convert price) (converter "convert" "USD" code price))
+ (define symbol (converter "symbol" code))
+ (list
+ (list (list 'name "Apple") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 2.99)))
+ (list (list 'name "Orange") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 3.55)))
+ (list (list 'name "Pear") (list 'currencyCode code) (list 'currencySymbol symbol) (list 'price (convert 1.55)))
+ )
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-sql/htdocs/index.html
new file mode 100644
index 0000000000..3945e45bb7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/htdocs/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-sql/server-test
new file mode 100755
index 0000000000..1612bc59e2
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/server-test
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://localhost:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://localhost:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/shopping-cart.scm b/sandbox/sebastien/cpp/apr-2/samples/store-sql/shopping-cart.scm
new file mode 100644
index 0000000000..61b169426f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/shopping-cart.scm
@@ -0,0 +1,82 @@
+; 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.
+
+; Shopping cart implementation
+
+(define cartId "1234")
+
+; Get the shopping cart from the cache
+; Return an empty cart if not found
+(define (getcart id cache)
+ (define cart (cache "get" (list id)))
+ (if (nul cart)
+ (list)
+ cart)
+)
+
+; Post a new item to the cart, create a new cart if necessary
+(define (post collection item cache)
+ (define id (uuid))
+ (define newItem (list (car item) id (caddr item)))
+ (define cart (cons newItem (getcart cartId cache)))
+ (cache "put" (list cartId) cart)
+ (list id)
+)
+
+; Find an item in the cart
+(define (find id cart)
+ (if (nul cart)
+ (cons "Item" (list "0" (list)))
+ (if (= id (cadr (car cart)))
+ (car cart)
+ (find id (cdr cart))))
+)
+
+; Get items from the cart
+(define (get id cache)
+ (if (nul id)
+ (cons "Your Cart" (cons cartId (getcart cartId cache)))
+ (find (car id) (getcart cartId cache))
+ )
+)
+
+; Delete items from the cart
+(define (delete id cache)
+ (if (nul id)
+ (cache "delete" (list cartId))
+ true
+ )
+)
+
+; Return the price of an item
+(define (price item)
+ (cadr (assoc 'price (caddr item)))
+)
+
+; Sum the prices of a list of items
+(define (sum items)
+ (if (nul items)
+ 0
+ (+ (price (car items)) (sum (cdr items))))
+)
+
+; Return the total price of the items in the cart
+(define (total cache)
+ (define cart (getcart cartId cache))
+ (sum cart)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-sql/ssl-start
new file mode 100755
index 0000000000..58ce2070ee
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/ssl-start
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/ssl-ca-conf tmp localhost
+../../modules/http/ssl-cert-conf tmp localhost
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../components/sqldb/pgsql-conf tmp
+../../components/sqldb/pgsql-start tmp
+../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/start b/sandbox/sebastien/cpp/apr-2/samples/store-sql/start
new file mode 100755
index 0000000000..95881294d1
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/start
@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp localhost 8090 htdocs
+../../modules/server/server-conf tmp
+../../modules/server/scheme-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/
+SCAComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../components/sqldb/pgsql-conf tmp
+../../components/sqldb/pgsql-start tmp
+../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/stop b/sandbox/sebastien/cpp/apr-2/samples/store-sql/stop
new file mode 100755
index 0000000000..2226018a3f
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/stop
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/sqldb/pgsql-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.composite
new file mode 100644
index 0000000000..a10740b5f9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.composite
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.scheme script="store.scm"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.scheme script="fruits-catalog.scm"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.scheme script="shopping-cart.scm"/>
+ <service name="Cart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.scheme script="currency-converter.scm"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+ <component name="Cache">
+ <implementation.cpp path="../../components/cache" library="libdatacache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <reference name="l1reader" target="Memcache"/>
+ <reference name="l1writer" target="Memcache"/>
+ <reference name="l2reader" target="Sqldb"/>
+ <reference name="l2writer" target="Sqldb"/>
+ </component>
+
+ <component name="Memcache">
+ <implementation.cpp path="../../components/cache" library="libmemcache"/>
+ <service name="Memcache">
+ <t:binding.atom uri="memcache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+ <component name="Sqldb">
+ <implementation.cpp path="../../components/sqldb" library="libsqldb"/>
+ <property name="conninfo">host=localhost port=5432 dbname=db</property>
+ <property name="table">store</property>
+ <service name="Sqldb">
+ <t:binding.atom uri="sqldb"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.scm b/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.scm
new file mode 100644
index 0000000000..f54257343e
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-sql/store.scm
@@ -0,0 +1,47 @@
+; 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.
+
+; Store implementation
+
+(define (post item catalog shoppingCart shoppingTotal)
+ (shoppingCart "post" item)
+)
+
+(define (getall catalog shoppingCart shoppingTotal)
+ (shoppingCart "getall")
+)
+
+(define (get id catalog shoppingCart shoppingTotal)
+ (shoppingCart "get" id)
+)
+
+(define (items catalog shoppingCart shoppingTotal)
+ (catalog "items")
+)
+
+(define (total catalog shoppingCart shoppingTotal)
+ (shoppingCart "total")
+)
+
+(define (deleteall catalog shoppingCart shoppingTotal)
+ (shoppingCart "deleteall")
+)
+
+(define (delete id catalog shoppingCart shoppingTotal)
+ (shoppingCart "delete" id)
+)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/Makefile.am b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/Makefile.am
new file mode 100644
index 0000000000..6c7dba1808
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/Makefile.am
@@ -0,0 +1,28 @@
+# 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.
+
+if WANT_PYTHON
+
+dist_sample_SCRIPTS = start stop ssl-start uec2-start
+sampledir = $(prefix)/samples/store-vhost
+
+nobase_dist_sample_DATA = htdocs/*.html htdocs/domains/*/*.html domains/*/*.py domains/*/*.composite shared/*.composite
+
+dist_noinst_SCRIPTS = server-test
+#TESTS = server-test
+
+endif
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/fruits-catalog.py
new file mode 100644
index 0000000000..fb20b4ff27
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Passion"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Mango"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Pineapple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/shopping-cart.py
new file mode 100644
index 0000000000..feb7398ed9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/shopping-cart.py
@@ -0,0 +1,75 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get((id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache.put((cartId,), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache):
+ if id == ():
+ return cache.delete((cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.composite
new file mode 100644
index 0000000000..01553025d9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.composite
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.py
new file mode 100644
index 0000000000..ff82f1d327
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/jane/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.total()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deleteall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/currency-converter.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/currency-converter.py
new file mode 100644
index 0000000000..2fded8f616
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/currency-converter.py
@@ -0,0 +1,29 @@
+# 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.
+
+# Currency converter implementation
+
+def convert(fr, to, amount):
+ if to == "EUR":
+ return amount * 0.70
+ return amount
+
+def symbol(currency):
+ if currency == "EUR":
+ return "E"
+ return "$"
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/fruits-catalog.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/fruits-catalog.py
new file mode 100644
index 0000000000..6644421683
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/fruits-catalog.py
@@ -0,0 +1,30 @@
+# 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.
+
+# Catalog implementation
+
+def items(converter, currencyCode):
+ code = currencyCode.eval()
+ def convert(price):
+ return converter.convert("USD", code, price)
+ symbol = converter.symbol(code)
+ return (
+ (("'name", "Apple"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(2.99))),
+ (("'name", "Orange"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(3.55))),
+ (("'name", "Pear"), ("'currencyCode", code), ("'currencySymbol", symbol), ("'price", convert(1.55)))
+ )
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/shopping-cart.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/shopping-cart.py
new file mode 100644
index 0000000000..feb7398ed9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/shopping-cart.py
@@ -0,0 +1,75 @@
+# 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.
+
+# Shopping cart implementation
+import uuid
+import sys
+
+cartId = "1234"
+
+# Get the shopping cart from the cache
+# Return an empty cart if not found
+def getcart(id, cache):
+ cart = cache.get((id,))
+ if cart is None:
+ return ()
+ return cart
+
+# Post a new item to the cart, create a new cart if necessary
+def post(collection, item, cache):
+ id = str(uuid.uuid1())
+ cart = ((item[0], id, item[2]),) + getcart(cartId, cache)
+ cache.put((cartId,), cart)
+ return (id,)
+
+
+# Find an item in the cart
+def find(id, cart):
+ if cart == ():
+ return ("Item", "0", ())
+ elif id == cart[0][1]:
+ return cart[0]
+ else:
+ return find(id, cart[1:])
+
+# Get items from the cart
+def get(id, cache):
+ if id == ():
+ return ("Your Cart", cartId) + getcart(cartId, cache)
+ return find(id[0], getcart(cartId, cache))
+
+# Delete items from the cart
+def delete(id, cache):
+ if id == ():
+ return cache.delete((cartId,))
+ return True
+
+# Return the price of an item
+def price(item):
+ return float(filter(lambda x: x[0] == "'price", item[2])[0][1])
+
+# Sum the prices of a list of items
+def sum(items):
+ if items == ():
+ return 0
+ return price(items[0]) + sum(items[1:])
+
+# Return the total price of the items in the cart
+def total(cache):
+ cart = getcart(cartId, cache)
+ return sum(cart)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.composite b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.composite
new file mode 100644
index 0000000000..01553025d9
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.composite
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://store"
+ name="store">
+
+ <component name="Store">
+ <t:implementation.python script="store.py"/>
+ <service name="Widget">
+ <t:binding.http uri="store"/>
+ </service>
+ <reference name="catalog" target="Catalog"/>
+ <reference name="shoppingCart" target="ShoppingCart/Cart"/>
+ <reference name="shoppingTotal" target="ShoppingCart/Total"/>
+ </component>
+
+ <component name="Catalog">
+ <t:implementation.python script="fruits-catalog.py"/>
+ <property name="currencyCode">USD</property>
+ <service name="Catalog">
+ <t:binding.jsonrpc uri="catalog"/>
+ </service>
+ <reference name="currencyConverter" target="CurrencyConverter"/>
+ </component>
+
+ <component name="ShoppingCart">
+ <t:implementation.python script="shopping-cart.py"/>
+ <service name="ShoppingCart">
+ <t:binding.atom uri="shoppingCart"/>
+ </service>
+ <service name="Total">
+ <t:binding.jsonrpc uri="total"/>
+ </service>
+ <reference name="cache" target="Cache"/>
+ </component>
+
+ <component name="CurrencyConverter">
+ <t:implementation.python script="currency-converter.py"/>
+ <service name="CurrencyConverter">
+ <t:binding.jsonrpc uri="currencyConverter"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.py b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.py
new file mode 100644
index 0000000000..ff82f1d327
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/domains/joe/store.py
@@ -0,0 +1,40 @@
+# 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.
+
+# Store implementation
+
+def post(item, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.post(item)
+
+def getall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.getall()
+
+def get(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.get(id)
+
+def items(catalog, shoppingCart, shoppingTotal):
+ return catalog.items()
+
+def total(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.total()
+
+def deleteall(catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.deleteall()
+
+def delete(id, catalog, shoppingCart, shoppingTotal):
+ return shoppingCart.delete(id)
+
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/jane/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/jane/index.html
new file mode 100644
index 0000000000..238ed701f0
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/jane/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Jane's Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/joe/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/joe/index.html
new file mode 100644
index 0000000000..c1cfc59aa7
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/domains/joe/index.html
@@ -0,0 +1,150 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+
+<script type="text/javascript" src="/component.js"></script>
+
+<script type="text/javascript">
+var store = sca.component("Store");
+var catalog = sca.defun(sca.reference(store, "catalog"), "items");
+var shoppingCart = sca.reference(store, "shoppingCart");
+var shoppingTotal = sca.defun(sca.reference(store, "shoppingTotal"), "total");
+
+var catalogItems;
+
+function catalog_itemsResponse(items, exception) {
+ if (exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++) {
+ var item = items[i].name + ' - ' + items[i].price;
+ catalog += '<input name="items" type="checkbox" value="' +
+ item + '">' + item + ' <br>';
+ }
+ document.getElementById('catalog').innerHTML=catalog;
+ catalogItems = items;
+
+}
+
+function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var content = entries[i].getElementsByTagName("content")[0];
+ var name = content.getElementsByTagName("name")[0].firstChild.nodeValue;
+ var price = content.getElementsByTagName("price")[0].firstChild.nodeValue;
+ list += name + ' - ' + price + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+
+ shoppingTotal.total(shoppingTotal_totalResponse);
+ }
+}
+
+function shoppingTotal_totalResponse(total, exception) {
+ if (exception) {
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('total').innerHTML = total;
+}
+
+function shoppingCart_postResponse(entry) {
+ shoppingCart.get("", shoppingCart_getResponse);
+}
+
+function addToCart() {
+ var items = document.catalogForm.items;
+ var j = 0;
+ for (var i=0; i<items.length; i++)
+ if (items[i].checked) {
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title type="text">Item</title><content type="application/xml">' +
+ '<item>' +
+ '<name>' + catalogItems[i].name + '</name>' +
+ '<currencyCode>' + catalogItems[i].currencyCode + '</currencyCode>' +
+ '<currencySymbol>' + catalogItems[i].currencySymbol + '</currencySymbol>' +
+ '<price>' + catalogItems[i].price + '</price>' +
+ '</item>' +
+ '</content></entry>';
+ shoppingCart.post(entry, shoppingCart_postResponse);
+ items[i].checked = false;
+ }
+}
+function checkoutCart() {
+ document.getElementById('store').innerHTML='<h2>' +
+ 'Thanks for Shopping With Us!</h2>'+
+ '<h2>Your Order</h2>'+
+ '<form name="orderForm">'+
+ document.getElementById('shoppingCart').innerHTML+
+ '<br>'+
+ document.getElementById('total').innerHTML+
+ '<br>'+
+ '<br>'+
+ '<input type="submit" value="Continue Shopping">'+
+ '</form>';
+ shoppingCart.del("", null);
+}
+function deleteCart() {
+ shoppingCart.del("", null);
+ document.getElementById('shoppingCart').innerHTML = "";
+ document.getElementById('total').innerHTML = "";
+}
+
+function init() {
+ try {
+ catalog.items(catalog_itemsResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+ } catch(e){
+ alert(e);
+ }
+}
+</script>
+
+</head>
+
+<body onload="init()">
+<h1>Joe's Store</h1>
+<div id="store">
+<h2>Catalog</h2>
+<form name="catalogForm">
+<div id="catalog" ></div>
+<br>
+<input type="button" onClick="addToCart()" value="Add to Cart">
+</form>
+<br>
+
+<h2>Your Shopping Cart</h2>
+<form name="shoppingCartForm">
+<div id="shoppingCart"></div>
+<br>
+<div id="total"></div>
+<br>
+<input type="button" onClick="checkoutCart()" value="Checkout">
+<input type="button" onClick="deleteCart()" value="Empty">
+<a href="shoppingCart/">(feed)</a>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/index.html b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/index.html
new file mode 100644
index 0000000000..e0239392ff
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/htdocs/index.html
@@ -0,0 +1,34 @@
+<!--
+ * 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.
+-->
+<html>
+<head>
+<title>Store</title>
+</head>
+
+<body>
+<h1>Store</h1>
+<p>For this sample to work, add the sample domain to your /etc/hosts as follows:<br/>
+127.0.0.1 sca-store.com jane.sca-store.com joe.sca-store.com</p>
+
+<p/>
+<p>Jane's store at <a href="http://jane.sca-store.com:8090/">jane.sca-store.com</a>
+<br/>Joe's store at <a href="http://joe.sca-store.com:8090/">joe.sca-store.com</a></p>
+
+</body>
+</html>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/server-test b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/server-test
new file mode 100755
index 0000000000..405da2165d
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/server-test
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+echo "Testing..."
+here=`readlink -f $0`; here=`dirname $here`
+curl_prefix=`cat $here/../../modules/http/curl.prefix`
+
+# Setup
+./start
+sleep 2
+
+# For this test to work, add the test domain to your etc/hosts as follows:
+# 127.0.0.1 sca-store.com joe.sca-store.com joe.sca-store.com
+
+# Test HTTP GET
+$curl_prefix/bin/curl http://joe.sca-store.com:8090/ 2>/dev/null >tmp/index.html
+diff tmp/index.html htdocs/domains/joe/index.html
+rc=$?
+
+# Test Catalog
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com:8090/references/Store/catalog -X POST -H "Content-type: application/json-rpc" --data @../store-cpp/htdocs/test/items-request.txt >tmp/items-result.txt 2>/dev/null
+ diff tmp/items-result.txt ../store-cpp/htdocs/test/items-result.txt
+ rc=$?
+fi
+
+# Test Shopping Cart
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com:8090/references/Store/shoppingCart -X POST -H "Content-type: application/atom+xml" --data @../store-cpp/htdocs/test/shopping-cart-entry.xml 2>/dev/null
+ rc=$?
+fi
+if [ "$rc" = "0" ]; then
+ $curl_prefix/bin/curl http://joe.sca-store.com:8090/references/Store/shoppingCart >tmp/shopping-cart-feed.xml 2>/dev/null
+ grep "3.55" tmp/shopping-cart-feed.xml >/dev/null
+ rc=$?
+fi
+
+# Cleanup
+./stop
+sleep 2
+
+if [ "$rc" = "0" ]; then
+ echo "OK"
+fi
+return $rc
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/shared/shared.composite b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/shared/shared.composite
new file mode 100644
index 0000000000..55a0c1f8d6
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/shared/shared.composite
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ targetNamespace="http://shared"
+ name="shared">
+
+ <component name="Cache">
+ <implementation.cpp path="../../../components/cache" library="libmemcache"/>
+ <service name="Cache">
+ <t:binding.atom uri="cache"/>
+ </service>
+ <property name="servers">localhost:11211</property>
+ </component>
+
+</composite>
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/ssl-start b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/ssl-start
new file mode 100755
index 0000000000..6f715afb89
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/ssl-start
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+# For this sample to work, add the sample domain to your /etc/hosts as follows:
+# 127.0.0.1 sca-store.com jane.sca-store.com joe.sca-store.com
+
+../../modules/http/ssl-ca-conf tmp sca-store.com
+../../modules/http/ssl-cert-conf tmp sca-store.com server
+../../modules/http/ssl-cert-conf tmp *.sca-store.com vhost
+../../modules/http/httpd-conf tmp sca-store.com 8090 htdocs
+../../modules/http/vhost-conf tmp
+../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/vhost-ssl-conf tmp
+../../modules/http/basic-auth-conf tmp
+../../modules/http/passwd-auth-conf tmp foo foo
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/shared/
+SCAComposite shared.composite
+
+# Configure SCA Composite for mass dynamic virtual Hosting
+SCAVirtualContribution `pwd`/domains/
+SCAVirtualComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/start b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/start
new file mode 100755
index 0000000000..16ffe351ec
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/start
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-conf tmp sca-store.com 8090 htdocs
+../../modules/http/vhost-conf tmp
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite
+SCAContribution `pwd`/shared/
+SCAComposite shared.composite
+
+# Configure SCA Composite for mass dynamic virtual hosting
+SCAVirtualContribution `pwd`/domains/
+SCAVirtualComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/stop b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/stop
new file mode 100755
index 0000000000..a59273b8ed
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/stop
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+../../modules/http/httpd-stop tmp
+../../components/cache/memcached-stop
diff --git a/sandbox/sebastien/cpp/apr-2/samples/store-vhost/uec2-start b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/uec2-start
new file mode 100755
index 0000000000..b8a267d617
--- /dev/null
+++ b/sandbox/sebastien/cpp/apr-2/samples/store-vhost/uec2-start
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# 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.
+
+# Pass your EC2 public host name
+if [ "$1" != "" ]; then
+ host=$1
+else
+ # Default to dummy test domain
+ host="sca-store.com"
+fi
+
+# Ports 80, 443, 444, 8090, 8453, 8454 need to be open
+sudo ../../ubuntu/ip-redirect-all 80 8090
+sudo ../../ubuntu/ip-redirect-all 443 8453
+
+../../modules/http/ssl-ca-conf tmp $host
+../../modules/http/ssl-cert-conf tmp $host server
+../../modules/http/ssl-cert-conf tmp "*.$host" vhost
+../../modules/http/httpd-conf tmp $host 8090/80 htdocs
+../../modules/http/vhost-conf tmp
+../../modules/http/httpd-ssl-conf tmp 8453/443
+../../modules/http/vhost-ssl-conf tmp
+../../modules/server/server-conf tmp
+../../modules/python/python-conf tmp
+cat >>tmp/conf/httpd.conf <<EOF
+# Configure SCA Composite for mass dynamic virtual Hosting
+SCAVirtualContribution `pwd`/domains/
+SCAVirtualComposite store.composite
+
+EOF
+
+../../components/cache/memcached-start
+../../modules/http/httpd-start tmp
+