summaryrefslogtreecommitdiffstats
path: root/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src
diff options
context:
space:
mode:
Diffstat (limited to 'branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src')
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/java/org/apache/tuscany/sca/implementation/widget/tuscany/TuscanyJavaScriptComponentGeneratorImpl.java203
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/resources/META-INF/services/org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator19
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/org/apache/tuscany/sca/implementation/widget/WidgetImplementationTestCase.java48
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/Catalog.java32
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/CatalogImpl.java47
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/ShoppingCartImpl.java124
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/store.html127
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/storeJS.html152
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/unitTests.html250
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widget.composite54
-rw-r--r--branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widgetJS.composite58
11 files changed, 1114 insertions, 0 deletions
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/java/org/apache/tuscany/sca/implementation/widget/tuscany/TuscanyJavaScriptComponentGeneratorImpl.java b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/java/org/apache/tuscany/sca/implementation/widget/tuscany/TuscanyJavaScriptComponentGeneratorImpl.java
new file mode 100644
index 0000000000..21961a9094
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/java/org/apache/tuscany/sca/implementation/widget/tuscany/TuscanyJavaScriptComponentGeneratorImpl.java
@@ -0,0 +1,203 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.widget.tuscany;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator;
+import org.apache.tuscany.sca.web.javascript.JavascriptProxyFactory;
+import org.apache.tuscany.sca.web.javascript.JavascriptProxyFactoryExtensionPoint;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+public class TuscanyJavaScriptComponentGeneratorImpl implements ComponentJavaScriptGenerator {
+ private static final QName NAME = new QName("http://tuscany.apache.org/xmlns/sca/1.0", "component.script.generator.tuscany");
+
+ private JavascriptProxyFactoryExtensionPoint javascriptProxyFactories;
+
+ public TuscanyJavaScriptComponentGeneratorImpl(ExtensionPointRegistry extensionPoints) {
+ this.javascriptProxyFactories = extensionPoints.getExtensionPoint(JavascriptProxyFactoryExtensionPoint.class);
+ }
+
+ public QName getQName() {
+ return NAME;
+ }
+
+ public void generateJavaScriptCode(RuntimeComponent component, PrintWriter pw) throws IOException {
+ pw.println();
+ pw.println("/* Apache Tuscany SCA Widget header */");
+ pw.println();
+
+ Map<String, Boolean> bindingClientProcessed = new HashMap<String, Boolean>();
+
+ for(ComponentReference reference : component.getReferences()) {
+ for(Binding binding : reference.getBindings()) {
+ JavascriptProxyFactory jsProxyFactory = javascriptProxyFactories.getProxyFactory(binding.getClass());
+
+ String bindingProxyName = jsProxyFactory.getJavascriptProxyFile();
+ //check if binding client code was already processed and inject to the generated script
+ if(bindingProxyName != null) {
+ Boolean processedFlag = bindingClientProcessed.get(bindingProxyName);
+ if( processedFlag == null || processedFlag.booleanValue() == false) {
+ generateJavaScriptBindingProxy(jsProxyFactory, pw);
+ bindingClientProcessed.put(bindingProxyName, Boolean.TRUE);
+ }
+ }
+
+ }
+ }
+
+ pw.println();
+ pw.println("/* Tuscany Reference/Property injection code */");
+ pw.println();
+
+
+ //define tuscany.sca namespace
+ generateJavaScriptNamespace(pw);
+
+ pw.println();
+
+ //process properties
+ generateJavaScriptPropertyFunction(component, pw);
+
+ pw.println();
+
+ //process references
+ generateJavaScriptReferenceFunction(component, javascriptProxyFactories,pw);
+
+
+ pw.println();
+ pw.println("/** End of Apache Tuscany SCA Widget */");
+ pw.println();
+ pw.flush();
+ pw.close();
+ }
+
+
+ /**
+ * Retrieve the binding proxy based on the bind name
+ * and embedded the JavaScript into this js
+ */
+ private static void generateJavaScriptBindingProxy(JavascriptProxyFactory javascriptProxyFactory, PrintWriter pw) throws IOException {
+ InputStream is = javascriptProxyFactory.getJavascriptProxyFileAsStream();
+ if (is != null) {
+ int i;
+ while ((i = is.read()) != -1) {
+ pw.write(i);
+ }
+ }
+
+ pw.println();
+ pw.println();
+ }
+
+ /**
+ * Generate the tuscany.sca namespace if not yet available
+ * @param pw
+ * @throws IOException
+ */
+ private static void generateJavaScriptNamespace(PrintWriter pw) throws IOException {
+ pw.println("if (!tuscany) { \n" +
+ "var tuscany = {}; \n" +
+ "}");
+ pw.println("if (!tuscany.sca) { \n" +
+ "tuscany.sca = {}; \n" +
+ "}");
+ }
+
+ /**
+ * Generate JavaScript code to inject SCA Properties
+ * @param pw
+ * @throws IOException
+ */
+ private static void generateJavaScriptPropertyFunction(RuntimeComponent component, PrintWriter pw) throws IOException {
+ pw.println("tuscany.sca.propertyMap = new String();");
+ for(ComponentProperty property : component.getProperties()) {
+ String propertyName = property.getName();
+
+ pw.println("tuscany.sca.propertyMap." + propertyName + " = new String(\"" + getPropertyValue(property) + "\");");
+ }
+
+ pw.println("tuscany.sca.Property = function (name) {");
+ pw.println(" return tuscany.sca.propertyMap[name];");
+ pw.println("}");
+ }
+
+ /**
+ * Convert property value to String
+ * @param property
+ * @return
+ */
+ private static String getPropertyValue(ComponentProperty property) {
+ Document doc = (Document)property.getValue();
+ Element rootElement = doc.getDocumentElement();
+
+ String value = null;
+
+ //FIXME : Provide support for isMany and other property types
+
+ if (rootElement.getChildNodes().getLength() > 0) {
+ value = rootElement.getChildNodes().item(0).getTextContent();
+ }
+
+ return value;
+ }
+
+
+
+ /**
+ * Generate JavaScript code to inject SCA References
+ * @param pw
+ * @throws IOException
+ */
+ private static void generateJavaScriptReferenceFunction (RuntimeComponent component, JavascriptProxyFactoryExtensionPoint javascriptProxyFactories, PrintWriter pw) throws IOException {
+
+ pw.println("tuscany.sca.referenceMap = new Object();");
+ for(ComponentReference reference : component.getReferences()) {
+ Binding binding = reference.getBindings().get(0);
+
+ if (binding != null) {
+
+ String referenceName = reference.getName();
+ JavascriptProxyFactory jsProxyFactory = javascriptProxyFactories.getProxyFactory(binding.getClass());
+
+ pw.println("tuscany.sca.referenceMap." + referenceName + " = new " + jsProxyFactory.createJavascriptReference(reference) + ";");
+
+ }
+ }
+
+ pw.println("tuscany.sca.Reference = function (name) {");
+ pw.println(" return tuscany.sca.referenceMap[name];");
+ pw.println("}");
+ }
+
+
+}
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/resources/META-INF/services/org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/resources/META-INF/services/org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator
new file mode 100644
index 0000000000..b98b940b47
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/main/resources/META-INF/services/org.apache.tuscany.sca.web.javascript.ComponentJavaScriptGenerator
@@ -0,0 +1,19 @@
+# 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.
+
+# Implementation class for the Javascript Generator
+org.apache.tuscany.sca.implementation.widget.tuscany.TuscanyJavaScriptComponentGeneratorImpl \ No newline at end of file
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/org/apache/tuscany/sca/implementation/widget/WidgetImplementationTestCase.java b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/org/apache/tuscany/sca/implementation/widget/WidgetImplementationTestCase.java
new file mode 100644
index 0000000000..3b5c6f89b2
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/org/apache/tuscany/sca/implementation/widget/WidgetImplementationTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * 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 org.apache.tuscany.sca.implementation.widget;
+
+import java.net.Socket;
+
+import junit.framework.TestCase;
+
+import org.apache.tuscany.sca.host.embedded.SCADomain;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class WidgetImplementationTestCase extends TestCase {
+
+ private SCADomain scaDomain;
+
+ @Override
+ protected void setUp() throws Exception {
+ scaDomain = SCADomain.newInstance("widget.composite");
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ scaDomain.close();
+ }
+
+ public void testPing() throws Exception {
+ new Socket("127.0.0.1", 8085);
+ }
+
+}
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/Catalog.java b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/Catalog.java
new file mode 100644
index 0000000000..370474f29f
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/Catalog.java
@@ -0,0 +1,32 @@
+/*
+ * 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 org.osoa.sca.annotations.Remotable;
+
+/**
+ * Interface for the Catalog Service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Remotable
+public interface Catalog {
+ String[] get();
+}
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/CatalogImpl.java b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/CatalogImpl.java
new file mode 100644
index 0000000000..bed053eeee
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/CatalogImpl.java
@@ -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.
+ */
+
+package store;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osoa.sca.annotations.Init;
+
+/**
+ * Implementation of the Catalog Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CatalogImpl implements Catalog {
+ private List<String> catalog = new ArrayList<String>();
+
+ @Init
+ public void init() {
+ catalog.add("Apple - $ 2.99");
+ catalog.add("Orange - $ 3.55");
+ catalog.add("Pear - $ 1.55");
+ }
+
+ public String[] get() {
+ String[] catalogArray = new String[catalog.size()];
+ catalog.toArray(catalogArray);
+ return catalogArray;
+ }
+}
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/ShoppingCartImpl.java b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/ShoppingCartImpl.java
new file mode 100644
index 0000000000..37e8d0161a
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/java/store/ShoppingCartImpl.java
@@ -0,0 +1,124 @@
+/*
+ * 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 java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import org.apache.abdera.Abdera;
+import org.apache.abdera.model.Entry;
+import org.apache.abdera.model.Feed;
+import org.apache.tuscany.sca.binding.atom.collection.Collection;
+import org.apache.tuscany.sca.binding.atom.collection.NotFoundException;
+
+/**
+ * Implementation of a Shopping Cart.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ShoppingCartImpl implements Collection {
+
+ private static Map<String, Entry> cart = new HashMap<String, Entry>();
+
+ public Feed getFeed() {
+ Feed feed = Abdera.getNewFactory().newFeed();
+ feed.setTitle("shopping cart");
+ feed.setSubtitle("Total : " + getTotal());
+
+ for (Entry entry : cart.values()) {
+ feed.addEntry(entry);
+ }
+ return feed;
+ }
+
+ public Feed query(String queryString) {
+ if (queryString.startsWith("name=")) {
+ String name = queryString.substring(5);
+
+ Feed feed = Abdera.getNewFactory().newFeed();
+ feed.setTitle("shopping cart");
+ feed.setSubtitle("Total : " + getTotal());
+
+ for (Entry entry : cart.values()) {
+ if (entry.getTitle().contains(name)) {
+ feed.addEntry(entry);
+ }
+ }
+ return feed;
+
+ } else {
+ return getFeed();
+ }
+ }
+
+ public Entry get(String id) throws NotFoundException {
+ return cart.get(id);
+ }
+
+ public Entry post(Entry entry) {
+ System.out.println("post" + entry);
+ String id = "cart-" + UUID.randomUUID().toString();
+ entry.setId(id);
+
+ entry.addLink(id, "edit");
+ entry.addLink(id, "alternate");
+
+ entry.setUpdated(new Date());
+
+ cart.put(id, entry);
+ return entry;
+ }
+
+ public void put(String id, Entry entry) throws NotFoundException {
+ entry.setUpdated(new Date());
+ cart.put(id, entry);
+ }
+
+ public void delete(String id) throws NotFoundException {
+ if (id.equals(""))
+ cart.clear();
+ else
+ cart.remove(id);
+ }
+
+ private String getTotal() {
+ float total = 0;
+ String currencySymbol = "";
+ if (!cart.isEmpty()) {
+ String item = ((Entry)cart.values().iterator().next()).getContent();
+ // Select first symbol after dash.
+ currencySymbol = item.substring(item.indexOf("-") + 2, item.indexOf("-") + 3);
+ }
+ for (Entry entry : cart.values()) {
+ String item = entry.getContent();
+
+ int index = item.length()-1;
+ char digit;
+ while ((digit = item.charAt(index)) == '.' || Character.isDigit(digit)) {
+ index--;
+ }
+
+ total += Float.valueOf(item.substring(index));
+ }
+ return currencySymbol + String.valueOf(total);
+ }
+}
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/store.html b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/store.html
new file mode 100644
index 0000000000..95b0d10a15
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/store.html
@@ -0,0 +1,127 @@
+<!--
+ * 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>
+
+<!-- one js include per sca component -->
+<script type="text/javascript" src="store.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("Catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("ShoppingCart");
+
+ //@Property
+ var locale = Property("locale");
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++)
+ catalog += '<input name="items" type="checkbox" value="' +
+ items[i] + '">' + items[i]+ ' <br>';
+ document.getElementById('catalog').innerHTML=catalog;
+ }
+
+ function shoppingCart_getResponse(feed) {
+ if (feed != null) {
+ var entries = feed.getElementsByTagName("entry");
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ var item = entries[i].getElementsByTagName("content")[0].firstChild.nodeValue;
+ list += item + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+ document.getElementById('total').innerHTML = feed.getElementsByTagName("subtitle")[0].firstChild.nodeValue;
+ }
+ }
+ 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>cart-item</title><content type="text">'+items[i].value+'</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" action="/ufs/store.html">'+
+ 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 = "";
+ }
+
+ //alert(locale);
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+</script>
+
+</head>
+
+<body>
+<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/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/storeJS.html b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/storeJS.html
new file mode 100644
index 0000000000..2e3d76d9a3
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/storeJS.html
@@ -0,0 +1,152 @@
+<!--
+ * 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>
+
+<!-- one js include per sca component -->
+<!-- For Atom, the Tuscany JavaScript client includes the model for Atom.
+ Using this JavaScript model, users can use syntax such as:
+ item += "name=" + entry.getName() + ", price=" + entry.getContent()
+ rather than
+ item += entries[i].getElementsByTagName("content")[0].firstChild.nodeValue;
+ -->
+<script type="text/javascript" src="storeJS.js"></script>
+
+<script language="JavaScript">
+
+ //@Reference
+ var catalog = new tuscany.sca.Reference("Catalog");
+
+ //@Reference
+ var shoppingCart = new tuscany.sca.Reference("ShoppingCart");
+
+ //@Property
+ var locale = Property("locale");
+
+ function catalog_getResponse(items,exception) {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ var catalog = "";
+ for (var i=0; i<items.length; i++)
+ catalog += '<input name="items" type="checkbox" value="' +
+ items[i] + '">' + items[i]+ ' <br>';
+ document.getElementById('catalog').innerHTML=catalog;
+ }
+
+ function shoppingCart_getResponse(feedDoc) {
+ // var xmlString = new XMLSerializer().serializeToString(feedDoc);
+ // alert("shoppingCart_getResponse feed xml=" + xmlString);
+ var feed = new Feed( feedDoc );
+
+ if (feed != null) {
+ // var entries = feed.getElementsByTagName("entry");
+ var entries = feed.getEntries();
+ var list = "";
+ for (var i=0; i<entries.length; i++) {
+ // var item = entries[i].getElementsByTagName("content")[0].firstChild.nodeValue;
+ var item = entries[ i ].getContent().getText();
+ list += item + ' <br>';
+ }
+ document.getElementById("shoppingCart").innerHTML = list;
+ // document.getElementById('total').innerHTML = feed.getElementsByTagName("subtitle")[0].firstChild.nodeValue;
+ var text = feed.getSubtitle().getText();
+ document.getElementById('total').innerHTML = text;
+ }
+ }
+
+ 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 = new Entry( "cart-item" );
+ entry.setContent( items[i].value );
+ var entryXML = entry.toXML();
+ var entry = '<entry xmlns="http://www.w3.org/2005/Atom"><title>cart-item</title><content type="text">'+items[i].value+'</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" action="/ufs/store.html">'+
+ 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 testFeedtoXML() {
+ if(exception){
+ alert(exception.message);
+ return;
+ }
+ document.getElementById('results').innerHTML = text;
+ }
+
+ //alert(locale);
+ catalog.get(catalog_getResponse);
+ shoppingCart.get("", shoppingCart_getResponse);
+</script>
+
+</head>
+
+<body>
+<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/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/unitTests.html b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/unitTests.html
new file mode 100644
index 0000000000..352dd85508
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/content/unitTests.html
@@ -0,0 +1,250 @@
+<!--
+ * 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>Atom JavaScript Client Unit Tests</title>
+
+<!-- Include Tuscany JavaScript client model for Atom.
+ Using this JavaScript model, users can use syntax such as:
+ item += "name=" + entry.getName() + ", price=" + entry.getContent()
+ rather than
+ item += entries[i].getElementsByTagName("content")[0].firstChild.nodeValue;
+ -->
+<script type="text/javascript" src="atomModel.js"></script>
+
+<script language="JavaScript">
+
+ function testUritoXML() {
+ var test = new Uri( "http://example.org/edit/first-post.atom" );
+ var text = text.toXML();
+ alert( "Uri=" + text );
+ }
+
+ function testEmailtoXML() {
+ var test = new Email( "john.doe@ibm.com" );
+ var text = test.toXML();
+ alert( "Email=" + text );
+ }
+
+ function testIdtoXML() {
+ var test = new Id( "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a" );
+ var text = test.toXML();
+ alert( "Id=" + text );
+ }
+
+ function testLogotoXML() {
+ var test = new Logo( "goofyGraphic.png" );
+ var text = test.toXML();
+ alert( "Logo=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testTexttoXML() {
+ var test = new Text( "This is ordinary text." );
+ var text = test.toXML();
+ alert( "Text=" + text );
+ var test = new Text( "This is <b>HTML</b> text.", "html" );
+ var text = test.toXML( "supertext" );
+ alert( "Text=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testPersontoXML() {
+ var test = new Person( "John Doe", "john.doe@ibm.com" );
+ var text = test.toXML();
+ alert( "Person=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testGeneratortoXML() {
+ var test = new Generator( "Power Station", "http://www.powerstation.com" );
+ var text = test.toXML();
+ alert( "Generator=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testCategorytoXML() {
+ var test = new Category( "CategoryXYZ", "http://www.site.com/?category=CategoryXYZ" );
+ var text = test.toXML();
+ alert( "Category=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testLinktoXML() {
+ var test = new Link( "http://example.org/edit/first-post.atom", "edit" );
+ var text = test.toXML();
+ alert( "Link=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testEntrytoXML() {
+ // <?xml version="1.0"?>
+ // <entry xmlns="http://www.w3.org/2005/Atom">
+ // <title>Atom-Powered Robots Run Amok</title>
+ // <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
+ // <updated>2003-12-13T18:30:02Z</updated>
+ // <author><name>John Doe</name></author>
+ // <content>Some text.</content>
+ // <link rel="edit" href="http://example.org/edit/first-post.atom"/>
+ // </entry>
+
+ var entry = new Entry();
+ entry.setNamespace( "http://www.w3.org/2005/Atom" );
+ entry.setTitle( "Atom-Powered Robots Run Amok" );
+ entry.setId( "urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a" );
+ entry.setUpdated( "2003-12-13T18:30:02Z" );
+ entry.setContent( "Some text." );
+ entry.addAuthor( new Person( "John Doe" ) );
+ entry.addAuthor( new Person( "Mark Pilgrim", "f8dy@example.com" ));
+ entry.addContributor( new Person( "Sam Ruby" ));
+ entry.addContributor( new Person( "Joe Gregorio" ));
+ entry.addLink( new Link( "http://example.org/edit/first-post.atom", "edit" ));
+ var text = entry.toXML();
+
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function testFeedtoXML() {
+ // <feed xmlns="http://www.w3.org/2005/Atom">
+ // <title type="text">dive into mark</title>
+ // <subtitle type="html">A &lt;em&gt;lot&lt;/em&gt; of effort went into making this effortless </subtitle>
+ // <updated>2005-07-31T12:29:29Z</updated>
+ // <id>tag:example.org,2003:3</id>
+ // <link rel="alternate" type="text/html" hreflang="en" href="http://example.org/"/>
+ // <link rel="self" type="application/atom+xml" href="http://example.org/feed.atom"/>
+ // <rights>Copyright (c) 2003, Mark Pilgrim</rights>
+ // <generator uri="http://www.example.com/" version="1.0">Example Toolkit</generator>
+ // <entry>
+ // <title>Atom draft-07 snapshot</title>
+ // <link rel="alternate" type="text/html" href="http://example.org/2005/04/02/atom"/>
+ // <link rel="enclosure" type="audio/mpeg" length="1337" href="http://example.org/audio/ph34r_my_podcast.mp3"/>
+ // <id>tag:example.org,2003:3.2397</id>
+ // <updated>2005-07-31T12:29:29Z</updated>
+ // <published>2003-12-13T08:29:29-04:00</published>
+ // <author><name>Mark Pilgrim</name><uri>http://example.org/</uri><email>f8dy@example.com</email></author>
+ // <contributor><name>Sam Ruby</name></contributor>
+ // <contributor><name>Joe Gregorio</name></contributor>
+ // <content type="xhtml" xml:lang="en" xml:base="http://diveintomark.org/">
+ // <div xmlns="http://www.w3.org/1999/xhtml">
+ // <p><i>[Update: The Atom draft is finished.]</i></p>
+ // </div>
+ // </content>
+ // </entry>
+ // <entry>
+ // <title>Dan Becker's Triathlon Site - Best Hills In Austin</title>
+ // <category term="triathlons"/>
+ // <id>tag:www.io.com,2008-09-05:/~beckerdo/triathlons/besthills.html</id>
+ // <link href="http://www.io.com/~beckerdo/triathlons/besthills.html"/>
+ // <published>2008-09-05T14:09:32-05:00</published>
+ // <updated>2008-09-06T08:49:12-05:00</updated>
+ // <summary type='html'>
+ // &lt;a href='http://www.io.com/~beckerdo/triathlons/besthills.html'&gt;&lt;img src='http://www.io.com/~beckerdo/pictures/LittleDan25.png' width='25' height='25' alt='Little Dan' align='left'&gt;&lt;/a&gt;
+ // A description and Google maps of the best running and biking hills in Austin, Texas.
+ // </summary>
+ // </entry>
+ // </feed>
+
+ var feed = new Feed( "Dive into Mark" );
+ feed.setSubtitle( new Text( "A &lt;em&gt;lot&lt;/em&gt; of effort went into making this effortless", "html" ));
+ feed.setUpdated( "2005-07-31T12:29:29Z" );
+ feed.setId( "tag:example.org,2003:3" );
+ var link = new Link( "http://example.org", "alternate" );
+ link.setMimeType( "text/html" );
+ link.setHRefLang( "en" );
+ feed.addLink( link );
+ feed.addLink( new Link( "http://example.org/feed.atom", "self" ));
+ feed.setRights( "Copyright (c) 2003, Mark Pilgrim" );
+ feed.setGenerator( new Generator( "Example Toolkit", "http://www.example.com/" ));
+ feed.addAuthor( new Person( "Mark Pilgrim", "f8dy@example.com" ));
+ feed.addContributor( new Person( "Sam Ruby" ));
+ feed.addContributor( new Person( "Joe Gregorio" ));
+ // <entry>
+ // <title>Atom draft-07 snapshot</title>
+ // <link rel="alternate" type="text/html" href="http://example.org/2005/04/02/atom"/>
+ // <link rel="enclosure" type="audio/mpeg" length="1337" href="http://example.org/audio/ph34r_my_podcast.mp3"/>
+ // <id>tag:example.org,2003:3.2397</id>
+ // <updated>2005-07-31T12:29:29Z</updated>
+ // <published>2003-12-13T08:29:29-04:00</published>
+ // <author><name>Mark Pilgrim</name><uri>http://example.org/</uri><email>f8dy@example.com</email></author>
+ // <contributor><name>Sam Ruby</name></contributor>
+ // <contributor><name>Joe Gregorio</name></contributor>
+ // <content type="xhtml" xml:lang="en" xml:base="http://diveintomark.org/">
+ // <div xmlns="http://www.w3.org/1999/xhtml">
+ // <p><i>[Update: The Atom draft is finished.]</i></p>
+ // </div>
+ // </content>
+ // </entry>
+ // <entry>
+ // <title>Dan Becker's Triathlon Site - Best Hills In Austin</title>
+ // <category term="triathlons"/>
+ // <id>tag:www.io.com,2008-09-05:/~beckerdo/triathlons/besthills.html</id>
+ // <link href="http://www.io.com/~beckerdo/triathlons/besthills.html"/>
+ // <published>2008-09-05T14:09:32-05:00</published>
+ // <updated>2008-09-06T08:49:12-05:00</updated>
+ // <summary type='html'>
+ // &lt;a href='http://www.io.com/~beckerdo/triathlons/besthills.html'&gt;&lt;img src='http://www.io.com/~beckerdo/pictures/LittleDan25.png' width='25' height='25' alt='Little Dan' align='left'&gt;&lt;/a&gt;
+ // A description and Google maps of the best running and biking hills in Austin, Texas.
+ // </summary>
+ // </entry>
+ // </feed>
+ var entry = new Entry( "Dan Becker's Triathlon Site - Best Hills In Austin" );
+ entry.addCategory( new Category( "running" ));
+ entry.addCategory( new Category( "triathlons" ));
+ entry.setId( "tag:www.io.com,2008-09-05:/~beckerdo/triathlons/besthills.html" );
+ entry.addLink( new Link ( "http://www.io.com/~beckerdo/triathlons/besthills.html" ));
+ entry.setPublished( "2008-09-05T14:09:32-05:00" );
+ entry.setUpdated( "2008-09-06T08:49:12-05:00" );
+ entry.setSummary( new Text (
+ "&lt;a href='http://www.io.com/~beckerdo/triathlons/besthills.html'&gt;&lt;img src='http://www.io.com/~beckerdo/pictures/LittleDan25.png' width='25' height='25' alt='Little Dan' align='left'&gt;&lt;/a&gt;\n" +
+ "A description and Google maps of the best running and biking hills in Austin, Texas.", "html" ));
+ feed.addEntry( entry );
+
+ var text = feed.toXML();
+ alert( "Feed xml=" + text );
+ document.getElementById('results').innerHTML = removeBrackets( text );
+ }
+
+ function removeBrackets( input ) {
+ input = input.replace( /</g, "&lt;" ); // replaceAll
+ input = input.replace( />/g, "&gt;" ); // replaceAll
+ return input;
+ }
+</script>
+</head>
+
+<body>
+<h1>Atom JavaScript Client Unit Tests</h1>
+<p>This document tests the serialization and deserialization of the Atom JavaScript client.
+ <h2>Model to XML Tests</h2>
+ <input type="button" onClick="testUritoXML()" value="Uri to XML"><br>
+ <input type="button" onClick="testEmailtoXML()" value="Email to XML"><br>
+ <input type="button" onClick="testIdtoXML()" value="Id to XML"><br>
+ <input type="button" onClick="testLogotoXML()" value="Logo to XML"><br>
+ <input type="button" onClick="testTexttoXML()" value="Text to XML"><br>
+ <input type="button" onClick="testPersontoXML()" value="Person to XML"><br>
+ <input type="button" onClick="testGeneratortoXML()" value="Generator to XML"><br>
+ <input type="button" onClick="testCategorytoXML()" value="Category to XML"><br>
+ <input type="button" onClick="testLinktoXML()" value="Link to XML"><br>
+ <input type="button" onClick="testEntrytoXML()" value="Entry to XML"><br>
+ <input type="button" onClick="testFeedtoXML()" value="Feed to XML"><br>
+ <h2>Results</h2>
+ <code id="results">
+ </code>
+</body>
+</html>
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widget.composite b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widget.composite
new file mode 100644
index 0000000000..f23d6a20f5
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widget.composite
@@ -0,0 +1,54 @@
+<?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://www.osoa.org/xmlns/sca/1.0"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace="http://sample/resource"
+ xmlns:sr="http://sample/resource"
+ name="resource">
+
+ <component name="store">
+ <tuscany:implementation.widget location="content/store.html"/>
+ <property name="locale">en</property>
+ <service name="Widget">
+ <tuscany:binding.http uri="http://localhost:8085/store"/>
+ </service>
+ <reference name="Catalog" target="Catalog">
+ <tuscany:binding.jsonrpc uri="http://localhost:8085/Catalog"/>
+ </reference>
+ <reference name="ShoppingCart" target="ShoppingCart">
+ <tuscany:binding.atom uri="http://localhost:8085/ShoppingCart"/>
+ </reference>
+ </component>
+
+ <component name="Catalog">
+ <implementation.java class="store.CatalogImpl"/>
+ <service name="Catalog">
+ <tuscany:binding.jsonrpc uri="http://localhost:8085/Catalog"/>
+ </service>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.java class="store.ShoppingCartImpl"/>
+ <service name="Collection">
+ <tuscany:binding.atom uri="http://localhost:8085/ShoppingCart"/>
+ </service>
+ </component>
+
+</composite>
diff --git a/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widgetJS.composite b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widgetJS.composite
new file mode 100644
index 0000000000..e44a56e520
--- /dev/null
+++ b/branches/sca-java-1.5.2/modules/implementation-widget-runtime-tuscany/src/test/resources/widgetJS.composite
@@ -0,0 +1,58 @@
+<?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://www.osoa.org/xmlns/sca/1.0"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace="http://sample/resource"
+ xmlns:sr="http://sample/resource"
+ name="resource">
+
+ <component name="storeJS">
+ <!-- Note: the store.html and storeJS.html clients are similar
+ except that store.html edits the client document using JavaScript
+ and many node queries, and storeJS.html uses the client Atom
+ JavaScript mode (fewer node queries and less XML knowledge needed.-->
+ <tuscany:implementation.widget location="content/storeJS.html"/>
+ <property name="locale">en</property>
+ <service name="Widget">
+ <tuscany:binding.http uri="/storeJS"/>
+ </service>
+ <reference name="Catalog" target="Catalog">
+ <tuscany:binding.jsonrpc uri="/Catalog"/>
+ </reference>
+ <reference name="ShoppingCart" target="ShoppingCart">
+ <tuscany:binding.atom uri="/ShoppingCart"/>
+ </reference>
+ </component>
+
+ <component name="Catalog">
+ <implementation.java class="store.CatalogImpl"/>
+ <service name="Catalog">
+ <tuscany:binding.jsonrpc uri="/Catalog"/>
+ </service>
+ </component>
+
+ <component name="ShoppingCart">
+ <implementation.java class="store.ShoppingCartImpl"/>
+ <service name="Collection">
+ <tuscany:binding.atom uri="/ShoppingCart"/>
+ </service>
+ </component>
+
+</composite>