summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/implementation-java/src
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-05-15 07:48:45 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2009-05-15 07:48:45 +0000
commitb51d6788a6cca0b0cf63ab650cae6712a2c821ba (patch)
tree727a1ab6193e14d9ef1fc52431badfc393954b7e /java/sca/modules/implementation-java/src
parentf55c4b03b728a7e5e7a0d418dfac66072c0fc10e (diff)
Merge implementation-java-xml into implementation-java module
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@775053 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/implementation-java/src')
-rw-r--r--java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java35
-rw-r--r--java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java309
-rw-r--r--java/sca/modules/implementation-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor19
-rw-r--r--java/sca/modules/implementation-java/src/main/resources/impl-javaxml-validation-messages.properties23
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/AddService.java30
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/AddServiceImpl.java37
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/CalculatorService.java36
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/CalculatorServiceImpl.java73
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/DivideService.java30
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/DivideServiceImpl.java35
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/MultiplyService.java30
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/MultiplyServiceImpl.java35
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/SubtractService.java30
-rw-r--r--java/sca/modules/implementation-java/src/test/java/calculator/SubtractServiceImpl.java35
-rw-r--r--java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/ReadTestCase.java225
-rw-r--r--java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/TestModelResolver.java88
-rw-r--r--java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/WriteTestCase.java66
-rw-r--r--java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/Calculator.composite66
-rw-r--r--java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions.xml100
-rw-r--r--java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions_with_policysets.xml113
20 files changed, 1415 insertions, 0 deletions
diff --git a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.java
new file mode 100644
index 0000000000..3537dc97cf
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationConstants.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 org.apache.tuscany.sca.implementation.java.xml;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Constants for the Java Implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface JavaImplementationConstants {
+ String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200903";
+ String IMPLEMENTATION_JAVA = "implementation.java";
+ QName IMPLEMENTATION_JAVA_QNAME = new QName(SCA11_NS, "implementation.java");
+ String CLASS = "class";
+ String OPERATION = "operation";
+ QName OPERATION_QNAME = new QName(SCA11_NS, OPERATION);
+}
diff --git a/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java
new file mode 100644
index 0000000000..c325c871f4
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/xml/JavaImplementationProcessor.java
@@ -0,0 +1,309 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.CLASS;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.IMPLEMENTATION_JAVA;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.IMPLEMENTATION_JAVA_QNAME;
+import static org.apache.tuscany.sca.implementation.java.xml.JavaImplementationConstants.SCA11_NS;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+
+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.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.xml.PolicySubjectProcessor;
+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.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.implementation.java.IntrospectionException;
+import org.apache.tuscany.sca.implementation.java.JavaElementImpl;
+import org.apache.tuscany.sca.implementation.java.JavaImplementation;
+import org.apache.tuscany.sca.implementation.java.JavaImplementationFactory;
+import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.interfacedef.Interface;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterface;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class JavaImplementationProcessor implements StAXArtifactProcessor<JavaImplementation> {
+
+ private JavaImplementationFactory javaFactory;
+ private AssemblyFactory assemblyFactory;
+ private PolicyFactory policyFactory;
+ private PolicySubjectProcessor policyProcessor;
+ private Monitor monitor;
+
+ public JavaImplementationProcessor(FactoryExtensionPoint modelFactories, Monitor monitor) {
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ this.policyFactory = modelFactories.getFactory(PolicyFactory.class);
+ this.javaFactory = modelFactories.getFactory(JavaImplementationFactory.class);
+ this.policyProcessor = new PolicySubjectProcessor(policyFactory);
+ this.monitor = monitor;
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-javaxml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Report a exception.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "impl-javaxml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public JavaImplementation read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+
+ // Read an <implementation.java>
+ JavaImplementation javaImplementation = javaFactory.createJavaImplementation();
+
+ ExtensionType implType = policyFactory.createImplementationType();
+ implType.setType(getArtifactType());
+ implType.setUnresolved(true);
+ javaImplementation.setType(implType);
+
+ javaImplementation.setUnresolved(true);
+ javaImplementation.setName(reader.getAttributeValue(null, CLASS));
+
+ // Read policies
+ policyProcessor.readPolicies(javaImplementation, reader);
+
+ // read operation elements if exists or skip unto end element
+ int event;
+ while (reader.hasNext()) {
+ event = reader.next();
+ if (event == END_ELEMENT && IMPLEMENTATION_JAVA_QNAME.equals(reader.getName())) {
+ break;
+ }
+ }
+ return javaImplementation;
+ }
+
+ public void write(JavaImplementation javaImplementation, XMLStreamWriter writer) throws ContributionWriteException,
+ XMLStreamException {
+
+ // Write an <implementation.java>
+ policyProcessor.writePolicyPrefixes(javaImplementation, writer);
+ writer.writeStartElement(SCA11_NS, IMPLEMENTATION_JAVA);
+ policyProcessor.writePolicyAttributes(javaImplementation, writer);
+
+ if (javaImplementation.getName() != null) {
+ writer.writeAttribute(CLASS, javaImplementation.getName());
+ }
+
+ writer.writeEndElement();
+ }
+
+ public void resolve(JavaImplementation javaImplementation, ModelResolver resolver)
+ throws ContributionResolveException {
+
+ try {
+ ClassReference classReference = new ClassReference(javaImplementation.getName());
+ classReference = resolver.resolveModel(ClassReference.class, classReference);
+ Class<?> javaClass = classReference.getJavaClass();
+ if (javaClass == null) {
+ error("ClassNotFoundException", resolver, javaImplementation.getName());
+ //throw new ContributionResolveException(new ClassNotFoundException(javaImplementation.getName()));
+ return;
+ }
+
+ javaImplementation.setJavaClass(javaClass);
+
+ try {
+ javaFactory.createJavaImplementation(javaImplementation, javaImplementation.getJavaClass());
+ } catch (IntrospectionException e) {
+ ContributionResolveException ce = new ContributionResolveException(e);
+ error("ContributionResolveException", javaFactory, ce);
+ //throw ce;
+ return;
+ }
+
+ javaImplementation.setUnresolved(false);
+ mergeComponentType(resolver, javaImplementation);
+
+ // FIXME the introspector should always create at least one service
+ if (javaImplementation.getServices().isEmpty()) {
+ javaImplementation.getServices().add(assemblyFactory.createService());
+ }
+ } catch (Throwable e ) {
+ throw new ContributionResolveException( "Resolving Java implementation: " + javaImplementation.getName(), e);
+ } // end try
+ } // end method
+
+ private JavaElementImpl getMemeber(JavaImplementation impl, String name, Class<?> type) {
+ String setter = JavaIntrospectionHelper.toSetter(name);
+ try {
+ Method method = impl.getJavaClass().getDeclaredMethod(setter, type);
+ int mod = method.getModifiers();
+ if ((Modifier.isPublic(mod) || Modifier.isProtected(mod)) && (!Modifier.isStatic(mod))) {
+ return new JavaElementImpl(method, 0);
+ }
+ } catch (NoSuchMethodException e) {
+ Field field;
+ try {
+ field = impl.getJavaClass().getDeclaredField(name);
+ int mod = field.getModifiers();
+ if ((Modifier.isPublic(mod) || Modifier.isProtected(mod)) && (!Modifier.isStatic(mod))) {
+ return new JavaElementImpl(field);
+ }
+ } catch (NoSuchFieldException e1) {
+ // Ignore
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Merge the componentType from introspection and external file
+ * @param resolver
+ * @param impl
+ */
+ private void mergeComponentType(ModelResolver resolver, JavaImplementation impl) {
+ // FIXME: Need to clarify how to merge
+ ComponentType componentType = getComponentType(resolver, impl);
+ if (componentType != null && !componentType.isUnresolved()) {
+ Map<String, Reference> refMap = new HashMap<String, Reference>();
+ for (Reference ref : impl.getReferences()) {
+ refMap.put(ref.getName(), ref);
+ }
+ for (Reference reference : componentType.getReferences()) {
+ refMap.put(reference.getName(), reference);
+ }
+ impl.getReferences().clear();
+ impl.getReferences().addAll(refMap.values());
+
+ // Try to match references by type
+ Map<String, JavaElementImpl> refMembers = impl.getReferenceMembers();
+ for (Reference ref : impl.getReferences()) {
+ if (ref.getInterfaceContract() != null) {
+ Interface i = ref.getInterfaceContract().getInterface();
+ if (i instanceof JavaInterface) {
+ Class<?> type = ((JavaInterface)i).getJavaClass();
+ if (!refMembers.containsKey(ref.getName())) {
+ JavaElementImpl e = getMemeber(impl, ref.getName(), type);
+ if (e != null) {
+ refMembers.put(ref.getName(), e);
+ }
+ }
+ }
+ }
+ }
+
+ Map<String, Service> serviceMap = new HashMap<String, Service>();
+ for (Service svc : impl.getServices()) {
+ serviceMap.put(svc.getName(), svc);
+ }
+ for (Service service : componentType.getServices()) {
+ serviceMap.put(service.getName(), service);
+ }
+ impl.getServices().clear();
+ impl.getServices().addAll(serviceMap.values());
+
+ Map<String, Property> propMap = new HashMap<String, Property>();
+ for (Property prop : impl.getProperties()) {
+ propMap.put(prop.getName(), prop);
+ }
+ for (Property property : componentType.getProperties()) {
+ propMap.put(property.getName(), property);
+ }
+ impl.getProperties().clear();
+ impl.getProperties().addAll(propMap.values());
+
+ if (componentType.getConstrainingType() != null) {
+ impl.setConstrainingType(componentType.getConstrainingType());
+ }
+ }
+ }
+
+ private ComponentType getComponentType(ModelResolver resolver, JavaImplementation impl) {
+ String className = impl.getJavaClass().getName();
+ String componentTypeURI = className.replace('.', '/') + ".componentType";
+ ComponentType componentType = assemblyFactory.createComponentType();
+ componentType.setUnresolved(true);
+ componentType.setURI(componentTypeURI);
+ componentType = resolver.resolveModel(ComponentType.class, componentType);
+ if (!componentType.isUnresolved()) {
+ return componentType;
+ }
+ return null;
+ }
+
+ public QName getArtifactType() {
+ return IMPLEMENTATION_JAVA_QNAME;
+ }
+
+ public Class<JavaImplementation> getModelType() {
+ return JavaImplementation.class;
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/java/sca/modules/implementation-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..85f38f04f4
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,19 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.implementation.java.xml.JavaImplementationProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200903#implementation.java,model=org.apache.tuscany.sca.implementation.java.JavaImplementation
diff --git a/java/sca/modules/implementation-java/src/main/resources/impl-javaxml-validation-messages.properties b/java/sca/modules/implementation-java/src/main/resources/impl-javaxml-validation-messages.properties
new file mode 100644
index 0000000000..210b715da8
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/main/resources/impl-javaxml-validation-messages.properties
@@ -0,0 +1,23 @@
+#
+#
+# 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.
+#
+#
+ClassNotFoundException = Class Not Found Exception: {0}
+ContributionResolveException = Contribution Resolve Exception occured due to:
+
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/AddService.java b/java/sca/modules/implementation-java/src/test/java/calculator/AddService.java
new file mode 100644
index 0000000000..9c22177684
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/AddService.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package calculator;
+
+/**
+ * Interface for the Add Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface AddService {
+
+ double add(double n1, double n2);
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/AddServiceImpl.java b/java/sca/modules/implementation-java/src/test/java/calculator/AddServiceImpl.java
new file mode 100644
index 0000000000..64298b6275
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/AddServiceImpl.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 calculator;
+
+import org.oasisopen.sca.annotation.EagerInit;
+import org.oasisopen.sca.annotation.Scope;
+
+/**
+ * An implementation of the Add service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+@EagerInit
+public class AddServiceImpl implements AddService {
+
+ public double add(double n1, double n2) {
+ return n1 + n2;
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorService.java b/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorService.java
new file mode 100644
index 0000000000..e0cf23dc17
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorService.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package calculator;
+
+/**
+ * The Calculator service interface.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface CalculatorService {
+
+ double add(double n1, double n2);
+
+ double subtract(double n1, double n2);
+
+ double multiply(double n1, double n2);
+
+ double divide(double n1, double n2);
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorServiceImpl.java b/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorServiceImpl.java
new file mode 100644
index 0000000000..9f64dc8bca
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/CalculatorServiceImpl.java
@@ -0,0 +1,73 @@
+/*
+ * 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 calculator;
+
+import org.oasisopen.sca.annotation.Reference;
+import org.oasisopen.sca.annotation.Scope;
+
+/**
+ * An implementation of the Calculator service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public class CalculatorServiceImpl implements CalculatorService {
+
+ private AddService addService;
+ private SubtractService subtractService;
+ private MultiplyService multiplyService;
+ private DivideService divideService;
+
+ @Reference
+ public void setAddService(AddService addService) {
+ this.addService = addService;
+ }
+
+ @Reference
+ public void setSubtractService(SubtractService subtractService) {
+ this.subtractService = subtractService;
+ }
+
+ @Reference
+ public void setDivideService(DivideService divideService) {
+ this.divideService = divideService;
+ }
+
+ @Reference
+ public void setMultiplyService(MultiplyService multiplyService) {
+ this.multiplyService = multiplyService;
+ }
+
+ public double add(double n1, double n2) {
+ return addService.add(n1, n2);
+ }
+
+ public double subtract(double n1, double n2) {
+ return subtractService.subtract(n1, n2);
+ }
+
+ public double multiply(double n1, double n2) {
+ return multiplyService.multiply(n1, n2);
+ }
+
+ public double divide(double n1, double n2) {
+ return divideService.divide(n1, n2);
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/DivideService.java b/java/sca/modules/implementation-java/src/test/java/calculator/DivideService.java
new file mode 100644
index 0000000000..9599c86292
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/DivideService.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package calculator;
+
+/**
+ * Interface for the Divide Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DivideService {
+
+ double divide(double n1, double n2);
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/DivideServiceImpl.java b/java/sca/modules/implementation-java/src/test/java/calculator/DivideServiceImpl.java
new file mode 100644
index 0000000000..f5b8ff5be0
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/DivideServiceImpl.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 calculator;
+
+import org.oasisopen.sca.annotation.Scope;
+
+/**
+ * An implementation of the Divide service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public class DivideServiceImpl implements DivideService {
+
+ public double divide(double n1, double n2) {
+ return n1 / n2;
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyService.java b/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyService.java
new file mode 100644
index 0000000000..7a3d06c15e
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyService.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package calculator;
+
+/**
+ * Interface for the Multiply Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface MultiplyService {
+
+ double multiply(double n1, double n2);
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyServiceImpl.java b/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyServiceImpl.java
new file mode 100644
index 0000000000..d146d23153
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/MultiplyServiceImpl.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 calculator;
+
+import org.oasisopen.sca.annotation.Scope;
+
+/**
+ * An implementation of the Multiply service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public class MultiplyServiceImpl implements MultiplyService {
+
+ public double multiply(double n1, double n2) {
+ return n1 * n2;
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/SubtractService.java b/java/sca/modules/implementation-java/src/test/java/calculator/SubtractService.java
new file mode 100644
index 0000000000..21af91f392
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/SubtractService.java
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package calculator;
+
+/**
+ * Interface for the Subtract Service.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface SubtractService {
+
+ double subtract(double n1, double n2);
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/calculator/SubtractServiceImpl.java b/java/sca/modules/implementation-java/src/test/java/calculator/SubtractServiceImpl.java
new file mode 100644
index 0000000000..ffe09c3dde
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/calculator/SubtractServiceImpl.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 calculator;
+
+import org.oasisopen.sca.annotation.Scope;
+
+/**
+ * An implementation of the subtract service.
+ *
+ * @version $Rev$ $Date$
+ */
+@Scope("COMPOSITE")
+public class SubtractServiceImpl implements SubtractService {
+
+ public double subtract(double n1, double n2) {
+ return n1 - n2;
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/ReadTestCase.java b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/ReadTestCase.java
new file mode 100644
index 0000000000..18435e205c
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/ReadTestCase.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 org.apache.tuscany.sca.implementation.java.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.definitions.Definitions;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.PolicySubject;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Test reading Java implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReadTestCase {
+
+ private static XMLInputFactory inputFactory;
+ private static StAXArtifactProcessor<Object> staxProcessor;
+ private static URLArtifactProcessor<Definitions> policyDefinitionsProcessor;
+ private static CompositeBuilder compositeBuilder;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+ inputFactory = XMLInputFactory.newInstance();
+ StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null, null);
+
+ compositeBuilder = extensionPoints.getExtensionPoint(CompositeBuilderExtensionPoint.class).getCompositeBuilder("org.apache.tuscany.sca.assembly.builder.CompositeBuilder");
+
+ URLArtifactProcessorExtensionPoint documentProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+ policyDefinitionsProcessor = documentProcessors.getProcessor(Definitions.class);
+ }
+
+ @Test
+ public void testReadComposite() throws Exception {
+ InputStream is = getClass().getResourceAsStream("Calculator.composite");
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
+ Composite composite = (Composite)staxProcessor.read(reader);
+ assertNotNull(composite);
+
+ compositeBuilder.build(composite, null, null);
+
+ }
+
+ @Ignore("To be fixed")
+ @Test
+ public void testPolicyIntents() throws Exception {
+ ModelResolver resolver = new TestModelResolver(getClass().getClassLoader());
+
+ URL url = getClass().getResource("definitions.xml");
+ URI uri = URI.create("definitions.xml");
+ Definitions scaDefns = policyDefinitionsProcessor.read(null, uri, url);
+
+ InputStream is = getClass().getResourceAsStream("Calculator.composite");
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
+ Composite composite = (Composite)staxProcessor.read(reader);
+ assertNotNull(composite);
+
+ staxProcessor.resolve(scaDefns, resolver);
+ staxProcessor.resolve(composite, resolver);
+
+ compositeBuilder.build(composite, null, null);
+
+ //intents are computed and aggregate intents from ancestor elements
+ assertEquals(((PolicySubject)composite.getComponents().get(0)).getRequiredIntents().size(), 3);
+ assertEquals(((PolicySubject)composite.getComponents().get(5)).getRequiredIntents().size(), 3);
+
+ //assertEquals(((OperationsConfigurator)composite.getComponents().get(0)).getConfiguredOperations().isEmpty(), true);
+ //assertEquals(((OperationsConfigurator)composite.getComponents().get(5)).getConfiguredOperations().isEmpty(), false);
+
+
+ //test for proper aggregation of policy intents on implementation elements
+ for ( Intent intent : ((PolicySubject)composite.getComponents().get(0).getImplementation()).getRequiredIntents() ) {
+ String intentName = intent.getName().getLocalPart();
+ if ( !(intentName.equals("tuscanyIntent_1") || intentName.equals("tuscanyIntent_2") ||
+ intentName.equals("tuscanyIntent_3")) ) {
+ fail();
+ }
+ }
+
+ for ( Intent intent : ((PolicySubject)composite.getComponents().get(5)).getRequiredIntents() ) {
+ String intentName = intent.getName().getLocalPart();
+ if ( !(intentName.equals("tuscanyIntent_1") || intentName.equals("tuscanyIntent_4") ||
+ intentName.equals("tuscanyIntent_5")) ) {
+ fail();
+ }
+ }
+
+ /*
+ //test for proper aggregation of policy intents and policysets on operations of implementation
+ OperationsConfigurator opConf = (OperationsConfigurator)composite.getComponents().get(5);
+ assertEquals(opConf.getConfiguredOperations().get(0).getRequiredIntents().size(), 4);
+ for ( Intent intent : opConf.getConfiguredOperations().get(0).getRequiredIntents()) {
+ String intentName = intent.getName().getLocalPart();
+ if ( !(intentName.equals("tuscanyIntent_1") || intentName.equals("tuscanyIntent_4") ||
+ intentName.equals("tuscanyIntent_5") || intentName.equals("tuscanyIntent_6") ) ) {
+ fail();
+ }
+ }
+
+ opConf = (OperationsConfigurator)composite.getComponents().get(6);
+ assertEquals(opConf.getConfiguredOperations().get(0).getRequiredIntents().size(), 3);
+ for ( Intent intent : opConf.getConfiguredOperations().get(0).getRequiredIntents()) {
+ String intentName = intent.getName().getLocalPart();
+ if ( !(intentName.equals("tuscanyIntent_1") || intentName.equals("tuscanyIntent_4") ||
+ intentName.equals("tuscanyIntent_6.qualified2") ) ) {
+ fail();
+ }
+ }
+ */
+ }
+
+ @Test
+ @Ignore("Broken for now in 2.0 bringup")
+ public void testPolicySets() throws Exception {
+ ModelResolver resolver = new TestModelResolver(getClass().getClassLoader());
+
+ URL url = getClass().getResource("definitions_with_policysets.xml");
+ URI uri = URI.create("definitions_with_policysets.xml");
+ Definitions policyDefinitions = policyDefinitionsProcessor.read(null, uri, url);
+
+ InputStream is = getClass().getResourceAsStream("Calculator.composite");
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
+ Composite composite = (Composite)staxProcessor.read(reader);
+ assertNotNull(composite);
+
+ for ( Component component : composite.getComponents() ) {
+ for ( PolicySet policySet : policyDefinitions.getPolicySets() ) {
+ component.getPolicySets().add(policySet);
+ }
+ }
+
+ staxProcessor.resolve(policyDefinitions, resolver);
+ staxProcessor.resolve(composite, resolver);
+
+ compositeBuilder.build(composite, null, null);
+
+ //test for determination of policysets for implementation
+ assertEquals(((PolicySubject)composite.getComponents().get(0)).getPolicySets().size(), 1);
+ for ( PolicySet policySet : ((PolicySubject)composite.getComponents().get(0).getImplementation()).getPolicySets() ) {
+ String policySetName = policySet.getName().getLocalPart();
+ if ( !(policySetName.equals("tuscanyPolicySet_1")) ) {
+ fail();
+ }
+ }
+
+ assertEquals(((PolicySubject)composite.getComponents().get(5)).getPolicySets().size(), 2);
+ for ( PolicySet policySet : ((PolicySubject)composite.getComponents().get(5).getImplementation()).getPolicySets() ) {
+ String policySetName = policySet.getName().getLocalPart();
+ if ( !(policySetName.equals("tuscanyPolicySet_1") || policySetName.equals("tuscanyPolicySet_2")) ) {
+ fail();
+ }
+ }
+
+ /*
+ //test for computation of policysets on operations of implementation
+ OperationsConfigurator opConf = (OperationsConfigurator)composite.getComponents().get(5);
+ assertEquals(opConf.getConfiguredOperations().get(0).getPolicySets().size(), 3);
+ for ( PolicySet policySet : opConf.getConfiguredOperations().get(0).getPolicySets() ) {
+ String policySetName = policySet.getName().getLocalPart();
+ if ( !(policySetName.equals("tuscanyPolicySet_1") || policySetName.equals("tuscanyPolicySet_2")
+ || policySetName.equals("tuscanyPolicySet_3")) ) {
+ fail();
+ }
+ }
+
+ opConf = (OperationsConfigurator)composite.getComponents().get(6);
+ assertEquals(opConf.getConfiguredOperations().get(0).getPolicySets().size(), 4);
+ for ( PolicySet policySet : opConf.getConfiguredOperations().get(0).getPolicySets() ) {
+ String policySetName = policySet.getName().getLocalPart();
+ if ( !(policySetName.equals("tuscanyPolicySet_1") || policySetName.equals("tuscanyPolicySet_2")
+ || policySetName.equals("tuscanyPolicySet_3")
+ || policySetName.equals("tuscanyPolicySet_4")) ) {
+ fail();
+ }
+ }
+ */
+
+ //new PrintUtil(System.out).print(composite);
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/TestModelResolver.java b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/TestModelResolver.java
new file mode 100644
index 0000000000..085b21a652
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/TestModelResolver.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.xml;
+
+import java.lang.ref.WeakReference;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.contribution.resolver.ClassReference;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+
+/**
+ * A default implementation of an artifact resolver, based on a map.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestModelResolver implements ModelResolver {
+ private static final long serialVersionUID = -7826976465762296634L;
+
+ private Map<Object, Object> map = new HashMap<Object, Object>();
+
+ private WeakReference<ClassLoader> classLoader;
+
+ public TestModelResolver(ClassLoader classLoader) {
+ this.classLoader = new WeakReference<ClassLoader>(classLoader);
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+ Object resolved = map.get(unresolved);
+ if (resolved != null) {
+
+ // Return the resolved object
+ return modelClass.cast(resolved);
+
+ } else if (unresolved instanceof ClassReference) {
+
+ // Load a class on demand
+ ClassReference classReference = (ClassReference)unresolved;
+ Class<?> clazz;
+ try {
+ clazz = Class.forName(classReference.getClassName(), true, classLoader.get());
+ } catch (ClassNotFoundException e) {
+
+ // Return the unresolved object
+ return unresolved;
+ }
+
+ // Store a new ClassReference wrapping the loaded class
+ resolved = new ClassReference(clazz);
+ map.put(resolved, resolved);
+
+ // Return the resolved ClassReference
+ return modelClass.cast(resolved);
+
+ } else {
+
+ // Return the unresolved object
+ return unresolved;
+ }
+ }
+
+ public void addModel(Object resolved) {
+ map.put(resolved, resolved);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(resolved);
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/WriteTestCase.java b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/WriteTestCase.java
new file mode 100644
index 0000000000..7d863c99de
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/java/org/apache/tuscany/sca/implementation/java/xml/WriteTestCase.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.implementation.java.xml;
+
+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.processor.ExtensibleStAXArtifactProcessor;
+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.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test writing Java implementations.
+ *
+ * @version $Rev$ $Date$
+ */
+public class WriteTestCase {
+
+ private static StAXArtifactProcessor<Object> staxProcessor;
+ private static XMLInputFactory inputFactory;
+ private static XMLOutputFactory outputFactory;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+ inputFactory = XMLInputFactory.newInstance();
+ outputFactory = XMLOutputFactory.newInstance();
+ StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, null);
+ }
+
+ @Test
+ public void testReadWriteComposite() throws Exception {
+ InputStream is = getClass().getResourceAsStream("Calculator.composite");
+ Composite composite = (Composite)staxProcessor.read(inputFactory.createXMLStreamReader(is));
+ Assert.assertNotNull(composite);
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ staxProcessor.write(composite, outputFactory.createXMLStreamWriter(bos));
+ }
+
+}
diff --git a/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/Calculator.composite b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/Calculator.composite
new file mode 100644
index 0000000000..f4182679bc
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/Calculator.composite
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200903"
+ xmlns:calc="http://sample.calculator"
+ requires="cns:tuscanyIntent_1"
+ targetNamespace="http://sample.calculator"
+ xmlns:cns="http://test"
+ name="Calculator">
+
+ <service name="CalculatorService" promote="CalculatorServiceComponent">
+ <interface.java interface="calculator.CalculatorService"/>
+ </service>
+
+ <component name="CalculatorServiceComponent" requires="cns:tuscanyIntent_2">
+ <implementation.java class="calculator.CalculatorServiceImpl" requires="cns:tuscanyIntent_3" />
+ <reference name="addService" target="AddServiceComponent"/>
+ <reference name="subtractService" target="SubtractServiceComponent"/>
+ <reference name="multiplyService" target="MultiplyServiceComponent"/>
+ <reference name="divideService" target="DivideServiceComponent"/>
+ </component>
+
+ <component name="AddServiceComponent">
+ <implementation.java class="calculator.AddServiceImpl"/>
+ </component>
+
+ <component name="SubtractServiceComponent">
+ <implementation.java class="calculator.SubtractServiceImpl"/>
+ </component>
+
+ <component name="MultiplyServiceComponent">
+ <implementation.java class="calculator.MultiplyServiceImpl"/>
+ </component>
+
+ <component name="DivideServiceComponent">
+ <implementation.java class="calculator.DivideServiceImpl"/>
+ </component>
+
+ <component name="AnotherCalculatorServiceComponent" requires="cns:tuscanyIntent_4">
+ <implementation.java class="calculator.CalculatorServiceImpl" requires="cns:tuscanyIntent_5">
+ <operation name="add" requires="cns:tuscanyIntent_6"/>
+ </implementation.java>
+ </component>
+
+ <component name="YetAnotherCalculatorServiceComponent" requires="cns:tuscanyIntent_4">
+ <implementation.java class="calculator.CalculatorServiceImpl" requires="cns:tuscanyIntent_6.qualified1">
+ <operation name="add" requires="cns:tuscanyIntent_6.qualified2" policySets="cns:tuscanyPolicySet_4"/>
+ </implementation.java>
+ </component>
+</composite>
diff --git a/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions.xml b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions.xml
new file mode 100644
index 0000000000..cad25f1f73
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="ASCII"?>
+<!--
+ * 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.
+-->
+<sca:definitions xmlns="http://test"
+ targetNamespace="http://test"
+ xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903">
+
+<!-- simple intent -->
+ <sca:intent name="tuscanyIntent_1"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_2"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_3"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_4"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+<sca:intent name="tuscanyIntent_5"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_6"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_7"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_8"
+ constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <!-- qualified intents -->
+ <sca:intent name="tuscanyIntent_1.qualified" />
+ <sca:intent name="tuscanyIntent_2.qualified" />
+ <sca:intent name="tuscanyIntent_6.qualified1" />
+ <sca:intent name="tuscanyIntent_6.qualified2" />
+
+ <sca:policySet name="tuscanyPolicySet_4"
+ provides="tuscanyIntent_6"
+ appliesTo="/sca:composite/sca:component"
+ xmlns="http://test"
+ xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
+ <sca:intentMap provides="tuscanyIntent_6" default="qualified2">
+ <sca:qualifier name="qualified2">
+ <wsp:Policy>
+ <!-- policy expression and policy subject for "qualified2" alternative" -->
+ </wsp:Policy>
+ </sca:qualifier>
+ </sca:intentMap>
+ </sca:policySet>
+</sca:definitions> \ No newline at end of file
diff --git a/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions_with_policysets.xml b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions_with_policysets.xml
new file mode 100644
index 0000000000..00319950c6
--- /dev/null
+++ b/java/sca/modules/implementation-java/src/test/resources/org/apache/tuscany/sca/implementation/java/xml/definitions_with_policysets.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="ASCII"?>
+<!--
+ * 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.
+-->
+<sca:definitions xmlns="http://test" targetNamespace="http://test" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200903">
+
+ <!-- simple intent -->
+ <sca:intent name="tuscanyIntent_1" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ <!-- qualified intents -->
+ <sca:qualifier name="qualified" default="true"/>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_2" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ <sca:qualifier name="qualified" default="true"/>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_3" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_4" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_5" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_6" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ <sca:qualifier name="qualified1" default="true"/>
+ <sca:qualifier name="qualified2" />
+
+
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_7" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="tuscanyIntent_8" constrains="sca:binding sca:implementation.java">
+ <sca:description>
+ Sample Intent
+ </sca:description>
+ </sca:intent>
+
+ <sca:policySet name="tuscanyPolicySet_1" provides="tuscanyIntent_1 tuscanyIntent_2 tuscanyIntent_3"
+ appliesTo="/sca:composite/sca:component" xmlns="http://test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
+ </sca:policySet>
+
+ <sca:policySet name="tuscanyPolicySet_2" provides="tuscanyIntent_4 tuscanyIntent_5" appliesTo="/sca:composite/sca:component"
+ xmlns="http://test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
+ </sca:policySet>
+
+ <sca:policySet name="tuscanyPolicySet_3" provides="tuscanyIntent_6" appliesTo="/sca:composite/sca:component"
+ xmlns="http://test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
+ <sca:intentMap provides="tuscanyIntent_6" default="qualified1">
+ <sca:qualifier name="qualified1">
+ <wsp:Policy>
+ <!-- policy expression and policy subject for "qualified1" alternative -->
+ </wsp:Policy>
+ </sca:qualifier>
+ <sca:qualifier name="qualifed2">
+ <wsp:Policy>
+ <!-- policy expression and policy subject for "qualified2" alternative" -->
+ </wsp:Policy>
+ </sca:qualifier>
+ </sca:intentMap>
+ </sca:policySet>
+
+ <sca:policySet name="tuscanyPolicySet_4" provides="tuscanyIntent_6" appliesTo="/sca:composite/sca:component"
+ xmlns="http://test" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
+ <sca:intentMap provides="tuscanyIntent_6" default="qualified2">
+ <sca:qualifier name="qualified2">
+ <wsp:Policy>
+ <!-- policy expression and policy subject for "qualified2" alternative" -->
+ </wsp:Policy>
+ </sca:qualifier>
+ </sca:intentMap>
+ </sca:policySet>
+
+</sca:definitions> \ No newline at end of file