summaryrefslogtreecommitdiffstats
path: root/java/sca/modules/node-impl/src
diff options
context:
space:
mode:
authorrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2008-08-19 00:08:11 +0000
committerrfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68>2008-08-19 00:08:11 +0000
commit994c753d4c4f224e7b93fa8dc6ae807367317678 (patch)
treeea4ce5ea2cdb66ffc4d60b1bf1d7786eb8c731f5 /java/sca/modules/node-impl/src
parent400713c5c4c89dfcc7e77f502003af63e1098c15 (diff)
Add SCANodeFactory/SCANode and rename the artifact ids from node2-xxx to node-xxx
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@686901 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/node-impl/src')
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2FactoryImpl.java57
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2Impl.java63
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java55
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java818
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBootStrapper.java385
-rw-r--r--java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBuilder.java261
-rw-r--r--java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANode2Factory17
-rw-r--r--java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANodeFactory17
-rw-r--r--java/sca/modules/node-impl/src/test/java/hello/HelloWorld.java30
-rw-r--r--java/sca/modules/node-impl/src/test/java/hello/HelloWorldImpl.java30
-rw-r--r--java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/Node2ImplTestCase.java119
-rw-r--r--java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeImplTestCase.java119
-rw-r--r--java/sca/modules/node-impl/src/test/resources/HelloWorld.composite30
-rw-r--r--java/sca/modules/node-impl/src/test/resources/META-INF/sca-contribution.xml23
14 files changed, 2024 insertions, 0 deletions
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2FactoryImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2FactoryImpl.java
new file mode 100644
index 0000000000..419900c5ac
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2FactoryImpl.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 org.apache.tuscany.sca.node.impl;
+
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode2;
+import org.apache.tuscany.sca.node.SCANode2Factory;
+
+/**
+ * Default implementation of an SCA node factory.
+ *
+ * @version $Rev$ $Date$
+ * @deprecated
+ */
+@Deprecated
+public class Node2FactoryImpl extends SCANode2Factory {
+ public Node2FactoryImpl() {
+ }
+
+ @Override
+ public SCANode2 createSCANodeFromClassLoader(String compositeURI, ClassLoader classLoader) {
+ return new Node2Impl(classLoader, compositeURI);
+ }
+
+ @Override
+ public SCANode2 createSCANodeFromURL(String configurationURI) {
+ return new Node2Impl(configurationURI);
+ }
+
+ @Override
+ public SCANode2 createSCANode(String compositeURI, SCAContribution... contributions) {
+ return new Node2Impl(compositeURI, contributions);
+ }
+
+ @Override
+ public SCANode2 createSCANode(String compositeURI, String compositeContent, SCAContribution... contributions) {
+ return new Node2Impl(compositeURI, compositeContent, contributions);
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2Impl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2Impl.java
new file mode 100644
index 0000000000..bc2f10fb7e
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/Node2Impl.java
@@ -0,0 +1,63 @@
+/*
+ * 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.node.impl;
+
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode2;
+
+/**
+ * Node2 Impl
+ */
+public class Node2Impl extends NodeImpl implements SCANode2 {
+
+ /**
+ * @param configurationURI
+ */
+ public Node2Impl(String configurationURI) {
+ super(configurationURI);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param classLoader
+ * @param compositeURI
+ */
+ public Node2Impl(ClassLoader classLoader, String compositeURI) {
+ super(classLoader, compositeURI);
+ }
+
+ /**
+ * @param compositeURI
+ * @param contributions
+ */
+ public Node2Impl(String compositeURI, SCAContribution[] contributions) {
+ super(compositeURI, contributions);
+ }
+
+ /**
+ * @param compositeURI
+ * @param compositeContent
+ * @param contributions
+ */
+ public Node2Impl(String compositeURI, String compositeContent, SCAContribution[] contributions) {
+ super(compositeURI, compositeContent, contributions);
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java
new file mode 100644
index 0000000000..18b166acdd
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeFactoryImpl.java
@@ -0,0 +1,55 @@
+/*
+ * 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.node.impl;
+
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode;
+import org.apache.tuscany.sca.node.SCANodeFactory;
+
+/**
+ * Default implementation of an SCA node factory.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NodeFactoryImpl extends SCANodeFactory {
+ public NodeFactoryImpl() {
+ }
+
+ @Override
+ public SCANode createSCANodeFromClassLoader(String compositeURI, ClassLoader classLoader) {
+ return new NodeImpl(classLoader, compositeURI);
+ }
+
+ @Override
+ public SCANode createSCANodeFromURL(String configurationURI) {
+ return new NodeImpl(configurationURI);
+ }
+
+ @Override
+ public SCANode createSCANode(String compositeURI, SCAContribution... contributions) {
+ return new NodeImpl(compositeURI, contributions);
+ }
+
+ @Override
+ public SCANode createSCANode(String compositeURI, String compositeContent, SCAContribution... contributions) {
+ return new NodeImpl(compositeURI, compositeContent, contributions);
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java
new file mode 100644
index 0000000000..e35203bc5b
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/NodeImpl.java
@@ -0,0 +1,818 @@
+/*
+* 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.node.impl;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.xml.CompositeDocumentProcessor;
+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.ModelFactoryExtensionPoint;
+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.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.service.util.FileHelper;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.implementation.node.ConfiguredNodeImplementation;
+import org.apache.tuscany.sca.implementation.node.NodeImplementationFactory;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.node.SCAClient;
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode;
+import org.apache.tuscany.sca.runtime.RuntimeComponent;
+import org.apache.tuscany.sca.runtime.RuntimeComponentContext;
+import org.osoa.sca.CallableReference;
+import org.osoa.sca.ServiceReference;
+import org.osoa.sca.ServiceRuntimeException;
+
+/**
+ * A local representation of the SCADomain running on a single node
+ *
+ * @version $Rev$ $Date$
+ */
+public class NodeImpl implements SCANode, SCAClient {
+
+ private static final Logger logger = Logger.getLogger(NodeImpl.class.getName());
+
+ // The node configuration name, used for logging
+ private String configurationName;
+
+ // The Tuscany runtime that does the hard work
+ private RuntimeBootStrapper runtime;
+ private CompositeActivator compositeActivator;
+ private XMLInputFactory inputFactory;
+ private ModelFactoryExtensionPoint modelFactories;
+ private StAXArtifactProcessorExtensionPoint artifactProcessors;
+ private URLArtifactProcessorExtensionPoint documentProcessors;
+ private Monitor monitor;
+
+ private List<Contribution> contributions;
+ // The composite loaded into this node
+ private Composite composite;
+
+ /**
+ * Constructs a new SCA node.
+ *
+ * @param configurationURI the URI of the node configuration information.
+ */
+ NodeImpl(String configurationURI) {
+ configurationName = configurationURI;
+ logger.log(Level.INFO, "Creating node: " + configurationName);
+
+ try {
+ // Initialize the runtime
+ initRuntime();
+
+ // Read the node configuration feed
+ StAXArtifactProcessor<ConfiguredNodeImplementation> configurationProcessor =
+ artifactProcessors.getProcessor(ConfiguredNodeImplementation.class);
+ URL configurationURL = new URL(configurationURI);
+ InputStream is = configurationURL.openStream();
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
+ reader.nextTag();
+ ConfiguredNodeImplementation configuration = configurationProcessor.read(reader);
+ is.close();
+
+ // Resolve contribution URLs
+ for (Contribution contribution : configuration.getContributions()) {
+ URL contributionURL = new URL(configurationURL, contribution.getLocation());
+ contribution.setLocation(contributionURL.toString());
+ }
+
+ // Resolve composite URL
+ URL compositeURL = new URL(configurationURL, configuration.getComposite().getURI());
+ configuration.getComposite().setURI(compositeURL.toString());
+
+ // Configure the node
+ configureNode(configuration);
+
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Construct a node by discovering the node configuration (composite+contrbutions) on the classpath
+ * @param classLoader
+ * @param compositeURI
+ */
+ NodeImpl(ClassLoader classLoader, String compositeURI) {
+ configurationName = compositeURI;
+ logger.log(Level.INFO, "Creating node: " + configurationName);
+
+ if (compositeURI != null) {
+ URI uri = URI.create(compositeURI);
+ if (uri.isAbsolute()) {
+ throw new IllegalArgumentException("Composite URI must be a resource name: " + compositeURI);
+ }
+ }
+ try {
+ // Initialize the runtime
+ initRuntime();
+
+ ConfiguredNodeImplementation config = findNodeConfiguration(compositeURI, classLoader);
+ configureNode(config);
+ } catch (Throwable e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Discover the contribution on the classpath
+ * @param compositeURI
+ * @param classLoader
+ * @return A configured node implementation
+ * @throws Exception
+ */
+ private ConfiguredNodeImplementation findNodeConfiguration(final String compositeURI, ClassLoader classLoader)
+ throws Exception {
+ NodeImplementationFactory nodeImplementationFactory =
+ modelFactories.getFactory(NodeImplementationFactory.class);
+ ConfiguredNodeImplementation config = nodeImplementationFactory.createConfiguredNodeImplementation();
+
+ // Default to thread context classloader
+ if (classLoader == null) {
+ classLoader = Thread.currentThread().getContextClassLoader();
+ }
+ String contributionArtifactPath = compositeURI;
+ URL contributionArtifactURL = null;
+ if (compositeURI != null) {
+ contributionArtifactURL = getResource(classLoader, compositeURI);
+ if (contributionArtifactURL == null) {
+ throw new IllegalArgumentException("Composite not found: " + contributionArtifactPath);
+ }
+ // Set to relative URI to avoid duplicate loading
+ Composite composite = createComposite(compositeURI);
+ config.setComposite(composite);
+ } else {
+ // No composite is specified, tring to search the SCA metadata files
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_META;
+ contributionArtifactURL = getResource(classLoader, Contribution.SCA_CONTRIBUTION_META);
+
+ if (contributionArtifactURL == null) {
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_GENERATED_META;
+ contributionArtifactURL = getResource(classLoader, Contribution.SCA_CONTRIBUTION_GENERATED_META);
+ }
+ if (contributionArtifactURL == null) {
+ contributionArtifactPath = Contribution.SCA_CONTRIBUTION_DEPLOYABLES;
+ contributionArtifactURL = getResource(classLoader, Contribution.SCA_CONTRIBUTION_DEPLOYABLES);
+ }
+
+ // No contribution can be discovered
+ if (contributionArtifactURL == null) {
+ throw new IllegalArgumentException("No default contribution can be discovered on the classpath");
+ }
+
+ // No composite will be created, all deployable composites will be used later
+ }
+
+ Contribution c = getContribution(contributionArtifactURL, contributionArtifactPath);
+ config.getContributions().add(c);
+
+ return config;
+ }
+
+ private Contribution getContribution(URL contributionArtifactURL, String contributionArtifactPath) {
+ URL contributionURL = getContributionURL(contributionArtifactURL, contributionArtifactPath);
+
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+
+ SCAContribution contribution = new SCAContribution(contributionURL.toString(), contributionURL.toString());
+ Contribution c = createContribution(contributionFactory, contribution);
+ return c;
+ }
+
+ public static URL getContributionURL(URL contributionArtifactURL, String contributionArtifactPath) {
+ URL contributionURL = null;
+ // "jar:file://....../something.jar!/a/b/c/app.composite"
+ try {
+ String url = contributionArtifactURL.toExternalForm();
+ String protocol = contributionArtifactURL.getProtocol();
+ if ("file".equals(protocol)) {
+ // directory contribution
+ if (url.endsWith(contributionArtifactPath)) {
+ final String location = url.substring(0, url.lastIndexOf(contributionArtifactPath));
+ // workaround from evil URL/URI form Maven
+ // contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
+ // Allow privileged access to open URL stream. Add FilePermission to added to
+ // security policy file.
+ try {
+ contributionURL = AccessController.doPrivileged(new PrivilegedExceptionAction<URL>() {
+ public URL run() throws IOException {
+ return FileHelper.toFile(new URL(location)).toURI().toURL();
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (MalformedURLException)e.getException();
+ }
+ }
+
+ } else if ("jar".equals(protocol)) {
+ // jar contribution
+ String location = url.substring(4, url.lastIndexOf("!/"));
+ // workaround for evil URL/URI from Maven
+ contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
+
+ } else if ("wsjar".equals(protocol)) {
+ // See https://issues.apache.org/jira/browse/TUSCANY-2219
+ // wsjar contribution
+ String location = url.substring(6, url.lastIndexOf("!/"));
+ // workaround for evil url/uri from maven
+ contributionURL = FileHelper.toFile(new URL(location)).toURI().toURL();
+
+ } else if (protocol != null && (protocol.equals("bundle") || protocol.equals("bundleresource"))) {
+ contributionURL =
+ new URL(contributionArtifactURL.getProtocol(), contributionArtifactURL.getHost(),
+ contributionArtifactURL.getPort(), "/");
+ }
+ } catch (MalformedURLException mfe) {
+ throw new IllegalArgumentException(mfe);
+ }
+ return contributionURL;
+ }
+
+ private static URL getResource(final ClassLoader classLoader, final String compositeURI) {
+ return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ public URL run() {
+ return classLoader.getResource(compositeURI);
+ }
+ });
+ }
+
+ /**
+ * Constructs a new SCA node.
+ *
+ * @param compositeURI
+ * @param contributions
+ */
+ NodeImpl(String compositeURI, SCAContribution[] contributions) {
+ configurationName = compositeURI;
+ logger.log(Level.INFO, "Creating node: " + configurationName);
+
+ try {
+ // Initialize the runtime
+ initRuntime();
+
+ URI uri = compositeURI == null ? null : URI.create(compositeURI);
+ ConfiguredNodeImplementation configuration = null;
+ if (contributions == null || contributions.length == 0) {
+ if (uri != null && uri.getScheme() != null) {
+ throw new IllegalArgumentException("No SCA contributions are provided");
+ }
+ configuration = findNodeConfiguration(compositeURI, null);
+ } else {
+
+ // Create a node configuration
+ NodeImplementationFactory nodeImplementationFactory =
+ modelFactories.getFactory(NodeImplementationFactory.class);
+ configuration = nodeImplementationFactory.createConfiguredNodeImplementation();
+
+ Composite composite = compositeURI == null ? null : createComposite(compositeURI);
+ configuration.setComposite(composite);
+
+
+ // Create contribution models
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ for (SCAContribution c : contributions) {
+ Contribution contribution = createContribution(contributionFactory, c);
+ configuration.getContributions().add(contribution);
+ }
+ }
+
+ // Configure the node
+ configureNode(configuration);
+
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ private Composite createComposite(String compositeURI) {
+ // Create composite model
+ AssemblyFactory assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ Composite composite = assemblyFactory.createComposite();
+ composite.setURI(compositeURI);
+ composite.setUnresolved(true);
+ return composite;
+ }
+
+ /**
+ * Constructs a new SCA node.
+ *
+ * @param compositeURI
+ * @param compositeContent
+ * @param contributions
+ */
+ NodeImpl(String compositeURI, String compositeContent, SCAContribution[] contributions) {
+ configurationName = compositeURI;
+ logger.log(Level.INFO, "Creating node: " + configurationName);
+
+ try {
+ // Initialize the runtime
+ initRuntime();
+
+ ConfiguredNodeImplementation configuration = null;
+ if (contributions == null || contributions.length == 0) {
+ configuration = findNodeConfiguration(compositeURI, null);
+ } else {
+ // Create a node configuration
+ NodeImplementationFactory nodeImplementationFactory =
+ modelFactories.getFactory(NodeImplementationFactory.class);
+ configuration = nodeImplementationFactory.createConfiguredNodeImplementation();
+
+ // Read the composite model
+ StAXArtifactProcessor<Composite> compositeProcessor = artifactProcessors.getProcessor(Composite.class);
+ // URL compositeURL = new URL(compositeURI);
+ logger.log(Level.INFO, "Loading composite: " + compositeURI);
+
+ CompositeDocumentProcessor compositeDocProcessor =
+ (CompositeDocumentProcessor)documentProcessors.getProcessor(Composite.class);
+ composite =
+ compositeDocProcessor.read(URI.create(compositeURI), new ByteArrayInputStream(compositeContent
+ .getBytes("UTF-8")));
+
+ analyzeProblems();
+
+ configuration.setComposite(composite);
+
+ // Create contribution models
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ for (SCAContribution c : contributions) {
+ Contribution contribution = createContribution(contributionFactory, c);
+ configuration.getContributions().add(contribution);
+ }
+ }
+
+ // Configure the node
+ configureNode(configuration);
+
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ private static Contribution createContribution(ContributionFactory contributionFactory, SCAContribution c) {
+ Contribution contribution = contributionFactory.createContribution();
+ contribution.setURI(c.getURI());
+ contribution.setLocation(c.getLocation());
+ contribution.setUnresolved(true);
+ return contribution;
+ }
+
+ /**
+ * Initialize the Tuscany runtime.
+ *
+ * @throws Exception
+ */
+ private void initRuntime() throws Exception {
+
+ // Create a node runtime
+ runtime = new RuntimeBootStrapper(Thread.currentThread().getContextClassLoader());
+ runtime.start();
+
+ // Get the various factories we need
+ ExtensionPointRegistry registry = runtime.getExtensionPointRegistry();
+ modelFactories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ inputFactory = modelFactories.getFactory(XMLInputFactory.class);
+
+ // Create the required artifact processors
+ artifactProcessors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ documentProcessors = registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+
+ // Save the composite activator
+ compositeActivator = runtime.getCompositeActivator();
+
+ // save the monitor
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
+ monitor = monitorFactory.createMonitor();
+ }
+
+ /**
+ * Escape the space in URL string
+ * @param uri
+ * @return
+ */
+ private static URI createURI(String uri) {
+ if (uri.indexOf(' ') != -1) {
+ uri = uri.replace(" ", "%20");
+ }
+ return URI.create(uri);
+ }
+
+ private void configureNode(ConfiguredNodeImplementation configuration) throws Exception {
+
+ // Find if any contribution JARs already available locally on the classpath
+ Map<String, URL> localContributions = localContributions();
+
+ // Load the specified contributions
+ ContributionService contributionService = runtime.getContributionService();
+ contributions = new ArrayList<Contribution>();
+ for (Contribution contribution : configuration.getContributions()) {
+ URI uri = createURI(contribution.getLocation());
+ if (uri.getScheme() == null) {
+ uri = new File(contribution.getLocation()).toURI();
+ }
+ URL contributionURL = uri.toURL();
+
+ // Extract contribution file name
+ String file = contributionURL.getPath();
+ int i = file.lastIndexOf('/');
+ if (i != -1 && i < file.length() - 1) {
+ file = file.substring(i + 1);
+
+ // If we find the local contribution file on the classpath, use it in
+ // place of the original contribution URL
+ URL localContributionURL = localContributions.get(file);
+ if (localContributionURL != null) {
+ contributionURL = localContributionURL;
+ }
+ }
+
+ // Load the contribution
+ logger.log(Level.INFO, "Loading contribution: " + contributionURL);
+ contributions.add(contributionService.contribute(contribution.getURI(), contributionURL, false));
+ analyzeProblems();
+ }
+
+ composite = configuration.getComposite();
+
+ // FIXME: This is a hack to get a list of deployable composites. By design, the deployment composite should
+ // has been configured
+ if (composite == null) {
+ List<Composite> deployables = new ArrayList<Composite>();
+ for (Contribution c : contributions) {
+ deployables.addAll(c.getDeployables());
+ }
+ aggregate(deployables);
+ configuration.setComposite(composite);
+ }
+
+ Contribution contribution = null;
+ if (composite.getName() == null) {
+ // Load the specified composite
+ URL compositeURL;
+
+ URI uri = createURI(configuration.getComposite().getURI());
+ if (uri.getScheme() == null) {
+
+ // If the composite URI is a relative URI, try to resolve it within the contributions
+ contribution = contribution(contributions, uri.toString());
+ if (contribution == null) {
+ throw new IllegalArgumentException("Composite is not found in contributions: " + uri);
+ }
+ compositeURL = new URL(location(contribution, uri.toString()));
+
+ } else {
+
+ // If the composite URI is an absolute URI, use it as is
+ compositeURL = uri.toURL();
+ }
+
+ URLArtifactProcessor<Composite> compositeDocProcessor = documentProcessors.getProcessor(Composite.class);
+ // Read the composite
+ logger.log(Level.INFO, "Loading composite: " + compositeURL);
+ // InputStream is = compositeURL.openStream();
+ // XMLStreamReader reader = inputFactory.createXMLStreamReader(is);
+ composite = compositeDocProcessor.read(null, uri, compositeURL);
+ // reader.close();
+
+ analyzeProblems();
+
+ }
+ // And resolve the composite within the scope of the last contribution
+ if (contribution == null && contributions.size() != 0) {
+ contribution = contributions.get(contributions.size() - 1);
+ }
+
+ // Resolve the given composite within the scope of the selected contribution
+ if (contribution != null) {
+ StAXArtifactProcessor<Composite> compositeProcessor = artifactProcessors.getProcessor(Composite.class);
+ compositeProcessor.resolve(composite, contribution.getModelResolver());
+ analyzeProblems();
+ }
+ // Create a top level composite to host our composite
+ // This is temporary to make the activator happy
+ AssemblyFactory assemblyFactory = runtime.getAssemblyFactory();
+ Composite tempComposite = assemblyFactory.createComposite();
+ tempComposite.setName(new QName("http://tempuri.org", "temp"));
+ tempComposite.setURI("http://tempuri.org");
+
+ // Include the node composite in the top-level composite
+ tempComposite.getIncludes().add(composite);
+
+ // set the top level composite on the composite activator as
+ // logic in callable reference resolution relies on this being
+ // available
+ compositeActivator.setDomainComposite(tempComposite);
+
+ // Build the composite
+ runtime.buildComposite(composite);
+
+ analyzeProblems();
+ }
+
+ /**
+ * Create a deployment composite that includes a list of deployable composites
+ * @param composites
+ */
+ private void aggregate(List<Composite> composites) {
+ if (composites.size() == 0) {
+ throw new IllegalArgumentException("No deployable composite is declared");
+ } else if (composites.size() == 1) {
+ composite = composites.get(0);
+ } else {
+ // Include all composites
+ AssemblyFactory assemblyFactory = runtime.getAssemblyFactory();
+ Composite aggregated = assemblyFactory.createComposite();
+ aggregated.setName(new QName("http://tempuri.org", "aggregated"));
+ aggregated.setURI("http://tempuri.org/aggregated");
+ aggregated.getIncludes().addAll(composites);
+ composite = aggregated;
+ }
+ }
+
+ /**
+ * Returns the artifact representing the given composite.
+ *
+ * @param contribution
+ * @param compositeURI
+ * @return
+ */
+ private String location(Contribution contribution, String uri) {
+ if (uri != null && uri.startsWith("/")) {
+ uri = uri.substring(1);
+ }
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ Artifact compositeFile = contributionFactory.createArtifact();
+ compositeFile.setUnresolved(true);
+ compositeFile.setURI(uri);
+ ModelResolver resolver = contribution.getModelResolver();
+ Artifact resolved = resolver.resolveModel(Artifact.class, compositeFile);
+ if (resolved != null && !resolved.isUnresolved()) {
+ return resolved.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the contribution containing the given composite.
+ *
+ * @param contributions
+ * @param compositeURI
+ * @return
+ */
+ private Contribution contribution(List<Contribution> contributions, String compositeURI) {
+ if (compositeURI != null && compositeURI.startsWith("/")) {
+ compositeURI = compositeURI.substring(1);
+ }
+ ContributionFactory contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ Artifact compositeFile = contributionFactory.createArtifact();
+ compositeFile.setUnresolved(true);
+ compositeFile.setURI(compositeURI);
+ for (Contribution c : contributions) {
+ ModelResolver resolver = c.getModelResolver();
+ Artifact resolved = resolver.resolveModel(Artifact.class, compositeFile);
+ if (resolved != null && !resolved.isUnresolved()) {
+ return c;
+ }
+ }
+ return null;
+ }
+
+ private void analyzeProblems() throws Exception {
+
+ for (Problem problem : monitor.getProblems()) {
+ if ((problem.getSeverity() == Severity.ERROR) && (!problem.getMessageId().equals("SchemaError"))) {
+ if (problem.getCause() != null) {
+ throw problem.getCause();
+ } else {
+ throw new ServiceRuntimeException(problem.toString());
+ }
+ }
+ }
+ }
+
+ public void start() {
+ logger.log(Level.INFO, "Starting node: " + configurationName);
+
+ try {
+
+ // Activate the composite
+ compositeActivator.activate(composite);
+
+ // Start the composite
+ compositeActivator.start(composite);
+
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public void stop() {
+ logger.log(Level.INFO, "Stopping node: " + configurationName);
+
+ try {
+
+ // Stop the composite
+ compositeActivator.stop(composite);
+
+ // Deactivate the composite
+ compositeActivator.deactivate(composite);
+
+ runtime.stop();
+ } catch (ActivationException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ public <B, R extends CallableReference<B>> R cast(B target) throws IllegalArgumentException {
+ return (R)runtime.getProxyFactory().cast(target);
+ }
+
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+
+ ServiceReference<B> serviceReference = getServiceReference(businessInterface, serviceName);
+ if (serviceReference == null) {
+ throw new ServiceRuntimeException("Service not found: " + serviceName);
+ }
+ return serviceReference.getService();
+ }
+
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String name) {
+
+ // Extract the component name
+ String componentName;
+ String serviceName;
+ int i = name.indexOf('/');
+ if (i != -1) {
+ componentName = name.substring(0, i);
+ serviceName = name.substring(i + 1);
+
+ } else {
+ componentName = name;
+ serviceName = null;
+ }
+
+ // Lookup the component
+ Component component = null;
+
+ for (Component compositeComponent : composite.getComponents()) {
+ if (compositeComponent.getName().equals(componentName)) {
+ component = compositeComponent;
+ }
+ }
+
+ if (component == null) {
+ throw new ServiceRuntimeException("The service " + name + " has not been contributed to the domain");
+ }
+ RuntimeComponentContext componentContext = null;
+
+ // If the component is a composite, then we need to find the
+ // non-composite component that provides the requested service
+ if (component.getImplementation() instanceof Composite) {
+ for (ComponentService componentService : component.getServices()) {
+ if (serviceName == null || serviceName.equals(componentService.getName())) {
+ CompositeService compositeService = (CompositeService)componentService.getService();
+ if (compositeService != null) {
+ if (serviceName != null) {
+ serviceName = "$promoted$." + component.getName() + "." + serviceName;
+ }
+ componentContext =
+ ((RuntimeComponent)compositeService.getPromotedComponent()).getComponentContext();
+ return componentContext.createSelfReference(businessInterface, compositeService
+ .getPromotedService());
+ }
+ break;
+ }
+ }
+ // No matching service found
+ throw new ServiceRuntimeException("Composite service not found: " + name);
+ } else {
+ componentContext = ((RuntimeComponent)component).getComponentContext();
+ if (serviceName != null) {
+ return componentContext.createSelfReference(businessInterface, serviceName);
+ } else {
+ return componentContext.createSelfReference(businessInterface);
+ }
+ }
+ }
+
+ /**
+ * Returns the extension point registry used by this node.
+ *
+ * @return
+ */
+ public ExtensionPointRegistry getExtensionPointRegistry() {
+ return runtime.getExtensionPointRegistry();
+ }
+
+ /**
+ * Returns the composite being run by this node.
+ *
+ * @return
+ */
+ public Composite getComposite() {
+ return composite;
+ }
+
+ /**
+ * Returns contribution JARs available on the classpath.
+ *
+ * @return
+ */
+ private static Map<String, URL> localContributions() {
+ Map<String, URL> localContributions = new HashMap<String, URL>();
+ collectJARs(localContributions, Thread.currentThread().getContextClassLoader());
+ return localContributions;
+ }
+
+ /**
+ * Collect JARs on the classpath of a URLClassLoader
+ * @param urls
+ * @param cl
+ */
+ private static void collectJARs(Map<String, URL> urls, ClassLoader cl) {
+ if (cl == null) {
+ return;
+ }
+
+ // Collect JARs from the URLClassLoader's classpath
+ if (cl instanceof URLClassLoader) {
+ URL[] jarURLs = ((URLClassLoader)cl).getURLs();
+ if (jarURLs != null) {
+ for (URL jarURL : jarURLs) {
+ String file = jarURL.getPath();
+ int i = file.lastIndexOf('/');
+ if (i != -1 && i < file.length() - 1) {
+ file = file.substring(i + 1);
+ urls.put(file, jarURL);
+ }
+ }
+ }
+ }
+
+ // Collect JARs from the parent ClassLoader
+ collectJARs(urls, cl.getParent());
+ }
+
+ public CompositeActivator getCompositeActivator() {
+ return compositeActivator;
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBootStrapper.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBootStrapper.java
new file mode 100644
index 0000000000..c9995d6024
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBootStrapper.java
@@ -0,0 +1,385 @@
+/*
+ * 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.node.impl;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.EndpointFactory;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilderException;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ModuleActivator;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;
+import org.apache.tuscany.sca.core.invocation.ExtensibleProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.invocation.ProxyFactoryExtensionPoint;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.definitions.SCADefinitions;
+import org.apache.tuscany.sca.definitions.impl.SCADefinitionsImpl;
+import org.apache.tuscany.sca.definitions.util.SCADefinitionsUtil;
+import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
+import org.apache.tuscany.sca.extensibility.ServiceDiscovery;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.monitor.impl.DefaultMonitorFactoryImpl;
+import org.apache.tuscany.sca.policy.DefaultIntentAttachPointTypeFactory;
+import org.apache.tuscany.sca.policy.DefaultPolicyFactory;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.IntentAttachPointType;
+import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.provider.SCADefinitionsProvider;
+import org.apache.tuscany.sca.provider.SCADefinitionsProviderExtensionPoint;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeBootStrapper {
+ private static final Logger logger = Logger.getLogger(RuntimeBootStrapper.class.getName());
+ private List<ModuleActivator> modules;
+ private ExtensionPointRegistry registry;
+
+ private ClassLoader classLoader;
+ private AssemblyFactory assemblyFactory;
+ private ContributionService contributionService;
+ private CompositeActivator compositeActivator;
+ private CompositeBuilder compositeBuilder;
+ // private DomainBuilder domainBuilder;
+ private WorkScheduler workScheduler;
+ private ScopeRegistry scopeRegistry;
+ private ProxyFactory proxyFactory;
+ private List<SCADefinitions> policyDefinitions;
+ private ModelResolver policyDefinitionsResolver;
+ private Monitor monitor;
+
+ public RuntimeBootStrapper(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ public void start() throws ActivationException {
+ long start = System.currentTimeMillis();
+
+ // Create our extension point registry
+ registry = new DefaultExtensionPointRegistry();
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+
+ // Get work scheduler
+ workScheduler = utilities.getUtility(WorkScheduler.class);
+
+ // Create an interface contract mapper
+ InterfaceContractMapper mapper = utilities.getUtility(InterfaceContractMapper.class);
+
+ // Get factory extension point
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+
+ // Get Message factory
+ MessageFactory messageFactory = factories.getFactory(MessageFactory.class);
+
+ // Get proxy factory
+ ProxyFactoryExtensionPoint proxyFactories = registry.getExtensionPoint(ProxyFactoryExtensionPoint.class);
+ proxyFactory = new ExtensibleProxyFactory(proxyFactories);
+
+ // Create model factories
+ assemblyFactory = new RuntimeAssemblyFactory();
+ factories.addFactory(assemblyFactory);
+ PolicyFactory policyFactory = new DefaultPolicyFactory();
+ factories.addFactory(policyFactory);
+
+ // Load the runtime modules
+ modules = loadModules(registry);
+
+ // Start the runtime modules
+ startModules(registry, modules);
+
+ SCABindingFactory scaBindingFactory = factories.getFactory(SCABindingFactory.class);
+ IntentAttachPointTypeFactory intentAttachPointTypeFactory = new DefaultIntentAttachPointTypeFactory();
+ factories.addFactory(intentAttachPointTypeFactory);
+ ContributionFactory contributionFactory = factories.getFactory(ContributionFactory.class);
+
+ // Create a monitor
+ MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
+
+ if (monitorFactory != null) {
+ monitor = monitorFactory.createMonitor();
+ } else {
+ monitorFactory = new DefaultMonitorFactoryImpl();
+ monitor = monitorFactory.createMonitor();
+ utilities.addUtility(monitorFactory);
+ //logger.fine("No MonitorFactory is found on the classpath.");
+ }
+
+ // Create a contribution service
+ policyDefinitions = new ArrayList<SCADefinitions>();
+ policyDefinitionsResolver = new DefaultModelResolver();
+ contributionService =
+ RuntimeBuilder.createContributionService(classLoader,
+ registry,
+ contributionFactory,
+ assemblyFactory,
+ policyFactory,
+ mapper,
+ policyDefinitions,
+ policyDefinitionsResolver,
+ monitor);
+
+ // Create the ScopeRegistry
+ scopeRegistry = RuntimeBuilder.createScopeRegistry(registry);
+
+ // Create a composite activator
+ compositeActivator =
+ RuntimeBuilder.createCompositeActivator(registry,
+ assemblyFactory,
+ messageFactory,
+ scaBindingFactory,
+ mapper,
+ proxyFactory,
+ scopeRegistry,
+ workScheduler);
+
+ // Load the definitions.xml
+ loadSCADefinitions();
+
+ if (logger.isLoggable(Level.FINE)) {
+ long end = System.currentTimeMillis();
+ logger.fine("The tuscany runtime is started in " + (end - start) + " ms.");
+ }
+ }
+
+ public void stop() throws ActivationException {
+ long start = System.currentTimeMillis();
+
+ // Stop the runtime modules
+ stopModules(registry, modules);
+
+ // Stop and destroy the work manager
+ workScheduler.destroy();
+
+ // Cleanup
+ modules = null;
+ registry = null;
+ assemblyFactory = null;
+ contributionService = null;
+ compositeActivator = null;
+ workScheduler = null;
+ scopeRegistry = null;
+
+ if (logger.isLoggable(Level.FINE)) {
+ long end = System.currentTimeMillis();
+ logger.fine("The tuscany runtime is stopped in " + (end - start) + " ms.");
+ }
+ }
+
+ public void buildComposite(Composite composite) throws CompositeBuilderException {
+ //Get factory extension point
+ ModelFactoryExtensionPoint factories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+ SCABindingFactory scaBindingFactory = factories.getFactory(SCABindingFactory.class);
+ IntentAttachPointTypeFactory intentAttachPointTypeFactory =
+ factories.getFactory(IntentAttachPointTypeFactory.class);
+ EndpointFactory endpointFactory = factories.getFactory(EndpointFactory.class);
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ InterfaceContractMapper mapper = utilities.getUtility(InterfaceContractMapper.class);
+
+ //Create a composite builder
+ SCADefinitions aggregatedDefinitions = new SCADefinitionsImpl();
+ for (SCADefinitions definition : ((List<SCADefinitions>)policyDefinitions)) {
+ SCADefinitionsUtil.aggregateSCADefinitions(definition, aggregatedDefinitions);
+ }
+ compositeBuilder =
+ RuntimeBuilder.createCompositeBuilder(monitor,
+ assemblyFactory,
+ scaBindingFactory,
+ endpointFactory,
+ intentAttachPointTypeFactory,
+ mapper,
+ aggregatedDefinitions);
+ compositeBuilder.build(composite);
+
+ }
+
+ public ContributionService getContributionService() {
+ return contributionService;
+ }
+
+ public CompositeActivator getCompositeActivator() {
+ return compositeActivator;
+ }
+
+ public CompositeBuilder getCompositeBuilder() {
+ return compositeBuilder;
+ }
+
+ public AssemblyFactory getAssemblyFactory() {
+ return assemblyFactory;
+ }
+
+ private void loadSCADefinitions() throws ActivationException {
+ try {
+ URLArtifactProcessorExtensionPoint documentProcessors =
+ registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+ URLArtifactProcessor<SCADefinitions> definitionsProcessor =
+ documentProcessors.getProcessor(SCADefinitions.class);
+ SCADefinitionsProviderExtensionPoint scaDefnProviders =
+ registry.getExtensionPoint(SCADefinitionsProviderExtensionPoint.class);
+
+ SCADefinitions systemSCADefinitions = new SCADefinitionsImpl();
+ SCADefinitions aSCADefn = null;
+ for (SCADefinitionsProvider aProvider : scaDefnProviders.getSCADefinitionsProviders()) {
+ aSCADefn = aProvider.getSCADefinition();
+ SCADefinitionsUtil.aggregateSCADefinitions(aSCADefn, systemSCADefinitions);
+ }
+
+ policyDefinitions.add(systemSCADefinitions);
+
+ //we cannot expect that providers will add the intents and policysets into the resolver
+ //so we do this here explicitly
+ for (Intent intent : systemSCADefinitions.getPolicyIntents()) {
+ policyDefinitionsResolver.addModel(intent);
+ }
+
+ for (PolicySet policySet : systemSCADefinitions.getPolicySets()) {
+ policyDefinitionsResolver.addModel(policySet);
+ }
+
+ for (IntentAttachPointType attachPoinType : systemSCADefinitions.getBindingTypes()) {
+ policyDefinitionsResolver.addModel(attachPoinType);
+ }
+
+ for (IntentAttachPointType attachPoinType : systemSCADefinitions.getImplementationTypes()) {
+ policyDefinitionsResolver.addModel(attachPoinType);
+ }
+
+ //now that all system sca definitions have been read, lets resolve them right away
+ definitionsProcessor.resolve(systemSCADefinitions, policyDefinitionsResolver);
+ } catch (Exception e) {
+ throw new ActivationException(e);
+ }
+ }
+
+ private List<ModuleActivator> loadModules(ExtensionPointRegistry registry) throws ActivationException {
+
+ // Load and instantiate the modules found on the classpath (or any registered ClassLoaders)
+ modules = new ArrayList<ModuleActivator>();
+ try {
+ Set<ServiceDeclaration> moduleActivators =
+ ServiceDiscovery.getInstance().getServiceDeclarations(ModuleActivator.class);
+ Set<String> moduleClasses = new HashSet<String>();
+ for (ServiceDeclaration moduleDeclarator : moduleActivators) {
+ if (moduleClasses.contains(moduleDeclarator.getClassName())) {
+ continue;
+ }
+ moduleClasses.add(moduleDeclarator.getClassName());
+ Class<?> moduleClass = moduleDeclarator.loadClass();
+ ModuleActivator module = (ModuleActivator)moduleClass.newInstance();
+ modules.add(module);
+ }
+ } catch (IOException e) {
+ throw new ActivationException(e);
+ } catch (ClassNotFoundException e) {
+ throw new ActivationException(e);
+ } catch (InstantiationException e) {
+ throw new ActivationException(e);
+ } catch (IllegalAccessException e) {
+ throw new ActivationException(e);
+ }
+
+ return modules;
+ }
+
+ private void startModules(ExtensionPointRegistry registry, List<ModuleActivator> modules)
+ throws ActivationException {
+ boolean debug = logger.isLoggable(Level.FINE);
+ // Start all the extension modules
+ for (ModuleActivator module : modules) {
+ long start = 0L;
+ if (debug) {
+ logger.fine(module.getClass().getName() + " is starting.");
+ start = System.currentTimeMillis();
+ }
+ try {
+ module.start(registry);
+ if (debug) {
+ long end = System.currentTimeMillis();
+ logger.fine(module.getClass().getName() + " is started in " + (end - start) + " ms.");
+ }
+ } catch (Throwable e) {
+ logger.log(Level.WARNING, "Exception starting module " + module.getClass().getName()
+ + " :"
+ + e.getMessage());
+ logger.log(Level.FINE, "Exception starting module " + module.getClass().getName(), e);
+ }
+ }
+ }
+
+ private void stopModules(final ExtensionPointRegistry registry, List<ModuleActivator> modules) {
+ boolean debug = logger.isLoggable(Level.FINE);
+ for (ModuleActivator module : modules) {
+ long start = 0L;
+ if (debug) {
+ logger.fine(module.getClass().getName() + " is stopping.");
+ start = System.currentTimeMillis();
+ }
+ module.stop(registry);
+ if (debug) {
+ long end = System.currentTimeMillis();
+ logger.fine(module.getClass().getName() + " is stopped in " + (end - start) + " ms.");
+ }
+ }
+ }
+
+ /**
+ * @return the proxyFactory
+ */
+ public ProxyFactory getProxyFactory() {
+ return proxyFactory;
+ }
+
+ /**
+ * @return the registry
+ */
+ public ExtensionPointRegistry getExtensionPointRegistry() {
+ return registry;
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBuilder.java b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBuilder.java
new file mode 100644
index 0000000000..98a44cef9e
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/java/org/apache/tuscany/sca/node/impl/RuntimeBuilder.java
@@ -0,0 +1,261 @@
+/*
+ * 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.node.impl;
+
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.List;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.EndpointFactory;
+import org.apache.tuscany.sca.assembly.SCABindingFactory;
+import org.apache.tuscany.sca.assembly.builder.CompositeBuilder;
+import org.apache.tuscany.sca.assembly.builder.impl.CompositeBuilderImpl;
+import org.apache.tuscany.sca.assembly.xml.CompositeDocumentProcessor;
+import org.apache.tuscany.sca.context.ContextFactoryExtensionPoint;
+import org.apache.tuscany.sca.context.RequestContextFactory;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ModelFactoryExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.DefaultValidatingXMLInputFactory;
+import org.apache.tuscany.sca.contribution.processor.DefaultValidationSchemaExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ExtensiblePackageProcessor;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.PackageProcessor;
+import org.apache.tuscany.sca.contribution.processor.PackageProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.contribution.service.ContributionListenerExtensionPoint;
+import org.apache.tuscany.sca.contribution.service.ContributionRepository;
+import org.apache.tuscany.sca.contribution.service.ContributionService;
+import org.apache.tuscany.sca.contribution.service.ExtensibleContributionListener;
+import org.apache.tuscany.sca.contribution.service.TypeDescriber;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionRepositoryImpl;
+import org.apache.tuscany.sca.contribution.service.impl.ContributionServiceImpl;
+import org.apache.tuscany.sca.contribution.service.impl.PackageTypeDescriberImpl;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.ActivationException;
+import org.apache.tuscany.sca.core.assembly.CompositeActivator;
+import org.apache.tuscany.sca.core.assembly.CompositeActivatorImpl;
+import org.apache.tuscany.sca.core.conversation.ConversationManager;
+import org.apache.tuscany.sca.core.invocation.ExtensibleWireProcessor;
+import org.apache.tuscany.sca.core.invocation.ProxyFactory;
+import org.apache.tuscany.sca.core.scope.CompositeScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ConversationalScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.RequestScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ScopeContainerFactory;
+import org.apache.tuscany.sca.core.scope.ScopeRegistry;
+import org.apache.tuscany.sca.core.scope.ScopeRegistryImpl;
+import org.apache.tuscany.sca.core.scope.StatelessScopeContainerFactory;
+import org.apache.tuscany.sca.definitions.SCADefinitions;
+import org.apache.tuscany.sca.endpointresolver.EndpointResolverFactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper;
+import org.apache.tuscany.sca.interfacedef.java.JavaInterfaceFactory;
+import org.apache.tuscany.sca.invocation.MessageFactory;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.policy.IntentAttachPointTypeFactory;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.provider.ProviderFactoryExtensionPoint;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessor;
+import org.apache.tuscany.sca.runtime.RuntimeWireProcessorExtensionPoint;
+import org.apache.tuscany.sca.work.WorkScheduler;
+
+/**
+ *
+ * @version $Rev$ $Date$
+ */
+public class RuntimeBuilder {
+
+ // private static final Logger logger = Logger.getLogger(RuntimeBuilder.class.getName());
+
+ public static CompositeActivator createCompositeActivator(ExtensionPointRegistry registry,
+ AssemblyFactory assemblyFactory,
+ MessageFactory messageFactory,
+ SCABindingFactory scaBindingFactory,
+ InterfaceContractMapper mapper,
+ ProxyFactory proxyFactory,
+ ScopeRegistry scopeRegistry,
+ WorkScheduler workScheduler) {
+
+ // Create a wire post processor extension point
+ RuntimeWireProcessorExtensionPoint wireProcessors =
+ registry.getExtensionPoint(RuntimeWireProcessorExtensionPoint.class);
+ RuntimeWireProcessor wireProcessor = new ExtensibleWireProcessor(wireProcessors);
+
+ // Retrieve the processors extension point
+ StAXArtifactProcessorExtensionPoint processors =
+ registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ // Create a provider factory extension point
+ ProviderFactoryExtensionPoint providerFactories =
+ registry.getExtensionPoint(ProviderFactoryExtensionPoint.class);
+
+ // Create a endpoint resolver factory extension point
+ EndpointResolverFactoryExtensionPoint endpointResolverFactories =
+ registry.getExtensionPoint(EndpointResolverFactoryExtensionPoint.class);
+
+ JavaInterfaceFactory javaInterfaceFactory =
+ registry.getExtensionPoint(ModelFactoryExtensionPoint.class).getFactory(JavaInterfaceFactory.class);
+ RequestContextFactory requestContextFactory =
+ registry.getExtensionPoint(ContextFactoryExtensionPoint.class).getFactory(RequestContextFactory.class);
+
+ UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class);
+ ConversationManager conversationManager = utilities.getUtility(ConversationManager.class);
+
+ // Create the composite activator
+ CompositeActivator compositeActivator =
+ new CompositeActivatorImpl(assemblyFactory, messageFactory, javaInterfaceFactory, scaBindingFactory,
+ mapper, scopeRegistry, workScheduler, wireProcessor, requestContextFactory,
+ proxyFactory, providerFactories, endpointResolverFactories, processors,
+ conversationManager);
+
+ return compositeActivator;
+ }
+
+ public static CompositeBuilder createCompositeBuilder(Monitor monitor,
+ AssemblyFactory assemblyFactory,
+ SCABindingFactory scaBindingFactory,
+ EndpointFactory endpointFactory,
+ IntentAttachPointTypeFactory intentAttachPointTypeFactory,
+ InterfaceContractMapper interfaceContractMapper,
+ SCADefinitions policyDefinitions) {
+
+ return new CompositeBuilderImpl(assemblyFactory, endpointFactory, scaBindingFactory,
+ intentAttachPointTypeFactory, interfaceContractMapper, policyDefinitions,
+ monitor);
+ }
+
+ /**
+ * Create the contribution service used by this domain.
+ *
+ * @throws ActivationException
+ */
+ public static ContributionService createContributionService(ClassLoader classLoader,
+ ExtensionPointRegistry registry,
+ ContributionFactory contributionFactory,
+ AssemblyFactory assemblyFactory,
+ PolicyFactory policyFactory,
+ InterfaceContractMapper mapper,
+ List<SCADefinitions> policyDefinitions,
+ ModelResolver policyDefinitionResolver,
+ Monitor monitor) throws ActivationException {
+
+ // Get the model factory extension point
+ ModelFactoryExtensionPoint modelFactories = registry.getExtensionPoint(ModelFactoryExtensionPoint.class);
+
+ // Create a new XML input factory
+ // Allow privileged access to factory. Requires RuntimePermission in security policy file.
+ XMLInputFactory inputFactory = AccessController.doPrivileged(new PrivilegedAction<XMLInputFactory>() {
+ public XMLInputFactory run() {
+ return XMLInputFactory.newInstance();
+ }
+ });
+ modelFactories.addFactory(inputFactory);
+
+ // Create a validation XML schema extension point
+ ValidationSchemaExtensionPoint schemas = new DefaultValidationSchemaExtensionPoint();
+
+ // Create a validating XML input factory
+ XMLInputFactory validatingInputFactory = new DefaultValidatingXMLInputFactory(inputFactory, schemas, monitor);
+ modelFactories.addFactory(validatingInputFactory);
+
+ // Create StAX artifact processor extension point
+ StAXArtifactProcessorExtensionPoint staxProcessors =
+ registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+
+ // Create and register StAX processors for SCA assembly XML
+ // Allow privileged access to factory. Requires RuntimePermission in security policy file.
+ XMLOutputFactory outputFactory = AccessController.doPrivileged(new PrivilegedAction<XMLOutputFactory>() {
+ public XMLOutputFactory run() {
+ return XMLOutputFactory.newInstance();
+ }
+ });
+ ExtensibleStAXArtifactProcessor staxProcessor =
+ new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, monitor);
+
+ // Create URL artifact processor extension point
+ URLArtifactProcessorExtensionPoint documentProcessors =
+ registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+
+ // Create and register document processors for SCA assembly XML
+ documentProcessors.getProcessor(Composite.class);
+ documentProcessors.addArtifactProcessor(new CompositeDocumentProcessor(staxProcessor, validatingInputFactory,
+ policyDefinitions, monitor));
+
+ // Create Model Resolver extension point
+ ModelResolverExtensionPoint modelResolvers = registry.getExtensionPoint(ModelResolverExtensionPoint.class);
+
+ // Create contribution package processor extension point
+ TypeDescriber describer = new PackageTypeDescriberImpl();
+ PackageProcessor packageProcessor =
+ new ExtensiblePackageProcessor(registry.getExtensionPoint(PackageProcessorExtensionPoint.class), describer,
+ monitor);
+
+ // Create contribution listener
+ ExtensibleContributionListener contributionListener =
+ new ExtensibleContributionListener(registry.getExtensionPoint(ContributionListenerExtensionPoint.class));
+
+ // Create a contribution repository
+ ContributionRepository repository;
+ try {
+ repository = new ContributionRepositoryImpl("target", inputFactory, monitor);
+ } catch (IOException e) {
+ throw new ActivationException(e);
+ }
+
+ ExtensibleURLArtifactProcessor documentProcessor =
+ new ExtensibleURLArtifactProcessor(documentProcessors, monitor);
+
+ // Create the contribution service
+ ContributionService contributionService =
+ new ContributionServiceImpl(repository, packageProcessor, documentProcessor, staxProcessor,
+ contributionListener, policyDefinitionResolver, modelResolvers, modelFactories,
+ assemblyFactory, contributionFactory, inputFactory, policyDefinitions, monitor);
+ return contributionService;
+ }
+
+ public static ScopeRegistry createScopeRegistry(ExtensionPointRegistry registry) {
+ ScopeRegistry scopeRegistry = new ScopeRegistryImpl();
+ ScopeContainerFactory[] factories =
+ new ScopeContainerFactory[] {new CompositeScopeContainerFactory(), new StatelessScopeContainerFactory(),
+ new RequestScopeContainerFactory(),
+ new ConversationalScopeContainerFactory(null),
+ // new HttpSessionScopeContainer(monitor)
+ };
+ for (ScopeContainerFactory f : factories) {
+ scopeRegistry.register(f);
+ }
+
+ //FIXME Pass the scope container differently as it's not an extension point
+ registry.addExtensionPoint(scopeRegistry);
+
+ return scopeRegistry;
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANode2Factory b/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANode2Factory
new file mode 100644
index 0000000000..4215855ac9
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANode2Factory
@@ -0,0 +1,17 @@
+# 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.
+org.apache.tuscany.sca.node.impl.Node2FactoryImpl \ No newline at end of file
diff --git a/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANodeFactory b/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANodeFactory
new file mode 100644
index 0000000000..800bdd84cc
--- /dev/null
+++ b/java/sca/modules/node-impl/src/main/resources/META-INF/services/org.apache.tuscany.sca.node.SCANodeFactory
@@ -0,0 +1,17 @@
+# 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.
+org.apache.tuscany.sca.node.impl.NodeFactoryImpl \ No newline at end of file
diff --git a/java/sca/modules/node-impl/src/test/java/hello/HelloWorld.java b/java/sca/modules/node-impl/src/test/java/hello/HelloWorld.java
new file mode 100644
index 0000000000..2f519cb81d
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/java/hello/HelloWorld.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 hello;
+
+import org.osoa.sca.annotations.Remotable;
+
+/**
+ * HelloWorld interface
+ */
+@Remotable
+public interface HelloWorld {
+ String hello(String name);
+}
diff --git a/java/sca/modules/node-impl/src/test/java/hello/HelloWorldImpl.java b/java/sca/modules/node-impl/src/test/java/hello/HelloWorldImpl.java
new file mode 100644
index 0000000000..c9a7560b12
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/java/hello/HelloWorldImpl.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 hello;
+
+/**
+ * HelloWorldImpl
+ */
+public class HelloWorldImpl implements HelloWorld {
+ public String hello(String name) {
+ System.out.println("Hello: " + name);
+ return "Hello, " + name;
+ }
+}
diff --git a/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/Node2ImplTestCase.java b/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/Node2ImplTestCase.java
new file mode 100644
index 0000000000..52d96dd72d
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/Node2ImplTestCase.java
@@ -0,0 +1,119 @@
+/*
+ * 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.node.impl;
+
+import hello.HelloWorld;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.node.SCAClient;
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode2;
+import org.apache.tuscany.sca.node.SCANode2Factory;
+import org.junit.Test;
+
+/**
+ * Test case for Node2Impl
+ */
+public class Node2ImplTestCase {
+ private static String composite =
+ "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\"" + " xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\""
+ + " targetNamespace=\"http://sample/composite\""
+ + " xmlns:sc=\"http://sample/composite\""
+ + " name=\"HelloWorld\">"
+ + " <component name=\"HelloWorld\">"
+ + " <implementation.java class=\"hello.HelloWorldImpl\"/>"
+ + " </component>"
+ + " </composite>";
+
+ @Test
+ public void testNodeWithCompositeContent() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ SCANode2 node = factory.createSCANode("HelloWorld.composite", composite, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithCompositeContentAndNoContribution() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCANode2 node = factory.createSCANode("HelloWorld.composite", composite);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithoutCompositeURI() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ SCANode2 node = factory.createSCANode(null, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithCompositeURI() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ String compositeURI = new File("target/test-classes/HelloWorld.composite").toURI().toString();
+ SCANode2 node = factory.createSCANode(compositeURI, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithRelativeCompositeURI() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ String compositeURI = "HelloWorld.composite";
+ SCANode2 node = factory.createSCANode(compositeURI, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithRelativeCompositeURIAndNoContribution() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ String compositeURI = "HelloWorld.composite";
+ SCANode2 node = factory.createSCANode(compositeURI, new SCAContribution[0]);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithClassLoader() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ String compositeURI = "HelloWorld.composite";
+ SCANode2 node = factory.createSCANodeFromClassLoader(compositeURI, HelloWorld.class.getClassLoader());
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithClassLoaderAndNullComposite() {
+ SCANode2Factory factory = SCANode2Factory.newInstance();
+ SCANode2 node = factory.createSCANodeFromClassLoader(null, HelloWorld.class.getClassLoader());
+ testNode(node);
+ }
+
+ private void testNode(SCANode2 node) {
+ node.start();
+ HelloWorld hw = ((SCAClient)node).getService(HelloWorld.class, "HelloWorld");
+ Assert.assertEquals("Hello, Node", hw.hello("Node"));
+ node.stop();
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeImplTestCase.java b/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeImplTestCase.java
new file mode 100644
index 0000000000..d620f6b62a
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/java/org/apache/tuscany/sca/node/impl/NodeImplTestCase.java
@@ -0,0 +1,119 @@
+/*
+ * 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.node.impl;
+
+import hello.HelloWorld;
+
+import java.io.File;
+
+import junit.framework.Assert;
+
+import org.apache.tuscany.sca.node.SCAClient;
+import org.apache.tuscany.sca.node.SCAContribution;
+import org.apache.tuscany.sca.node.SCANode;
+import org.apache.tuscany.sca.node.SCANodeFactory;
+import org.junit.Test;
+
+/**
+ * Test case for NodeImpl
+ */
+public class NodeImplTestCase {
+ private static String composite =
+ "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\"" + " xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\""
+ + " targetNamespace=\"http://sample/composite\""
+ + " xmlns:sc=\"http://sample/composite\""
+ + " name=\"HelloWorld\">"
+ + " <component name=\"HelloWorld\">"
+ + " <implementation.java class=\"hello.HelloWorldImpl\"/>"
+ + " </component>"
+ + " </composite>";
+
+ @Test
+ public void testNodeWithCompositeContent() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ SCANode node = factory.createSCANode("HelloWorld.composite", composite, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithCompositeContentAndNoContribution() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCANode node = factory.createSCANode("HelloWorld.composite", composite);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithoutCompositeURI() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ SCANode node = factory.createSCANode(null, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithCompositeURI() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ String compositeURI = new File("target/test-classes/HelloWorld.composite").toURI().toString();
+ SCANode node = factory.createSCANode(compositeURI, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithRelativeCompositeURI() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCAContribution contribution = new SCAContribution("c1", new File("target/test-classes").toURI().toString());
+ String compositeURI = "HelloWorld.composite";
+ SCANode node = factory.createSCANode(compositeURI, contribution);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithRelativeCompositeURIAndNoContribution() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ String compositeURI = "HelloWorld.composite";
+ SCANode node = factory.createSCANode(compositeURI, new SCAContribution[0]);
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithClassLoader() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ String compositeURI = "HelloWorld.composite";
+ SCANode node = factory.createSCANodeFromClassLoader(compositeURI, HelloWorld.class.getClassLoader());
+ testNode(node);
+ }
+
+ @Test
+ public void testNodeWithClassLoaderAndNullComposite() {
+ SCANodeFactory factory = new NodeFactoryImpl();
+ SCANode node = factory.createSCANodeFromClassLoader(null, HelloWorld.class.getClassLoader());
+ testNode(node);
+ }
+
+ private void testNode(SCANode node) {
+ node.start();
+ HelloWorld hw = ((SCAClient)node).getService(HelloWorld.class, "HelloWorld");
+ Assert.assertEquals("Hello, Node", hw.hello("Node"));
+ node.stop();
+ }
+
+}
diff --git a/java/sca/modules/node-impl/src/test/resources/HelloWorld.composite b/java/sca/modules/node-impl/src/test/resources/HelloWorld.composite
new file mode 100644
index 0000000000..9e3299d691
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/resources/HelloWorld.composite
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
+ xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
+ targetNamespace="http://sample/composite"
+ xmlns:sc="http://sample/composite"
+ name="HelloWorld">
+
+ <component name="HelloWorld">
+ <implementation.java class="hello.HelloWorldImpl"/>
+ </component>
+
+</composite>
diff --git a/java/sca/modules/node-impl/src/test/resources/META-INF/sca-contribution.xml b/java/sca/modules/node-impl/src/test/resources/META-INF/sca-contribution.xml
new file mode 100644
index 0000000000..1d37bcebe0
--- /dev/null
+++ b/java/sca/modules/node-impl/src/test/resources/META-INF/sca-contribution.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<contribution xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:sc="http://sample/composite">
+ <deployable composite="sc:HelloWorld" />
+</contribution>