diff options
Diffstat (limited to 'sandbox/sebastien/java/embed/modules/node-api')
20 files changed, 2185 insertions, 0 deletions
diff --git a/sandbox/sebastien/java/embed/modules/node-api/LICENSE b/sandbox/sebastien/java/embed/modules/node-api/LICENSE new file mode 100644 index 0000000000..6e529a25c4 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/LICENSE @@ -0,0 +1,205 @@ +
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed 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.
+
+
+
diff --git a/sandbox/sebastien/java/embed/modules/node-api/META-INF/MANIFEST.MF b/sandbox/sebastien/java/embed/modules/node-api/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..ac89f5383a --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/META-INF/MANIFEST.MF @@ -0,0 +1,18 @@ +Manifest-Version: 1.0
+Export-Package: org.apache.tuscany.sca.node;version="2.0.0";uses:="org.oasisopen.sca",
+ org.apache.tuscany.sca.node.configuration;version="2.0.0"
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA Node API
+DynamicImport-Package: org.apache.tuscany.sca.node.impl,org.apache.tus
+ cany.sca.extensibility
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA Node API
+Import-Package: org.apache.tuscany.sca.node;version="2.0.0",
+ org.apache.tuscany.sca.node.configuration;version="2.0.0",
+ org.oasisopen.sca;version="2.0.0"
+Bundle-SymbolicName: org.apache.tuscany.sca.node.api
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6 diff --git a/sandbox/sebastien/java/embed/modules/node-api/NOTICE b/sandbox/sebastien/java/embed/modules/node-api/NOTICE new file mode 100644 index 0000000000..9ddba06a32 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/NOTICE @@ -0,0 +1,6 @@ +${pom.name}
+Copyright (c) 2005 - 2010 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/sandbox/sebastien/java/embed/modules/node-api/pom.xml b/sandbox/sebastien/java/embed/modules/node-api/pom.xml new file mode 100644 index 0000000000..2de9c088a6 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/pom.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<project> + + <modelVersion>4.0.0</modelVersion> + <parent> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-modules</artifactId> + <version>2.0-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + + <artifactId>tuscany-node-api</artifactId> + <name>Apache Tuscany SCA Node API</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-sca-api</artifactId> + <version>2.0-SNAPSHOT</version> + </dependency> + </dependencies> + +</project> diff --git a/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Contribution.java new file mode 100644 index 0000000000..f69e18dc63 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java new file mode 100644 index 0000000000..2e73322917 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/Node.java new file mode 100644 index 0000000000..502b2f854c --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java new file mode 100644 index 0000000000..2d2df84f42 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java @@ -0,0 +1,623 @@ +/* + * 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(); + properties.setProperty("defaultScheme", "vm"); + properties.setProperty("defaultDomainName", "default"); + } + + 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 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(); +} diff --git a/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java new file mode 100644 index 0000000000..c42bacdd00 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/BindingConfiguration.java new file mode 100644 index 0000000000..a6dab059a3 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java new file mode 100644 index 0000000000..05c718dbd0 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/ContributionConfiguration.java @@ -0,0 +1,102 @@ +/* + * 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); +} diff --git a/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DefaultNodeConfigurationFactory.java new file mode 100644 index 0000000000..a23cef7e81 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/DeploymentComposite.java new file mode 100644 index 0000000000..18fecf8044 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfiguration.java new file mode 100644 index 0000000000..12c6994dda --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/NodeConfigurationFactory.java new file mode 100644 index 0000000000..71833bc7e7 --- /dev/null +++ b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/BindingConfigurationImpl.java b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java new file mode 100644 index 0000000000..5229801731 --- /dev/null +++ b/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/ContributionConfigurationImpl.java @@ -0,0 +1,155 @@ +/* + * 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; + + 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); + } +} diff --git a/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/DeploymentCompositeImpl.java b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationFactoryImpl.java b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/modules/node-api/src/main/java/org/apache/tuscany/sca/node/configuration/impl/NodeConfigurationImpl.java b/sandbox/sebastien/java/embed/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/sandbox/sebastien/java/embed/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; + } + +} |