diff options
author | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-05-15 18:36:42 +0000 |
---|---|---|
committer | rfeng <rfeng@13f79535-47bb-0310-9956-ffa450edef68> | 2009-05-15 18:36:42 +0000 |
commit | 73ffdb3c639f918474bc0df9dac57af8b121f3ab (patch) | |
tree | 3b9301fb26221936bbb6b7e1bccacc5498953bc3 /java/sca/modules/node-api | |
parent | 80f7efa886898658571776162c633bd5399d43e6 (diff) |
Push down some of the createNode() methods to NodeFactory and only require the createNode(NodeConfiguration) to be implemented by subclasses
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@775283 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/sca/modules/node-api')
3 files changed, 252 insertions, 22 deletions
diff --git a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java index 96a25dfa63..f891f1e329 100644 --- a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java +++ b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/ContributionLocationHelper.java @@ -6,22 +6,28 @@ * 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. + * 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 @@ -32,7 +38,7 @@ public class ContributionLocationHelper { /** * Returns the location of the SCA contribution containing the given class. - * + * * @param anchorClass * @return */ @@ -53,6 +59,15 @@ public class ContributionLocationHelper { */ 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); } @@ -74,6 +89,32 @@ public class ContributionLocationHelper { 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(); @@ -98,4 +139,16 @@ public class ContributionLocationHelper { }); } + 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/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java index 1f30045bd1..485c159287 100644 --- a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java +++ b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeFactory.java @@ -19,11 +19,22 @@ package org.apache.tuscany.sca.node; +import static org.apache.tuscany.sca.node.ContributionLocationHelper.getContributionLocations; + +import java.io.IOException; import java.io.InputStream; +import java.io.Reader; import java.lang.reflect.InvocationTargetException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.List; 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.CallableReference; import org.oasisopen.sca.ServiceReference; import org.oasisopen.sca.ServiceRuntimeException; @@ -35,6 +46,15 @@ import org.oasisopen.sca.ServiceRuntimeException; * @version $Rev$ $Date$ */ 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 nodeFactory; @@ -174,33 +194,109 @@ public abstract class NodeFactory extends DefaultNodeConfigurationFactory { } /** - * Creates a new SCA node using defaults for the contribution location and runnable composite - * - * @return a new SCA node. + * 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 */ - public abstract Node createNode(); + 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 ATOM feed + * @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 abstract Node createNode(String configurationURL); + public Node createNode(URL configurationURL) { + try { + InputStream is = openStream(configurationURL); + return createNode(is); + } 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) { + try { + NodeConfiguration configuration = loadConfiguration(is); + is.close(); + return createNode(configuration); + } catch (IOException e) { + throw new ServiceRuntimeException(e); + } + } /** * Creates a new SCA node. * - * @param compositeURI the URI of the composite to use + * @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 abstract Node createNode(String compositeURI, Contribution... contributions); + 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 + contributions = getContributions(getContributionLocations(null, deploymentCompositeURI)); + } + NodeConfiguration configuration = createConfiguration(contributions); + if (deploymentCompositeURI != null && configuration.getContributions().size() > 0) { + configuration.getContributions().get(0).addDeploymentComposite(createURI(deploymentCompositeURI)); + } + return createNode(configuration); + } + + /** + * 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. @@ -209,8 +305,87 @@ public abstract class NodeFactory extends DefaultNodeConfigurationFactory { * @param compositeContent the XML content of the composite to use * @param contributions the URI of the contributions that provides the composites and related artifacts * @return a new SCA node. + * + * @deprecated Please use createNode(InputStream compositeContent, Contribution... contributions) or + * createNode(Reader compositeContent, Contribution... contributions) + */ + @Deprecated + public Node createNode(String compositeURI, String 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(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 abstract Node createNode(String compositeURI, String compositeContent, Contribution... contributions); + 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); + } + + private NodeConfiguration createConfiguration(Contribution... contributions) { + NodeConfigurationFactory factory = this; + NodeConfiguration configuration = factory.createNodeConfiguration(); + if (contributions != null) { + for (Contribution c : contributions) { + configuration.addContribution(c.getURI(), c.getLocation()); + } + } + return 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)); + Contribution[] contributions = getContributions(locations); + return createNode(contributions); + } + + private Contribution[] getContributions(List<String> locations) { + if (locations.isEmpty()) { + throw new ServiceRuntimeException("No SCA contributions are found on the classpath"); + } + Contribution[] contributions = new Contribution[locations.size()]; + int index = 0; + for (String location : locations) { + contributions[index++] = new Contribution(location, location); + } + return contributions; + } /** * Create a new SCA node based on the configuration @@ -225,4 +400,6 @@ public abstract class NodeFactory extends DefaultNodeConfigurationFactory { * @return The node configuration */ public abstract NodeConfiguration loadConfiguration(InputStream xml); + + } diff --git a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java index 6c26db5a25..9bbf77a2a9 100644 --- a/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java +++ b/java/sca/modules/node-api/src/main/java/org/apache/tuscany/sca/node/NodeMain2.java @@ -6,15 +6,15 @@ * 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.
+ * under the License.
*/
package org.apache.tuscany.sca.node;
@@ -24,13 +24,13 @@ import java.io.File; public class NodeMain2 {
/**
- * Start an SCA node
+ * 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++) {
+ for (int i = 0; i < args.length; i++) {
File f = new File(args[i]);
if (!f.exists()) {
System.err.println("contribution not found: " + f);
@@ -39,18 +39,18 @@ public class NodeMain2 { contributions[i] = new Contribution(f.toURI().toString(), f.toURI().toString());
}
- Node node = NodeFactory.newInstance().createNode(null, contributions);
- node.start();
-
+ 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) {
+ synchronized (lock) {
lock.wait();
}
}
node.stop();
+ node.destroy();
}
}
|