summaryrefslogtreecommitdiffstats
path: root/sandbox/samples/extending-tuscany/implementation-sample
diff options
context:
space:
mode:
authorfmoga <fmoga@13f79535-47bb-0310-9956-ffa450edef68>2010-09-20 13:58:03 +0000
committerfmoga <fmoga@13f79535-47bb-0310-9956-ffa450edef68>2010-09-20 13:58:03 +0000
commited2c314c5370e94e5dfbd23bd6ff6fdebd8dd9b0 (patch)
treeed86d8e7e881cb67f20419ee47caa7bd385633da /sandbox/samples/extending-tuscany/implementation-sample
parent3c85b4d299bc319beb54f1133d1776a763cb22ea (diff)
Moved more samples.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@998932 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sandbox/samples/extending-tuscany/implementation-sample')
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/README8
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/pom.xml79
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/Java.java34
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDL.java34
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDLReference.java28
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/EmbedUtil.java311
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/ImplUtil.java148
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementation.java41
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementationProcessor.java174
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleJavaInvoker.java52
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProvider.java91
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProviderFactory.java48
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLInvoker.java56
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLProxy.java57
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor20
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchema18
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory20
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/sample/impl/sample.xsd38
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Client.java35
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/ClientTest.java65
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Hello.java33
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/JelloTest.java40
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Upper.java33
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/UpperTest.java37
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/WelloTest.java59
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Xutil.java225
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/EmbedTestCase.java151
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/ReadWriteTestCase.java84
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunTestCase.java75
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunWSTestCase.java120
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/TestUtil.java31
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Hello.wsdl62
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Upper.wsdl62
-rw-r--r--sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/test.composite60
34 files changed, 2429 insertions, 0 deletions
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/README b/sandbox/samples/extending-tuscany/implementation-sample/README
new file mode 100644
index 0000000000..3c3ef5e3d5
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/README
@@ -0,0 +1,8 @@
+Sample Implementation Extension
+===============================
+This sample demonstrates how to develop a new component implementation type
+for Apache Tuscany SCA.
+
+The README in the samples directory (the directory above this) provides
+instructions about building and running the samples. Take a look there.
+
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/pom.xml b/sandbox/samples/extending-tuscany/implementation-sample/pom.xml
new file mode 100644
index 0000000000..47aff7e941
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/pom.xml
@@ -0,0 +1,79 @@
+<?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.
+-->
+<project>
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-samples</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>sample-implementation-extension</artifactId>
+ <name>Apache Tuscany SCA Sample Implementation Extension</name>
+ <packaging>jar</packaging>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-feature-api</artifactId>
+ <type>pom</type>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-feature-core</artifactId>
+ <type>pom</type>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-feature-webservice</artifactId>
+ <type>pom</type>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-feature-web20</artifactId>
+ <type>pom</type>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-host-webapp</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.8.1</version>
+ <scope>test</scope>
+ </dependency>
+
+ </dependencies>
+
+ <build>
+ <finalName>${artifactId}</finalName>
+ </build>
+</project>
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/Java.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/Java.java
new file mode 100644
index 0000000000..6c9240005f
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/Java.java
@@ -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.
+ */
+
+package sample.api;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target( {TYPE, FIELD})
+@Retention(RUNTIME)
+public @interface Java {
+
+ Class<?> value();
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDL.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDL.java
new file mode 100644
index 0000000000..655770ec32
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDL.java
@@ -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.
+ */
+
+package sample.api;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Target( {TYPE, FIELD})
+@Retention(RUNTIME)
+public @interface WSDL {
+
+ String value();
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDLReference.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDLReference.java
new file mode 100644
index 0000000000..cad8478a2a
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/api/WSDLReference.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 sample.api;
+
+import org.w3c.dom.Element;
+
+public interface WSDLReference {
+
+ Element call(String op, Element e);
+
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/EmbedUtil.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/EmbedUtil.java
new file mode 100644
index 0000000000..0ccbcc9e36
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/EmbedUtil.java
@@ -0,0 +1,311 @@
+/*
+ * 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 sample.impl;
+
+import java.net.URI;
+import java.net.URL;
+import java.util.Arrays;
+
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLObject;
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+
+/**
+ * A few utility functions to help embed a Tuscany runtime, and a simple DSL
+ * to help assemble and run SCDL.
+ */
+public class EmbedUtil {
+
+ /**
+ * A runtime embedder context, which conveniently initializes a Node factory
+ * and gets the various registries, factories and extension points we need.
+ */
+ static class Context {
+ final NodeFactory nf;
+ final ExtensionPointRegistry epr;
+ final FactoryExtensionPoint fep;
+ final ContributionFactory cf;
+ final AssemblyFactory af;
+ final JavaInterfaceFactory jif;
+ final WSDLFactory wif;
+ final URLArtifactProcessorExtensionPoint apep;
+ final ExtensibleURLArtifactProcessor aproc;
+ final ModelResolverExtensionPoint mrep;
+ final ProviderFactoryExtensionPoint pfep;
+
+ Context(final NodeFactory nf) {
+ this.nf = nf;
+ epr = nf.getExtensionPointRegistry();
+ fep = epr.getExtensionPoint(FactoryExtensionPoint.class);
+ cf = fep.getFactory(ContributionFactory.class);
+ af = fep.getFactory(AssemblyFactory.class);
+ jif = fep.getFactory(JavaInterfaceFactory.class);
+ wif = fep.getFactory(WSDLFactory.class);
+ apep = epr.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+ aproc = new ExtensibleURLArtifactProcessor(apep);
+ mrep = epr.getExtensionPoint(ModelResolverExtensionPoint.class);
+ pfep = epr.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+ }
+ }
+
+ static Context embedContext(NodeFactory nf) {
+ return new Context(nf);
+ }
+
+ /**
+ * A mini DSL to help build and assemble contributions and SCDL composites.
+ */
+ interface Builder<T> {
+ T build(Context ec);
+ }
+
+ static <T> T build(final Builder<T> builder, final Context ec) {
+ return builder.build(ec);
+ }
+
+ /**
+ * Return a contribution builder.
+ */
+ static Builder<Contribution> contrib(final String uri, final String loc, final Builder<Artifact>... artifacts) {
+ return new Builder<Contribution>() {
+ public Contribution build(final Context ec) {
+ final Contribution c = ec.cf.createContribution();
+ c.setURI(uri);
+ c.setLocation(loc);
+ c.setModelResolver(new ExtensibleModelResolver(c, ec.mrep, ec.fep));
+ for(Builder<Artifact> a: artifacts)
+ c.getArtifacts().add(a.build(ec));
+ return c;
+ }
+ };
+ }
+
+ /**
+ * Return an artifact builder.
+ */
+ static Builder<Artifact> artifact(final String uri, final Object model) {
+ return new Builder<Artifact>() {
+ public Artifact build(final Context ec) {
+ final Artifact a = ec.cf.createArtifact();
+ a.setURI(uri);
+ a.setModel(model);
+ return a;
+ }
+ };
+ }
+
+ /**
+ * Return a composite builder.
+ */
+ static Builder<Composite> composite(final String ns, final String name, final Builder<Component>... components) {
+ return new Builder<Composite>() {
+ public Composite build(final Context ec) {
+ final Composite compos = ec.af.createComposite();
+ compos.setName(new QName(ns, name));
+ for(final Builder<Component> c: components)
+ compos.getComponents().add(c.build(ec));
+ return compos;
+ }
+ };
+ }
+
+ /**
+ * Return a component builder.
+ */
+ static Builder<Component> component(final String name, final Builder<Implementation> impl, final Builder<ComponentReference>... references) {
+ return new Builder<Component>() {
+ public Component build(final Context ec) {
+ final Component c = ec.af.createComponent();
+ c.setName(name);
+ c.setImplementation(impl.build(ec));
+ for(Builder<ComponentReference> r: references)
+ c.getReferences().add(r.build(ec));
+ return c;
+ }
+ };
+ }
+
+ /**
+ * Return an implementation builder.
+ */
+ static Builder<Implementation> implementation(final Class<?> clazz, final Builder<Contract>... contracts) {
+ return new Builder<Implementation>() {
+ public SampleImplementation build(final Context ec) {
+ final SampleImplementation impl = ImplUtil.implementation(clazz.getName());
+ impl.clazz = clazz;
+ impl.setUnresolved(false);
+ for(final Builder<Contract> b: contracts) {
+ Contract c = b.build(ec);
+ if(c instanceof Service)
+ impl.getServices().add((Service)c);
+ else
+ impl.getReferences().add((Reference)c);
+ }
+ return impl;
+ }
+ };
+ }
+
+ /**
+ * Return a reference builder.
+ */
+ static Builder<Contract> reference(final String name, final Class<?> c) {
+ return new Builder<Contract>() {
+ public Reference build(final Context ec) {
+ try {
+ return ImplUtil.reference(name, c, ec.jif, ec.af);
+ } catch(InvalidInterfaceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ static Builder<Contract> reference(final String name, final WSDLInterface c) {
+ return new Builder<Contract>() {
+ public Reference build(final Context ec) {
+ return ImplUtil.reference(name, c, ec.wif, ec.af);
+ }
+ };
+ }
+
+ static Builder<ComponentReference> reference(final String name, final String target) {
+ return new Builder<ComponentReference>() {
+ public ComponentReference build(final Context ec) {
+ final ComponentReference r = ec.af.createComponentReference();
+ r.setName(name);
+ final ComponentService s = ec.af.createComponentService();
+ s.setUnresolved(true);
+ s.setName(target);
+ r.getTargets().add(s);
+ return r;
+ }
+ };
+ }
+
+ /**
+ * Return a service builder.
+ */
+ static Builder<Contract> service(final Class<?> c) {
+ return new Builder<Contract>() {
+ public Service build(final Context ec) {
+ try {
+ return ImplUtil.service(c, ec.jif, ec.af);
+ } catch(InvalidInterfaceException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ static Builder<Contract> service(final WSDLInterface c) {
+ return new Builder<Contract>() {
+ public Service build(final Context ec) {
+ return ImplUtil.service(c, ec.wif, ec.af);
+ }
+ };
+ }
+
+ /**
+ * Return a WSDLInterface builder which loads a WSDL into a contribution.
+ */
+ static Builder<WSDLInterface> wsdli(final String uri, final String ns, final String name, final Contribution c) {
+ return new Builder<WSDLInterface>() {
+ public WSDLInterface build(final Context ec) {
+ try {
+ final ProcessorContext ctx = new ProcessorContext();
+ final WSDLDefinition wd = ec.aproc.read(null, new URI(uri), new URL(new URL(c.getLocation()), uri), ctx, WSDLDefinition.class);
+ c.getModelResolver().addModel(wd, ctx);
+ c.getModelResolver().resolveModel(WSDLDefinition.class, wd, ctx);
+ final WSDLObject<PortType> pt = wd.getWSDLObject(PortType.class, new QName(ns, name));
+ if(pt == null)
+ throw new ContributionResolveException("Couldn't find " + name);
+ final WSDLInterface nwi = ec.wif.createWSDLInterface(pt.getElement(), wd, c.getModelResolver(), null);
+ nwi.setWsdlDefinition(wd);
+ nwi.resetDataBinding(DOMDataBinding.NAME);
+ return nwi;
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
+ /**
+ * Return the extension point registry used by our nodes.
+ */
+ static ExtensionPointRegistry extensionPoints(final Context ec) {
+ return ec.epr;
+ }
+
+ /**
+ * Return the provider factory extension point used by our nodes.
+ */
+ static ProviderFactoryExtensionPoint providerFactories(final Context ec) {
+ return ec.pfep;
+ }
+
+ /**
+ * Add a deployable composite to a contribution.
+ */
+ static Contribution deploy(final Contribution contrib, final Composite... comps) {
+ for(Composite c: comps)
+ contrib.getDeployables().add(c);
+ return contrib;
+ }
+
+ /**
+ * Configure a node with a list of contributions.
+ */
+ static Node node(final NodeFactory nf, final Contribution... contributions) {
+ return nf.createNode(Arrays.asList(contributions));
+ }
+
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/ImplUtil.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/ImplUtil.java
new file mode 100644
index 0000000000..abd4cd7ab0
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/ImplUtil.java
@@ -0,0 +1,148 @@
+/*
+ * 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 sample.impl;
+
+import java.lang.annotation.Annotation;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceContract;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterfaceContract;
+
+import sample.api.Java;
+import sample.api.WSDL;
+
+/**
+ * Utility functions to help develop a component implementation extension.
+ */
+class ImplUtil {
+
+ /**
+ * Return a Sample implementation with the given name.
+ */
+ static SampleImplementation implementation(String name) {
+ final SampleImplementation impl = new SampleImplementation(name);
+ impl.setUnresolved(true);
+ return impl;
+ }
+
+ /**
+ * Return the Java class configured on an annotation.
+ */
+ static Class<?> clazz(final Annotation a) {
+ return ((Java)a).value();
+ }
+
+ /**
+ * Return the WSDL QName configured on an annotation.
+ */
+ static QName qname(final Annotation a) {
+ final String uri = ((WSDL)a).value();
+ final int h = uri.indexOf('#');
+ return new QName(uri.substring(0, h), uri.substring(h + 1));
+ }
+
+ /**
+ * Convert a Java class to an interface contract.
+ */
+ static JavaInterfaceContract contract(final Class<?> c, final JavaInterfaceFactory jif) throws InvalidInterfaceException {
+ final JavaInterfaceContract ic = jif.createJavaInterfaceContract();
+ ic.setInterface(jif.createJavaInterface(c));
+ return ic;
+ }
+
+ /**
+ * Convert a WSDL interface to an interface contract.
+ */
+ static WSDLInterfaceContract contract(final WSDLInterface wi, final WSDLFactory wf) {
+ final WSDLInterfaceContract ic = wf.createWSDLInterfaceContract();
+ ic.setInterface(wi);
+ return ic;
+ }
+
+ /**
+ * Convert a Java class to a service.
+ */
+ static Service service(final Class<?> c, final JavaInterfaceFactory jif, final AssemblyFactory af) throws InvalidInterfaceException {
+ Service s = af.createService();
+ s.setName(c.getSimpleName());
+ s.setInterfaceContract(contract(c, jif));
+ return s;
+ }
+
+ /**
+ * Convert a WSDL interface to a service.
+ */
+ static Service service(final WSDLInterface wi, final WSDLFactory wf, final AssemblyFactory af) {
+ Service s = af.createService();
+ s.setName(wi.getName().getLocalPart());
+ s.setInterfaceContract(contract(wi, wf));
+ return s;
+ }
+
+ /**
+ * Convert a name and Java class to a reference.
+ */
+ static Reference reference(final String name, final Class<?> c, final JavaInterfaceFactory jif, final AssemblyFactory af) throws InvalidInterfaceException {
+ final Reference r = af.createReference();
+ r.setName(name);
+ r.setInterfaceContract(contract(c, jif));
+ return r;
+ }
+
+ /**
+ * Convert a name and WSDL interface to a reference.
+ */
+ static Reference reference(final String name, final WSDLInterface wi, final WSDLFactory wf, final AssemblyFactory af) {
+ final Reference r = af.createReference();
+ r.setName(name);
+ r.setInterfaceContract(contract(wi, wf));
+ return r;
+ }
+
+ /**
+ * Convert a WSDL qname to a WSDL interface.
+ */
+ static WSDLInterface interfaze(final QName name, final WSDLFactory wif) {
+ final WSDLInterface wir = wif.createWSDLInterface();
+ wir.setUnresolved(true);
+ wir.setName(name);
+ return wir;
+ }
+
+ /**
+ * Convert a WSDL qname to a WSDL definition.
+ */
+ static WSDLDefinition definition(final QName name, final WSDLFactory wif) {
+ final WSDLDefinition wdr = wif.createWSDLDefinition();
+ wdr.setUnresolved(true);
+ wdr.setNamespace(name.getNamespaceURI());
+ wdr.setNameOfPortTypeToResolve(name);
+ return wdr;
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementation.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementation.java
new file mode 100644
index 0000000000..41ce71a732
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementation.java
@@ -0,0 +1,41 @@
+/*
+ * 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 sample.impl;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.impl.ImplementationImpl;
+
+/**
+ * Model representing a Sample implementation in an SCA assembly.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SampleImplementation extends ImplementationImpl {
+ static final QName QN = new QName(SCA11_TUSCANY_NS, "implementation.sample");
+
+ final String name;
+ Class<?> clazz;
+
+ SampleImplementation(final String name) {
+ super(QN);
+ this.name = name;
+ }
+
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementationProcessor.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementationProcessor.java
new file mode 100644
index 0000000000..6017030d35
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleImplementationProcessor.java
@@ -0,0 +1,174 @@
+/*
+ * 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 sample.impl;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static sample.impl.SampleImplementation.QN;
+import static sample.impl.ImplUtil.clazz;
+import static sample.impl.ImplUtil.definition;
+import static sample.impl.ImplUtil.implementation;
+import static sample.impl.ImplUtil.interfaze;
+import static sample.impl.ImplUtil.qname;
+import static sample.impl.ImplUtil.reference;
+import static sample.impl.ImplUtil.service;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+
+import javax.wsdl.PortType;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.databinding.xml.DOMDataBinding;
+import org.apache.tuscany.sca.interfacedef.InvalidInterfaceException;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLFactory;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLObject;
+
+import sample.api.Java;
+import sample.api.WSDL;
+
+/**
+ * StAX artifact processor for Sample implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SampleImplementationProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<SampleImplementation> {
+ final AssemblyFactory af;
+ final JavaInterfaceFactory jif;
+ final WSDLFactory wf;
+
+ public SampleImplementationProcessor(final ExtensionPointRegistry ep) {
+ final FactoryExtensionPoint fep = ep.getExtensionPoint(FactoryExtensionPoint.class);
+ this.af = fep.getFactory(AssemblyFactory.class);
+ this.jif = fep.getFactory(JavaInterfaceFactory.class);
+ this.wf = fep.getFactory(WSDLFactory.class);
+ }
+
+ public QName getArtifactType() {
+ return QN;
+ }
+
+ public Class<SampleImplementation> getModelType() {
+ return SampleImplementation.class;
+ }
+
+ public SampleImplementation read(final XMLStreamReader r, final ProcessorContext ctx) throws ContributionReadException, XMLStreamException {
+ // Read the component implementation element
+ final SampleImplementation impl = implementation(r.getAttributeValue(null, "class"));
+ while(r.hasNext() && !(r.next() == END_ELEMENT && QN.equals(r.getName())))
+ ;
+ return impl;
+ }
+
+ public void resolve(final SampleImplementation impl, final ModelResolver res, final ProcessorContext ctx) throws ContributionResolveException {
+ try {
+ // Resolve and introspect the implementation class
+ impl.clazz = resolve(impl.name, res, ctx);
+
+ for(final Annotation a: impl.clazz.getAnnotations()) {
+ if(a instanceof Java)
+ impl.getServices().add(service(clazz(a), jif, af));
+ else if(a instanceof WSDL)
+ impl.getServices().add(service(resolve(qname(a), res, ctx, wf), wf, af));
+ }
+
+ for(Field f: impl.clazz.getDeclaredFields()) {
+ for(final Annotation a: f.getAnnotations()) {
+ if(a instanceof Java)
+ impl.getReferences().add(reference(f.getName(), clazz(a), jif, af));
+ else if(a instanceof WSDL)
+ impl.getReferences().add(reference(f.getName(), resolve(qname(a), res, ctx, wf), wf, af));
+ }
+ }
+
+ impl.setUnresolved(false);
+ } catch(InvalidInterfaceException e) {
+ throw new ContributionResolveException(e);
+ }
+ }
+
+ public void write(final SampleImplementation impl, final XMLStreamWriter w, final ProcessorContext ctx) throws ContributionWriteException, XMLStreamException {
+ writeStart(w, QN.getNamespaceURI(), QN.getLocalPart(), new XAttr("class", impl.name));
+ writeEnd(w);
+ }
+
+ /**
+ * Resolve a Java class.
+ */
+ static Class<?> resolve(final String name, final ModelResolver res, final ProcessorContext ctx) throws ContributionResolveException {
+ final ClassReference cr = res.resolveModel(ClassReference.class, new ClassReference(name), ctx);
+ if(cr.getJavaClass() != null)
+ return cr.getJavaClass();
+ throw new ContributionResolveException(new ClassNotFoundException(name));
+ }
+
+ /**
+ * Resolve a WSDL interface.
+ */
+ static WSDLInterface resolve(final QName name, final ModelResolver res, final ProcessorContext ctx, final WSDLFactory wif) throws ContributionResolveException {
+ final WSDLInterface wi = res.resolveModel(WSDLInterface.class, interfaze(name, wif), ctx);
+ if(!wi.isUnresolved())
+ return domBound(wi);
+
+ final WSDLDefinition wd = res.resolveModel(WSDLDefinition.class, definition(wi.getName(), wif), ctx);
+ if(wd.isUnresolved())
+ throw new ContributionResolveException("Couldn't find " + name.getNamespaceURI());
+
+ WSDLObject<PortType> pt = wd.getWSDLObject(PortType.class, name);
+ if(pt == null)
+ throw new ContributionResolveException("Couldn't find " + name);
+ try {
+ final WSDLInterface nwi = wif.createWSDLInterface(pt.getElement(), wd, res, ctx.getMonitor());
+ nwi.setWsdlDefinition(wd);
+ res.addModel(nwi, ctx);
+ return domBound(nwi);
+ } catch(InvalidInterfaceException e) {
+ throw new ContributionResolveException(e);
+ }
+ }
+
+ /**
+ * Return a WSDL interface configured to use a DOM databinding.
+ */
+ static WSDLInterface domBound(WSDLInterface wi) throws ContributionResolveException {
+ try {
+ final WSDLInterface domwi = (WSDLInterface)wi.clone();
+ domwi.resetDataBinding(DOMDataBinding.NAME);
+ return domwi;
+ } catch(CloneNotSupportedException e) {
+ throw new ContributionResolveException(e);
+ }
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleJavaInvoker.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleJavaInvoker.java
new file mode 100644
index 0000000000..244251c4c9
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleJavaInvoker.java
@@ -0,0 +1,52 @@
+/*
+ * 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 sample.impl;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+
+/**
+ * Invoker for Sample components that implement a Java interface.
+ *
+ * @version $Rev$ $Date$
+ */
+class SampleJavaInvoker implements Invoker {
+ final Object instance;
+ final Method method;
+
+ SampleJavaInvoker(final JavaOperation op, final Class<?> clazz, final Object instance) throws SecurityException, NoSuchMethodException {
+ this.instance = instance;
+ this.method = clazz.getMethod(op.getJavaMethod().getName(), op.getJavaMethod().getParameterTypes());
+ }
+
+ public Message invoke(final Message msg) {
+ try {
+ // Call the method that implements the operation
+ msg.setBody(method.invoke(instance, (Object[])msg.getBody()));
+ } catch(Exception e) {
+ e.printStackTrace();
+ msg.setFaultBody(e.getCause());
+ }
+ return msg;
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProvider.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProvider.java
new file mode 100644
index 0000000000..5d946b037b
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProvider.java
@@ -0,0 +1,91 @@
+/*
+ * 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 sample.impl;
+
+import java.lang.reflect.Field;
+
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.interfacedef.java.JavaOperation;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLOperation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentService;
+
+/**
+ * Implementation provider for Sample component implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+class SampleProvider implements ImplementationProvider {
+ final RuntimeComponent comp;
+ final SampleImplementation impl;
+ final ProxyFactory pxf;
+ Object instance;
+
+ SampleProvider(final RuntimeComponent comp, final SampleImplementation impl, ProxyFactory pf) {
+ this.comp = comp;
+ this.impl = impl;
+ this.pxf = pf;
+ }
+
+ public void start() {
+ // Construct implementation instance and inject reference proxies
+ try {
+ instance = impl.clazz.newInstance();
+
+ for(ComponentReference r: comp.getReferences()) {
+ final Field f = impl.clazz.getDeclaredField(r.getName());
+ f.setAccessible(true);
+ // Inject a Java or WSDLReference proxy
+ final Interface i = r.getInterfaceContract().getInterface();
+ if(i instanceof JavaInterface)
+ f.set(instance, pxf.createProxy(comp.getComponentContext().getServiceReference(f.getType(), r.getName())));
+ else
+ f.set(instance, new SampleWSDLProxy(r.getEndpointReferences().get(0), i));
+ }
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void stop() {
+ instance = null;
+ }
+
+ public boolean supportsOneWayInvocation() {
+ return false;
+ }
+
+ public Invoker createInvoker(final RuntimeComponentService s, final Operation op) {
+ try {
+ // Creating an invoker for a Java or WSDL-typed implementation
+ if(op instanceof JavaOperation)
+ return new SampleJavaInvoker((JavaOperation)op, impl.clazz, instance);
+ return new SampleWSDLInvoker((WSDLOperation)op, impl.clazz, instance);
+ } catch(Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProviderFactory.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProviderFactory.java
new file mode 100644
index 0000000000..4ad24d33ff
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleProviderFactory.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 sample.impl;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ImplementationProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+
+/**
+ * Factory for Sample implementation providers.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SampleProviderFactory implements ImplementationProviderFactory<SampleImplementation> {
+ final ProxyFactory pxf;
+
+ public SampleProviderFactory(final ExtensionPointRegistry ep) {
+ pxf = ExtensibleProxyFactory.getInstance(ep);
+ }
+
+ public ImplementationProvider createImplementationProvider(final RuntimeComponent comp, final SampleImplementation impl) {
+ return new SampleProvider(comp, impl, pxf);
+ }
+
+ public Class<SampleImplementation> getModelType() {
+ return SampleImplementation.class;
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLInvoker.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLInvoker.java
new file mode 100644
index 0000000000..6c5317274f
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLInvoker.java
@@ -0,0 +1,56 @@
+/*
+ * 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 sample.impl;
+
+import java.lang.reflect.Method;
+
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLOperation;
+import org.apache.tuscany.sca.invocation.Invoker;
+import org.apache.tuscany.sca.invocation.Message;
+import org.w3c.dom.Element;
+
+/**
+ * Invoker for Sample components that implement a WSDL interface using a generic
+ * call method.
+ *
+ * @version $Rev$ $Date$
+ */
+class SampleWSDLInvoker implements Invoker {
+ final String name;
+ final Object instance;
+ final Method method;
+
+ SampleWSDLInvoker(final WSDLOperation op, final Class<?> clazz, final Object instance) throws SecurityException, NoSuchMethodException {
+ this.name = op.getName();
+ this.instance = instance;
+ this.method = clazz.getMethod("call", String.class, Element.class);
+ }
+
+ public Message invoke(final Message msg) {
+ try {
+ // Invoke the generic call method
+ msg.setBody(method.invoke(instance, name, ((Object[])msg.getBody())[0]));
+ } catch(Exception e) {
+ e.printStackTrace();
+ msg.setFaultBody(e.getCause());
+ }
+ return msg;
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLProxy.java b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLProxy.java
new file mode 100644
index 0000000000..a6882a0103
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/java/sample/impl/SampleWSDLProxy.java
@@ -0,0 +1,57 @@
+/*
+ * 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 sample.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.EndpointReference;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.runtime.RuntimeEndpointReference;
+import org.w3c.dom.Element;
+
+import sample.api.WSDLReference;
+
+/**
+ * Proxy used to call operations on WSDL references.
+ */
+class SampleWSDLProxy implements WSDLReference {
+ final RuntimeEndpointReference repr;
+ final Map<String, Operation> ops;
+
+ SampleWSDLProxy(EndpointReference epr, Interface wi) {
+ repr = (RuntimeEndpointReference)epr;
+ ops = new HashMap<String, Operation>();
+ for(Operation o: wi.getOperations())
+ ops.put(o.getName(), o);
+ }
+
+ @Override
+ public Element call(String op, Element e) {
+ try {
+ // Invoke the named operation on the endpoint reference
+ return (Element)repr.invoke(ops.get(op), new Object[] {e});
+ } catch(InvocationTargetException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..908ac95a2e
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,20 @@
+# 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 artifact processor extension
+sample.impl.SampleImplementationProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#implementation.sample,model=sample.impl.SampleImplementation
+
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchema b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchema
new file mode 100644
index 0000000000..85aff44074
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.ValidationSchema
@@ -0,0 +1,18 @@
+# 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.
+#
+sample/impl/sample.xsd
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
new file mode 100644
index 0000000000..32a7efcaf9
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/META-INF/services/org.apache.tuscany.sca.provider.ImplementationProviderFactory
@@ -0,0 +1,20 @@
+# 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 provider for Sample components
+sample.impl.SampleProviderFactory;model=sample.impl.SampleImplementation
+
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/sample/impl/sample.xsd b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/sample/impl/sample.xsd
new file mode 100644
index 0000000000..c057aef1c1
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/main/resources/sample/impl/sample.xsd
@@ -0,0 +1,38 @@
+<?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.
+-->
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://tuscany.apache.org/xmlns/sca/1.1"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1"
+ elementFormDefault="qualified">
+
+ <import namespace="http://docs.oasis-open.org/ns/opencsa/sca/200912"/>
+
+ <element name="implementation.sample" type="t:SampleImplementation" substitutionGroup="sca:implementation"/>
+
+ <complexType name="SampleImplementation">
+ <complexContent>
+ <extension base="sca:Implementation">
+ <attribute name="class" type="string" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Client.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Client.java
new file mode 100644
index 0000000000..1b7e11c786
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Client.java
@@ -0,0 +1,35 @@
+/*
+ * 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 sample;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Sample service interface.
+ *
+ * @version $Rev$ $Date$
+ */
+@Remotable
+public interface Client {
+
+ String jello(String s);
+
+ String wello(String s);
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/ClientTest.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/ClientTest.java
new file mode 100644
index 0000000000..92291c98a1
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/ClientTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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 sample;
+
+import static java.lang.System.out;
+import static sample.Xutil.elem;
+import static sample.Xutil.elems;
+import static sample.Xutil.print;
+import static sample.Xutil.select;
+import static sample.Xutil.text;
+import static sample.Xutil.xdom;
+import static sample.Xutil.xfilter;
+import static sample.Xutil.xreduce;
+
+import org.w3c.dom.Element;
+
+import sample.api.Java;
+import sample.api.WSDL;
+import sample.api.WSDLReference;
+
+/**
+ * Sample component implementation that uses a mix of Java and WSDL interfaces.
+ *
+ * @version $Rev$ $Date$
+ */
+@Java(Client.class)
+public class ClientTest {
+
+ @Java(Hello.class)
+ Hello jello;
+
+ @WSDL("http://sample/hello#Hello")
+ WSDLReference wello;
+
+ public String jello(String s) {
+ out.println("ClientTest.jello(" + s + ")");
+ return jello.hello(s);
+ }
+
+ public String wello(String s) {
+ out.println("ClientTest.wello(" + s + ")");
+ final Element hreq = xdom("http://sample/hello", "hello", elem("name", text(s)));
+
+ final Element hres = wello.call("hello", hreq);
+
+ return xreduce(print, "", xfilter(select("result"), elems(hres)));
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Hello.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Hello.java
new file mode 100644
index 0000000000..247fc8aa78
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Hello.java
@@ -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.
+ */
+
+package sample;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Sample service interface.
+ *
+ * @version $Rev$ $Date$
+ */
+@Remotable
+public interface Hello {
+
+ String hello(String s);
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/JelloTest.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/JelloTest.java
new file mode 100644
index 0000000000..5c999a6c80
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/JelloTest.java
@@ -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.
+ */
+
+package sample;
+
+import static java.lang.System.out;
+import sample.api.Java;
+
+/**
+ * Sample component implementation that uses Java interfaces.
+ *
+ * @version $Rev$ $Date$
+ */
+@Java(Hello.class)
+public class JelloTest {
+
+ @Java(Upper.class)
+ Upper upper;
+
+ public String hello(String s) {
+ out.println("JelloTest.hello(" + s + ")");
+ return upper.upper("Hello " + s);
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Upper.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Upper.java
new file mode 100644
index 0000000000..9c772b3487
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Upper.java
@@ -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.
+ */
+
+package sample;
+
+import org.oasisopen.sca.annotation.Remotable;
+
+/**
+ * Sample service interface.
+ *
+ * @version $Rev$ $Date$
+ */
+@Remotable
+public interface Upper {
+
+ String upper(String s);
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/UpperTest.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/UpperTest.java
new file mode 100644
index 0000000000..5399e4410d
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/UpperTest.java
@@ -0,0 +1,37 @@
+/*
+ * 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 sample;
+
+import static java.lang.System.out;
+import sample.api.Java;
+
+/**
+ * Sample component implementation that uses Java interfaces.
+ *
+ * @version $Rev$ $Date$
+ */
+@Java(Upper.class)
+public class UpperTest {
+
+ public String upper(String s) {
+ out.println("UpperTest.upper(" + s + ")");
+ return s.toUpperCase();
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/WelloTest.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/WelloTest.java
new file mode 100644
index 0000000000..1bb9fc11ce
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/WelloTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 sample;
+
+import static java.lang.System.out;
+import static sample.Xutil.elem;
+import static sample.Xutil.elems;
+import static sample.Xutil.print;
+import static sample.Xutil.select;
+import static sample.Xutil.text;
+import static sample.Xutil.xdom;
+import static sample.Xutil.xfilter;
+import static sample.Xutil.xml;
+import static sample.Xutil.xreduce;
+
+import org.w3c.dom.Element;
+
+import sample.api.WSDL;
+import sample.api.WSDLReference;
+
+/**
+ * Sample component implementation that uses WSDL interfaces.
+ *
+ * @version $Rev$ $Date$
+ */
+@WSDL("http://sample/hello#Hello")
+public class WelloTest {
+
+ @WSDL("http://sample/upper#Upper")
+ WSDLReference upper;
+
+ public Element call(String op, Element e) {
+ out.println("WelloTest." + op + "(" + xml(e) + ")");
+ final String name = xreduce(print, "", xfilter(select("name"), elems(e)));
+
+ final Element ureq = xdom("http://sample/upper", "upper", elem("s", text("Hello " + name)));
+ final Element ures = upper.call("upper", ureq);
+
+ final String s = xreduce(print, "", xfilter(select("result"), elems(ures)));
+ return xdom("http://sample/hello", "helloResponse", elem("result", text(s)));
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Xutil.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Xutil.java
new file mode 100644
index 0000000000..ce89f9dd8c
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/Xutil.java
@@ -0,0 +1,225 @@
+/*
+ * 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 sample;
+
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Just for fun, a little bit of magic code and utility functions to help work with XML DOM.
+ */
+class Xutil {
+ interface NodeBuilder {
+ Node build(Document doc);
+ }
+
+ /**
+ * Convert a name and a list of children to a document element.
+ */
+ static Element xdom(String ns, String name, final NodeBuilder... nodes) {
+ return (Element)elem(ns, name, nodes).build(db.newDocument());
+ }
+
+ /**
+ * Convert a name and children to an element.
+ */
+ static NodeBuilder elem(final String uri, final String n, final NodeBuilder... nodes) {
+ return new NodeBuilder() {
+ public Node build(Document doc) {
+ final Element e = doc.createElementNS(uri, n);
+ for(final NodeBuilder n: nodes)
+ e.appendChild(n.build(doc));
+ return e;
+ }
+ };
+ }
+
+ static NodeBuilder elem(final String n, final NodeBuilder... nodes) {
+ return elem(null, n, nodes);
+ }
+
+ /**
+ * Convert a string to a text element.
+ */
+ static NodeBuilder text(final String t) {
+ return new NodeBuilder() {
+ public Node build(final Document doc) {
+ return doc.createTextNode(t);
+ }
+ };
+ }
+
+ private final static DocumentBuilder db = db();
+
+ private static DocumentBuilder db() {
+ try {
+ return DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ } catch(ParserConfigurationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Convert an element to XML.
+ */
+ static TransformerFactory trf = TransformerFactory.newInstance();
+
+ static String xml(final Node node) {
+ try {
+ final StreamResult r = new StreamResult(new StringWriter());
+ trf.newTransformer().transform(new DOMSource(node), r);
+ return r.getWriter().toString();
+ } catch(TransformerException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Evaluate an xpath expression.
+ */
+ private static XPathFactory xpf = XPathFactory.newInstance();
+
+ static String xpath(final String expr, final Node node) {
+ final XPath xp = xpf.newXPath();
+ try {
+ return (String)xp.evaluate(expr, node, XPathConstants.STRING);
+ } catch(XPathExpressionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * A pure Java FP-style alternative to xpath for DOM.
+ */
+ interface Mapper<T> {
+ T map(final Element e);
+ }
+
+ static Mapper<Element> identity = new Mapper<Element>() {
+ public Element map(Element e) {
+ return e;
+ };
+ };
+
+ interface Reducer<T> {
+ T reduce(final T accum, final Element e);
+ }
+
+ static Reducer<String> print = new Reducer<String>() {
+ public String reduce(String accum, Element e) {
+ return accum + e.getTextContent();
+ }
+ };
+
+ /**
+ * Apply a mapper to a list of elements.
+ */
+ static <T> List<T> xmap(final Mapper<T> f, final Iterable<Element> l) {
+ final List<T> v = new ArrayList<T>();
+ for(Element e: l)
+ v.add(f.map(e));
+ return v;
+ }
+
+ /**
+ * Apply a filter to a list of elements.
+ */
+ static List<Element> xfilter(final Mapper<Boolean> f, final Iterable<Element> l) {
+ final List<Element> v = new ArrayList<Element>();
+ for(Element e: l)
+ if(f.map(e))
+ v.add(e);
+ return v;
+ }
+
+ /**
+ * Perform a reduction over a list of elements.
+ */
+ static <T> T xreduce(final Reducer<T> f, final T initial, final Iterable<Element> l) {
+ T accum = initial;
+ for(Element e: l)
+ accum = f.reduce(accum, e);
+ return accum;
+ }
+
+ /**
+ * Return a filter that selects elements by name.
+ */
+ static Mapper<Boolean> select(final String name) {
+ return new Mapper<Boolean>() {
+ public Boolean map(Element e) {
+ return name.equals(e.getLocalName());
+ }
+ };
+ }
+
+ /**
+ * Return the child elements of a node.
+ */
+ static Iterable<Element> elems(final Node parent) {
+ final List<Element> l = new ArrayList<Element>();
+ for (Node n: children(parent))
+ if (n instanceof Element)
+ l.add((Element)n);
+ return l;
+ }
+
+ /**
+ * An iterable over the children of a node.
+ */
+ private static Iterable<Node> children(Node parent) {
+ final NodeList l = parent.getChildNodes();
+ final int n = l.getLength();
+ return new Iterable<Node>() {
+ public Iterator<Node> iterator() {
+ return new Iterator<Node>() {
+ int i = 0;
+ public boolean hasNext() {
+ return i < n;
+ }
+ public Node next() {
+ return l.item(i++);
+ }
+ public void remove() {
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/EmbedTestCase.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/EmbedTestCase.java
new file mode 100644
index 0000000000..406dbabee0
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/EmbedTestCase.java
@@ -0,0 +1,151 @@
+/*
+ * 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 sample.impl;
+
+import static java.lang.System.out;
+import static org.junit.Assert.assertEquals;
+import static sample.impl.EmbedUtil.build;
+import static sample.impl.EmbedUtil.component;
+import static sample.impl.EmbedUtil.composite;
+import static sample.impl.EmbedUtil.contrib;
+import static sample.impl.EmbedUtil.deploy;
+import static sample.impl.EmbedUtil.embedContext;
+import static sample.impl.EmbedUtil.extensionPoints;
+import static sample.impl.EmbedUtil.implementation;
+import static sample.impl.EmbedUtil.node;
+import static sample.impl.EmbedUtil.providerFactories;
+import static sample.impl.EmbedUtil.reference;
+import static sample.impl.EmbedUtil.service;
+import static sample.impl.EmbedUtil.wsdli;
+import static sample.impl.TestUtil.here;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.interfacedef.wsdl.WSDLInterface;
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.apache.tuscany.sca.provider.ImplementationProvider;
+import org.apache.tuscany.sca.provider.ProviderFactory;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import sample.Client;
+import sample.ClientTest;
+import sample.Hello;
+import sample.JelloTest;
+import sample.Upper;
+import sample.UpperTest;
+import sample.WelloTest;
+
+/**
+ * Test how to assemble a contribution, a SCDL composite and run it on an embedded
+ * Tuscany runtime node. Also shows how pass in a ProviderFactory instead of having
+ * it loaded and constructed by the runtime node.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EmbedTestCase {
+ static NodeFactory nf;
+ static EmbedUtil.Context ec;
+ static Node node;
+
+ @SuppressWarnings("unchecked")
+ @BeforeClass
+ public static void setUp() throws Exception {
+ nf = NodeFactory.newInstance();
+ ec = embedContext(nf);
+
+ // Load the test WSDL definitions (could also construct the WSDL
+ // and XSD models in code but that'd be quite painful, so just
+ // load them from XML for now)
+ final Contribution contrib = build(contrib("test", here()), ec);
+ WSDLInterface Hello_wsdl = build(wsdli("Hello.wsdl", "http://sample/hello", "Hello", contrib), ec);
+ WSDLInterface Upper_wsdl = build(wsdli("Upper.wsdl", "http://sample/upper", "Upper", contrib), ec);
+
+ // Assemble a test composite model (see EmbedUtil
+ // for the little DSL used here, much more concise
+ // than using the assembly model interfaces)
+ final Composite comp =
+ build(composite("http://sample", "test",
+ component("client-test",
+ implementation(ClientTest.class,
+ service(Client.class),
+ reference("jello", Hello.class),
+ reference("wello", Hello_wsdl)),
+ reference("jello", "jello-test"),
+ reference("wello", "wello-test")),
+ component("wello-test",
+ implementation(WelloTest.class,
+ service(Hello_wsdl),
+ reference("upper", Upper_wsdl)),
+ reference("upper", "upper-test")),
+ component("jello-test",
+ implementation(JelloTest.class,
+ service(Hello.class),
+ reference("upper", Upper.class)),
+ reference("upper", "upper-test")),
+ component("upper-test",
+ implementation(UpperTest.class,
+ service(Upper.class)))), ec);
+
+ // Register a test instance of our sample implementation ProviderFactory
+ providerFactories(ec).addProviderFactory(testProviderFactory());
+
+ // Run with it
+ node = node(nf, deploy(contrib, comp));
+ node.start();
+ }
+
+ static ProviderFactory<SampleImplementation> testProviderFactory() {
+ // This shows how to get called when a provider is created
+ return new SampleProviderFactory(extensionPoints(ec)) {
+ public ImplementationProvider createImplementationProvider(RuntimeComponent comp, SampleImplementation impl) {
+ out.println("Creating a provider for component " + comp.getName());
+ return super.createImplementationProvider(comp, impl);
+ }};
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ node.stop();
+ }
+
+ @Test
+ public void jello() {
+ out.println("RunTestCase.jello");
+ final String r = client().jello("Java");
+ out.println(r);
+ assertEquals("HELLO JAVA", r);
+ }
+
+ @Test
+ public void wello() {
+ out.println("RunTestCase.wello");
+ final String r = client().wello("WSDL");
+ out.println(r);
+ assertEquals("HELLO WSDL", r);
+ }
+
+ static Client client() {
+ return node.getService(Client.class, "client-test/Client");
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/ReadWriteTestCase.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/ReadWriteTestCase.java
new file mode 100644
index 0000000000..8a4768cd9e
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/ReadWriteTestCase.java
@@ -0,0 +1,84 @@
+/*
+ * 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 sample.impl;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static sample.impl.TestUtil.here;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.DefaultContributionFactory;
+import org.apache.tuscany.sca.contribution.processor.DefaultStAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test read/write Sample SCDL implementation elements.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReadWriteTestCase {
+ static XMLInputFactory xif;
+ static XMLOutputFactory xof;
+ static StAXArtifactProcessor<Object> xproc;
+ static ProcessorContext ctx;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ final DefaultExtensionPointRegistry ep = new DefaultExtensionPointRegistry();
+ final Contribution contrib = new DefaultContributionFactory().createContribution();
+ contrib.setLocation(here());
+ ctx = new ProcessorContext(contrib, null);
+ xif = XMLInputFactory.newInstance();
+ xof = XMLOutputFactory.newInstance();
+ final StAXArtifactProcessorExtensionPoint xpep = new DefaultStAXArtifactProcessorExtensionPoint(ep);
+ xproc = new ExtensibleStAXArtifactProcessor(xpep, xif, xof);
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ final InputStream is = getClass().getClassLoader().getResourceAsStream("test.composite");
+ final Composite c = (Composite)xproc.read(xif.createXMLStreamReader(is), ctx);
+ assertNotNull(c);
+ assertEquals("sample.ClientTest", ((SampleImplementation)c.getComponents().get(0).getImplementation()).name);
+ }
+
+ @Test
+ public void testReadWrite() throws Exception {
+ final InputStream is = getClass().getClassLoader().getResourceAsStream("test.composite");
+ final Composite c = (Composite)xproc.read(xif.createXMLStreamReader(is), ctx);
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ xproc.write(c, xof.createXMLStreamWriter(bos), ctx);
+ assertTrue(bos.toString().contains("class=\"sample.WelloTest\""));
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunTestCase.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunTestCase.java
new file mode 100644
index 0000000000..29bf02d26b
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunTestCase.java
@@ -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.
+ */
+
+package sample.impl;
+
+import static java.lang.System.out;
+import static org.junit.Assert.assertEquals;
+import static sample.impl.TestUtil.here;
+
+import org.apache.tuscany.sca.node.Contribution;
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import sample.Client;
+
+/**
+ * Test how to run an SCA contribution containing a test composite on a
+ * Tuscany runtime node.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RunTestCase {
+ static Node node;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ final NodeFactory nf = NodeFactory.newInstance();
+ node = nf.createNode(new Contribution("test", here()));
+ node.start();
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ node.stop();
+ }
+
+ @Test
+ public void jello() {
+ out.println("RunTestCase.jello");
+ final String r = client().jello("Java");
+ out.println(r);
+ assertEquals("HELLO JAVA", r);
+ }
+
+ @Test
+ public void wello() {
+ out.println("RunTestCase.wello");
+ final String r = client().wello("WSDL");
+ out.println(r);
+ assertEquals("HELLO WSDL", r);
+ }
+
+ static Client client() {
+ return node.getService(Client.class, "client-test/Client");
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunWSTestCase.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunWSTestCase.java
new file mode 100644
index 0000000000..61133d0fbf
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/RunWSTestCase.java
@@ -0,0 +1,120 @@
+/*
+ * 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 sample.impl;
+
+import static java.lang.System.out;
+import static org.junit.Assert.assertTrue;
+import static sample.impl.TestUtil.here;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.Socket;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.http.jetty.JettyServer;
+import org.apache.tuscany.sca.node.Contribution;
+import org.apache.tuscany.sca.node.Node;
+import org.apache.tuscany.sca.node.NodeFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test a component that provides and consumes SOAP Web services.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RunWSTestCase {
+ static Node node;
+ static JettyServer jetty;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ // Start test composite on a Tuscany node
+ final NodeFactory nf = NodeFactory.newInstance();
+ node = nf.createNode(new Contribution("test", here()));
+ node.start();
+
+ // Mock up a test Web service on http://localhost:8086/wsupper
+ jetty = new JettyServer((ExtensionPointRegistry)nf.getExtensionPointRegistry());
+ jetty.start();
+ jetty.addServletMapping("http://localhost:8086/wsupper", new HttpServlet() {
+ private static final long serialVersionUID = 1L;
+ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
+ assertTrue(read(req.getInputStream()).contains("Hello SOAP"));
+ final String soapresp =
+ "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
+ "<soapenv:Body><upperResponse xmlns=\"http://sample/upper\">" +
+ "<result xmlns=\"\">HELLO SOAP</result>" +
+ "</upperResponse></soapenv:Body></soapenv:Envelope>";
+
+ write(soapresp, resp.getOutputStream());
+ }
+ });
+ }
+
+ @AfterClass
+ public static void tearDown() throws Exception {
+ jetty.stop();
+ node.stop();
+ }
+
+ @Test
+ public void wsello() throws Exception {
+ out.println("RunWSTestCase.wsello");
+ // Send a SOAP request to the Web service provided by SCA component wsello-test
+ // on http://localhost:8085/wsello
+ final Socket s = new Socket("localhost", 8085);
+ final String soapreq =
+ "POST /wsello HTTP/1.0\r\n" +
+ "Content-Type: text/xml; charset=UTF-8\r\n" +
+ "Content-length: 231\r\n\r\n" +
+ "<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
+ "<soapenv:Body><hello xmlns=\"http://sample/hello\">" +
+ "<name xmlns=\"\">SOAP</name>" +
+ "</hello></soapenv:Body></soapenv:Envelope>";
+ write(soapreq, s.getOutputStream());
+ assertTrue(read(s.getInputStream()).contains("HELLO SOAP"));
+ }
+
+ static void write(final String s, final OutputStream o) throws IOException {
+ final OutputStreamWriter w = new OutputStreamWriter(o);
+ w.write(s);
+ w.flush();
+ }
+
+ static String read(final InputStream i) throws IOException {
+ return read(new BufferedReader(new InputStreamReader(i)));
+ }
+
+ static String read(final BufferedReader r) throws IOException {
+ final String s = r.readLine();
+ return s == null? "" : s + read(r);
+ }
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/TestUtil.java b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/TestUtil.java
new file mode 100644
index 0000000000..6dcfb33912
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/java/sample/impl/TestUtil.java
@@ -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.
+ */
+
+package sample.impl;
+
+/**
+ * A hack to determine the test contribution location.
+ */
+public class TestUtil {
+
+ static String here() {
+ return TestUtil.class.getProtectionDomain().getCodeSource().getLocation().toString();
+ }
+
+}
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Hello.wsdl b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Hello.wsdl
new file mode 100644
index 0000000000..360cea5ff3
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Hello.wsdl
@@ -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.
+-->
+<wsdl:definitions targetNamespace="http://sample/hello" xmlns:tns="http://sample/hello"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ name="Hello">
+
+ <wsdl:types>
+ <schema elementFormDefault="qualified" targetNamespace="http://sample/hello"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <element name="hello">
+ <complexType>
+ <sequence>
+ <element name="name" type="xsd:string" />
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="helloResponse">
+ <complexType>
+ <sequence>
+ <element name="result" type="xsd:string" />
+ </sequence>
+ </complexType>
+ </element>
+
+ </schema>
+ </wsdl:types>
+
+ <wsdl:message name="helloRequest">
+ <wsdl:part element="tns:hello" name="parameters" />
+ </wsdl:message>
+
+ <wsdl:message name="helloResponse">
+ <wsdl:part element="tns:helloResponse" name="parameters" />
+ </wsdl:message>
+
+ <wsdl:portType name="Hello">
+ <wsdl:operation name="hello">
+ <wsdl:input message="tns:helloRequest" name="helloRequest" />
+ <wsdl:output message="tns:helloResponse" name="helloResponse" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+</wsdl:definitions>
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Upper.wsdl b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Upper.wsdl
new file mode 100644
index 0000000000..8a148bb5e8
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/Upper.wsdl
@@ -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.
+-->
+<wsdl:definitions targetNamespace="http://sample/upper" xmlns:tns="http://sample/upper"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ name="Upper">
+
+ <wsdl:types>
+ <schema elementFormDefault="qualified" targetNamespace="http://sample/upper"
+ xmlns="http://www.w3.org/2001/XMLSchema">
+ <element name="upper">
+ <complexType>
+ <sequence>
+ <element name="s" type="xsd:string" />
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="upperResponse">
+ <complexType>
+ <sequence>
+ <element name="result" type="xsd:string" />
+ </sequence>
+ </complexType>
+ </element>
+
+ </schema>
+ </wsdl:types>
+
+ <wsdl:message name="upperRequest">
+ <wsdl:part element="tns:upper" name="parameters" />
+ </wsdl:message>
+
+ <wsdl:message name="upperResponse">
+ <wsdl:part element="tns:upperResponse" name="parameters" />
+ </wsdl:message>
+
+ <wsdl:portType name="Upper">
+ <wsdl:operation name="upper">
+ <wsdl:input message="tns:upperRequest" name="upperRequest" />
+ <wsdl:output message="tns:upperResponse" name="upperResponse" />
+ </wsdl:operation>
+ </wsdl:portType>
+
+</wsdl:definitions>
diff --git a/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/test.composite b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/test.composite
new file mode 100644
index 0000000000..43a75f50a7
--- /dev/null
+++ b/sandbox/samples/extending-tuscany/implementation-sample/src/test/resources/test.composite
@@ -0,0 +1,60 @@
+<?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://test"
+ name="wstest">
+
+ <!-- Client test component used by the JUnit tests -->
+ <component name="client-test">
+ <t:implementation.sample class="sample.ClientTest"/>
+ <reference name="wello" target="wello-test"/>
+ <reference name="jello" target="jello-test"/>
+ </component>
+
+ <!-- HelloWorld test component that uses WSDL interfaces -->
+ <component name="wello-test">
+ <t:implementation.sample class="sample.WelloTest"/>
+ <reference name="upper" target="upper-test"/>
+ </component>
+
+ <!-- HelloWorld test component that uses Java interfaces -->
+ <component name="jello-test">
+ <t:implementation.sample class="sample.JelloTest"/>
+ <reference name="upper" target="upper-test"/>
+ </component>
+
+ <!-- HelloWorld test component that uses WSDL interfaces and SOAP Web Services -->
+ <component name="Wsello-test">
+ <t:implementation.sample class="sample.WelloTest"/>
+ <service name="Hello">
+ <binding.ws uri="http://localhost:8085/wsello"/>
+ </service>
+ <reference name="upper">
+ <binding.ws uri="http://localhost:8086/wsupper"/>
+ </reference>
+ </component>
+
+ <!-- Test component converts a string to uppercase -->
+ <component name="upper-test">
+ <t:implementation.sample class="sample.UpperTest"/>
+ </component>
+
+</composite>