summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org')
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java54
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java160
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java86
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java631
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java55
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.java55
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java141
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java46
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java64
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java108
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java50
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/BindingConfigurationImpl.java54
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java188
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/DeploymentCompositeImpl.java64
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationFactoryImpl.java63
-rw-r--r--sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationImpl.java176
16 files changed, 1995 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java
new file mode 100644
index 0000000000..f69e18dc63
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java
@@ -0,0 +1,54 @@
+/*
+ * 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;
+
+/**
+ * Represents an SCA contribution uri + location.
+ */
+public final class Contribution {
+ private String uri;
+ private String location;
+
+ /**
+ * Constructs a new SCA contribution.
+ *
+ * @param uri The URI that uniquely identifies the contribution in the SCA domain
+ * @param location The URL of the contribution archive
+ */
+ public Contribution(String uri, String location) {
+ this.uri = uri;
+ this.location = location;
+ }
+
+ /**
+ * Get the URI of the contribution
+ * @return The URI that uniquely identifies the contribution in the SCA domain
+ */
+ public String getURI() {
+ return uri;
+ }
+
+ /**
+ * The location of the contribution
+ * @return The URL of the contribution archive
+ */
+ public String getLocation() {
+ return location;
+ }
+} \ No newline at end of file
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java
new file mode 100644
index 0000000000..2e73322917
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java
@@ -0,0 +1,160 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * ContributionLocationHelper
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionLocationHelper {
+
+ /**
+ * Returns the location of the SCA contribution containing the given class.
+ *
+ * @param anchorClass
+ * @return
+ */
+ public static String getContributionLocation(final Class<?> anchorClass) {
+ URL url = AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ public URL run() {
+ return anchorClass.getProtectionDomain().getCodeSource().getLocation();
+ }
+ });
+ String uri = url.toString();
+ return uri;
+ }
+
+ /**
+ * Find the contribution location by seraching a resource on the classpath
+ * @param resourceName
+ * @return
+ */
+ public static String getContributionLocation(String resourceName) {
+ return getContributionLocation(null, resourceName);
+ }
+
+ /**
+ * Find the contribution locations by seraching a resource on the classpath
+ * @param resourceName
+ * @return
+ */
+ public static List<String> getContributionLocations(String resourceName) {
+ return getContributionLocations(null, resourceName);
+
+ }
+
+ /**
+ * Find the contribution location by seraching a resource using the given classloader
+ * @param classLoader
+ * @param resourceName
+ * @return
+ */
+ public static String getContributionLocation(ClassLoader classLoader, String resourceName) {
+ if (classLoader == null) {
+ classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+ URL resourceURL = getResource(classLoader, resourceName);
+ if (resourceURL == null) {
+ return null;
+ }
+ return getRootLocation(resourceURL, resourceName);
+ }
+
+ /**
+ * Find the contribution locations by seraching a resource using the given classloader
+ * @param classLoader The classloader that is used to call getResources()
+ * @param resourceName The name of the resource
+ * @return A list of locations that contain the resource
+ */
+ public static List<String> getContributionLocations(ClassLoader classLoader, String resourceName) {
+ if (classLoader == null) {
+ classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+ public ClassLoader run() {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+ Enumeration<URL> resourceURLs = getResources(classLoader, resourceName);
+ List<String> locations = new ArrayList<String>();
+ while (resourceURLs != null && resourceURLs.hasMoreElements()) {
+ locations.add(getRootLocation(resourceURLs.nextElement(), resourceName));
+ }
+ return locations;
+ }
+
+ private static String getRootLocation(URL resourceURL, String resourceName) {
+ String location = null;
+ // "jar:file://....../something.jar!/a/b/c/app.composite"
+ String url = resourceURL.toExternalForm();
+ String protocol = resourceURL.getProtocol();
+ if ("file".equals(protocol)) {
+ // directory contribution
+ if (url.endsWith(resourceName)) {
+ location = url.substring(0, url.lastIndexOf(resourceName));
+ }
+ } else if ("jar".equals(protocol) || "wsjar".equals(protocol) || "zip".equals(protocol)) {
+ // jar contribution
+ location = url.substring(protocol.length() + 1, url.lastIndexOf("!/"));
+ } else if (url.endsWith(resourceName)) {
+ location = url.substring(0, url.lastIndexOf(resourceName));
+ } else {
+ throw new IllegalArgumentException("The root of the resource cannot be determined: " + resourceURL
+ + ","
+ + resourceName);
+ }
+ return location;
+ }
+
+ private static URL getResource(final ClassLoader classLoader, final String compositeURI) {
+ return AccessController.doPrivileged(new PrivilegedAction<URL>() {
+ public URL run() {
+ return classLoader.getResource(compositeURI);
+ }
+ });
+ }
+
+ private static Enumeration<URL> getResources(final ClassLoader classLoader, final String compositeURI) {
+ return AccessController.doPrivileged(new PrivilegedAction<Enumeration<URL>>() {
+ public Enumeration<URL> run() {
+ try {
+ return classLoader.getResources(compositeURI);
+ } catch (IOException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+ });
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java
new file mode 100644
index 0000000000..502b2f854c
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java
@@ -0,0 +1,86 @@
+/*
+ * 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;
+
+import org.apache.tuscany.sca.node.configuration.NodeConfiguration;
+import org.oasisopen.sca.ServiceReference;
+
+
+
+
+/**
+ * Represents an SCA processing node.
+ * A node is loaded with an SCA composites. It can start and stop that composite.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public interface Node {
+ String DEFAULT_DOMAIN_URI = NodeConfiguration.DEFAULT_DOMAIN_URI;
+ String DEFAULT_NODE_URI = NodeConfiguration.DEFAULT_NODE_URI;
+ /**
+ * Start the composite loaded in the node.
+ * @return Return the node itself so that we can call NodeFactory.newInstance().createNode(...).start()
+ */
+ Node start();
+
+ /**
+ * Stop the composite loaded in the node.
+ */
+ void stop();
+
+ /**
+ * Cast a type-safe reference to a CallableReference. Converts a type-safe
+ * reference to an equivalent CallableReference; if the target refers to a
+ * service then a ServiceReference will be returned, if the target refers to
+ * a callback then a CallableReference will be returned.
+ *
+ * @param target a reference proxy provided by the SCA runtime
+ * @param <B> the Java type of the business interface for the reference
+ * @param <R> the type of reference to be returned
+ * @return a CallableReference equivalent for the proxy
+ * @throws IllegalArgumentException if the supplied instance is not a
+ * reference supplied by the SCA runtime
+ */
+ <B, R extends ServiceReference<B>> R cast(B target) throws IllegalArgumentException;
+
+ /**
+ * Returns a proxy for a service provided by a component in the SCA domain.
+ *
+ * @param businessInterface the interface that will be used to invoke the
+ * service
+ * @param serviceName the name of the service
+ * @param <B> the Java type of the business interface for the service
+ * @return an object that implements the business interface
+ */
+ <B> B getService(Class<B> businessInterface, String serviceName);
+
+ /**
+ * Returns a ServiceReference for a service provided by a component in the
+ * SCA domain.
+ *
+ * @param businessInterface the interface that will be used to invoke the
+ * service
+ * @param serviceName the name of the service
+ * @param <B> the Java type of the business interface for the service
+ * @return a ServiceReference for the designated service
+ */
+ <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String serviceName);
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java
new file mode 100644
index 0000000000..10b49bae4a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java
@@ -0,0 +1,631 @@
+/*
+ * 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;
+
+import static org.apache.tuscany.sca.node.ContributionLocationHelper.getContributionLocations;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.tuscany.sca.node.configuration.DefaultNodeConfigurationFactory;
+import org.apache.tuscany.sca.node.configuration.NodeConfiguration;
+import org.apache.tuscany.sca.node.configuration.NodeConfigurationFactory;
+import org.oasisopen.sca.ServiceReference;
+import org.oasisopen.sca.ServiceRuntimeException;
+
+/**
+ * A factory for SCA processing nodes. An SCA processing node can be loaded
+ * with an SCA composite and the SCA contributions required by the composite.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public abstract class NodeFactory extends DefaultNodeConfigurationFactory {
+ /**
+ * Default location of contribution metadata in an SCA contribution.
+ */
+ private static final String SCA_CONTRIBUTION_META = "META-INF/sca-contribution.xml";
+
+ /**
+ * Default location of a generated contribution metadata in an SCA contribution.
+ */
+ private static final String SCA_CONTRIBUTION_GENERATED_META = "META-INF/sca-contribution-generated.xml";
+
+ protected static NodeFactory instance;
+ protected static Class<?> factoryImplClass;
+
+ protected static List<NodeFactory> factories = new ArrayList<NodeFactory>();
+
+ protected static void setNodeFactory(NodeFactory factory) {
+ instance = factory;
+ }
+
+ public static class NodeProxy implements Node {
+ private Object node;
+
+ private NodeProxy(Object node) {
+ super();
+ this.node = node;
+ }
+
+ public static <T> T createProxy(Class<T> type, Object node) {
+ try {
+ return type.getDeclaredConstructor(Object.class).newInstance(node);
+ } catch (Exception e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public <B, R extends ServiceReference<B>> R cast(B target) throws IllegalArgumentException {
+ try {
+ return (R)node.getClass().getMethod("cast", Object.class).invoke(node, target);
+ } catch (Throwable e) {
+ handleException(e);
+ return null;
+ }
+ }
+
+ public <B> B getService(Class<B> businessInterface, String serviceName) {
+ try {
+ return (B)node.getClass().getMethod("getService", Class.class, String.class).invoke(node, businessInterface, serviceName);
+ } catch (Throwable e) {
+ handleException(e);
+ return null;
+ }
+ }
+
+ public <B> ServiceReference<B> getServiceReference(Class<B> businessInterface, String serviceName) {
+ try {
+ return (ServiceReference<B>)node.getClass().getMethod("getServiceReference", Class.class, String.class).invoke(node, businessInterface, serviceName);
+ } catch (Throwable e) {
+ handleException(e);
+ return null;
+ }
+ }
+
+ public Node start() {
+ try {
+ return new NodeProxy(node.getClass().getMethod("start").invoke(node));
+ } catch (Throwable e) {
+ handleException(e);
+ return null;
+ }
+ }
+
+ public void stop() {
+ try {
+ node.getClass().getMethod("stop").invoke(node);
+ } catch (Throwable e) {
+ handleException(e);
+ }
+ }
+
+ public void destroy() {
+ try {
+ node.getClass().getMethod("destroy").invoke(node);
+ } catch (Throwable e) {
+ handleException(e);
+ }
+ }
+
+ private static void handleException(Throwable ex) {
+ if (ex instanceof InvocationTargetException) {
+ ex = ((InvocationTargetException)ex).getTargetException();
+ }
+ if (ex instanceof RuntimeException) {
+ throw (RuntimeException)ex;
+ }
+ if (ex instanceof Error) {
+ throw (Error)ex;
+ } else {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ }
+
+ /**
+ * Returns the SCA node factory instance.
+ *
+ * @return the SCA node factory
+ */
+ public synchronized static NodeFactory getInstance() {
+ if (instance == null) {
+ instance = newInstance();
+ }
+ return instance;
+ }
+
+ /**
+ * Returns a new SCA node factory instance.
+ *
+ * @return a new SCA node factory
+ */
+ public static NodeFactory newInstance() {
+ NodeFactory nodeFactory = null;
+ try {
+ Class<?> factoryClass = getFactoryImplClass();
+ nodeFactory = (NodeFactory)factoryClass.newInstance();
+
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ factories.add(nodeFactory);
+ return nodeFactory;
+ }
+
+ public static NodeFactory newInstance(Map<String, Map<String, String>> attributes) {
+ NodeFactory nodeFactory = null;
+ try {
+ Class<?> factoryClass = getFactoryImplClass();
+ nodeFactory = (NodeFactory)factoryClass.newInstance();
+ nodeFactory.configure(attributes);
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ factories.add(nodeFactory);
+ return nodeFactory;
+ }
+
+ protected Properties properties;
+
+ protected NodeFactory() {
+ this.properties = new Properties();
+ }
+
+ public static NodeFactory newInstance(Properties configProperties) {
+ NodeFactory nodeFactory = null;
+ try {
+ Class<?> factoryClass = getFactoryImplClass();
+ nodeFactory = (NodeFactory)factoryClass.newInstance();
+ nodeFactory.properties = configProperties;
+ nodeFactory.configure(new HashMap<String, Map<String,String>>());
+ } catch (Exception e) {
+ throw new ServiceRuntimeException(e);
+ }
+ factories.add(nodeFactory);
+ return nodeFactory;
+ }
+
+ public static NodeFactory newInstance(String configURI) {
+ Properties properties;
+ if (configURI == null || configURI.length() < 1) {
+ return newInstance();
+ } else if (configURI.startsWith("properties:")) {
+ try {
+ properties = loadProperties(configURI.substring("properties:".length()));
+ } catch (IOException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ } else if (configURI.startsWith("uri:")) {
+ properties = parseConfigURI(configURI.substring("uri:".length()));
+ } else {
+ properties = new Properties();
+ properties.setProperty("defaultDomainName", configURI);
+ }
+ return newInstance(properties);
+ }
+
+ /**
+ * Parse the config string into a Properties object.
+ * The config URI has the following format:
+ * uri:<domainName>?name=value&...
+ */
+ private static Properties parseConfigURI(String configURI) {
+ Properties properties = new Properties();
+ int qm = configURI.indexOf('?');
+ if (qm < 0) {
+ properties.setProperty("defaultDomainName", configURI);
+ } else {
+ if (qm == 0) {
+ properties.setProperty("defaultDomainName", "default");
+ } else {
+ properties.setProperty("defaultDomainName", configURI.substring(0, qm));
+ }
+ if (configURI.length() > qm+1) {
+ Map<String, String> params = new HashMap<String, String>();
+ for (String param : configURI.substring(qm+1).split("&")) {
+ String[] px = param.split("=");
+ if (px.length == 2) {
+ params.put(px[0], px[1]);
+ } else {
+ params.put(px[0], "");
+ }
+ }
+ for (String name : params.keySet()) {
+ properties.setProperty(name, params.get(name));
+ }
+ }
+ }
+ return properties;
+ }
+
+ /**
+ * load the properties from external URL or a relative file
+ * properties:<url to properties file>
+ */
+ private static Properties loadProperties(String propsURL) throws IOException {
+
+ Properties properties = new Properties();
+ File file = new File(propsURL);
+
+ InputStream inputStream = null;
+ if (file.exists()) {
+ inputStream = new FileInputStream(file);
+ } else {
+ URL url = null;
+ try {
+ url = new URL(propsURL);
+ } catch (MalformedURLException e) {
+ inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(propsURL);
+ if (inputStream == null) {
+ throw new IOException("File does not exist: " + propsURL + ", could not be found on the classpath and is not a valid URL: " + e);
+ }
+ }
+ if (inputStream == null && url != null) {
+ inputStream = url.openStream();
+ }
+ }
+ if (inputStream != null) {
+ properties.load(inputStream);
+ inputStream.close();
+ }
+
+ return properties;
+ }
+
+ /**
+ * Configure the NodeFactory instance
+ * @param attributes
+ */
+ public void configure(Map<String, Map<String, String>> attributes) {
+ }
+
+ private synchronized static Class<?> getFactoryImplClass() throws Exception {
+ if (factoryImplClass == null) {
+ // Use reflection APIs to call ServiceDiscovery to avoid hard dependency to tuscany-extensibility
+ try {
+ Class<?> discoveryClass = Class.forName("org.apache.tuscany.sca.extensibility.ServiceDiscovery");
+ Object instance = discoveryClass.getMethod("getInstance").invoke(null);
+ Object factoryDeclaration =
+ discoveryClass.getMethod("getServiceDeclaration", Class.class).invoke(instance, NodeFactory.class);
+ if (factoryDeclaration != null) {
+ factoryImplClass =
+ (Class<?>)factoryDeclaration.getClass().getMethod("loadClass").invoke(factoryDeclaration);
+ }
+ } catch (ClassNotFoundException e) {
+ // Ignore
+ }
+
+ if (factoryImplClass == null) {
+ // Fail back to default impl
+ String className = "org.apache.tuscany.sca.node.impl.NodeFactoryImpl";
+
+ factoryImplClass = Class.forName(className);
+ }
+ }
+ return factoryImplClass;
+ }
+
+ /**
+ * Open a URL connection without cache
+ * @param url
+ * @return
+ * @throws IOException
+ */
+ private static InputStream openStream(URL url) throws IOException {
+ InputStream is = null;
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ is = connection.getInputStream();
+ return is;
+ }
+
+ /**
+ * Escape the space in URL string
+ * @param uri
+ * @return
+ */
+ private static URI createURI(String uri) {
+ int index = uri.indexOf(':');
+ String scheme = null;
+ String ssp = uri;
+ if (index != -1) {
+ scheme = uri.substring(0, index);
+ ssp = uri.substring(index + 1);
+ }
+ try {
+ return new URI(scheme, ssp, null);
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Creates a new SCA node from the configuration URL
+ *
+ * @param configurationURL the URL of the node configuration which is the XML document
+ * that contains the URI of the composite and a collection of URLs for the contributions
+ *
+ * @return a new SCA node.
+ */
+ public Node createNode(URL configurationURL) {
+ try {
+ InputStream is = openStream(configurationURL);
+ NodeConfiguration configuration = loadConfiguration(is, configurationURL);
+ return createNode(configuration);
+ } catch (IOException e) {
+ throw new ServiceRuntimeException(e);
+ }
+ }
+
+ /**
+ * Creates a new SCA node from the XML configuration of the node
+ * @param is The input stream that the XML configuration can be read. The stream will be closed
+ * after this call.
+ * @return a new SCA node
+ */
+ public Node createNode(InputStream is) {
+ NodeConfiguration configuration = loadConfiguration(is, null);
+ return createNode(configuration);
+ }
+
+ /**
+ * Creates a new SCA node.
+ *
+ * @param deploymentCompositeURI the URI of the deployment composite. If the URI is relative, it should
+ * be resolved against the first contribution. Otherwise, the absolute URI is used to load the XML
+ * description of the composite. The deployment composite will be attached to the first contribution.
+ *
+ * @param contributions the URI of the contributions that provides the composites and related
+ * artifacts. If the list is empty, then we will use the thread context classloader to discover
+ * the contribution on the classpath
+ *
+ * @return a new SCA node.
+ */
+ public Node createNode(String deploymentCompositeURI, Contribution... contributions) {
+ if (contributions == null || contributions.length == 0) {
+ if (deploymentCompositeURI == null || deploymentCompositeURI.indexOf(':') != -1) {
+ throw new ServiceRuntimeException("No SCA contribution is provided or discovered");
+ }
+ // Try to find contributions on the classpath by the composite URI
+ List<String> locations = getContributionLocations(null, deploymentCompositeURI);
+ if (locations.isEmpty()) {
+ throw new ServiceRuntimeException("No SCA contributions are found on the classpath");
+ }
+ contributions = getContributions(locations);
+ }
+ NodeConfiguration configuration = createConfiguration(contributions);
+ if (deploymentCompositeURI != null && configuration.getContributions().size() > 0) {
+ configuration.getContributions().get(0).addDeploymentComposite(createURI(deploymentCompositeURI));
+ }
+ return createNode(configuration);
+ }
+
+ public final Node createNode(URI domainRegistryURI, String... locations) {
+ return createNode(domainRegistryURI, null, locations);
+ }
+
+ public final Node createNode(URI domainRegistryURI, String deploymentCompositeURI, String[] locations) {
+ Contribution[] contributions = getContributions(Arrays.asList(locations));
+ NodeConfiguration configuration = createConfiguration(contributions);
+ if (deploymentCompositeURI != null && configuration.getContributions().size() > 0) {
+ configuration.getContributions().get(0).addDeploymentComposite(createURI(deploymentCompositeURI));
+ }
+ configuration.setDomainRegistryURI(domainRegistryURI.toString());
+ configuration.setDomainURI(getDomainURI(domainRegistryURI));
+ return createNode(configuration);
+ }
+
+ /**
+ * TODO: cleanup node use of registry uri, domain uri, and domain name
+ * so that its consistent across the code base
+ */
+ public static String getDomainURI(URI configURI) {
+ String s = configURI.getHost();
+ if (s == null) {
+ s = configURI.getSchemeSpecificPart();
+ if (s != null) {
+ if (s.indexOf('?') > -1) {
+ s = s.substring(0, s.indexOf('?'));
+ }
+ }
+ }
+ return s;
+ }
+
+ /**
+ * The following methods are used by the node launcher
+ */
+ public final Node createNode(String deploymentCompositeURI, String[] uris, String locations[]) {
+ return createNode(deploymentCompositeURI, getContributions(Arrays.asList(uris), Arrays.asList(locations)));
+ }
+
+ public final Node createNode(String deploymentCompositeURI, String locations[]) {
+ return createNode(deploymentCompositeURI, getContributions(Arrays.asList(locations)));
+ }
+
+ public final Node createNode(Reader deploymentCompositeContent, String[] uris, String locations[]) {
+ return createNode(deploymentCompositeContent, getContributions(Arrays.asList(uris), Arrays.asList(locations)));
+ }
+
+ public final Node createNode(String compositeURI, ClassLoader classLoader) {
+ List<String> locations = ContributionLocationHelper.getContributionLocations(classLoader, compositeURI);
+ return createNode(compositeURI, locations.toArray(new String[locations.size()]));
+ }
+ /**
+ * ------------------- end of methods -----------------
+ */
+
+ /**
+ * Create a new SCA node using the list of SCA contributions
+ * @param contributions
+ * @return
+ */
+ public Node createNode(Contribution... contributions) {
+ NodeConfiguration configuration = createConfiguration(contributions);
+ return createNode(configuration);
+ }
+
+
+ /**
+ * Creates a new SCA node.
+ *
+ * @param compositeContent the XML content of the deployment composite
+ * @param contributions the URI of the contributions that provides the composites and related artifacts
+ * @return a new SCA node.
+ */
+ public Node createNode(InputStream compositeContent, Contribution... contributions) {
+ NodeConfiguration configuration = createConfiguration(contributions);
+ if (compositeContent != null && configuration.getContributions().size() > 0) {
+ configuration.getContributions().get(0).addDeploymentComposite(compositeContent);
+ }
+ return createNode(configuration);
+ }
+
+ /**
+ * Creates a new SCA node.
+ *
+ * @param compositeContent the XML content of the deployment composite
+ * @param contributions the URI of the contributions that provides the composites and related artifacts
+ * @return a new SCA node.
+ */
+ public Node createNode(Reader compositeContent, Contribution... contributions) {
+ NodeConfiguration configuration = createConfiguration(contributions);
+ if (compositeContent != null && configuration.getContributions().size() > 0) {
+ configuration.getContributions().get(0).addDeploymentComposite(compositeContent);
+ }
+ return createNode(configuration);
+ }
+
+ /**
+ * Creates a new SCA node using defaults for the contribution location and deployable composites.
+ * By default, it uses the Thread context classloader to find META-INF/sca-contribution.xml or
+ * META-INF/sca-contribution-generated.xml on the classpath. The locations that contain such resources
+ * are taken as the SCA contributions.
+ *
+ * @return a new SCA node.
+ */
+ public Node createNode() {
+ List<String> locations = new ArrayList<String>();
+ locations.addAll(getContributionLocations(null, SCA_CONTRIBUTION_META));
+ locations.addAll(getContributionLocations(null, SCA_CONTRIBUTION_GENERATED_META));
+ if (locations.isEmpty()) {
+ throw new ServiceRuntimeException("No SCA contributions are found on the classpath");
+ }
+ Contribution[] contributions = getContributions(locations);
+ return createNode(contributions);
+ }
+
+ private NodeConfiguration createConfiguration(Contribution... contributions) {
+ NodeConfigurationFactory factory = this;
+ NodeConfiguration configuration = factory.createNodeConfiguration();
+ if (properties.getProperty("defaultDomainName") != null) {
+ configuration.setDomainURI(properties.getProperty("defaultDomainName"));
+ }
+ // Make sure a unique node URI is created for the same node factory
+ configuration.setURI(generateNodeURI());
+ if (contributions != null) {
+ for (Contribution c : contributions) {
+ configuration.addContribution(c.getURI(), c.getLocation());
+ }
+ }
+ return configuration;
+ }
+
+ private static int count = 0;
+
+ protected synchronized String generateNodeURI() {
+ return Node.DEFAULT_NODE_URI + (count++);
+ }
+
+ private Contribution[] getContributions(List<String> locations) {
+ Contribution[] contributions = new Contribution[locations.size()];
+ int index = 0;
+ for (String location : locations) {
+ contributions[index++] = new Contribution(location, location);
+ }
+ return contributions;
+ }
+
+ private Contribution[] getContributions(List<String> uris, List<String> locations) {
+ if (uris.size() != locations.size()) {
+ throw new IllegalArgumentException("The number of URIs does not match the number of locations");
+ }
+ Contribution[] contributions = new Contribution[locations.size()];
+ for (int i = 0, n = locations.size(); i < n; i++) {
+ contributions[i] = new Contribution(uris.get(i), locations.get(i));
+ }
+ return contributions;
+ }
+
+ public void destroy() {
+ count = 0;
+ instance = null;
+ factories.remove(this);
+ }
+
+ public static List<NodeFactory> getNodeFactories() {
+ return factories;
+ }
+
+ /**
+ * Create a new SCA node based on the configuration
+ * @param configuration The configuration of a node
+ * @return The SCA node
+ */
+ public abstract Node createNode(NodeConfiguration configuration);
+
+ /**
+ * Create an SCA node from a list of pre-built o.a.t.sca.contribution.Contribution objects.
+ * Pass java.lang.Objects for now as this class doesn't have direct dependencies on
+ * o.a.t.sca.contribution.Contribution.
+ */
+ public abstract Node createNode(List<?> contributions);
+
+ /**
+ * Create the node configuration from the XML document
+ * @param configuration The input stream of the XML document
+ * @return The node configuration
+ */
+ public abstract NodeConfiguration loadConfiguration(InputStream xml, URL base);
+
+ public abstract <T> T getExtensionPointRegistry();
+
+ public abstract void init();
+
+ public void setAutoDestroy(boolean b) {
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java
new file mode 100644
index 0000000000..c42bacdd00
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.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;
+
+import java.io.File;
+
+public class NodeMain2 {
+
+ /**
+ * Start an SCA node
+ * @param args a list of contribution jars for the node to run
+ */
+ public static void main(String[] args) throws Exception {
+
+ Contribution[] contributions = new Contribution[args.length];
+ for (int i = 0; i < args.length; i++) {
+ File f = new File(args[i]);
+ if (!f.exists()) {
+ System.err.println("contribution not found: " + f);
+ System.exit(1);
+ }
+ contributions[i] = new Contribution(f.toURI().toString(), f.toURI().toString());
+ }
+
+ Node node = NodeFactory.newInstance().createNode(contributions).start();
+
+ System.out.println("Hit enter to stop node...");
+ if (System.in.read() == -1) {
+ // no sysin so wait for ever letting caller do the terminate
+ Object lock = new Object();
+ synchronized (lock) {
+ lock.wait();
+ }
+ }
+
+ node.stop();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.java
new file mode 100644
index 0000000000..a6dab059a3
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.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.configuration;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Configuration for bindings used by an SCA node
+ */
+public interface BindingConfiguration {
+ /**
+ * Get the QName of the binding type
+ * @return the QName of the binding type
+ */
+ QName getBindingType();
+
+ /**
+ * Set the type of the binding
+ * @param type The QName of the binding type
+ */
+ BindingConfiguration setBindingType(QName type);
+
+ /**
+ * Get a list of base URIs for the binding. For each protocol supported by the binding,
+ * one base URI can be configured
+ * @return A list of base URIs
+ */
+ List<String> getBaseURIs();
+
+ /**
+ * Add a base URI
+ * @param baseURI
+ * @return
+ */
+ BindingConfiguration addBaseURI(String baseURI);
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java
new file mode 100644
index 0000000000..ee790f54bf
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java
@@ -0,0 +1,141 @@
+/*
+ * 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.configuration;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * Configuration for an SCA contribution used by the SCA node
+ */
+public interface ContributionConfiguration {
+ /**
+ * Get the URI of the contribution
+ * @return The URI of the contribution
+ */
+ String getURI();
+
+ /**
+ * Set the URI of the contribution
+ * @param uri The URI of the contribution
+ */
+ ContributionConfiguration setURI(String uri);
+
+ /**
+ * Get the location of the contribution
+ * @return The location of the contribution
+ */
+ String getLocation();
+
+ /**
+ * Set the location of the contribution
+ * @param location The location of the contribution
+ */
+ ContributionConfiguration setLocation(String location);
+
+ /**
+ * Get the list of deployment composites that are attached to the contribution
+ * @return A list of deployment composites
+ */
+ List<DeploymentComposite> getDeploymentComposites();
+
+ /**
+ * Add a deployment composite to this contribution
+ * @param deploymentComposite The deployment composite
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(DeploymentComposite deploymentComposite);
+
+ /**
+ * Create a deployment composite and add it to the contribution configuration
+ * @param location The location is either relative to the contribution or
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(URI location);
+
+ /**
+ * Attach a deployment composite to this contribution
+ * @param location
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(URL location);
+
+ /**
+ * Attach a deployment composite to this contribution
+ * @param content The string that contains the XML description of the SCA composite
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(String content);
+
+ /**
+ * Attach a deployment composite to this contribution
+ * @param content The XML description of the SCA composite from a reader
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(Reader content);
+ /**
+ * Attach a deployment composite to this contribution
+ * @param content The XML description of the SCA composite from an input stream
+ * @return
+ */
+ ContributionConfiguration addDeploymentComposite(InputStream content);
+
+ /**
+ * Set if the deployable composites should be started when the contribution is installed
+ * @param startDeployables whether or not deployable composites should be started. The default is false.
+ */
+ void setStartDeployables(boolean startDeployables);
+
+ /**
+ * Tests if the deployable composites should be started when the contribution is installed
+ */
+ boolean isStartDeployables();
+
+ /**
+ * Gets the URIs of any dependent contributions. The dependent contributions are the
+ * contributions that will be used to resolve any imports used by this contribution.
+ * @return the URIs of any dependent contribution
+ */
+ List<String> getDependentContributionURIs();
+
+ /**
+ * Sets the dependent contribution URIs for this contribution. The dependent contributions are the
+ * contributions that will be used to resolve any imports used by this contribution.
+ * @param dependentContributionURIs
+ */
+ void setDependentContributionURIs(List<String> dependentContributionURIs);
+
+ /**
+ * Get the contribution meta data url. This is sca-contribution.xml data that is added to any
+ * existing meta-inf/sca-contribution.xml file within the contribution.
+ * @return the metadata url string
+ */
+ String getMetaDataURL();
+
+ /**
+ * Set the contribution meta data url. This is sca-contribution.xml data that is added to any
+ * existing meta-inf/sca-contribution.xml file within the contribution.
+ * @param metaDataURL the url string to the metadata file.
+ */
+ void setMetaDataURL(String metaDataURL);
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java
new file mode 100644
index 0000000000..a23cef7e81
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java
@@ -0,0 +1,46 @@
+/*
+ * 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.configuration;
+
+import org.apache.tuscany.sca.node.configuration.impl.NodeConfigurationFactoryImpl;
+
+/**
+ * Default NodeConfigurationFactory
+ */
+public class DefaultNodeConfigurationFactory implements NodeConfigurationFactory {
+ private NodeConfigurationFactory factory = new NodeConfigurationFactoryImpl();
+
+ public BindingConfiguration createBindingConfiguration() {
+ return factory.createBindingConfiguration();
+ }
+
+ public ContributionConfiguration createContributionConfiguration() {
+ return factory.createContributionConfiguration();
+ }
+
+ public DeploymentComposite createDeploymentComposite() {
+ return factory.createDeploymentComposite();
+ }
+
+ public NodeConfiguration createNodeConfiguration() {
+ return factory.createNodeConfiguration();
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java
new file mode 100644
index 0000000000..18fecf8044
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java
@@ -0,0 +1,64 @@
+/*
+ * 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.configuration;
+
+
+/**
+ * Configuration for a deployment composite
+ */
+public interface DeploymentComposite {
+ /**
+ * Get the location of the deployment composite, it can be relative to the owning
+ * contribution or an external resource
+ * @return
+ */
+ String getLocation();
+
+ /**
+ * Set the location of the deployment composite
+ * @param location
+ */
+ DeploymentComposite setLocation(String location);
+
+ /**
+ * Get string content of the deployment composite (XML)
+ * @return
+ */
+ String getContent();
+
+ /**
+ * Set the XML content for the composite
+ * @param compositeXML
+ */
+ DeploymentComposite setContent(String compositeXML);
+
+ /**
+ * Get the URI of the contribution that the deployment composite is attached to
+ * @return the URI of the contribution that the deployment composite is attached to
+ */
+ String getContributionURI();
+
+ /**
+ * Set the URI of the contribution that the deployment composite is attached to
+ * @param contributionURI
+ */
+ DeploymentComposite setContributionURI(String contributionURI);
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java
new file mode 100644
index 0000000000..12c6994dda
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java
@@ -0,0 +1,108 @@
+/*
+ * 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.configuration;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URL;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+/**
+ * The configuration for a Node which represents the deployment of an SCA composite application
+ * @tuscany.spi.extension.asclient
+ */
+public interface NodeConfiguration {
+ String DEFAULT_DOMAIN_URI = "default";
+ String DEFAULT_NODE_URI = "http://tuscany.apache.org/sca/1.1/nodes/default";
+ String DEFAULT_DOMAIN_REGISTRY_URI = "default";
+
+ /**
+ * Get the URI of the SCA domain that manages the composite application
+ * @return The URI of the SCA domain
+ */
+ String getDomainURI();
+
+ /**
+ * Set the URI of the SCA domain
+ * @param domainURI The URI of the SCA domain
+ */
+ NodeConfiguration setDomainURI(String domainURI);
+
+ /**
+ * Return the URI of the domain registry
+ * @return
+ */
+ String getDomainRegistryURI();
+
+ /**
+ * Set the URI of the domain registry
+ * @param domainRegistryURI The URI of the domain registry. The scheme will be used
+ * by Tusany to choose the implementation of DomainRegistry interface. Examples are:
+ * <ul>
+ * <li>vm://localhost (a JVM local registry)
+ * <li>multicast://228.0.0.100:50000?timeout=50 (Tomcat Tribes multicast based registry)
+ * </ul>
+ * @return The NodeConfiguration
+ */
+ NodeConfiguration setDomainRegistryURI(String domainRegistryURI);
+
+ /**
+ * Get the URI of the node. It uniquely identifies a node within the SCA domain
+ * @return The URI of the node
+ */
+ String getURI();
+
+ /**
+ * Set the URI of the node
+ * @param uri The URI of the node
+ */
+ NodeConfiguration setURI(String uri);
+
+ /**
+ * Get a list of confiurations for SCA contributions
+ * @return A list of configurations for SCA contributions
+ */
+ List<ContributionConfiguration> getContributions();
+
+ /**
+ * Get a list of configurations for SCA bindings
+ * @return A list of configurations for SCA bindings
+ */
+ List<BindingConfiguration> getBindings();
+
+ NodeConfiguration addContribution(ContributionConfiguration contribution);
+ NodeConfiguration addContribution(String contributionURI, String location);
+ NodeConfiguration addContribution(String contributionURI, URL location);
+ NodeConfiguration addContribution(URI contributionURI, URL location);
+ NodeConfiguration addContribution(URL...location);
+
+ NodeConfiguration addDeploymentComposite(String contributionURI, String location);
+ NodeConfiguration addDeploymentComposite(String contributionURI, Reader content);
+ NodeConfiguration addDeploymentComposite(String contributionURI, InputStream content);
+
+ NodeConfiguration addBinding(BindingConfiguration binding);
+ NodeConfiguration addBinding(QName bindingType, String...baseURIs);
+ NodeConfiguration addBinding(QName bindingType, URI...baseURIs);
+
+ List<Object> getExtensions();
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java
new file mode 100644
index 0000000000..71833bc7e7
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java
@@ -0,0 +1,50 @@
+/*
+ * 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.configuration;
+
+
+/**
+ * The factory to create java models related to the node configuration
+ */
+public interface NodeConfigurationFactory {
+ /**
+ * Create a new instance of NodeConfiguration
+ * @return
+ */
+ NodeConfiguration createNodeConfiguration();
+
+ /**
+ * Create a new instance of ContributionConfiguration
+ * @return
+ */
+ ContributionConfiguration createContributionConfiguration();
+
+ /**
+ * Create a new instance of BindingConfiguration
+ * @return
+ */
+ BindingConfiguration createBindingConfiguration();
+
+ /**
+ * Create a new instance of DeploymentComposite
+ * @return
+ */
+ DeploymentComposite createDeploymentComposite();
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/BindingConfigurationImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/BindingConfigurationImpl.java
new file mode 100644
index 0000000000..5658187c4f
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/BindingConfigurationImpl.java
@@ -0,0 +1,54 @@
+/*
+ * 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.configuration.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.node.configuration.BindingConfiguration;
+
+/**
+ * Default implementation of BindingConfiguration
+ */
+public class BindingConfigurationImpl implements BindingConfiguration {
+ private QName type;
+ private List<String> baseURIs = new ArrayList<String>();
+
+ public List<String> getBaseURIs() {
+ return baseURIs;
+ }
+
+ public QName getBindingType() {
+ return type;
+ }
+
+ public BindingConfiguration setBindingType(QName type) {
+ this.type = type;
+ return this;
+ }
+
+ public BindingConfiguration addBaseURI(String baseURI) {
+ baseURIs.add(baseURI);
+ return this;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java
new file mode 100644
index 0000000000..f6e462142a
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java
@@ -0,0 +1,188 @@
+/*
+ * 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.configuration.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tuscany.sca.node.configuration.ContributionConfiguration;
+import org.apache.tuscany.sca.node.configuration.DeploymentComposite;
+
+/**
+ * Configuration for an SCA contribution used by the SCA node
+ */
+public class ContributionConfigurationImpl implements ContributionConfiguration {
+ private List<DeploymentComposite> deploymentComposites = new ArrayList<DeploymentComposite>();
+ private String uri;
+ private String location;
+ private boolean startDeployables;
+ private List<String> dependentContributionURIs;
+ private String metaDataURL;
+
+ public ContributionConfigurationImpl() {
+ super();
+ }
+
+ public ContributionConfigurationImpl(String uri, String location) {
+ super();
+ this.uri = uri;
+ this.location = location;
+ }
+
+ public ContributionConfigurationImpl(String location) {
+ super();
+ this.uri = location;
+ this.location = location;
+ }
+
+ /**
+ * Get the URI of the contribution
+ * @return The URI of the contribution
+ */
+ public String getURI() {
+ return uri;
+ }
+
+ /**
+ * Set the URI of the contribution
+ * @param uri The URI of the contribution
+ */
+ public ContributionConfiguration setURI(String uri) {
+ this.uri = uri;
+ return this;
+ }
+
+ /**
+ * Get the location of the contribution
+ * @return The location of the contribution
+ */
+ public String getLocation() {
+ return location;
+ }
+
+ /**
+ * Set the location of the contribution
+ * @param location The location of the contribution
+ */
+ public ContributionConfiguration setLocation(String location) {
+ this.location = location;
+ return this;
+ }
+
+ /**
+ * Get the list of deployment composites that are attached to the contribution
+ * @return
+ */
+ public List<DeploymentComposite> getDeploymentComposites() {
+ return deploymentComposites;
+ }
+
+ public ContributionConfiguration addDeploymentComposite(DeploymentComposite deploymentComposite) {
+ deploymentComposites.add(deploymentComposite);
+ if (uri != null) {
+ deploymentComposite.setContributionURI(uri);
+ }
+ return this;
+ }
+
+ public ContributionConfiguration addDeploymentComposite(Reader reader) {
+ try {
+ DeploymentComposite composite = new DeploymentCompositeImpl();
+ char[] buf = new char[8192];
+ StringWriter sw = new StringWriter();
+ int size = 0;
+ while (size >= 0) {
+ size = reader.read(buf);
+ if (size > 0) {
+ sw.write(buf, 0, size);
+ }
+ }
+ reader.close();
+ composite.setContent(sw.toString());
+ return addDeploymentComposite(composite);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public ContributionConfiguration addDeploymentComposite(InputStream content) {
+ try {
+ InputStreamReader reader = new InputStreamReader(content, "UTF-8");
+ return addDeploymentComposite(reader);
+ } catch (IOException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ public ContributionConfiguration addDeploymentComposite(String content) {
+ DeploymentComposite composite = new DeploymentCompositeImpl();
+ composite.setContent(content);
+ return addDeploymentComposite(composite);
+ }
+
+ public ContributionConfiguration addDeploymentComposite(URI location) {
+ DeploymentComposite composite = new DeploymentCompositeImpl();
+ composite.setLocation(location.toString());
+ return addDeploymentComposite(composite);
+ }
+
+ public ContributionConfiguration addDeploymentComposite(URL location) {
+ DeploymentComposite composite = new DeploymentCompositeImpl();
+ composite.setLocation(location.toString());
+ return addDeploymentComposite(composite);
+ }
+
+ @Override
+ public void setStartDeployables(boolean startDeployables) {
+ this.startDeployables = startDeployables;
+ }
+
+ @Override
+ public boolean isStartDeployables() {
+ return startDeployables;
+ }
+
+ @Override
+ public List<String> getDependentContributionURIs() {
+ return dependentContributionURIs;
+ }
+
+ @Override
+ public void setDependentContributionURIs(List<String> dependentContributionURIs) {
+ this.dependentContributionURIs = dependentContributionURIs;
+ }
+
+ @Override
+ public String getMetaDataURL() {
+ return metaDataURL;
+ }
+
+ @Override
+ public void setMetaDataURL(String metaDataURL) {
+ this.metaDataURL = metaDataURL;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/DeploymentCompositeImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/DeploymentCompositeImpl.java
new file mode 100644
index 0000000000..a161b426e7
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/DeploymentCompositeImpl.java
@@ -0,0 +1,64 @@
+/*
+ * 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.configuration.impl;
+
+import org.apache.tuscany.sca.node.configuration.DeploymentComposite;
+
+/**
+ * Configuration for a deployment composite
+ */
+public class DeploymentCompositeImpl implements DeploymentComposite {
+ private String location;
+ private String content;
+ private String contributionURI;
+
+ public String getLocation() {
+ return location;
+ }
+
+ public DeploymentComposite setLocation(String location) {
+ this.location = location;
+ return this;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public DeploymentComposite setContent(String content) {
+ this.content = content;
+ return this;
+ }
+
+ public String getContributionURI() {
+ return contributionURI;
+ }
+
+ public DeploymentComposite setContributionURI(String contributionURI) {
+ this.contributionURI = contributionURI;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "DeploymentCompositeImpl [contributionURI=" + contributionURI + ", location=" + location + "]";
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationFactoryImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationFactoryImpl.java
new file mode 100644
index 0000000000..86096c9aee
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationFactoryImpl.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.configuration.impl;
+
+import org.apache.tuscany.sca.node.configuration.BindingConfiguration;
+import org.apache.tuscany.sca.node.configuration.ContributionConfiguration;
+import org.apache.tuscany.sca.node.configuration.DeploymentComposite;
+import org.apache.tuscany.sca.node.configuration.NodeConfiguration;
+import org.apache.tuscany.sca.node.configuration.NodeConfigurationFactory;
+
+/**
+ * The factory to create java models related to the node configuration
+ */
+public class NodeConfigurationFactoryImpl implements NodeConfigurationFactory {
+ /**
+ * Create a new instance of NodeConfiguration
+ * @return
+ */
+ public NodeConfiguration createNodeConfiguration() {
+ return new NodeConfigurationImpl();
+ }
+
+ /**
+ * Create a new instance of ContributionConfiguration
+ * @return
+ */
+ public ContributionConfiguration createContributionConfiguration() {
+ return new ContributionConfigurationImpl();
+ }
+
+ /**
+ * Create a new instance of BindingConfiguration
+ * @return
+ */
+ public BindingConfiguration createBindingConfiguration() {
+ return new BindingConfigurationImpl();
+ }
+
+ /**
+ * Create a new instance of DeploymentComposite
+ * @return
+ */
+ public DeploymentComposite createDeploymentComposite() {
+ return new DeploymentCompositeImpl();
+ }
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationImpl.java
new file mode 100644
index 0000000000..b4ec05cae5
--- /dev/null
+++ b/sca-java-2.x/branches/2.0-Beta2/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationImpl.java
@@ -0,0 +1,176 @@
+/*
+ * 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.configuration.impl;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.node.configuration.BindingConfiguration;
+import org.apache.tuscany.sca.node.configuration.ContributionConfiguration;
+import org.apache.tuscany.sca.node.configuration.NodeConfiguration;
+
+/**
+ * Default implementation of NodeConfiguration
+ */
+public class NodeConfigurationImpl implements NodeConfiguration {
+ private String uri = DEFAULT_NODE_URI;
+ private String domainURI = DEFAULT_DOMAIN_URI;
+ private String domainRegistryURI = DEFAULT_DOMAIN_REGISTRY_URI;
+ private List<ContributionConfiguration> contributions = new ArrayList<ContributionConfiguration>();
+ private List<BindingConfiguration> bindings = new ArrayList<BindingConfiguration>();
+ private List<Object> extensions = new ArrayList<Object>();
+
+ public String getURI() {
+ return uri;
+ }
+
+ public NodeConfiguration setURI(String uri) {
+ this.uri = uri;
+ return this;
+ }
+
+ public String getDomainURI() {
+ return domainURI;
+ }
+
+ public NodeConfiguration setDomainURI(String domainURI) {
+ this.domainURI = domainURI;
+ return this;
+ }
+
+ public List<ContributionConfiguration> getContributions() {
+ return contributions;
+ }
+
+ public List<BindingConfiguration> getBindings() {
+ return bindings;
+ }
+
+ public NodeConfiguration addBinding(BindingConfiguration bindingConfiguration) {
+ for (BindingConfiguration bc : bindings) {
+ // Try to merge first by QName
+ if (bc.getBindingType().equals(bindingConfiguration.getBindingType())) {
+ bc.getBaseURIs().addAll(bindingConfiguration.getBaseURIs());
+ return this;
+ }
+ }
+ bindings.add(bindingConfiguration);
+ return this;
+ }
+
+ public NodeConfiguration addContribution(ContributionConfiguration contributionConfiguration) {
+ contributions.add(contributionConfiguration);
+ return this;
+ }
+
+ public NodeConfiguration addBinding(QName bindingType, String... baseURIs) {
+ BindingConfiguration binding = new BindingConfigurationImpl().setBindingType(bindingType);
+ for (String u : baseURIs) {
+ String[] uris = u.split("(\\s)+");
+ for (String uri : uris) {
+ if (uri.length() > 0) {
+ binding.addBaseURI(uri);
+ }
+ }
+ }
+ return addBinding(binding);
+ }
+
+ public NodeConfiguration addBinding(QName bindingType, URI... baseURIs) {
+ BindingConfiguration binding = new BindingConfigurationImpl().setBindingType(bindingType);
+ for (URI u : baseURIs) {
+ binding.addBaseURI(u.toString());
+ }
+ return addBinding(binding);
+ }
+
+ public NodeConfiguration addContribution(String contributionURI, String location) {
+ ContributionConfiguration contribution = new ContributionConfigurationImpl(contributionURI, location);
+ return addContribution(contribution);
+ }
+
+ public NodeConfiguration addContribution(String contributionURI, URL location) {
+ return addContribution(contributionURI, location.toString());
+ }
+
+ public NodeConfiguration addContribution(URI contributionURI, URL location) {
+ return addContribution(contributionURI.toString(), location.toString());
+ }
+
+ public NodeConfiguration addContribution(URL... locations) {
+ for (URL url : locations) {
+ ContributionConfiguration contribution = new ContributionConfigurationImpl(url.toString(), url.toString());
+ addContribution(contribution);
+ }
+ return this;
+ }
+
+ public NodeConfiguration addDeploymentComposite(String contributionURI, InputStream content) {
+ findContribution(contributionURI).addDeploymentComposite(content);
+ return this;
+ }
+
+ public NodeConfiguration addDeploymentComposite(String contributionURI, Reader content) {
+ findContribution(contributionURI).addDeploymentComposite(content);
+ return this;
+ }
+
+ public NodeConfiguration addDeploymentComposite(String contributionURI, String location) {
+ findContribution(contributionURI).addDeploymentComposite(URI.create(location));
+ return this;
+ }
+
+ private ContributionConfiguration findContribution(String uri) {
+ for (ContributionConfiguration c : contributions) {
+ if (c.getURI() != null && c.getURI().equals(uri)) {
+ return c;
+ }
+ }
+ throw new IllegalArgumentException("Contribution is not found (uri=" + uri + ")");
+ }
+
+ public String toString() {
+ if (domainURI != null) {
+ return "{" + domainURI + "}" + uri;
+ } else {
+ return uri;
+ }
+ }
+
+ public List<Object> getExtensions() {
+ return extensions;
+ }
+
+ public String getDomainRegistryURI() {
+ return domainRegistryURI;
+ }
+
+ public NodeConfiguration setDomainRegistryURI(String domainRegistryURI) {
+ this.domainRegistryURI = domainRegistryURI;
+ return this;
+ }
+
+}