diff options
Diffstat (limited to 'sca-cpp/branches/lightweight-sca/samples/store-java')
11 files changed, 649 insertions, 0 deletions
diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/Makefile.am b/sca-cpp/branches/lightweight-sca/samples/store-java/Makefile.am new file mode 100644 index 0000000000..f32ae72812 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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/sca-cpp/branches/lightweight-sca/samples/store-java/htdocs/index.html b/sca-cpp/branches/lightweight-sca/samples/store-java/htdocs/index.html new file mode 100644 index 0000000000..0698a32cc5 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/samples/store-java/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> +<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0"/> +<meta name="apple-mobile-web-app-capable" content="yes"/> +<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"/> +<link rel="stylesheet" type="text/css" href="/ui-min.css"/> +<title>Store</title> + +<script type="text/javascript" src="/all-min.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(doc) { + if (doc != null) { + var feed = parseXML([doc]); + 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 = '<?xml version="1.0" encoding="UTF-8"?>\n' + + '<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> +<br/> +<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/sca-cpp/branches/lightweight-sca/samples/store-java/server-test b/sca-cpp/branches/lightweight-sca/samples/store-java/server-test new file mode 100755 index 0000000000..fb629a6814 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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=`echo "import os; print os.path.realpath('$0')" | python`; 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 +exit $rc diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/ssl-start b/sca-cpp/branches/lightweight-sca/samples/store-java/ssl-start new file mode 100755 index 0000000000..a585f717aa --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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 tmp +../../modules/http/httpd-start tmp diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/start b/sca-cpp/branches/lightweight-sca/samples/store-java/start new file mode 100755 index 0000000000..99a3f982b7 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/samples/store-java/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. + +rm -rf tmp +../../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 tmp +../../modules/http/httpd-start tmp diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/stop b/sca-cpp/branches/lightweight-sca/samples/store-java/stop new file mode 100755 index 0000000000..c7a0bff857 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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 tmp diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/store.composite b/sca-cpp/branches/lightweight-sca/samples/store-java/store.composite new file mode 100644 index 0000000000..2795fe1769 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/samples/store-java/store.composite @@ -0,0 +1,69 @@ +<?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" + targetNamespace="http://store" + name="store"> + + <component name="Store"> + <implementation.widget location="store.html"/> + <service name="Widget"> + <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"> + <binding.jsonrpc uri="catalog"/> + </service> + <reference name="currencyConverter" target="CurrencyConverter"/> + </component> + + <component name="ShoppingCart"> + <implementation.java class="store.ShoppingCartImpl"/> + <service name="ShoppingCart"> + <binding.atom uri="shoppingCart"/> + </service> + <service name="Total"> + <binding.jsonrpc uri="total"/> + </service> + <reference name="cache" target="Cache"/> + </component> + + <component name="CurrencyConverter"> + <implementation.java class="store.CurrencyConverterImpl"/> + <service name="CurrencyConverter"> + <binding.jsonrpc uri="currencyConverter"/> + </service> + </component> + + <component name="Cache"> + <implementation.cpp path="../../components/cache" library="libmemcache"/> + <service name="Cache"> + <binding.atom uri="cache"/> + </service> + <property name="server">localhost:11211</property> + </component> + +</composite> diff --git a/sca-cpp/branches/lightweight-sca/samples/store-java/store/CurrencyConverter.java b/sca-cpp/branches/lightweight-sca/samples/store-java/store/CurrencyConverter.java new file mode 100644 index 0000000000..1ed15a670a --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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/sca-cpp/branches/lightweight-sca/samples/store-java/store/CurrencyConverterImpl.java b/sca-cpp/branches/lightweight-sca/samples/store-java/store/CurrencyConverterImpl.java new file mode 100644 index 0000000000..a6d0fd00b3 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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/sca-cpp/branches/lightweight-sca/samples/store-java/store/FruitsCatalogImpl.java b/sca-cpp/branches/lightweight-sca/samples/store-java/store/FruitsCatalogImpl.java new file mode 100644 index 0000000000..8881543103 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/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/sca-cpp/branches/lightweight-sca/samples/store-java/store/ShoppingCartImpl.java b/sca-cpp/branches/lightweight-sca/samples/store-java/store/ShoppingCartImpl.java new file mode 100644 index 0000000000..bd7678cce7 --- /dev/null +++ b/sca-cpp/branches/lightweight-sca/samples/store-java/store/ShoppingCartImpl.java @@ -0,0 +1,113 @@ +/* + * 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("'entry", cadr(car(item)), list("'id", id), cadddr(car(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 list(list("'entry", list("'title", "Item"), list("'id", "0"))); + if(id.equals(cadr(caddr(car(cart))))) + return list(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 list(append(list("'feed", list("'title", "Your Cart"), list("'id", 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) { + System.err.println("price!! " + cadr(cadddr(item))); + return Double.valueOf((String)cadr(assoc("'price", cdr(cadr(cadddr(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); + } + +} |