diff options
Diffstat (limited to 'sca-java-2.x/trunk/modules/domain-node/src')
4 files changed, 356 insertions, 0 deletions
diff --git a/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/NodeFactory.java b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/NodeFactory.java index c01befef5d..a49668a6be 100644 --- a/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/NodeFactory.java +++ b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/NodeFactory.java @@ -19,9 +19,16 @@ package org.apache.tuscany.sca.node2; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; import java.util.Properties; import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.common.java.io.IOHelper; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; @@ -30,12 +37,17 @@ import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory; import org.apache.tuscany.sca.core.assembly.impl.EndpointRegistryImpl; import org.apache.tuscany.sca.deployment.Deployer; +import org.apache.tuscany.sca.monitor.ValidationException; +import org.apache.tuscany.sca.node.configuration.ContributionConfiguration; +import org.apache.tuscany.sca.node.configuration.NodeConfiguration; import org.apache.tuscany.sca.node2.impl.NodeImpl; +import org.apache.tuscany.sca.runtime.ActivationException; import org.apache.tuscany.sca.runtime.CompositeActivator; import org.apache.tuscany.sca.runtime.EndpointRegistry; import org.apache.tuscany.sca.runtime.ExtensibleDomainRegistryFactory; import org.apache.tuscany.sca.runtime.RuntimeProperties; import org.apache.tuscany.sca.work.WorkScheduler; +import org.oasisopen.sca.ServiceRuntimeException; public class NodeFactory { @@ -100,6 +112,16 @@ public class NodeFactory { return new NodeImpl(domainName, deployer, compositeActivator, endpointRegistry, extensionPointRegistry, null); } + public Node createNodeFromXML(String configURL) throws ContributionReadException, ActivationException, ValidationException { + NodeConfiguration configuration = loadConfiguration(configURL); + Node node = createNode(configuration.getDomainURI()); + for ( ContributionConfiguration c : configuration.getContributions()) { +// node.installContribution(c.getURI(), c.getLocation(), c.getMetaDataURL(), c.getDependentContributionURIs(), c.getRunDeployables()); + node.installContribution(c.getURI(), c.getLocation(), null, null, true); + } + return node; + } + public void stop() { deployer.stop(); extensionPointRegistry.stop(); @@ -158,4 +180,30 @@ public class NodeFactory { return domainURI.substring(scheme+1, qm); } } + + protected NodeConfiguration loadConfiguration(String configURL) { + try { + URL base = IOHelper.getLocationAsURL(configURL); + InputStream xml = IOHelper.openStream(base); + InputStreamReader reader = new InputStreamReader(xml, "UTF-8"); + ProcessorContext context = deployer.createProcessorContext(); + NodeConfiguration config = deployer.loadXMLDocument(reader, context.getMonitor()); + if (base != null && config != null) { + // Resolve the contribution location against the node.xml + // TODO: absolute locations? + for (ContributionConfiguration c : config.getContributions()) { + String location = c.getLocation(); + if (location != null) { + URL url = new URL(base, location); + url = IOHelper.normalize(url); + c.setLocation(url.toString()); + } + } + } + return config; + } catch (Throwable e) { + throw new ServiceRuntimeException(e); + } + } + } diff --git a/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/xml/NodeConfigurationProcessor.java b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/xml/NodeConfigurationProcessor.java new file mode 100644 index 0000000000..f0f30bce7c --- /dev/null +++ b/sca-java-2.x/trunk/modules/domain-node/src/main/java/org/apache/tuscany/sca/node2/xml/NodeConfigurationProcessor.java @@ -0,0 +1,237 @@ +/* + * 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.node2.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import java.io.StringReader; +import java.io.StringWriter; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.common.xml.stax.StAXHelper; +import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.processor.ContributionWriteException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +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; + +/** + * Implements a StAX artifact processor for node implementations. + * + * @version $Rev$ $Date$ + */ +public class NodeConfigurationProcessor extends BaseStAXArtifactProcessor implements + StAXArtifactProcessor<NodeConfiguration> { + private static final String SCA11_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1"; + private static final QName NODE = new QName(SCA11_TUSCANY_NS, "node"); + private static final QName CONTRIBUTION = new QName(SCA11_TUSCANY_NS, "contribution"); + private static final QName BINDING = new QName(SCA11_TUSCANY_NS, "binding"); + private static final QName BASE_URI = new QName(SCA11_TUSCANY_NS, "baseURI"); + private static final QName DEPLOYMENT_COMPOSITE = new QName(SCA11_TUSCANY_NS, "deploymentComposite"); + + private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + private static final QName COMPOSITE = new QName(SCA11_NS, "composite"); + + private StAXArtifactProcessor processor; + private NodeConfigurationFactory nodeConfigurationFactory; + private StAXHelper helper; + + public NodeConfigurationProcessor(ExtensionPointRegistry registry, + StAXArtifactProcessor processor) { + FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); + this.nodeConfigurationFactory = modelFactories.getFactory(NodeConfigurationFactory.class); + this.processor = processor; + this.helper = StAXHelper.getInstance(registry); + } + + public QName getArtifactType() { + // Returns the QName of the XML element processed by this processor + return NODE; + } + + public Class<NodeConfiguration> getModelType() { + // Returns the type of model processed by this processor + return NodeConfiguration.class; + } + + public NodeConfiguration read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + + NodeConfiguration node = null; + ContributionConfiguration contribution = null; + DeploymentComposite composite = null; + BindingConfiguration binding = null; + + // Skip to end element + while (true) { + int event = reader.getEventType(); + switch (event) { + case XMLStreamConstants.START_ELEMENT: + QName name = reader.getName(); + if (NODE.equals(name)) { + node = nodeConfigurationFactory.createNodeConfiguration(); + node.setURI(reader.getAttributeValue(null, "uri")); + node.setDomainURI(reader.getAttributeValue(null, "domain")); + node.setDomainRegistryURI(reader.getAttributeValue(null, "domainRegistry")); + } else if (CONTRIBUTION.equals(name)) { + contribution = nodeConfigurationFactory.createContributionConfiguration(); + contribution.setURI(reader.getAttributeValue(null, "uri")); + contribution.setLocation(reader.getAttributeValue(null, "location")); + node.getContributions().add(contribution); + } else if (BINDING.equals(name)) { + binding = nodeConfigurationFactory.createBindingConfiguration(); + binding.setBindingType(getQName(reader, "name")); + String baseURIs = reader.getAttributeValue(null, "baseURIs"); + if (baseURIs != null) { + StringTokenizer tokenizer = new StringTokenizer(baseURIs); + while (tokenizer.hasMoreTokens()) { + binding.getBaseURIs().add(tokenizer.nextToken()); + } + } + node.getBindings().add(binding); + } else if (DEPLOYMENT_COMPOSITE.equals(name)) { + composite = nodeConfigurationFactory.createDeploymentComposite(); + composite.setLocation(reader.getAttributeValue(null, "location")); + if (contribution != null) { + contribution.getDeploymentComposites().add(composite); + } + } else if(BASE_URI.equals(name)) { + // We also support <baseURI> element + String baseURI = reader.getElementText(); + if (baseURI != null && binding != null) { + baseURI = baseURI.trim(); + binding.addBaseURI(baseURI); + } + // getElementText() moves the event to END_ELEMENT + continue; + } else if (COMPOSITE.equals(name)) { + /* + Object model = processor.read(reader); + if (model instanceof Composite) { + // FIXME: We need to capture the text here + // composite.setComposite((Composite)model); + } + */ + StringWriter sw = new StringWriter(); + XMLStreamWriter writer = helper.createXMLStreamWriter(sw); + helper.save(reader, writer); + composite.setContent(sw.toString()); + } else { + node.getExtensions().add(processor.read(reader, context)); + } + break; + + case END_ELEMENT: + name = reader.getName(); + if (NODE.equals(name)) { + return node; + } else if (CONTRIBUTION.equals(name)) { + contribution = null; + } else if (DEPLOYMENT_COMPOSITE.equals(name)) { + composite = null; + } else if (BINDING.equals(name)) { + binding = null; + } + } + if (reader.hasNext()) { + reader.next(); + } else { + break; + } + } + + return node; + } + + public void resolve(NodeConfiguration node, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + } + + public void write(NodeConfiguration node, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, + XMLStreamException { + + writeStart(writer, + NODE.getNamespaceURI(), + NODE.getLocalPart(), + new XAttr("uri", node.getURI()), + new XAttr("domainRegistry", node.getDomainRegistryURI()), + new XAttr("domain", node.getDomainURI())); + + for (ContributionConfiguration c : node.getContributions()) { + writeStart(writer, + CONTRIBUTION.getNamespaceURI(), + CONTRIBUTION.getLocalPart(), + new XAttr("uri", c.getURI()), + new XAttr("location", c.getLocation())); + for (DeploymentComposite dc : c.getDeploymentComposites()) { + writeStart(writer, + DEPLOYMENT_COMPOSITE.getNamespaceURI(), + DEPLOYMENT_COMPOSITE.getLocalPart(), + new XAttr("location", dc.getLocation()), + new XAttr("contribution", dc.getContributionURI())); + if (dc.getContent() != null) { + XMLStreamReader reader = helper.createXMLStreamReader(new StringReader(dc.getContent())); + reader.nextTag(); // Move to the first element + helper.save(reader, writer); + reader.close(); + } + writeEnd(writer); + } + writeEnd(writer); + } + + for (BindingConfiguration b : node.getBindings()) { + StringBuffer uris = new StringBuffer(); + for (String uri : b.getBaseURIs()) { + uris.append(uri).append(' '); + } + if (uris.length() > 0) { + uris.deleteCharAt(uris.length() - 1); // Remove the trailing space + } else { + uris = null; + } + String baseURIs = (uris == null) ? null : uris.toString(); + writeStart(writer, + BINDING.getNamespaceURI(), + BINDING.getLocalPart(), + new XAttr("name", b.getBindingType()), + new XAttr("baseURIs", baseURIs)); + writeEnd(writer); + } + + for(Object o: node.getExtensions()) { + processor.write(o, writer, context); + } + + writeEnd(writer); + } +} diff --git a/sca-java-2.x/trunk/modules/domain-node/src/test/java/org/apache/tuscany/sca/node2/NodeXMLTestCase.java b/sca-java-2.x/trunk/modules/domain-node/src/test/java/org/apache/tuscany/sca/node2/NodeXMLTestCase.java new file mode 100644 index 0000000000..110fbfd49e --- /dev/null +++ b/sca-java-2.x/trunk/modules/domain-node/src/test/java/org/apache/tuscany/sca/node2/NodeXMLTestCase.java @@ -0,0 +1,44 @@ +/* + * 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.node2; + +import java.util.List; + +import junit.framework.Assert; + +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.monitor.ValidationException; +import org.apache.tuscany.sca.runtime.ActivationException; +import org.junit.Test; + +public class NodeXMLTestCase { + + @Test + public void testHelloworldXML() throws ContributionReadException, ActivationException, ValidationException { + Node node = NodeFactory.newInstance().createNodeFromXML("src/test/resources/helloworldNode.xml"); + Assert.assertEquals("helloworld", node.getDomainName()); + List<String> cs = node.getInstalledContributions(); + Assert.assertEquals(1, cs.size()); + Assert.assertEquals("sample-helloworld", cs.get(0)); + List<String> compsoites = node.getDeployedComposites("sample-helloworld"); + Assert.assertEquals(1, compsoites.size()); + Assert.assertEquals("helloworld.composite", compsoites.get(0)); + } + +} diff --git a/sca-java-2.x/trunk/modules/domain-node/src/test/resources/helloworldNode.xml b/sca-java-2.x/trunk/modules/domain-node/src/test/resources/helloworldNode.xml new file mode 100644 index 0000000000..a46148ba0e --- /dev/null +++ b/sca-java-2.x/trunk/modules/domain-node/src/test/resources/helloworldNode.xml @@ -0,0 +1,27 @@ +<?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. +--> +<node xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns="http://tuscany.apache.org/xmlns/sca/1.1" + xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1" + domain="helloworld"> + + <contribution location="sample-helloworld.jar"/> + +</node>
\ No newline at end of file |