diff options
Diffstat (limited to '')
82 files changed, 12179 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/LICENSE b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/LICENSE new file mode 100644 index 0000000000..8aa906c321 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/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/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..fe285082bd --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/META-INF/MANIFEST.MF @@ -0,0 +1,71 @@ +Manifest-Version: 1.0
+Export-Package: org.apache.tuscany.sca.assembly.xml;version="2.0.0";
+ uses:="org.apache.tuscany.sca.assembly,
+ javax.xml.parsers,
+ org.apache.tuscany.sca.core,
+ org.apache.tuscany.sca.contribution,
+ org.apache.tuscany.sca.monitor,
+ org.apache.tuscany.sca.policy,
+ org.apache.tuscany.sca.interfacedef,
+ org.w3c.dom,
+ javax.xml.namespace,
+ javax.xml.stream,
+ org.apache.tuscany.sca.contribution.resolver,
+ org.apache.tuscany.sca.contribution.processor",
+ org.apache.tuscany.sca.definitions.xml;version="2.0.0";
+ uses:="javax.xml.stream,
+ org.apache.tuscany.sca.contribution.resolver,
+ org.apache.tuscany.sca.definitions,
+ org.apache.tuscany.sca.contribution.processor,
+ org.apache.tuscany.sca.core,
+ org.apache.tuscany.sca.monitor,
+ javax.xml.namespace",
+ org.apache.tuscany.sca.policy.xml;version="2.0.0";
+ uses:="javax.xml.xpath,
+ javax.xml.stream,
+ org.apache.tuscany.sca.contribution.resolver,
+ org.apache.tuscany.sca.contribution.processor,
+ org.apache.tuscany.sca.core,
+ org.apache.tuscany.sca.policy,
+ org.apache.tuscany.sca.monitor,
+ javax.xml.namespace"
+SCA-Version: 1.1
+Bundle-Name: Apache Tuscany SCA XML Assembly Model
+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 XML Assembly Model
+Import-Package: javax.xml.namespace,
+ javax.xml.parsers,
+ javax.xml.stream,
+ javax.xml.transform,
+ javax.xml.transform.dom,
+ javax.xml.transform.stream,
+ javax.xml.validation;resolution:=optional,
+ javax.xml.xpath,
+ org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.assembly.xml;version="2.0.0",
+ org.apache.tuscany.sca.common.java.io;version="2.0.0",
+ org.apache.tuscany.sca.common.xml.stax;version="2.0.0",
+ org.apache.tuscany.sca.common.xml.xpath;version="2.0.0",
+ org.apache.tuscany.sca.contribution;version="2.0.0",
+ org.apache.tuscany.sca.contribution.java;version="2.0.0",
+ org.apache.tuscany.sca.contribution.namespace;version="2.0.0",
+ org.apache.tuscany.sca.contribution.processor;version="2.0.0",
+ org.apache.tuscany.sca.contribution.resolver;version="2.0.0",
+ org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.definitions;version="2.0.0",
+ org.apache.tuscany.sca.definitions.util;version="2.0.0",
+ org.apache.tuscany.sca.definitions.xml;version="2.0.0",
+ org.apache.tuscany.sca.extensibility;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.impl;version="2.0.0",
+ org.apache.tuscany.sca.monitor;version="2.0.0",
+ org.apache.tuscany.sca.policy;version="2.0.0",
+ org.apache.tuscany.sca.xsd;version="2.0.0",
+ org.w3c.dom,
+ org.xml.sax;resolution:=optional
+Bundle-SymbolicName: org.apache.tuscany.sca.assembly.xml
+Bundle-DocURL: http://www.apache.org/
+Bundle-RequiredExecutionEnvironment: J2SE-1.5,JavaSE-1.6
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/NOTICE b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/NOTICE new file mode 100644 index 0000000000..ad2ba40961 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/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/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/pom.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/pom.xml new file mode 100644 index 0000000000..cff08c7426 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/pom.xml @@ -0,0 +1,78 @@ +<?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-Beta2-SNAPSHOT</version> + <relativePath>../pom.xml</relativePath> + </parent> + <artifactId>tuscany-assembly-xml</artifactId> + <name>Apache Tuscany SCA Assembly XML Model</name> + + <dependencies> + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-assembly</artifactId> + <version>2.0-Beta2-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-contribution</artifactId> + <version>2.0-Beta2-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-xsd</artifactId> + <version>2.0-Beta2-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-common-xml</artifactId> + <version>2.0-Beta2-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-assembly-xsd</artifactId> + <version>2.0-Beta2-SNAPSHOT</version> + <scope>runtime</scope> + </dependency> + + <dependency> + <groupId>org.codehaus.woodstox</groupId> + <artifactId>wstx-asl</artifactId> + <version>3.2.9</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>stax</groupId> + <artifactId>stax-api</artifactId> + </exclusion> + </exclusions> + </dependency> + + </dependencies> + +</project> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java new file mode 100644 index 0000000000..091b3c01d3 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java @@ -0,0 +1,713 @@ +/* + * 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.assembly.xml; + +import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI; +import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI; +import static javax.xml.stream.XMLStreamConstants.CDATA; +import static javax.xml.stream.XMLStreamConstants.CHARACTERS; +import static javax.xml.stream.XMLStreamConstants.COMMENT; +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.MANY; +import static org.apache.tuscany.sca.assembly.xml.Constants.MULTIPLICITY; +import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY; +import static org.apache.tuscany.sca.assembly.xml.Constants.NAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.ONE_N; +import static org.apache.tuscany.sca.assembly.xml.Constants.ONE_ONE; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.SCA11_NS; +import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET; +import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE; +import static org.apache.tuscany.sca.assembly.xml.Constants.VALUE; +import static org.apache.tuscany.sca.assembly.xml.Constants.VALUE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.ZERO_N; +import static org.apache.tuscany.sca.assembly.xml.Constants.ZERO_ONE; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.dom.DOMSource; + +import org.apache.tuscany.sca.assembly.AbstractContract; +import org.apache.tuscany.sca.assembly.AbstractProperty; +import org.apache.tuscany.sca.assembly.AbstractReference; +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Extensible; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +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.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A base class with utility methods for the other artifact processors in this module. + * + * @version $Rev$ $Date$ + */ +abstract class BaseAssemblyProcessor extends BaseStAXArtifactProcessor { + + protected AssemblyFactory assemblyFactory; + protected PolicyFactory policyFactory; + protected StAXArtifactProcessor<Object> extensionProcessor; + protected PolicySubjectProcessor policyProcessor; + private DocumentBuilderFactory documentBuilderFactory; + + + /** + * Constructs a new BaseArtifactProcessor. + * @param assemblyFactory + * @param policyFactory + */ + @SuppressWarnings("unchecked") + protected BaseAssemblyProcessor(AssemblyFactory assemblyFactory, + PolicyFactory policyFactory, + DocumentBuilderFactory documentBuilderFactory, + StAXArtifactProcessor extensionProcessor) { + this.assemblyFactory = assemblyFactory; + this.policyFactory = policyFactory; + this.documentBuilderFactory = documentBuilderFactory; + this.extensionProcessor = (StAXArtifactProcessor<Object>)extensionProcessor; + this.policyProcessor = new PolicySubjectProcessor(policyFactory); + } + + /** + * @param modelFactories + * @param staxProcessor + * @param monitor + */ + protected BaseAssemblyProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor staxProcessor) { + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.documentBuilderFactory = modelFactories.getFactory(DocumentBuilderFactory.class); + this.extensionProcessor = (StAXArtifactProcessor<Object>)staxProcessor; + this.policyProcessor = new PolicySubjectProcessor(policyFactory); + } + + /** + * Marshals warnings into the monitor + * + * @param message + * @param model + * @param messageParameters + */ + protected void warning(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.WARNING, + model, + message, + (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Marshals errors into the monitor + * + * @param problems + * @param message + * @param model + */ + protected void error(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + (Object[])messageParameters); + monitor.problem(problem); + } + } + + /** + * Marshals exceptions into the monitor + * + * @param problems + * @param message + * @param model + */ + protected void error(Monitor monitor, String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + ex); + monitor.problem(problem); + } + } + + /** + * Start an element. + * @param writer + * @param name + * @param attrs + * @throws XMLStreamException + */ + protected void writeStart(XMLStreamWriter writer, String name, XAttr... attrs) throws XMLStreamException { + super.writeStart(writer, SCA11_NS, name, attrs); + } + + /** + * Start a document. + * @param writer + * @throws XMLStreamException + */ + protected void writeStartDocument(XMLStreamWriter writer, String name, XAttr... attrs) throws XMLStreamException { + super.writeStartDocument(writer, SCA11_NS, name, attrs); + } + + /** + * Read list of reference targets + * @param reference + * @param reader + */ + protected void readTargets(Reference reference, XMLStreamReader reader) { + String value = getString(reader, TARGET); + ComponentService target = null; + if (value != null) { + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + target = assemblyFactory.createComponentService(); + target.setUnresolved(true); + target.setName(tokens.nextToken()); + reference.getTargets().add(target); + } + } + } + + /** + * Write a list of targets into an attribute + * @param reference + * @return + */ + protected XAttr writeTargets(Reference reference) { + List<String> targets = new ArrayList<String>(); + for (Service target : reference.getTargets()) { + targets.add(target.getName()); + } + return new XAttr(TARGET, targets); + } + + /** + * Read a multiplicity attribute. + * @param reference + * @param reader + */ + protected void readMultiplicity(AbstractReference reference, XMLStreamReader reader) { + String value = reader.getAttributeValue(null, MULTIPLICITY); + if (ZERO_ONE.equals(value)) { + reference.setMultiplicity(Multiplicity.ZERO_ONE); + } else if (ONE_N.equals(value)) { + reference.setMultiplicity(Multiplicity.ONE_N); + } else if (ZERO_N.equals(value)) { + reference.setMultiplicity(Multiplicity.ZERO_N); + } else if (ONE_ONE.equals(value)) { + reference.setMultiplicity(Multiplicity.ONE_ONE); + } + } + + protected XAttr writeMultiplicity(AbstractReference reference) { + Multiplicity multiplicity = reference.getMultiplicity(); + if (multiplicity != null) { + String value = null; + if (Multiplicity.ZERO_ONE.equals(multiplicity)) { + value = ZERO_ONE; + } else if (Multiplicity.ONE_N.equals(multiplicity)) { + value = ONE_N; + } else if (Multiplicity.ZERO_N.equals(multiplicity)) { + value = ZERO_N; + } else if (Multiplicity.ONE_ONE.equals(multiplicity)) { + value = ONE_ONE; + return null; + } + return new XAttr(MULTIPLICITY, value); + } + return null; + } + + + /** + * Reads an abstract property element. + * @param property + * @param reader + * @param context TODO + * @throws XMLStreamException + * @throws ContributionReadException + */ + protected void readAbstractProperty(AbstractProperty property, XMLStreamReader reader, ProcessorContext context) throws XMLStreamException, + ContributionReadException { + + property.setName(getString(reader, NAME)); + property.setMany(getBoolean(reader, MANY)); + property.setMustSupply(getBoolean(reader, MUST_SUPPLY)); + property.setXSDElement(getQName(reader, ELEMENT)); + property.setXSDType(getQName(reader, TYPE)); + // MJE added 14/05/2009 - check for both @element and @type being present - disallowed by OASIS Assembly spec + if( property.getXSDElement() != null && property.getXSDType() != null ) { + ContributionReadException ce = new ContributionReadException("[ASM40010,ASM60040] Error: property has both @type and @element attribute values - " + + property.getName()); + error(context.getMonitor(), "ContributionReadException", property, ce); + } // end if + + } + + /** + * Resolve an implementation. + * @param implementation + * @param resolver + * @param context + * @return + * @throws ContributionResolveException + */ + protected Implementation resolveImplementation(Implementation implementation, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (implementation != null) { + if (implementation.isUnresolved()) { + implementation = resolver.resolveModel(Implementation.class, implementation, context); + + // Lazily resolve implementations + if (implementation.isUnresolved()) { + extensionProcessor.resolve(implementation, resolver, context); + if (!implementation.isUnresolved()) { + resolver.addModel(implementation, context); + } + } + } + } + return implementation; + } + + /** + * Resolve interface, callback interface and bindings on a list of contracts. + * @param contracts the list of contracts + * @param resolver the resolver to use to resolve models + * @param context TODO + */ + protected <C extends Contract> void resolveContracts(List<C> contracts, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + resolveContracts(null, contracts, resolver, context); + } + + /** + * Resolve interface, callback interface and bindings on a list of contracts. + * @param parent element for the contracts + * @param contracts the list of contracts + * @param resolver the resolver to use to resolve models + * @param context TODO + */ + protected <C extends Contract> void resolveContracts(Base parent, List<C> contracts, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + + String parentName = + (parent instanceof Composite) ? ((Composite)parent).getName().toString() : (parent instanceof Component) + ? ((Component)parent).getName() : "UNKNOWN"; + + for (Contract contract : contracts) { + // Resolve the interface contract + InterfaceContract interfaceContract = contract.getInterfaceContract(); + if (interfaceContract != null) { + extensionProcessor.resolve(interfaceContract, resolver, context); + } + + // Resolve bindings + for (int i = 0, n = contract.getBindings().size(); i < n; i++) { + Binding binding = contract.getBindings().get(i); + extensionProcessor.resolve(binding, resolver, context); + + } + + // Resolve callback bindings + if (contract.getCallback() != null) { + + for (int i = 0, n = contract.getCallback().getBindings().size(); i < n; i++) { + Binding binding = contract.getCallback().getBindings().get(i); + extensionProcessor.resolve(binding, resolver, context); + } + } + } + } + + /** + * Resolve interface and callback interface on a list of abstract contracts. + * @param contracts the list of contracts + * @param resolver the resolver to use to resolve models + * @param context TODO + */ + protected <C extends AbstractContract> void resolveAbstractContracts(List<C> contracts, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + for (AbstractContract contract : contracts) { + + // Resolve the interface contract + InterfaceContract interfaceContract = contract.getInterfaceContract(); + if (interfaceContract != null) { + extensionProcessor.resolve(interfaceContract, resolver, context); + } + } + } + + /** + * Read a property value into a DOM document. + * @param element + * @param type + * @param reader + * @param context + * @return + * @throws XMLStreamException + * @throws ContributionReadException + * @throws ParserConfigurationException + */ + protected Document readPropertyValue(QName element, QName type, boolean isMany, XMLStreamReader reader, ProcessorContext context) throws XMLStreamException, + ContributionReadException { + Document document; + try { + if (documentBuilderFactory == null) { + documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setNamespaceAware(true); + } + document = documentBuilderFactory.newDocumentBuilder().newDocument(); + } catch (ParserConfigurationException e) { + ContributionReadException ce = new ContributionReadException(e); + error(context.getMonitor(), "ContributionReadException", documentBuilderFactory, ce); + throw ce; + } + + // Collect the property values as <value> elements under the <property> + Element root = document.createElementNS(SCA11_NS, "sca:" + PROPERTY); + String nameAttr = getString(reader, NAME); + if (nameAttr != null) { + root.setAttributeNS(SCA11_NS, "sca:" + NAME, nameAttr); + } + declareNamespace(root, "sca", SCA11_NS); + if (type != null) { + org.w3c.dom.Attr xsi = document.createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi"); + xsi.setValue(W3C_XML_SCHEMA_INSTANCE_NS_URI); + root.setAttributeNodeNS(xsi); + + String prefix = type.getPrefix(); + if (prefix == null || prefix.length() == 0) { + prefix = "ns"; + } + + declareNamespace(root, prefix, type.getNamespaceURI()); + + org.w3c.dom.Attr xsiType = document.createAttributeNS(W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type"); + xsiType.setValue(prefix + ":" + type.getLocalPart()); + root.setAttributeNodeNS(xsiType); + } + document.appendChild(root); + + // Start to parse the property + QName name = reader.getName(); // Should be sca:property + + // SCA 1.1 supports the @value for simple types + String valueAttr = getString(reader, VALUE); + if (valueAttr != null) { + Element valueElement = document.createElementNS(SCA11_NS, VALUE); + root.appendChild(valueElement); + valueElement.setTextContent(valueAttr); + } + + boolean gotOneValue = false; + boolean isTextForProperty = true; + StringBuffer text = new StringBuffer(); + + int event = reader.getEventType(); + while (true) { + switch (event) { + case START_ELEMENT: + name = reader.getName(); + if (PROPERTY_QNAME.equals(name)) { + isTextForProperty = true; + break; + } + isTextForProperty = false; + + // CONFORMANCE: ASM50033 + // A property <value/> subelement MUST NOT be used when the @value attribute is used + // to specify the value for that property. + if (valueAttr != null) { + error(context.getMonitor(), "ASM50033: value attribute exists for the property element", name, name); + } + // Read <value> + if (VALUE_QNAME.equals(name)) { + if (gotOneValue && !isMany) { + // TODO: TUSCANY-3231 this should be error not warning but that breaks OASIS tests + // [rfeng] We should not issue warning here as the component property many inherit @many from the componentType property + // warning(context.getMonitor(), "ASM50032: multiple value elements for single-valued property", name, name); + } + loadElement(reader, root); + gotOneValue = true; + } else { + // Global elements + loadElement(reader, root); + } + break; + case XMLStreamConstants.CHARACTERS: + case XMLStreamConstants.CDATA: + if (isTextForProperty) { + text.append(reader.getText()); + } + break; + case END_ELEMENT: + name = reader.getName(); + if (PROPERTY_QNAME.equals(name)) { + + if (root.getChildNodes().getLength() == 0) { + // Add an text as an <value> + if (isTextForProperty){ + if (text.length() > 0) { + Element valueElement = document.createElementNS(SCA11_NS, VALUE); + root.appendChild(valueElement); + valueElement.setTextContent(text.toString()); + } + } + } + return document; + } + break; + } + if (reader.hasNext()) { + event = reader.next(); + } else { + break; + } + } + return document; + } + + /** + * Create a DOM element + * @param document + * @param name + * @return + */ + private Element createElement(Document document, QName name) { + String prefix = name.getPrefix(); + String qname = + (prefix != null && prefix.length() > 0) ? prefix + ":" + name.getLocalPart() : name.getLocalPart(); + return document.createElementNS(name.getNamespaceURI(), qname); + } + + /** + * Declare a namespace. + * @param element + * @param prefix + * @param ns + */ + private void declareNamespace(Element element, String prefix, String ns) { + if (ns == null) { + ns = ""; + } + if (prefix == null) { + prefix = ""; + } + String qname = null; + if ("".equals(prefix)) { + qname = "xmlns"; + } else { + qname = "xmlns:" + prefix; + } + Node node = element; + boolean declared = false; + while (node != null && node.getNodeType() == Node.ELEMENT_NODE) { + NamedNodeMap attrs = node.getAttributes(); + if (attrs == null) { + break; + } + Node attr = attrs.getNamedItem(qname); + if (attr != null) { + declared = ns.equals(attr.getNodeValue()); + break; + } + node = node.getParentNode(); + } + if (!declared) { + org.w3c.dom.Attr attr = element.getOwnerDocument().createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, qname); + attr.setValue(ns); + element.setAttributeNodeNS(attr); + } + } + + /** + * Load a property value specification from an StAX stream into a DOM + * Document. Only elements, text and attributes are processed; all comments + * and other whitespace are ignored. + * + * @param reader the stream to read from + * @param root the DOM node to load + * @throws javax.xml.stream.XMLStreamException + */ + private void loadElement(XMLStreamReader reader, Element root) throws XMLStreamException { + Document document = root.getOwnerDocument(); + Node current = root; + while (true) { + switch (reader.getEventType()) { + case START_ELEMENT: + QName name = reader.getName(); + Element child = createElement(document, name); + + // push the new element and make it the current one + current.appendChild(child); + current = child; + + int count = reader.getNamespaceCount(); + for (int i = 0; i < count; i++) { + String prefix = reader.getNamespacePrefix(i); + String ns = reader.getNamespaceURI(i); + declareNamespace(child, prefix, ns); + } + + if (!"".equals(name.getNamespaceURI())) { + declareNamespace(child, name.getPrefix(), name.getNamespaceURI()); + } + + // add the attributes for this element + count = reader.getAttributeCount(); + for (int i = 0; i < count; i++) { + String ns = reader.getAttributeNamespace(i); + String prefix = reader.getAttributePrefix(i); + String qname = reader.getAttributeLocalName(i); + String value = reader.getAttributeValue(i); + if (prefix != null && prefix.length() != 0) { + qname = prefix + ":" + qname; + } + child.setAttributeNS(ns, qname, value); + if (ns != null) { + declareNamespace(child, prefix, ns); + } + } + + break; + case CDATA: + current.appendChild(document.createCDATASection(reader.getText())); + break; + case CHARACTERS: + current.appendChild(document.createTextNode(reader.getText())); + break; + case COMMENT: + current.appendChild(document.createComment(reader.getText())); + break; + case END_ELEMENT: + // pop the element off the stack + current = current.getParentNode(); + // if we are back at the root then we are done + if (current == root) { + return; + } + + } + if (reader.hasNext()) { + reader.next(); + } else { + return; + } + } + } + + /** + * + * @param reader + * @param elementName + * @param extensionAttributeProcessor + * @param context TODO + * @param estensibleElement + * @throws ContributionReadException + * @throws XMLStreamException + */ + protected void readExtendedAttributes(XMLStreamReader reader, + QName elementName, + Extensible extensible, + StAXAttributeProcessor extensionAttributeProcessor, + ProcessorContext context) throws ContributionReadException, + XMLStreamException { + super.readExtendedAttributes(reader, extensible, extensionAttributeProcessor, assemblyFactory, context); + } + + + /*protected void validatePolicySets(PolicySubject policySetAttachPoint) + throws ContributionResolveException { + validatePolicySets(policySetAttachPoint, policySetAttachPoint.getApplicablePolicySets()); + } + + + protected void validatePolicySets(PolicySubject policySetAttachPoint, + List<PolicySet> applicablePolicySets) throws ContributionResolveException { + //Since the applicablePolicySets in a policySetAttachPoint will already have the + //list of policysets that might ever be applicable to this attachPoint, just check + //if the defined policysets feature in the list of applicable policysets + ExtensionType attachPointType = policySetAttachPoint.getType(); + for ( PolicySet definedPolicySet : policySetAttachPoint.getPolicySets() ) { + if ( !definedPolicySet.isUnresolved() ) { + if ( !applicablePolicySets.contains(definedPolicySet)) { + throw new ContributionResolveException("Policy Set '" + definedPolicySet.getName() + + "' does not apply to binding type " + + attachPointType.getName()); + } + } else { + throw new ContributionResolveException("Policy Set '" + definedPolicySet.getName() + + "' is not defined in this domain "); + + + } + } + }*/ +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java new file mode 100644 index 0000000000..b5fe005812 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java @@ -0,0 +1,129 @@ +/* + * 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.assembly.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.common.java.io.IOHelper; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A componentType processor. + * + * @version $Rev$ $Date$ + */ +public class ComponentTypeDocumentProcessor extends BaseAssemblyProcessor implements URLArtifactProcessor<ComponentType> { + private ValidatingXMLInputFactory inputFactory; + + /** + * Constructs a new componentType processor. + * @param modelFactories + * @param staxProcessor + */ + public ComponentTypeDocumentProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor staxProcessor) { + super(modelFactories, staxProcessor); + this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class); + } + + public ComponentType read(URL contributionURL, URI uri, URL url, ProcessorContext context) throws ContributionReadException { + InputStream urlStream = null; + Monitor monitor = context.getMonitor(); + try { + + // Create a stream reader + urlStream = IOHelper.openStream(url); + XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream); + ValidatingXMLInputFactory.setMonitor(reader, monitor); + reader.nextTag(); + + // Reader the componentType model + ComponentType componentType = (ComponentType)extensionProcessor.read(reader, context); + if (componentType != null) { + componentType.setURI(uri.toString()); + } + + // For debugging purposes, write it back to XML +// if (componentType != null) { +// try { +// ByteArrayOutputStream bos = new ByteArrayOutputStream(); +// XMLOutputFactory outputFactory = XMLOutputFactory.newInstance(); +// outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); +// extensionProcessor.write(componentType, outputFactory.createXMLStreamWriter(bos)); +// Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray())); +// OutputFormat format = new OutputFormat(); +// format.setIndenting(true); +// format.setIndent(2); +// XMLSerializer serializer = new XMLSerializer(System.out, format); +// serializer.serialize(document); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } + + return componentType; + + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", inputFactory, ce); + throw ce; + } catch (IOException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", inputFactory, ce); + throw ce; + } finally { + try { + if (urlStream != null) { + urlStream.close(); + urlStream = null; + } + } catch (IOException ioe) { + //ignore + } + } + } + + public void resolve(ComponentType componentType, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + extensionProcessor.resolve(componentType, resolver, context); + } + + public String getArtifactType() { + return ".componentType"; + } + + public Class<ComponentType> getModelType() { + return ComponentType.class; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java new file mode 100644 index 0000000000..9a4a0dc035 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java @@ -0,0 +1,96 @@ +/* + * 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.assembly.xml; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.java.JavaImport; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; + +/** + * A Model Resolver for ComponentType models. + * + * @version $Rev$ $Date$ + */ +public class ComponentTypeModelResolver implements ModelResolver { + private Contribution contribution; + private Map<String, ComponentType> map = new HashMap<String, ComponentType>(); + + public ComponentTypeModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) { + this.contribution = contribution; + } + + public void addModel(Object resolved, ProcessorContext context) { + ComponentType componentType = (ComponentType)resolved; + map.put(componentType.getURI(), componentType); + } + + public Object removeModel(Object resolved, ProcessorContext context) { + return map.remove(((ComponentType)resolved).getURI()); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved, ProcessorContext context) { + + //get componentType artifact URI + String uri = ((ComponentType)unresolved).getURI(); + if (uri == null) { + return (T)unresolved; + } + + //lookup the componentType + ComponentType resolved = (ComponentType) map.get(uri); + if (resolved != null) { + return modelClass.cast(resolved); + } + + //If not found, delegate the resolution to the imports (in this case based on the java imports) + //compute the package name from the componentType URI + if (unresolved instanceof ComponentType) { + //FIXME The core assembly model now depends on java imports to + // resolve componentTypes of all kinds, this is not right at all!!! + int s = uri.lastIndexOf('/'); + if (s != -1) { + String packageName = uri.substring(0, uri.lastIndexOf("/")); + for (Import import_ : this.contribution.getImports()) { + if (import_ instanceof JavaImport) { + JavaImport javaImport = (JavaImport)import_; + //check the import location against the computed package name from the componentType URI + if (javaImport.getPackage().equals(packageName)) { + // Delegate the resolution to the import resolver + resolved = javaImport.getModelResolver().resolveModel(ComponentType.class, (ComponentType)unresolved, context); + if (!resolved.isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + } + } + } + + return (T)unresolved; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java new file mode 100644 index 0000000000..8f24cc41b9 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java @@ -0,0 +1,471 @@ +/* + * 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.assembly.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK; +import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_TYPE; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_TYPE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION; +import static org.apache.tuscany.sca.assembly.xml.Constants.MANY; +import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY; +import static org.apache.tuscany.sca.assembly.xml.Constants.NAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.OPERATION_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE; +import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE; +import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE; +import static org.apache.tuscany.sca.assembly.xml.Constants.EXTENSION; +import static org.apache.tuscany.sca.assembly.xml.Constants.EXTENSION_QNAME; + +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.assembly.Binding; +import org.apache.tuscany.sca.assembly.Callback; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Extensible; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.common.xml.stax.StAXHelper; +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.processor.StAXAttributeProcessor; +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.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.interfacedef.impl.OperationImpl; +import org.apache.tuscany.sca.policy.PolicySubject; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A componentType processor. + * + * @version $Rev$ $Date$ + */ +public class ComponentTypeProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<ComponentType> { + + private StAXHelper staxHelper; + + /** + * Constructs a new componentType processor. + * + * @param modelFactories + * @param extensionProcessor + * @param extensionAttributeProcessor + * @param monitor + */ + public ComponentTypeProcessor(ExtensionPointRegistry extensionPoints, + //public ComponentTypeProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor extensionProcessor, + StAXAttributeProcessor extensionAttributeProcessor) { + super(modelFactories(extensionPoints), extensionProcessor); + + // + staxHelper = StAXHelper.getInstance(extensionPoints); + } + + public ComponentType read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException { + ComponentType componentType = null; + Service service = null; + Reference reference = null; + Contract contract = null; + Property property = null; + Callback callback = null; + QName name = null; + + try { + // Read the componentType document + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + name = reader.getName(); + + if (Constants.COMPONENT_TYPE_QNAME.equals(name)) { + + // Read a <componentType> + componentType = assemblyFactory.createComponentType(); + + } else if (Constants.SERVICE_QNAME.equals(name)) { + + // Read a <service> + service = assemblyFactory.createService(); + contract = service; + service.setName(getString(reader, Constants.NAME)); + componentType.getServices().add(service); + policyProcessor.readPolicies(service, reader); + + } else if (Constants.REFERENCE_QNAME.equals(name)) { + + // Read a <reference> + reference = assemblyFactory.createReference(); + contract = reference; + reference.setName(getString(reader, Constants.NAME)); + reference.setWiredByImpl(getBoolean(reader, Constants.WIRED_BY_IMPL)); + readMultiplicity(reference, reader); + readTargets(reference, reader); + componentType.getReferences().add(reference); + policyProcessor.readPolicies(reference, reader); + + } else if (Constants.PROPERTY_QNAME.equals(name)) { + + // Read a <property> + property = assemblyFactory.createProperty(); + readAbstractProperty(property, reader, context); + policyProcessor.readPolicies(property, reader); + + // Read the property value + Document value = readPropertyValue(property.getXSDElement(), property.getXSDType(), property.isMany(), reader, context); + property.setValue(value); + + componentType.getProperties().add(property); + + } else if (Constants.IMPLEMENTATION_QNAME.equals(name)) { + + // Read an <implementation> element + policyProcessor.readPolicies(componentType, reader); + + } else if (Constants.CALLBACK_QNAME.equals(name)) { + + // Read a <callback> + callback = assemblyFactory.createCallback(); + contract.setCallback(callback); + policyProcessor.readPolicies(callback, reader); + + } else if (OPERATION_QNAME.equals(name)) { + + // Read an <operation> + Operation operation = new OperationImpl(); + operation.setName(getString(reader, NAME)); + operation.setUnresolved(true); + if (callback != null) { + policyProcessor.readPolicies(callback, operation, reader); + } else { + policyProcessor.readPolicies(contract, operation, reader); + } + } else if(EXTENSION_QNAME.equals(name)) { + // Handle <extension> + //ignore element as this is a wrapper for extensibility + break; + } else { + + + // Read an extension element + Object extension = extensionProcessor.read(reader, context); + if (extension != null) { + if (extension instanceof InterfaceContract) { + + // <service><interface> and <reference><interface> + contract.setInterfaceContract((InterfaceContract)extension); + + } else if (extension instanceof Binding) { + + // <service><binding> and <reference><binding> + if (callback != null) { + callback.getBindings().add((Binding)extension); + } else { + contract.getBindings().add((Binding)extension); + } + } else { + + // Add the extension element to the current element + if (callback != null) { + callback.getExtensions().add(extension); + } else if (contract != null) { + contract.getExtensions().add(extension); + } else if (property != null) { + property.getExtensions().add(extension); + } else { + if (componentType instanceof Extensible) { + ((Extensible)componentType).getExtensions().add(extension); + } + } + } + } + } + break; + + case END_ELEMENT: + name = reader.getName(); + + // Clear current state when reading reaching end element + if (SERVICE_QNAME.equals(name)) { + service = null; + contract = null; + } else if (REFERENCE_QNAME.equals(name)) { + reference = null; + contract = null; + } else if (PROPERTY_QNAME.equals(name)) { + property = null; + } else if (CALLBACK_QNAME.equals(name)) { + callback = null; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + } + catch (XMLStreamException e) { + ContributionReadException ex = new ContributionReadException(e); + error(context.getMonitor(), "XMLStreamException", reader, ex); + } + + return componentType; + } + + public void write(ComponentType componentType, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + + // Write <componentType> element + writeStartDocument(writer, COMPONENT_TYPE); + + // Write <service> elements + for (Service service : componentType.getServices()) { + writeStart(writer, SERVICE, new XAttr(NAME, service.getName()), + policyProcessor.writePolicies(service)); + + if (service.getInterfaceContract() != null) { + extensionProcessor.write(service.getInterfaceContract(), writer, context); + } + + for (Binding binding: service.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + if (service.getCallback() != null) { + Callback callback = service.getCallback(); + writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback)); + + for (Binding binding: callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + for (Object extension: callback.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEnd(writer); + } + + this.writeExtendedElements(writer, service, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <reference> elements + for (Reference reference : componentType.getReferences()) { + + writeStart(writer, REFERENCE, + new XAttr(NAME, reference.getName()), + writeMultiplicity(reference), + writeTargets(reference), + policyProcessor.writePolicies(reference)); + + extensionProcessor.write(reference.getInterfaceContract(), writer, context); + + for (Binding binding: reference.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + if (reference.getCallback() != null) { + Callback callback = reference.getCallback(); + writeStart(writer, CALLBACK, + policyProcessor.writePolicies(callback)); + + for (Binding binding: callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + for (Object extension: callback.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEnd(writer); + } + + this.writeExtendedElements(writer, reference, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <property> elements + for (Property property : componentType.getProperties()) { + writeStart(writer, + PROPERTY, + new XAttr(NAME, property.getName()), + new XAttr(MUST_SUPPLY, property.isMustSupply()), + new XAttr(MANY, property.isMany()), + new XAttr(TYPE, property.getXSDType()), + new XAttr(ELEMENT, property.getXSDElement()), + policyProcessor.writePolicies(property)); + + // Write property value + writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer); + + // Write extensions + for (Object extension : property.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEnd(writer); + } + + // Write extension elements + if (componentType instanceof Extensible) { + for (Object extension: ((Extensible)componentType).getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + } + + // Write <implementation> elements if the componentType has + // any intents or policySets + boolean writeImplementation = false; + if (componentType instanceof PolicySubject) { + if (!((PolicySubject)componentType).getRequiredIntents().isEmpty()) { + writeImplementation = true; + } + } + if (componentType instanceof PolicySubject) { + if (!((PolicySubject)componentType).getPolicySets().isEmpty()) { + writeImplementation = true; + } + } + if (writeImplementation) { + writeStart(writer, IMPLEMENTATION, + policyProcessor.writePolicies(componentType)); + } + + writeEndDocument(writer); + } + + /** + * Write the value of a property - override to use correct method of creating an XMLStreamReader + * @param document + * @param element + * @param type + * @param writer + * @throws XMLStreamException + */ + protected void writePropertyValue(Object propertyValue, QName element, QName type, XMLStreamWriter writer) + throws XMLStreamException { + + if (propertyValue instanceof Document) { + Document document = (Document)propertyValue; + NodeList nodeList = document.getDocumentElement().getChildNodes(); + + for (int item = 0; item < nodeList.getLength(); ++item) { + Node node = nodeList.item(item); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + // Correct way to create a reader for a node object... + XMLStreamReader reader = staxHelper.createXMLStreamReader(node); + + while (reader.hasNext()) { + switch (reader.next()) { + case XMLStreamConstants.START_ELEMENT: + QName name = reader.getName(); + writer.writeStartElement(name.getPrefix(), name.getLocalPart(), name.getNamespaceURI()); + + int namespaces = reader.getNamespaceCount(); + for (int i = 0; i < namespaces; i++) { + String prefix = reader.getNamespacePrefix(i); + String ns = reader.getNamespaceURI(i); + writer.writeNamespace(prefix, ns); + } + + if (!"".equals(name.getNamespaceURI())) { + writer.writeNamespace(name.getPrefix(), name.getNamespaceURI()); + } + + // add the attributes for this element + namespaces = reader.getAttributeCount(); + for (int i = 0; i < namespaces; i++) { + String ns = reader.getAttributeNamespace(i); + String prefix = reader.getAttributePrefix(i); + String qname = reader.getAttributeLocalName(i); + String value = reader.getAttributeValue(i); + + writer.writeAttribute(prefix, ns, qname, value); + } + + break; + case XMLStreamConstants.CDATA: + writer.writeCData(reader.getText()); + break; + case XMLStreamConstants.CHARACTERS: + writer.writeCharacters(reader.getText()); + break; + case XMLStreamConstants.END_ELEMENT: + writer.writeEndElement(); + break; + } + } + } else { + writer.writeCharacters(node.getTextContent()); + } + } + } + } // end method writePropertyValue + + public void resolve(ComponentType componentType, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + + // Resolve component type services and references + resolveContracts(componentType.getServices(), resolver, context); + resolveContracts(componentType.getReferences(), resolver, context); + } + + public QName getArtifactType() { + return COMPONENT_TYPE_QNAME; + } + + public Class<ComponentType> getModelType() { + return ComponentType.class; + } + + /** + * Returns the model factory extension point to use. + * + * @param extensionPoints + * @return + */ + private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) { + return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java new file mode 100644 index 0000000000..5ba42a0dec --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java @@ -0,0 +1,185 @@ +/* + * 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.assembly.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; + +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.transform.stream.StreamSource; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.common.java.io.IOHelper; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.xml.sax.SAXException; + +/** + * A composite processor. + * + * @version $Rev$ $Date$ + */ +public class CompositeDocumentProcessor extends BaseAssemblyProcessor implements URLArtifactProcessor<Composite>, + XMLStreamConstants { + private ValidatingXMLInputFactory inputFactory; + + + /** + * Constructs a composite document processor + * @param modelFactories + * @param staxProcessor + * @param monitor + */ + public CompositeDocumentProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor<?> staxProcessor) { + super(modelFactories, staxProcessor); + this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class); + } + + /** + * Reads the contents of a Composite document and returns a Composite object + * @param contributionURL - the URL of the contribution containing the Composite - can be null + * @param uri - the URI of the composite document + * @param url - the URL of the composite document + * @return a Composite object built from the supplied Composite document + */ + public Composite read(URL contributionURL, URI uri, URL url, ProcessorContext context) throws ContributionReadException { + if( uri == null || url == null ) { + throw new ContributionReadException("Request to read composite with uri or url NULL"); + } // end if + InputStream scdlStream = null; + + try { + scdlStream = IOHelper.openStream(url); + } catch (IOException e) { + ContributionReadException ce = new ContributionReadException("Exception reading " + uri, e); + error(context.getMonitor(), "ContributionReadException", url, ce); + throw ce; + } + return read(uri, url, scdlStream, context); + } + + public Composite read(URI uri, URL url, InputStream scdlStream, ProcessorContext context) throws ContributionReadException { + try { + + Composite composite = null; + Monitor monitor = context.getMonitor(); + // Tag the monitor with the name of the composite artifact + if( monitor != null ) { + monitor.setArtifactName(uri.toString()); + } //end if + + // Set up a StreamSource for the composite file, since this has an associated URL that + // can be used by the parser to find references to other files such as DTDs + StreamSource scdlSource = new StreamSource( scdlStream, url.toString() ); + XMLStreamReader reader = inputFactory.createXMLStreamReader(scdlSource); + + // set the monitor on the input factory as the standard XMLInputFactory + // methods used for creating readers don't allow for the context to + // be passed in + ValidatingXMLInputFactory.setMonitor(reader, context.getMonitor()); + + // Read the header (i.e. text before the <composite> element, if any + readCompositeFileHeader( reader ); + + // Read the composite model + composite = (Composite)extensionProcessor.read(reader, context); + if (composite != null) { + composite.setURI(uri.toString()); + } + + return composite; + + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException("Exception reading " + uri, e); + error(context.getMonitor(), "ContributionReadException", inputFactory, ce); + throw ce; + } finally { + try { + if (scdlStream != null) { + scdlStream.close(); + scdlStream = null; + } + } catch (IOException ioe) { + //ignore + } + } + } + + /** + * Reads the header portion of a composite file - i.e. the section of the file before the + * <composite> start tag + * In particular handle any DTD declarations + * @param reader - an XMLStreamReader which is reading the composite file + * @throws XMLStreamException + */ + private void readCompositeFileHeader( XMLStreamReader reader ) throws XMLStreamException { + + while (true) { + int event = reader.next(); + + if ( event == CHARACTERS + || event == CDATA + || event == SPACE + || event == PROCESSING_INSTRUCTION + || event == COMMENT + || event == DTD + || event == ENTITY_DECLARATION ) { + continue; + } // end if + + // The first start (or end) element terminates the header scan + if (event == START_ELEMENT || event == END_ELEMENT) { + return; + } // end if + } // end while + } // end method readCompositeFileHeader + + public void resolve(Composite composite, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + try { + if (composite != null) + extensionProcessor.resolve(composite, resolver, context); + } catch (Throwable e ) { + // Add information about which composite was being processed when the exception occurred + String newMessage = "Processing composite " + composite.getName() + ": " + e.getMessage(); + throw new ContributionResolveException( newMessage, e ); + } // end try + } + + public String getArtifactType() { + return ".composite"; + } + + public Class<Composite> getModelType() { + return Composite.class; + } + +} // end class diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java new file mode 100644 index 0000000000..7a396fe100 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java @@ -0,0 +1,96 @@ +/* + * 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.assembly.xml; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.Import; +import org.apache.tuscany.sca.contribution.namespace.NamespaceImport; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; + +/** + * A Model Resolver for Composite models. + * + * @version $Rev$ $Date$ + */ +public class CompositeModelResolver implements ModelResolver { + + private Contribution contribution; + private Map<QName, Composite> map = new HashMap<QName, Composite>(); + + public CompositeModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) { + this.contribution = contribution; + } + + public void addModel(Object resolved, ProcessorContext context) { + Composite composite = (Composite)resolved; + Composite old = map.put(composite.getName(), composite); + if (old != null) { + Monitor.error(context.getMonitor(), + this, + Messages.RESOURCE_BUNDLE, + "DuplicateCompositeName", + composite.getName().toString(), + contribution.getLocation()); + } + } + + public Object removeModel(Object resolved, ProcessorContext context) { + return map.remove(((Composite)resolved).getName()); + } + + public <T> T resolveModel(Class<T> modelClass, T unresolved, ProcessorContext context) { + + // Lookup a definition for the given namespace + QName qname = ((Composite)unresolved).getName(); + Composite resolved = null; + + // Delegate the resolution to the imports + for (Import import_ : this.contribution.getImports()) { + if (import_ instanceof NamespaceImport) { + NamespaceImport namespaceImport = (NamespaceImport)import_; + if (namespaceImport.getNamespace().equals(qname.getNamespaceURI())) { + + // Delegate the resolution to the import resolver + resolved = namespaceImport.getModelResolver().resolveModel(Composite.class, (Composite)unresolved, context); + if (!resolved.isUnresolved()) { + return modelClass.cast(resolved); + } + } + } + } + + // No definition found, search within the current contribution + resolved = (Composite) map.get(qname); + if (resolved != null) { + return modelClass.cast(resolved); + } + + return (T)unresolved; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java new file mode 100644 index 0000000000..eecb07e6cd --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java @@ -0,0 +1,1259 @@ +/* + * 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.assembly.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.AUTOWIRE; +import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK; +import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPOSITE; +import static org.apache.tuscany.sca.assembly.xml.Constants.COMPOSITE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT; +import static org.apache.tuscany.sca.assembly.xml.Constants.EXTENSION_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.FILE; +import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION_COMPOSITE; +import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION_COMPOSITE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.INCLUDE; +import static org.apache.tuscany.sca.assembly.xml.Constants.INCLUDE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.INTENTS; +import static org.apache.tuscany.sca.assembly.xml.Constants.LOCAL; +import static org.apache.tuscany.sca.assembly.xml.Constants.MANY; +import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY; +import static org.apache.tuscany.sca.assembly.xml.Constants.NAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.NONOVERRIDABLE; +import static org.apache.tuscany.sca.assembly.xml.Constants.POLICY_SET_ATTACHMENT_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROMOTE; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY; +import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE; +import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.REPLACE; +import static org.apache.tuscany.sca.assembly.xml.Constants.REQUIRES_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.SCA11_NS; +import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE; +import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE_QNAME; +import static org.apache.tuscany.sca.assembly.xml.Constants.SOURCE; +import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET; +import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET_NAMESPACE; +import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE; +import static org.apache.tuscany.sca.assembly.xml.Constants.URI; +import static org.apache.tuscany.sca.assembly.xml.Constants.WIRE; +import static org.apache.tuscany.sca.assembly.xml.Constants.WIRED_BY_IMPL; +import static org.apache.tuscany.sca.assembly.xml.Constants.WIRE_QNAME; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.dom.DOMSource; +import javax.xml.xpath.XPathExpressionException; + +import org.apache.tuscany.sca.assembly.Binding; +import org.apache.tuscany.sca.assembly.Callback; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentProperty; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeReference; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Contract; +import org.apache.tuscany.sca.assembly.Implementation; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.assembly.Reference; +import org.apache.tuscany.sca.assembly.Service; +import org.apache.tuscany.sca.assembly.Wire; +import org.apache.tuscany.sca.common.xml.stax.StAXHelper; +import org.apache.tuscany.sca.common.xml.xpath.XPathHelper; +import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; +import org.apache.tuscany.sca.contribution.ContributionFactory; +import org.apache.tuscany.sca.contribution.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.processor.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ResolverExtension; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.interfacedef.InterfaceContract; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySubject; +import org.apache.tuscany.sca.xsd.XSDFactory; +import org.apache.tuscany.sca.xsd.XSDefinition; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * A composite processor. + * + * @version $Rev$ $Date$ + */ +public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<Composite> { + private XPathHelper xpathHelper; + private PolicyFactory intentAttachPointTypeFactory; + private StAXAttributeProcessor<Object> extensionAttributeProcessor; + private ContributionFactory contributionFactory; + private XSDFactory xsdFactory; + + private StAXHelper staxHelper; + + /** + * Construct a new composite processor + * + * @param extensionPoints + * @param extensionProcessor + */ + public CompositeProcessor(ExtensionPointRegistry extensionPoints, + StAXArtifactProcessor extensionProcessor, + StAXAttributeProcessor extensionAttributeProcessor) { + + this(modelFactories(extensionPoints), extensionProcessor, extensionAttributeProcessor); + + this.xpathHelper = XPathHelper.getInstance(extensionPoints); + this.extensionAttributeProcessor = extensionAttributeProcessor; + + this.xsdFactory = extensionPoints.getExtensionPoint(XSDFactory.class); + + // + staxHelper = StAXHelper.getInstance(extensionPoints); + } + + /** + * Constructs a new composite processor + * + * @param modelFactories + * @param extensionProcessor + * @param monitor + */ + private CompositeProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor extensionProcessor, + StAXAttributeProcessor extensionAttributeProcessor) { + + super(modelFactories, extensionProcessor); + this.intentAttachPointTypeFactory = modelFactories.getFactory(PolicyFactory.class); + this.contributionFactory = modelFactories.getFactory(ContributionFactory.class); + this.extensionAttributeProcessor = extensionAttributeProcessor; + + this.xsdFactory = modelFactories.getFactory(XSDFactory.class); + } + + public Composite read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException { + Composite composite = null; + Composite include = null; + Component component = null; + Property property = null; + ComponentService componentService = null; + ComponentReference componentReference = null; + ComponentProperty componentProperty = null; + CompositeService compositeService = null; + CompositeReference compositeReference = null; + Contract contract = null; + Wire wire = null; + Callback callback = null; + QName name = null; + Monitor monitor = context.getMonitor(); + try { + // Read the composite document + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: + name = reader.getName(); + + if (COMPOSITE_QNAME.equals(name)) { + + // Read a <composite> + composite = assemblyFactory.createComposite(); + composite.setSpecVersion(Constants.SCA11_NS); + + composite.setName(new QName(getURIString(reader, TARGET_NAMESPACE), getString(reader, NAME))); + + if (!isSet(reader, TARGET_NAMESPACE)) { + // spec says that a composite must have a namespace + warning(monitor, "NoCompositeNamespace", composite, composite.getName().toString()); + } + + if (isSet(reader, AUTOWIRE)) { + composite.setAutowire(getBoolean(reader, AUTOWIRE)); + } + + //handle extension attributes + this.readExtendedAttributes(reader, name, composite, extensionAttributeProcessor, context); + + composite.setLocal(getBoolean(reader, LOCAL)); + policyProcessor.readPolicies(composite, reader); + + } else if (INCLUDE_QNAME.equals(name)) { + + // Read an <include> + include = assemblyFactory.createComposite(); + include.setName(getQName(reader, NAME)); + include.setURI(getURIString(reader, URI)); + include.setUnresolved(true); + composite.getIncludes().add(include); + + } else if (SERVICE_QNAME.equals(name)) { + if (component != null) { + + // Read a <component><service> + componentService = assemblyFactory.createComponentService(); + contract = componentService; + componentService.setName(getString(reader, NAME)); + + //handle extension attributes + this.readExtendedAttributes(reader, name, componentService, extensionAttributeProcessor, context); + + component.getServices().add(componentService); + policyProcessor.readPolicies(contract, reader); + } else { + + // Read a <composite><service> + compositeService = assemblyFactory.createCompositeService(); + contract = compositeService; + compositeService.setName(getString(reader, NAME)); + + String promoted = getURIString(reader, PROMOTE); + if (promoted != null) { + String promotedComponentName; + String promotedServiceName; + int s = promoted.indexOf('/'); + if (s == -1) { + promotedComponentName = promoted; + promotedServiceName = null; + } else { + promotedComponentName = promoted.substring(0, s); + promotedServiceName = promoted.substring(s + 1); + } + + Component promotedComponent = assemblyFactory.createComponent(); + promotedComponent.setUnresolved(true); + promotedComponent.setName(promotedComponentName); + compositeService.setPromotedComponent(promotedComponent); + + ComponentService promotedService = assemblyFactory.createComponentService(); + promotedService.setUnresolved(true); + promotedService.setName(promotedServiceName); + compositeService.setPromotedService(promotedService); + } + + //handle extension attributes + this.readExtendedAttributes(reader, name, compositeService, extensionAttributeProcessor, context); + + composite.getServices().add(compositeService); + policyProcessor.readPolicies(contract, reader); + } + + // set the parent model so that binding processing can + // detect it they're being read as part of a reference + // or a service + context.setParentModel(contract); + + } else if (REFERENCE_QNAME.equals(name)) { + if (component != null) { + // Read a <component><reference> + componentReference = assemblyFactory.createComponentReference(); + contract = componentReference; + componentReference.setName(getString(reader, NAME)); + readMultiplicity(componentReference, reader); + if (isSet(reader, AUTOWIRE)) { + componentReference.setAutowire(getBoolean(reader, AUTOWIRE)); + } + // Read @nonOverridable + String nonOverridable = reader.getAttributeValue(null, NONOVERRIDABLE); + if (nonOverridable != null) { + componentReference.setNonOverridable(Boolean.parseBoolean(nonOverridable)); + } + readTargets(componentReference, reader); + componentReference.setWiredByImpl(getBoolean(reader, WIRED_BY_IMPL)); + + //handle extension attributes + this.readExtendedAttributes(reader, + name, + componentReference, + extensionAttributeProcessor, context); + + component.getReferences().add(componentReference); + policyProcessor.readPolicies(contract, reader); + } else { + // Read a <composite><reference> + compositeReference = assemblyFactory.createCompositeReference(); + contract = compositeReference; + compositeReference.setName(getString(reader, NAME)); + readMultiplicity(compositeReference, reader); + readTargets(compositeReference, reader); + String promote = getString(reader, Constants.PROMOTE); + if (promote != null) { + for (StringTokenizer tokens = new StringTokenizer(promote); tokens.hasMoreTokens();) { + String refName = tokens.nextToken(); + Component promotedComponent = assemblyFactory.createComponent(); + int index = refName.indexOf('/'); + if (index == -1) { + error(monitor, "Invalid reference name", compositeReference, refName); + } + String promotedComponentName = refName.substring(0, index); + promotedComponent.setName(promotedComponentName); + promotedComponent.setUnresolved(true); + compositeReference.getPromotedComponents().add(promotedComponent); + ComponentReference promotedReference = + assemblyFactory.createComponentReference(); + promotedReference.setUnresolved(true); + promotedReference.setName(refName); + compositeReference.getPromotedReferences().add(promotedReference); + } + } + compositeReference.setWiredByImpl(getBoolean(reader, WIRED_BY_IMPL)); + + //handle extension attributes + this.readExtendedAttributes(reader, + name, + compositeReference, + extensionAttributeProcessor, context); + + composite.getReferences().add(compositeReference); + policyProcessor.readPolicies(contract, reader); + } + + // set the parent model so that binding processing can + // detect it they're being read as part of a reference + // or a service + context.setParentModel(contract); + + } else if (PROPERTY_QNAME.equals(name)) { + if (component != null) { + + // Read a <component><property> + componentProperty = assemblyFactory.createComponentProperty(); + property = componentProperty; + String source = getURIString(reader, SOURCE); + if (source != null) { + source = source.trim(); + } + componentProperty.setSource(source); + if (source != null) { + String xPath = prepareSourceXPathString( source ); + + try { + componentProperty.setSourceXPathExpression(xpathHelper.compile(reader + .getNamespaceContext(), xPath)); + } catch (XPathExpressionException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", source, ce); + //throw ce; + } + } + componentProperty.setFile(getURIString(reader, FILE)); + + //handle extension attributes + this.readExtendedAttributes(reader, + name, + componentProperty, + extensionAttributeProcessor, context); + + policyProcessor.readPolicies(property, reader); + readAbstractProperty(componentProperty, reader, context); + + // Read the property value + Document value = + readPropertyValue(property.getXSDElement(), property.getXSDType(), property + .isMany(), reader, context); + property.setValue(value); + + component.getProperties().add(componentProperty); + } else { + + // Read a <composite><property> + property = assemblyFactory.createProperty(); + policyProcessor.readPolicies(property, reader); + readAbstractProperty(property, reader, context); + + // Read the property value + Document value = + readPropertyValue(property.getXSDElement(), property.getXSDType(), property + .isMany(), reader, context); + property.setValue(value); + + composite.getProperties().add(property); + } + + // TUSCANY-1949 + // If the property doesn't have a value, the END_ELEMENT event is read by the readPropertyValue + if (reader.getEventType() == END_ELEMENT && PROPERTY_QNAME.equals(reader.getName())) { + property = null; + componentProperty = null; + } + + } else if (COMPONENT_QNAME.equals(name)) { + + // Read a <component> + component = assemblyFactory.createComponent(); + component.setName(getString(reader, NAME)); + if (isSet(reader, AUTOWIRE)) { + component.setAutowire(getBoolean(reader, AUTOWIRE)); + } + if (isSet(reader, URI)) { + component.setURI(getURIString(reader, URI)); + } + + //handle extension attributes + this.readExtendedAttributes(reader, name, component, extensionAttributeProcessor, context); + + composite.getComponents().add(component); + policyProcessor.readPolicies(component, reader); + + } else if (WIRE_QNAME.equals(name)) { + + // Read a <wire> + wire = assemblyFactory.createWire(); + ComponentReference source = assemblyFactory.createComponentReference(); + source.setUnresolved(true); + source.setName(getURIString(reader, SOURCE)); + wire.setSource(source); + + ComponentService target = assemblyFactory.createComponentService(); + target.setUnresolved(true); + target.setName(getURIString(reader, TARGET)); + wire.setTarget(target); + + // Read @replace + String replace = reader.getAttributeValue(null, REPLACE); + if (replace != null) { + wire.setReplace(Boolean.parseBoolean(replace)); + } + + //handle extension attributes + this.readExtendedAttributes(reader, name, wire, extensionAttributeProcessor, context); + + composite.getWires().add(wire); + policyProcessor.readPolicies(wire, reader); + + } else if (CALLBACK_QNAME.equals(name)) { + + // Read a <callback> + callback = assemblyFactory.createCallback(); + contract.setCallback(callback); + callback.setParentContract(contract); + + //handle extension attributes + this.readExtendedAttributes(reader, name, callback, extensionAttributeProcessor, context); + + policyProcessor.readPolicies(callback, reader); + + // set the parent model so that binding processing can + // detect it they're being read as part of a callback + context.setParentModel(callback); + + } else if (IMPLEMENTATION_COMPOSITE_QNAME.equals(name)) { + + // Read an implementation.composite + Composite implementation = assemblyFactory.createComposite(); + implementation.setName(getQName(reader, NAME)); + implementation.setUnresolved(true); + + //handle extension attributes + this.readExtendedAttributes(reader, name, implementation, extensionAttributeProcessor, context); + + component.setImplementation(implementation); + policyProcessor.readPolicies(implementation, reader); + } else if (REQUIRES_QNAME.equals(name)) { + List<QName> intents = getQNames(reader, INTENTS); + for (QName i : intents) { + Intent intent = policyFactory.createIntent(); + intent.setName(i); + if (composite != null) { + composite.getRequiredIntents().add(intent); + } else if (component != null) { + component.getRequiredIntents().add(intent); + } else if (contract != null) { + contract.getRequiredIntents().add(intent); + } else if (callback != null) { + callback.getRequiredIntents().add(intent); + } + } + } else if (POLICY_SET_ATTACHMENT_QNAME.equals(name)) { + QName ps = getQName(reader, NAME); + if (ps != null) { + PolicySet policySet = policyFactory.createPolicySet(); + policySet.setName(ps); + if (composite != null) { + composite.getPolicySets().add(policySet); + } else if (component != null) { + component.getPolicySets().add(policySet); + } else if (contract != null) { + contract.getPolicySets().add(policySet); + } else if (callback != null) { + callback.getPolicySets().add(policySet); + } + } + } else if(EXTENSION_QNAME.equals(name)) { + // Handle <extension> + //ignore element as this is a wrapper for extensibility + break; + } else { + + // Read an extension element + Object extension = extensionProcessor.read(reader, context); + if (extension != null) { + if (extension instanceof InterfaceContract) { + + // <service><interface> and + // <reference><interface> + if (contract != null) { + contract.setInterfaceContract((InterfaceContract)extension); + } else { + if (name.getNamespaceURI().equals(SCA11_NS)) { + error(monitor, "UnexpectedInterfaceElement", extension); + //throw new ContributionReadException("Unexpected <interface> element found. It should appear inside a <service> or <reference> element"); + } else { + composite.getExtensions().add(extension); + } + } + } else if (extension instanceof Binding) { + if (extension instanceof PolicySubject) { + ExtensionType bindingType = intentAttachPointTypeFactory.createBindingType(); + bindingType.setType(name); + bindingType.setUnresolved(true); + ((PolicySubject)extension).setExtensionType(bindingType); + } + // <service><binding> and + // <reference><binding> + if (callback != null) { + callback.getBindings().add((Binding)extension); + } else { + if (contract != null) { + contract.getBindings().add((Binding)extension); + } else { + if (name.getNamespaceURI().equals(SCA11_NS)) { + error(monitor, "UnexpectedBindingElement", extension); + //throw new ContributionReadException("Unexpected <binding> element found. It should appear inside a <service> or <reference> element"); + } else { + composite.getExtensions().add(extension); + } + } + } + + } else if (extension instanceof Implementation) { + if (extension instanceof PolicySubject) { + ExtensionType implType = + intentAttachPointTypeFactory.createImplementationType(); + implType.setType(name); + implType.setUnresolved(true); + ((PolicySubject)extension).setExtensionType(implType); + } + // <component><implementation> + if (component != null) { + component.setImplementation((Implementation)extension); + } else { + if (name.getNamespaceURI().equals(SCA11_NS)) { + error(monitor, "UnexpectedImplementationElement", extension); + //throw new ContributionReadException("Unexpected <implementation> element found. It should appear inside a <component> element"); + } else { + composite.getExtensions().add(extension); + } + } + } else { + + // Add the extension element to the current + // element + if (callback != null) { + callback.getExtensions().add(extension); + } else if (contract != null) { + contract.getExtensions().add(extension); + } else if (property != null) { + property.getExtensions().add(extension); + } else if (component != null) { + component.getExtensions().add(extension); + } else { + composite.getExtensions().add(extension); + } + } + } + } + break; + + case XMLStreamConstants.CHARACTERS: + break; + + case END_ELEMENT: + name = reader.getName(); + + // Clear current state when reading reaching end element + if (SERVICE_QNAME.equals(name)) { + componentService = null; + compositeService = null; + contract = null; + } else if (INCLUDE_QNAME.equals(name)) { + include = null; + } else if (REFERENCE_QNAME.equals(name)) { + componentReference = null; + compositeReference = null; + contract = null; + } else if (PROPERTY_QNAME.equals(name)) { + componentProperty = null; + property = null; + } else if (COMPONENT_QNAME.equals(name)) { + component = null; + } else if (WIRE_QNAME.equals(name)) { + wire = null; + } else if (CALLBACK_QNAME.equals(name)) { + callback = null; + } + break; + } + + // Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + } catch (XMLStreamException e) { + ContributionReadException ex = new ContributionReadException(e); + error(monitor, "XMLStreamException", reader, ex); + } + + return composite; + } + + /** + * Prepares the property @source XPath expression + * + * The form of the @source attribute in the composite file must take one of the forms + * $propertyName + * $propertyName/expression + * $propertyName[n] + * $propertyName[n]/expression + * Property values are stored as <sca:property> elements with one or more <sca:value> subelements or one or more + * global element subelements. The XPath constructed is designed to work against this XML structure and aims to + * retrieve one or more of the subelements or subportions of those subelements (eg some text content). + * Thus the XPath: + * - starts with "*", which means "all the child elements of the root" where root = the <property/> element + * - may then be followed by [xxx] (typically [n] to select one of the child elements) if the source string has [xxx] + * following the propertyName + * - may then be followed by /expression, if the source contains an expression, which will typically select some subportion + * of the child element(s) + * + * @param source - the @source attribute string from a <sca:property> element + * @return the XPath string to use for the source property + */ + private String prepareSourceXPathString( String source ) { + String output = null; + // Expression must begin with '$' + if( source.charAt(0) != '$' ) return output; + + int slash = source.indexOf('/'); + int bracket = source.indexOf('['); + if (slash == -1) { + // Form is $propertyName or $propertyName[n] + output = "*"; + if( bracket != -1 ) { + output = "*" + source.substring(bracket); + } + } else { + // Form is $propertyName/exp or $propertyName[n]/exp + output = "*/" + source.substring(slash + 1); + if( bracket != -1 && bracket < slash ) { + output = "*" + source.substring(bracket); + } + } // end if + + return output; + } // end method prepareSourceXPathString( source ) + + public void write(Composite composite, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, + XMLStreamException { + + // Write <composite> element + writeStartDocument(writer, + COMPOSITE, + new XAttr(TARGET_NAMESPACE, composite.getName().getNamespaceURI()), + new XAttr(NAME, composite.getName().getLocalPart()), + new XAttr(LOCAL, composite.isLocal() ? Boolean.TRUE : null), + new XAttr(AUTOWIRE, composite.getAutowire()), + policyProcessor.writePolicies(composite)); + + //write extended attributes + this.writeExtendedAttributes(writer, composite, extensionAttributeProcessor, context); + + // Write <include> elements + for (Composite include : composite.getIncludes()) { + String uri = include.isUnresolved() ? include.getURI() : null; + writeStart(writer, INCLUDE, new XAttr(NAME, include.getName()), new XAttr(URI, uri)); + + //write extended attributes + this.writeExtendedAttributes(writer, include, extensionAttributeProcessor, context); + + writeEnd(writer); + } + + // Write <service> elements + for (Service service : composite.getServices()) { + CompositeService compositeService = (CompositeService)service; + Component promotedComponent = compositeService.getPromotedComponent(); + ComponentService promotedService = compositeService.getPromotedService(); + String promote; + if (promotedService != null) { + if (promotedService.getName() != null) { + promote = promotedComponent.getName() + '/' + promotedService.getName(); + } else { + promote = promotedComponent.getName(); + } + } else { + promote = null; + } + writeStart(writer, + SERVICE, + new XAttr(NAME, service.getName()), + new XAttr(PROMOTE, promote), + policyProcessor.writePolicies(service)); + + //write extended attributes + this.writeExtendedAttributes(writer, service, extensionAttributeProcessor, context); + + // Write service interface + extensionProcessor.write(service.getInterfaceContract(), writer, context); + + // Write bindings + for (Binding binding : service.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write <callback> element + if (service.getCallback() != null) { + Callback callback = service.getCallback(); + writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback)); + + //write extended attributes + this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor, context); + + // Write callback bindings + for (Binding binding : callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write extensions + this.writeExtendedElements(writer, service, extensionProcessor, context); + + writeEnd(writer); + } + + // Write extensions + this.writeExtendedElements(writer, service, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <component> elements + for (Component component : composite.getComponents()) { + writeStart(writer, + COMPONENT, + new XAttr(NAME, component.getName()), + new XAttr(URI, component.getURI()), + new XAttr(AUTOWIRE, component.getAutowire()), + policyProcessor.writePolicies(component)); + + //write extended attributes + this.writeExtendedAttributes(writer, component, extensionAttributeProcessor, context); + + // Write the component implementation + Implementation implementation = component.getImplementation(); + if (implementation instanceof Composite) { + writeStart(writer, IMPLEMENTATION_COMPOSITE, new XAttr(NAME, ((Composite)implementation).getName()), policyProcessor.writePolicies(implementation)); + + //write extended attributes + this.writeExtendedAttributes(writer, (Composite)implementation, extensionAttributeProcessor, context); + + writeEnd(writer); + } else { + extensionProcessor.write(component.getImplementation(), writer, context); + } + + for (Object extension : component.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + // Write <service> elements + for (ComponentService service : component.getServices()) { + writeStart(writer, SERVICE, new XAttr(NAME, service.getName()), policyProcessor.writePolicies(service)); + + //write extended attributes + this.writeExtendedAttributes(writer, service, extensionAttributeProcessor, context); + + // Write service interface + extensionProcessor.write(service.getInterfaceContract(), writer, context); + + // Write bindings + for (Binding binding : service.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write <callback> element + if (service.getCallback() != null) { + Callback callback = service.getCallback(); + writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback)); + + //write extended attributes + this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor, context); + + // Write bindings + for (Binding binding : callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write extensions + this.writeExtendedElements(writer, callback, extensionProcessor, context); + + writeEnd(writer); + } + + // Write extensions + this.writeExtendedElements(writer, service, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <reference> elements + for (ComponentReference reference : component.getReferences()) { + writeStart(writer, + REFERENCE, + new XAttr(NAME, reference.getName()), + new XAttr(AUTOWIRE, reference.getAutowire()), + (reference.isNonOverridable() ? new XAttr(NONOVERRIDABLE, true) : null), + writeMultiplicity(reference), + writeTargets(reference), + policyProcessor.writePolicies(reference)); + + //write extended attributes + this.writeExtendedAttributes(writer, reference, extensionAttributeProcessor, context); + + // Write reference interface + extensionProcessor.write(reference.getInterfaceContract(), writer, context); + + // Write bindings + for (Binding binding : reference.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write callback + if (reference.getCallback() != null) { + Callback callback = reference.getCallback(); + writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback)); + + //write extended attributes + this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor, context); + + // Write callback bindings + for (Binding binding : callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write extensions + this.writeExtendedElements(writer, callback, extensionProcessor, context); + + writeEnd(writer); + } + + // Write extensions + this.writeExtendedElements(writer, reference, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <property> elements + for (ComponentProperty property : component.getProperties()) { + writeStart(writer, + PROPERTY, + new XAttr(NAME, property.getName()), + new XAttr(MUST_SUPPLY, property.isMustSupply()), + new XAttr(MANY, property.isMany()), + new XAttr(TYPE, property.getXSDType()), + new XAttr(ELEMENT, property.getXSDElement()), + new XAttr(SOURCE, property.getSource()), + new XAttr(FILE, property.getFile()), + policyProcessor.writePolicies(property)); + + //write extended attributes + this.writeExtendedAttributes(writer, property, extensionAttributeProcessor, context); + + // Write property value + writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer); + + // Write extensions + for (Object extension : property.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEnd(writer); + } + + writeEnd(writer); + } + + // Write <reference> elements + for (Reference reference : composite.getReferences()) { + CompositeReference compositeReference = (CompositeReference)reference; + + // Write list of promoted references + List<String> promote = new ArrayList<String>(); + for (ComponentReference promoted : compositeReference.getPromotedReferences()) { + promote.add(promoted.getName()); + } + + // Write <reference> element + writeStart(writer, + REFERENCE, + new XAttr(NAME, reference.getName()), + new XAttr(PROMOTE, promote), + writeMultiplicity(reference), + policyProcessor.writePolicies(reference)); + + //write extended attributes + this.writeExtendedAttributes(writer, reference, extensionAttributeProcessor, context); + + // Write reference interface + extensionProcessor.write(reference.getInterfaceContract(), writer, context); + + // Write bindings + for (Binding binding : reference.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write <callback> element + if (reference.getCallback() != null) { + Callback callback = reference.getCallback(); + writeStart(writer, CALLBACK); + + //write extended attributes + this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor, context); + + // Write callback bindings + for (Binding binding : callback.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + // Write extensions + this.writeExtendedElements(writer, callback, extensionProcessor, context); + + writeEnd(writer); + } + + // Write extensions + this.writeExtendedElements(writer, reference, extensionProcessor, context); + + writeEnd(writer); + } + + // Write <property> elements + for (Property property : composite.getProperties()) { + writeStart(writer, + PROPERTY, + new XAttr(NAME, property.getName()), + new XAttr(MUST_SUPPLY, property.isMustSupply()), + new XAttr(MANY, property.isMany()), + new XAttr(TYPE, property.getXSDType()), + new XAttr(ELEMENT, property.getXSDElement()), + policyProcessor.writePolicies(property)); + + //write extended attributes + this.writeExtendedAttributes(writer, property, extensionAttributeProcessor, context); + + // Write property value + writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer); + + // Write extensions + for (Object extension : property.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEnd(writer); + } + + // Write <wire> elements + for (Wire wire : composite.getWires()) { + writeStart(writer, WIRE, new XAttr(SOURCE, wire.getSource().getName()), new XAttr(TARGET, wire.getTarget() + .getName()), wire.isReplace() ? new XAttr(Constants.REPLACE, true) : null); + + //write extended attributes + this.writeExtendedAttributes(writer, wire, extensionAttributeProcessor, context); + + // Write extensions + for (Object extension : wire.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + writeEnd(writer); + } + + for (Object extension : composite.getExtensions()) { + extensionProcessor.write(extension, writer, context); + } + + writeEndDocument(writer); + } + + public void resolve(Composite composite, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + + Monitor monitor = context.getMonitor(); + try { + monitor.pushContext("Composite: " + composite.getName()); + + // Resolve includes in the composite + for (int i = 0, n = composite.getIncludes().size(); i < n; i++) { + Composite include = composite.getIncludes().get(i); + if (include != null) { + Composite resolved = resolver.resolveModel(Composite.class, include, context); + if (!resolved.isUnresolved()) { + if ((composite.isLocal() && resolved.isLocal()) || (!composite.isLocal() && !resolved.isLocal())) { + composite.getIncludes().set(i, resolved); + } else { + ContributionResolveException ce = + new ContributionResolveException("[ASM60041] Error: Composite " + composite.getName() + + " can only include another composite with the identical @local attribute value"); + error(monitor, "ContributionResolveException", include, ce); + } + } else { + ContributionResolveException ce = + new ContributionResolveException("[ASM60042] Error: Composite " + include.getName() + + " is not a valid composite within the domain"); + error(monitor, "ContributionResolveException", include, ce); + } + } + } + + // Resolve extensions + for (Object extension : composite.getExtensions()) { + if (extension != null) { + extensionProcessor.resolve(extension, resolver, context); + } + } + + //Resolve composite services and references + resolveContracts(composite, composite.getServices(), resolver, context); + resolveContracts(composite, composite.getReferences(), resolver, context); + + for (Property property : composite.getProperties()){ + resolvePropertyType("composite " + composite.getName().toString(), + property, + context.getContribution(), context); + } + + // Resolve component implementations, services and references + for (Component component : composite.getComponents()) { + + //resolve component services and references + resolveContracts(component, component.getServices(), resolver, context); + resolveContracts(component, component.getReferences(), resolver, context); + + for (ComponentProperty componentProperty : component.getProperties()) { + // resolve a reference to a property file + if (componentProperty.getFile() != null) { + Artifact artifact = contributionFactory.createArtifact(); + artifact.setURI(componentProperty.getFile()); + artifact = resolver.resolveModel(Artifact.class, artifact, context); + if (artifact.getLocation() != null) { + componentProperty.setFile(artifact.getLocation()); + } + } + + // resolve the reference to a complex property + resolvePropertyType("component " + component.getName(), + componentProperty, + context.getContribution(), context); + } + + //resolve component implementation + Implementation implementation = component.getImplementation(); + if (implementation != null) { + //now resolve the implementation so that even if there is a shared instance + //for this that is resolved, the specified intents and policysets are safe in the + //component and not lost + + List<PolicySet> policySets = new ArrayList<PolicySet>(implementation.getPolicySets()); + List<Intent> intents = new ArrayList<Intent>(implementation.getRequiredIntents()); + implementation = resolveImplementation(implementation, resolver, context); + + // If there are any policy sets on the implementation or component we have to + // ignore policy sets from the component type (policy spec 4.9) + if ( !policySets.isEmpty() || !component.getPolicySets().isEmpty() ) { + implementation.getPolicySets().clear(); + implementation.getPolicySets().addAll(policySets); + } + + implementation.getRequiredIntents().addAll(intents); + + component.setImplementation(implementation); + } + + //add model resolver to component + if (component instanceof ResolverExtension) { + ((ResolverExtension)component).setModelResolver(resolver); + } + } + + // Add model resolver to promoted components + for (Service service : composite.getServices()) { + CompositeService compositeService = (CompositeService)service; + Component promotedComponent = compositeService.getPromotedComponent(); + if (promotedComponent instanceof ResolverExtension) { + ((ResolverExtension)promotedComponent).setModelResolver(resolver); + } + } // end for + + } finally { + // Pop context + monitor.popContext(); + } // end try + } + + public QName getArtifactType() { + return COMPOSITE_QNAME; + } + + public Class<Composite> getModelType() { + return Composite.class; + } + + /** + * Write the value of a property - override to use correct method of creating an XMLStreamReader + * @param document + * @param element + * @param type + * @param writer + * @throws XMLStreamException + */ + protected void writePropertyValue(Object propertyValue, QName element, QName type, XMLStreamWriter writer) + throws XMLStreamException { + + if (propertyValue instanceof Document) { + Document document = (Document)propertyValue; + NodeList nodeList = document.getDocumentElement().getChildNodes(); + + for (int item = 0; item < nodeList.getLength(); ++item) { + Node node = nodeList.item(item); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + // Correct way to create a reader for a node object... + XMLStreamReader reader = staxHelper.createXMLStreamReader(node); + + while (reader.hasNext()) { + switch (reader.next()) { + case XMLStreamConstants.START_ELEMENT: + QName name = reader.getName(); + writer.writeStartElement(name.getPrefix(), name.getLocalPart(), name.getNamespaceURI()); + + int namespaces = reader.getNamespaceCount(); + for (int i = 0; i < namespaces; i++) { + String prefix = reader.getNamespacePrefix(i); + String ns = reader.getNamespaceURI(i); + writer.writeNamespace(prefix, ns); + } + + if (!"".equals(name.getNamespaceURI())) { + writer.writeNamespace(name.getPrefix(), name.getNamespaceURI()); + } + + // add the attributes for this element + namespaces = reader.getAttributeCount(); + for (int i = 0; i < namespaces; i++) { + String ns = reader.getAttributeNamespace(i); + String prefix = reader.getAttributePrefix(i); + String qname = reader.getAttributeLocalName(i); + String value = reader.getAttributeValue(i); + + writer.writeAttribute(prefix, ns, qname, value); + } + + break; + case XMLStreamConstants.CDATA: + writer.writeCData(reader.getText()); + break; + case XMLStreamConstants.CHARACTERS: + writer.writeCharacters(reader.getText()); + break; + case XMLStreamConstants.END_ELEMENT: + writer.writeEndElement(); + break; + } + } + } else { + writer.writeCharacters(node.getTextContent()); + } + } + } + } // end method writePropertyValue + + + /** + * Returns the model factory extension point to use. + * + * @param extensionPoints + * @return + */ + private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) { + return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + } + + /** + * Property elements can have XSD types attributes so, in the case of a complex type, we need to find + * the XSD definition that defines that type in the contribution while we still have access to the + * contribution. Later, in the builder, we use this XSD definition to ensure that the property value + * is of the correct type + * + * @param property + * @param contribution + */ + private void resolvePropertyType(String parentName, Property property, Contribution contribution, ProcessorContext context){ + // resolve the reference to a complex property + // we ignore any types in the schema namespace + if (property.getXSDType() != null && + property.getXSDType().getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema") != true){ + XSDefinition xsdDefinition = xsdFactory.createXSDefinition(); + xsdDefinition.setUnresolved(true); + xsdDefinition.setNamespace(property.getXSDType().getNamespaceURI()); + // some unit tests don't set up contribution and model resolvers properly + if (contribution != null && contribution.getModelResolver() != null) { + XSDefinition resolved = contribution.getModelResolver().resolveModel(XSDefinition.class, xsdDefinition, context); + if (resolved == null || resolved.isUnresolved()){ + // raise an error + // [rfeng] The XSD might be not available if we use JAXB annotated classes, report it as a warning for now + warning(context.getMonitor(), "PropertyTypeNotFound", property, property.getXSDType().toString(), property.getName(), parentName); + } else { + // store the schema in the property + property.setXSDDefinition(resolved); + } + } + } + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConfiguredOperationProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConfiguredOperationProcessor.java new file mode 100644 index 0000000000..9930096a26 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConfiguredOperationProcessor.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.assembly.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.ConfiguredOperation; +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * Processor for dealing with 'operation' elements from composite definitions + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public class ConfiguredOperationProcessor implements StAXArtifactProcessor<ConfiguredOperation>, Constants{ + + private AssemblyFactory assemblyFactory; + private PolicySubjectProcessor policyProcessor; + private PolicyFactory policyFactory; + + + public ConfiguredOperationProcessor(FactoryExtensionPoint modelFactories) { + this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class); + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.policyProcessor = new PolicySubjectProcessor(policyFactory); + } + + public ConfiguredOperation read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + ConfiguredOperation configuredOp = assemblyFactory.createConfiguredOperation(); + + //Read an <operation> + configuredOp.setName(reader.getAttributeValue(null, NAME)); + configuredOp.setContractName(reader.getAttributeValue(null, SERVICE)); + configuredOp.setUnresolved(true); + + // Read policies + policyProcessor.readPolicies(configuredOp, reader); + + //Skip to end element + while (reader.hasNext()) { + if (reader.next() == END_ELEMENT && OPERATION_QNAME.equals(reader.getName())) { + break; + } + } + + return configuredOp; + } + + public void write(ConfiguredOperation configuredOperation, XMLStreamWriter writer, ProcessorContext context) + throws ContributionWriteException, XMLStreamException { + + // Write an <operation> + writer.writeStartElement(Constants.SCA11_NS, OPERATION); + policyProcessor.writePolicyAttributes(configuredOperation, writer); + + writer.writeAttribute(NAME, configuredOperation.getName()); + if ( configuredOperation.getContractName() != null ) { + writer.writeAttribute(SERVICE, configuredOperation.getContractName()); + } + writer.writeEndElement(); + } + + public void resolve(ConfiguredOperation configuredOperation, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + } + + public QName getArtifactType() { + return OPERATION_QNAME; + } + + public Class<ConfiguredOperation> getModelType() { + return ConfiguredOperation.class; + } + +} + + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java new file mode 100644 index 0000000000..0c88a01b19 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java @@ -0,0 +1,181 @@ +/* + * 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.assembly.xml; + +import javax.xml.namespace.QName; + +/** + * Constants used in SCA assembly XML files. + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension + */ +public interface Constants { + String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + String SCA11_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1"; + + String COMPONENT_TYPE = "componentType"; + QName COMPONENT_TYPE_QNAME = new QName(SCA11_NS, COMPONENT_TYPE); + + String SERVICE = "service"; + QName SERVICE_QNAME = new QName(SCA11_NS, SERVICE); + + String REFERENCE = "reference"; + QName REFERENCE_QNAME = new QName(SCA11_NS, REFERENCE); + + String PROPERTY = "property"; + QName PROPERTY_QNAME = new QName(SCA11_NS, PROPERTY); + + String COMPOSITE = "composite"; + QName COMPOSITE_QNAME = new QName(SCA11_NS, COMPOSITE); + + String INCLUDE = "include"; + QName INCLUDE_QNAME = new QName(SCA11_NS, INCLUDE); + + String COMPONENT = "component"; + QName COMPONENT_QNAME = new QName(SCA11_NS, COMPONENT); + + String WIRE = "wire"; + QName WIRE_QNAME = new QName(SCA11_NS, WIRE); + + String OPERATION = "operation"; + QName OPERATION_QNAME = new QName(SCA11_NS, OPERATION); + + String CALLBACK = "callback"; + QName CALLBACK_QNAME = new QName(SCA11_NS, CALLBACK); + + String IMPLEMENTATION_COMPOSITE = "implementation.composite"; + QName IMPLEMENTATION_COMPOSITE_QNAME = new QName(SCA11_NS, IMPLEMENTATION_COMPOSITE); + + String IMPLEMENTATION = "implementation"; + QName IMPLEMENTATION_QNAME = new QName(SCA11_NS, IMPLEMENTATION); + + String BINDING_SCA = "binding.sca"; + QName BINDING_SCA_QNAME = new QName(Constants.SCA11_NS, BINDING_SCA); + + String EXTENSION = "extensions"; + QName EXTENSION_QNAME = new QName(Constants.SCA11_NS, EXTENSION); + + String NAME = "name"; + String VALUE = "value"; + QName VALUE_QNAME = new QName(SCA11_NS, VALUE); + + String POLICY_SET_ATTACHMENT = "policySetAttachment"; + QName POLICY_SET_ATTACHMENT_QNAME = new QName(SCA11_NS, POLICY_SET_ATTACHMENT); + + String TARGET_NAMESPACE = "targetNamespace"; + String LOCAL = "local"; + String AUTOWIRE = "autowire"; + String NONOVERRIDABLE = "nonOverridable"; + String REPLACE = "replace"; + String REQUIRES = "requires"; + QName REQUIRES_QNAME = new QName(SCA11_NS, REQUIRES); + String INTENTS = "intents"; + + String POLICY_SETS = "policySets"; + String PROMOTE = "promote"; + String TARGET = "target"; + String WIRED_BY_IMPL = "wiredByImpl"; + String MULTIPLICITY = "multiplicity"; + String TYPE = "type"; + String ELEMENT = "element"; + String MANY = "many"; + String MUST_SUPPLY = "mustSupply"; + String SOURCE = "source"; + String FILE = "file"; + String URI = "uri"; + String ZERO_ONE = "0..1"; + String ZERO_N = "0..n"; + String ONE_ONE = "1..1"; + String ONE_N = "1..n"; + + String SERVER_AUTHENTICATION = "serverAuthentication"; + QName SERVER_AUTHENTICATION_INTENT = new QName(SCA11_NS, SERVER_AUTHENTICATION); + String SERVER_AUTHENTICATION_TRANSPORT = "serverAuthentication.transport"; + QName SERVER_AUTHENTICATION_TRANSPORT_INTENT = new QName(SCA11_NS, SERVER_AUTHENTICATION_TRANSPORT); + String SERVER_AUTHENTICATION_MESSAGE = "serverAuthentication.message"; + QName SERVER_AUTHENTICATION_MESSAGE_INTENT = new QName(SCA11_NS, SERVER_AUTHENTICATION_MESSAGE); + + String CLIENT_AUTHENTICATION = "clientAuthentication"; + QName CLIENT_AUTHENTICATION_INTENT = new QName(SCA11_NS, CLIENT_AUTHENTICATION); + String CLIENT_AUTHENTICATION_TRANSPORT = "clientAuthentication.transport"; + QName CLIENT_AUTHENTICATION_TRANSPORT_INTENT = new QName(SCA11_NS, CLIENT_AUTHENTICATION_TRANSPORT); + String CLIENT_AUTHENTICATION_MESSAGE = "clientAuthentication.message"; + QName CLIENT_AUTHENTICATION_MESSAGE_INTENT = new QName(SCA11_NS, CLIENT_AUTHENTICATION_MESSAGE); + + String AUTHENTICATION = "authentication"; + QName AUTHENTICATION_INTENT = new QName(SCA11_NS, AUTHENTICATION); + + String MUTUAL_AUTHENTICATION = "mutualAuthentication"; + QName MUTUAL_AUTHENTICATION_INTENT = new QName(SCA11_NS, MUTUAL_AUTHENTICATION); + + String CONFIDENTIALITY = "confidentiality"; + QName CONFIDENTIALITY_INTENT = new QName(SCA11_NS, CONFIDENTIALITY); + String CONFIDENTIALITY_TRANSPORT = "confidentiality.transport"; + QName CONFIDENTIALITY_TRANSPORT_INTENT = new QName(SCA11_NS, CONFIDENTIALITY_TRANSPORT); + String CONFIDENTIALITY_MESSAGE = "confidentiality.message"; + QName CONFIDENTIALITY_MESSAGE_INTENT = new QName(SCA11_NS, CONFIDENTIALITY_MESSAGE); + + String INTEGRITY = "integrity"; + QName INTEGRITY_INTENT = new QName(SCA11_NS, "INTEGRITY"); + String INTEGRITY_TRANSPORT = "integrity.transport"; + QName INTEGRITY_TRANSPORT_INTENT = new QName(SCA11_NS, INTEGRITY_TRANSPORT); + String INTEGRITY_MESSAGE = "integrity.message"; + QName INTEGRITY_MESSAGE_INTENT = new QName(SCA11_NS, INTEGRITY_MESSAGE); + + String AUTHORIZATION = "authorization"; + QName AUTHORIZATION_INTENT = new QName(SCA11_NS, "INTEGRITY"); + String AUTHORIZATION_FINE_GRAIN = "authorization.fineGrain"; + QName AUTHORIZATION_FINE_GRAIN_INTENT = new QName(SCA11_NS, AUTHORIZATION_FINE_GRAIN); + + String MANAGED_TRANSACTION = "managedTransaction"; + QName MANAGED_TRANSACTION_INTENT = new QName(SCA11_NS, MANAGED_TRANSACTION); + + String NO_MANAGED_TRANSACTION = "noManagedTransaction"; + QName NO_MANAGED_TRANSACTION_INTENT = new QName(SCA11_NS, NO_MANAGED_TRANSACTION); + + String MANAGED_TRANSACTION_LOCAL = "managedTransaction.local"; + QName MANAGED_TRANSACTION_LOCAL_INTENT = new QName(SCA11_NS, MANAGED_TRANSACTION_LOCAL); + + String MANAGED_TRANSACTION_GLOBAL = "managedTransaction.global"; + QName MANAGED_TRANSACTION_GLOBAL_INTENT = new QName(SCA11_NS, MANAGED_TRANSACTION_GLOBAL); + + String PROPAGATES_TRANSACTION = "propagatesTransaction"; + QName PROPAGATES_TRANSACTION_INTENT = new QName(SCA11_NS, PROPAGATES_TRANSACTION); + + String SUSPENDS_TRANSACTION = "suspendsTransaction"; + QName SUSPENDS_TRANSACTION_INTENT = new QName(SCA11_NS, SUSPENDS_TRANSACTION); + + String TRANSACTED_ONE_WAY = "transactedOneWay"; + QName TRANSACTED_ONE_WAY_INTENT = new QName(SCA11_NS, TRANSACTED_ONE_WAY); + + String IMMEDIATE_ONE_WAY = "immediateOneWay"; + QName IMMEDIATE_ONE_WAY_INTENT = new QName(SCA11_NS, IMMEDIATE_ONE_WAY); + + String NOLISTENER = "noListener"; + QName NOLISTENER_INTENT = new QName(SCA11_NS, NOLISTENER); + + String SOAP = "SOAP"; + QName SOAP_INTENT = new QName(SCA11_NS, SOAP); + String SOAP11 = "SOAP.v1_1"; + QName SOAP11_INTENT = new QName(SCA11_NS, SOAP11); + String SOAP12 = "SOAP.v1_2"; + QName SOAP12_INTENT = new QName(SCA11_NS, SOAP12); +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java new file mode 100644 index 0000000000..e6e172a44b --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java @@ -0,0 +1,257 @@ +/* + * 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.assembly.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.Base; +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Implementation; +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.policy.PolicySubject; + +/** + * Default Model Processor for beans. + * + * @version $Rev$ $Date$ + */ +public class DefaultBeanModelProcessor<T> extends BaseAssemblyProcessor implements StAXArtifactProcessor<T> { + + private QName artifactType; + private Class<T> modelClass; + private Object modelFactory; + private Method factoryMethod; + private Map<String, Method> setterMethods = new HashMap<String, Method>(); + private Map<String, Method> getterMethods = new HashMap<String, Method>(); + + public DefaultBeanModelProcessor(FactoryExtensionPoint modeFactories, + QName artifactType, + Class<T> modelClass, + Object modelFactory) { + super(modeFactories, null); + this.artifactType = artifactType; + this.modelClass = modelClass; + this.modelFactory = modelFactory; + + // Introspect the factory class and bean model class + if (modelFactory != null) { + + // Find the model create method + for (Method method: modelFactory.getClass().getMethods()) { + if (method.getName().startsWith("create") && method.getReturnType() == modelClass) { + factoryMethod = method; + break; + } + } + } + + // Index the bean's setter methods + for (Method method: modelClass.getMethods()) { + Method getter; + String name = method.getName(); + if (name.startsWith("set") && name.length() > 3) { + + // Get the corresponding getter method + try { + getter = modelClass.getMethod("get" + name.substring(3)); + } catch (Exception e) { + getter = null; + continue; + } + + // Get the property name + name = name.substring(3); + if (name.length() > 1) { + if (!name.toUpperCase().equals(name)) { + name = name.substring(0, 1).toLowerCase() + name.substring(1); + } + } + } else { + continue; + } + + // Map an uppercase property name to a lowercase attribute name + if (name.toUpperCase().equals(name)) { + name = name.toLowerCase(); + } + + // Trim trailing _ from property names + if (name.endsWith("_")) { + name = name.substring(0, name.length()-1); + } + setterMethods.put(name, method); + getterMethods.put(name, getter); + } + } + + public T read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + + // Read an element + try { + + // Create a new instance of the model + Object model; + if (modelFactory != null) { + // Invoke the factory create method + model = factoryMethod.invoke(modelFactory); + } else { + // Invoke the model bean class default constructor + model = modelClass.newInstance(); + } + + // Initialize the bean properties with the attributes found in the + // XML element + for (int i = 0, n = reader.getAttributeCount(); i < n; i++) { + String attributeName = reader.getAttributeLocalName(i); + Method setter = setterMethods.get(attributeName); + if (setter != null) { + String value = null; + if (attributeName.equals("uri")){ + value = getURIString(reader, "uri"); + } else { + value = reader.getAttributeValue(i); + } + setter.invoke(model, value); + } + } + + // Read policies + policyProcessor.readPolicies(model, reader); + + // FIXME read extension elements + + // By default mark the model object unresolved + if (model instanceof Base) { + ((Base)model).setUnresolved(true); + } + + // Skip to end element + while (reader.hasNext()) { + if (reader.next() == END_ELEMENT && artifactType.equals(reader.getName())) { + break; + } + } + return (T) model; + + } catch (Exception e) { + ContributionReadException ce = new ContributionReadException(e); + error(context.getMonitor(), "ContributionReadException", reader, ce); + throw ce; + } + } + + public void write(T bean, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + try { + // Write the bean properties as attributes + List<XAttr> attrs = new ArrayList<XAttr>(); + for (Map.Entry<String, Method> entry: getterMethods.entrySet()) { + if (entry.getValue().getReturnType() == String.class) { + String value = (String)entry.getValue().invoke(bean); + attrs.add(new XAttr(entry.getKey(), value)); + } + } + + // Write element + writeStart(writer, artifactType.getNamespaceURI(), artifactType.getLocalPart(), + policyProcessor.writePolicies(bean), new XAttr(null, attrs)); + + writeEnd(writer); + + } catch (Exception e) { + ContributionWriteException ce = new ContributionWriteException(e); + error(context.getMonitor(), "ContributionWriteException", writer, ce); + throw ce; + } + } + + public void resolve(T bean, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + + // Resolve and merge the component type associated with an + // implementation model + if (bean instanceof Implementation) { + Implementation implementation = (Implementation)bean; + String uri = implementation.getURI(); + if (uri != null) { + int d = uri.lastIndexOf('.'); + if (d != -1) { + uri = uri.substring(0, d) + ".componentType"; + + // Resolve the component type + ComponentType componentType = assemblyFactory.createComponentType(); + componentType.setURI(uri); + componentType.setUnresolved(true); + + componentType = resolver.resolveModel(ComponentType.class, componentType, context); + if (componentType != null && !componentType.isUnresolved()) { + + // We found a component type, merge it into the implementation model + implementation.getServices().addAll(componentType.getServices()); + implementation.getReferences().addAll(componentType.getReferences()); + implementation.getProperties().addAll(componentType.getProperties()); + + if (implementation instanceof PolicySubject && + componentType instanceof PolicySubject ) { + PolicySubject policiedImpl = (PolicySubject)implementation; + PolicySubject policiedCompType = (PolicySubject)componentType; + + if ( policiedImpl.getPolicySets() != null) { + policiedImpl.getPolicySets().addAll(policiedCompType.getPolicySets()); + } + if (policiedImpl.getRequiredIntents() != null) { + policiedImpl.getRequiredIntents().addAll(policiedCompType.getRequiredIntents()); + } + } + } + } + } + } + + // Mark the model resolved + if (bean instanceof Base) { + ((Base)bean).setUnresolved(false); + } + } + + public QName getArtifactType() { + return artifactType; + } + + public Class<T> getModelType() { + return modelClass; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java new file mode 100644 index 0000000000..d128897df0 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointProcessor.java @@ -0,0 +1,132 @@ +/* + * 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.assembly.xml; + +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.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Endpoint; +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.processor.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; + +/** + * + */ +public class EndpointProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<Endpoint> { + private final static String ENDPOINT = "endpoint"; + private final static QName ENDPOINT_QNAME = new QName(Constants.SCA11_TUSCANY_NS, ENDPOINT); + + private ExtensionPointRegistry registry; + + public EndpointProcessor(ExtensionPointRegistry registry, + StAXArtifactProcessor extensionProcessor, + StAXAttributeProcessor extensionAttributeProcessor) { + + super(modelFactories(registry), extensionProcessor); + this.registry = registry; + } + + /** + * Returns the model factory extension point to use. + * + * @param extensionPoints + * @return + */ + private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) { + return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + } + + public QName getArtifactType() { + return ENDPOINT_QNAME; + } + + public Endpoint read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + Endpoint endpoint = assemblyFactory.createEndpoint(); + if (reader.getEventType() == XMLStreamConstants.START_DOCUMENT) { + reader.nextTag(); + } + Object model = extensionProcessor.read(reader, context); + if (model instanceof Composite) { + Composite composite = (Composite)model; + Component component = composite.getComponents().get(0); + ComponentService service = component.getServices().get(0); + Binding binding = service.getBindings().get(0); + endpoint.setComponent(component); + endpoint.setService(service); + endpoint.setBinding(binding); + } + return endpoint; + } + + public void write(Endpoint model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + // writeStart(writer, ENDPOINT_QNAME); + extensionProcessor.write(wrap(model), writer, context); + // writeEnd(writer); + } + + private Composite wrap(Endpoint endpoint) { + try { + Composite composite = assemblyFactory.createComposite(); + composite.setName(ENDPOINT_QNAME); + composite.setLocal(false); + if (endpoint.getComponent() != null) { + Component component = (Component)endpoint.getComponent().clone(); + component.setImplementation(null); + composite.getComponents().add(component); + component.getReferences().clear(); + component.getServices().clear(); + if (endpoint.getService() != null) { + ComponentService service = (ComponentService)endpoint.getService().clone(); + component.getServices().add(service); + service.getBindings().clear(); + service.setInterfaceContract(endpoint.getComponentServiceInterfaceContract()); + if (endpoint.getBinding() != null) { + Binding binding = (Binding)endpoint.getBinding().clone(); + service.getBindings().add(binding); + } + } + } + return composite; + } catch (CloneNotSupportedException e) { + return null; + } + } + + public Class<Endpoint> getModelType() { + return Endpoint.class; + } + + public void resolve(Endpoint model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointReferenceProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointReferenceProcessor.java new file mode 100644 index 0000000000..eda90c9d44 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/EndpointReferenceProcessor.java @@ -0,0 +1,151 @@ +/* + * 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.assembly.xml; + +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.assembly.Binding; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.assembly.EndpointReference; +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.processor.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; + +/** + * + */ +public class EndpointReferenceProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<EndpointReference> { + private final static String ENDPOINT_REFERENCE = "endpointReference"; + private final static QName ENDPOINT_REFERENCE_QNAME = new QName(Constants.SCA11_TUSCANY_NS, ENDPOINT_REFERENCE); + + private ExtensionPointRegistry registry; + + public EndpointReferenceProcessor(ExtensionPointRegistry registry, + StAXArtifactProcessor extensionProcessor, + StAXAttributeProcessor extensionAttributeProcessor) { + + super(modelFactories(registry), extensionProcessor); + this.registry = registry; + } + + /** + * Returns the model factory extension point to use. + * + * @param extensionPoints + * @return + */ + private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) { + return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + } + + public QName getArtifactType() { + return ENDPOINT_REFERENCE_QNAME; + } + + public EndpointReference read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + EndpointReference endpointReference = assemblyFactory.createEndpointReference(); + if (reader.getEventType() == XMLStreamConstants.START_DOCUMENT) { + reader.nextTag(); + } + Object model = extensionProcessor.read(reader, context); + if (model instanceof Composite) { + Composite composite = (Composite)model; + Component component = composite.getComponents().get(0); + ComponentReference reference = component.getReferences().get(0); + Binding binding = reference.getBindings().get(0); + endpointReference.setComponent(component); + endpointReference.setReference(reference); + reference.getEndpointReferences().add(endpointReference); + endpointReference.setBinding(binding); + + // set up the EPR so that resolution will happen + // at wire creation time if needs be + Endpoint endpoint = assemblyFactory.createEndpoint(); + endpointReference.setTargetEndpoint(endpoint); + + if (reference.getTargets().size() > 0){ + // create a dummy endpoint with the URI set so that + // the endpoint registry will be consulted + endpoint.setUnresolved(true); + endpoint.setURI(reference.getTargets().get(0).getName()); + endpointReference.setStatus(EndpointReference.Status.WIRED_TARGET_NOT_FOUND); + endpointReference.setUnresolved(true); + } else { + endpoint.setUnresolved(false); + endpoint.setBinding(reference.getBindings().get(0)); + endpointReference.setStatus(EndpointReference.Status.RESOLVED_BINDING); + endpointReference.setUnresolved(false); + } + } + return endpointReference; + } + + public void write(EndpointReference model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + extensionProcessor.write(wrap(model), writer, context); + } + + private Composite wrap(EndpointReference endpointReference) { + try { + Composite composite = assemblyFactory.createComposite(); + composite.setName(ENDPOINT_REFERENCE_QNAME); + composite.setLocal(false); + Component component = (Component)endpointReference.getComponent().clone(); + composite.getComponents().add(component); + component.getReferences().clear(); + component.getServices().clear(); + ComponentReference reference = (ComponentReference)endpointReference.getReference().clone(); + component.getReferences().add(reference); + reference.getBindings().clear(); + Binding binding = (Binding)endpointReference.getBinding().clone(); + reference.getBindings().add(binding); + //reference.setInterfaceContract(endpointReference.getInterfaceContract()); + if (endpointReference.getStatus() != EndpointReference.Status.RESOLVED_BINDING){ + ComponentService service = assemblyFactory.createComponentService(); + service.setName(endpointReference.getTargetEndpoint().getURI()); + reference.getTargets().clear(); + reference.getTargets().add(service); + } + return composite; + } catch (CloneNotSupportedException e) { + return null; + } + } + + public Class<EndpointReference> getModelType() { + return EndpointReference.class; + } + + public void resolve(EndpointReference model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Messages.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Messages.java new file mode 100644 index 0000000000..0391acc676 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Messages.java @@ -0,0 +1,28 @@ +/* + * 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.assembly.xml; + +/** + * Constants for resource bundle names + * @tuscany.spi.extension + */ +public interface Messages { + String RESOURCE_BUNDLE = "org.apache.tuscany.sca.assembly.xml.assembly-xml-validation-messages"; +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java new file mode 100644 index 0000000000..286f109f44 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java @@ -0,0 +1,242 @@ +/* + * 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.assembly.xml; + +import static org.apache.tuscany.sca.assembly.xml.Constants.POLICY_SETS; +import static org.apache.tuscany.sca.assembly.xml.Constants.REQUIRES; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +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.interfacedef.Operation; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySubject; + +/** + * A Policy Attach Point processor. + * + * @version $Rev$ $Date$ + * @tuscany.spi.extension.asclient + */ +public class PolicySubjectProcessor extends BaseStAXArtifactProcessor { + + private PolicyFactory policyFactory; + + public PolicySubjectProcessor(PolicyFactory policyFactory) { + this.policyFactory = policyFactory; + } + + public PolicySubjectProcessor(ExtensionPointRegistry registry) { + FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class); + this.policyFactory = factories.getFactory(PolicyFactory.class); + } + + /** + * Read policy intents associated with an operation. + * @param subject + * @param operation + * @param reader + */ + private void readIntents(Object subject, Operation operation, XMLStreamReader reader) { + if (!(subject instanceof PolicySubject)) + return; + PolicySubject intentAttachPoint = (PolicySubject)subject; + String value = reader.getAttributeValue(null, REQUIRES); + if (value != null) { + List<Intent> requiredIntents = intentAttachPoint.getRequiredIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent intent = policyFactory.createIntent(); + intent.setName(qname); + if (operation != null) { + //FIXME Don't we need to handle intent specification + // on an operation basis? + //intent.getOperations().add(operation); + } + requiredIntents.add(intent); + } + } + } + + /** + * Reads policy intents and policy sets associated with an operation. + * @param subject + * @param operation + * @param reader + */ + public void readPolicies(Object subject, Operation operation, XMLStreamReader reader) { + readIntents(subject, operation, reader); + readPolicySets(subject, operation, reader); + } + + /** + * Reads policy intents and policy sets. + * @param subject + * @param reader + */ + public void readPolicies(Object subject, XMLStreamReader reader) { + readPolicies(subject, null, reader); + } + + /** + * Reads policy sets associated with an operation. + * @param subject + * @param operation + * @param reader + */ + private void readPolicySets(Object subject, Operation operation, XMLStreamReader reader) { + if (!(subject instanceof PolicySubject)) { + return; + } + PolicySubject policySubject = (PolicySubject)subject; + String value = reader.getAttributeValue(null, POLICY_SETS); + if (value != null) { + List<PolicySet> policySets = policySubject.getPolicySets(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + PolicySet policySet = policyFactory.createPolicySet(); + policySet.setName(qname); + if (operation != null) { + //FIXME Don't we need to handle policySet specification + // on an operation basis? + //policySet.getOperations().add(operation); + } + policySets.add(policySet); + } + } + } + + /** + * Write policies + * @param subject + * @return + */ + XAttr writePolicies(Object subject) throws XMLStreamException { + return writePolicies(subject, (Operation)null); + } + + /** + * Write policies + * @param subject + * @return + */ + public void writePolicyAttributes(Object subject, XMLStreamWriter writer) throws XMLStreamException { + writePolicyAttributes(subject, (Operation)null, writer); + } + + /** + * Write policies associated with an operation + * @param subject + * @param operation + * @return + */ + XAttr writePolicies(Object subject, Operation operation) { + List<XAttr> attrs =new ArrayList<XAttr>(); + attrs.add(writeIntents(subject, operation)); + attrs.add(writePolicySets(subject, operation)); + return new XAttr(null, attrs); + } + + /** + * Write policies + * @param subject + * @return + */ + public void writePolicyAttributes(Object subject, Operation operation, XMLStreamWriter writer) throws XMLStreamException { + XAttr attr = writePolicies(subject, operation); + attr.write(writer); + } + + /** + * Write policy intents associated with an operation. + * @param subject + * @param operation + */ + private XAttr writeIntents(Object subject, Operation operation) { + if (!(subject instanceof PolicySubject)) { + return null; + } + PolicySubject intentAttachPoint = (PolicySubject)subject; + List<QName> qnames = new ArrayList<QName>(); + for (Intent intent: intentAttachPoint.getRequiredIntents()) { + qnames.add(intent.getName()); + } + return new XAttr(Constants.REQUIRES, qnames); + } + + /** + * Write policy sets associated with an operation. + * @param subject + * @param operation + */ + private XAttr writePolicySets(Object subject, Operation operation) { + if (!(subject instanceof PolicySubject)) { + return null; + } + PolicySubject policySetAttachPoint = (PolicySubject)subject; + List<QName> qnames = new ArrayList<QName>(); + for (PolicySet policySet: policySetAttachPoint.getPolicySets()) { + qnames.add(policySet.getName()); + } + return new XAttr(Constants.POLICY_SETS, qnames); + } + + public void resolvePolicies(Object subject, ModelResolver resolver, ProcessorContext context) { + if ( subject instanceof PolicySubject ) { + PolicySubject policySetAttachPoint = (PolicySubject)subject; + + List<Intent> requiredIntents = new ArrayList<Intent>(); + Intent resolvedIntent = null; + + if ( policySetAttachPoint.getRequiredIntents() != null && policySetAttachPoint.getRequiredIntents().size() > 0 ) { + for ( Intent intent : policySetAttachPoint.getRequiredIntents() ) { + resolvedIntent = resolver.resolveModel(Intent.class, intent, context); + requiredIntents.add(resolvedIntent); + } + policySetAttachPoint.getRequiredIntents().clear(); + policySetAttachPoint.getRequiredIntents().addAll(requiredIntents); + } + + if ( policySetAttachPoint.getPolicySets() != null && policySetAttachPoint.getPolicySets().size() > 0 ) { + List<PolicySet> resolvedPolicySets = new ArrayList<PolicySet>(); + PolicySet resolvedPolicySet = null; + for ( PolicySet policySet : policySetAttachPoint.getPolicySets() ) { + resolvedPolicySet = resolver.resolveModel(PolicySet.class, policySet, context); + resolvedPolicySets.add(resolvedPolicySet); + } + policySetAttachPoint.getPolicySets().clear(); + policySetAttachPoint.getPolicySets().addAll(resolvedPolicySets); + } + } + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/SCABindingProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/SCABindingProcessor.java new file mode 100644 index 0000000000..28f4f9fb25 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/SCABindingProcessor.java @@ -0,0 +1,132 @@ +/* + * 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.assembly.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.assembly.SCABindingFactory; +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.PolicySubject; + +/** + * A processor to read the XML that describes the SCA binding. + * + * @version $Rev$ $Date$ + */ + +public class SCABindingProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<SCABinding> { + private static final String NAME = "name"; + private static final String URI = "uri"; + + private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + private static final String BINDING_SCA = "binding.sca"; + private static final QName BINDING_SCA_QNAME = new QName(SCA11_NS, BINDING_SCA); + + private PolicyFactory policyFactory; + private SCABindingFactory scaBindingFactory; + private PolicySubjectProcessor policyProcessor; + private PolicyFactory intentAttachPointTypeFactory; + + + public SCABindingProcessor(FactoryExtensionPoint modelFactories) { + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.scaBindingFactory = modelFactories.getFactory(SCABindingFactory.class); + policyProcessor = new PolicySubjectProcessor(policyFactory); + this.intentAttachPointTypeFactory = modelFactories.getFactory(PolicyFactory.class); + } + + public QName getArtifactType() { + return BINDING_SCA_QNAME; + } + + public Class<SCABinding> getModelType() { + return SCABinding.class; + } + + public SCABinding read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + SCABinding scaBinding = scaBindingFactory.createSCABinding(); + ExtensionType bindingType = intentAttachPointTypeFactory.createBindingType(); + bindingType.setType(getArtifactType()); + bindingType.setUnresolved(true); + ((PolicySubject)scaBinding).setExtensionType(bindingType); + + // Read policies + policyProcessor.readPolicies(scaBinding, reader); + + // Read binding name + String name = reader.getAttributeValue(null, NAME); + if (name != null) { + scaBinding.setName(name); + } + + // Read binding URI + String uri = getURIString(reader, URI); + if (uri != null) { + scaBinding.setURI(uri); + } + + // Skip to end element + while (reader.hasNext()) { + if (reader.next() == END_ELEMENT && BINDING_SCA_QNAME.equals(reader.getName())) { + break; + } + } + return scaBinding; + } + + public void resolve(SCABinding model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + policyProcessor.resolvePolicies(model, resolver, context); + } + + public void write(SCABinding scaBinding, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + + // Write <binding.sca> + writer.writeStartElement(SCA11_NS, BINDING_SCA); + policyProcessor.writePolicyAttributes(scaBinding, writer); + + // Write binding name + if (scaBinding.getName() != null) { + writer.writeAttribute(NAME, scaBinding.getName()); + } + + // Write binding URI + if (scaBinding.getURI() != null) { + writer.writeAttribute(URI, scaBinding.getURI()); + } + + writer.writeEndElement(); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefaultDefinitionsExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefaultDefinitionsExtensionPoint.java new file mode 100644 index 0000000000..af59324c7c --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefaultDefinitionsExtensionPoint.java @@ -0,0 +1,128 @@ +/* + * 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.definitions.xml; + +import java.io.IOException; +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.UtilityExtensionPoint; +import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.extensibility.ServiceDeclaration; +import org.apache.tuscany.sca.extensibility.ServiceDiscovery; +import org.apache.tuscany.sca.monitor.MonitorFactory; + +/** + * Default implementation of an extension point for XML definitionss. + * + * @version $Rev$ $Date$ + */ +public class DefaultDefinitionsExtensionPoint implements DefinitionsExtensionPoint { + private static final Logger logger = Logger.getLogger(DefaultDefinitionsExtensionPoint.class.getName()); + private static final URI DEFINITIONS_URI = URI.create("META-INF/definitions.xml"); + private ExtensionPointRegistry registry; + private MonitorFactory monitorFactory; + private Set<URL> documents = new HashSet<URL>(); + private List<Definitions> definitions = new ArrayList<Definitions>(); + private boolean documentsLoaded; + private boolean loaded; + + public DefaultDefinitionsExtensionPoint(ExtensionPointRegistry registry) { + this.registry = registry; + this.monitorFactory = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(MonitorFactory.class); + } + + public void addDefinitionsDocument(URL url) { + documents.add(url); + } + + public void removeDefinitionsDocument(URL url) { + documents.remove(url); + } + + /** + * Load definitions declarations from META-INF/services/ + * org.apache.tuscany.sca.contribution.processor.Definitions files + */ + private synchronized void loadDefinitionsDocuments() { + if (documentsLoaded) + return; + + // Get the definitions declarations + Collection<ServiceDeclaration> definitionsDeclarations; + try { + definitionsDeclarations = registry.getServiceDiscovery().getServiceDeclarations(DEFINITIONS_FILE); + } catch (IOException e) { + throw new IllegalStateException(e); + } + + // Find each definitions + for (ServiceDeclaration definitionsDeclaration : definitionsDeclarations) { + URL url = definitionsDeclaration.getResource(definitionsDeclaration.getClassName()); + if (url == null) { + throw new IllegalArgumentException(definitionsDeclaration.getClassName() + " cannot be found"); + } + documents.add(url); + } + + documentsLoaded = true; + } + + public synchronized List<Definitions> getDefinitions() { + if (!loaded) { + loadDefinitionsDocuments(); + URLArtifactProcessorExtensionPoint processors = + registry.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + URLArtifactProcessor<Definitions> processor = processors.getProcessor(Definitions.class); + ProcessorContext context = new ProcessorContext(monitorFactory.createMonitor()); + for (URL url : documents) { + Definitions def; + try { + def = processor.read(null, DEFINITIONS_URI, url, context); + definitions.add(def); + } catch (ContributionReadException e) { + logger.log(Level.SEVERE, e.getMessage(), e); + } + } + loaded = true; + } + return definitions; + } + + public void addDefinitions(Definitions def) { + this.definitions.add(def); + } + + public void removeDefinitions(Definitions def) { + this.definitions.remove(def); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsDocumentProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsDocumentProcessor.java new file mode 100644 index 0000000000..d0a42be34e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsDocumentProcessor.java @@ -0,0 +1,171 @@ +/* + * 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.definitions.xml; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.common.java.io.IOHelper; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.definitions.DefinitionsFactory; +import org.apache.tuscany.sca.definitions.util.DefinitionsUtil; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; + +/** + * A SCA Definitions Document processor. + * + * @version $Rev$ $Date$ + */ +public class DefinitionsDocumentProcessor implements URLArtifactProcessor<Definitions> { + private StAXArtifactProcessor<Object> extensionProcessor; + private XMLInputFactory inputFactory; + private DefinitionsFactory definitionsFactory; + + + + /** + * Constructs a new SCADefinitions processor. + * + * @param modelFactories + * @param staxProcessor + */ + public DefinitionsDocumentProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> staxProcessor) { + this.extensionProcessor = (StAXArtifactProcessor<Object>)staxProcessor; + this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class); + this.definitionsFactory = modelFactories.getFactory(DefinitionsFactory.class); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(Monitor monitor, String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + ex); + monitor.problem(problem); + } + } + + public Definitions read(URL contributionURL, final URI uri, final URL url, ProcessorContext context) throws ContributionReadException { + InputStream urlStream = null; + Monitor monitor = context.getMonitor(); + monitor.pushContext("Definitions: " + url); + try { + // Allow privileged access to open URL stream. Add FilePermission to added to security + // policy file. + try { + urlStream = AccessController.doPrivileged(new PrivilegedExceptionAction<InputStream>() { + public InputStream run() throws IOException { + return IOHelper.openStream(url); + } + }); + } catch (PrivilegedActionException e) { + error(monitor, "PrivilegedActionException", url, (IOException)e.getException()); + throw (IOException)e.getException(); + } + + //urlStream = createInputStream(url); + XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream); + ValidatingXMLInputFactory.setMonitor(reader, context.getMonitor()); + Definitions definitions = definitionsFactory.createDefinitions(); + int event = reader.getEventType(); + while (reader.hasNext()) { + event = reader.next(); + + // We only deal with the root element + if (event == XMLStreamConstants.START_ELEMENT) { + // QName name = reader.getName(); + Object model = extensionProcessor.read(reader, context); + if (model instanceof Definitions) { + DefinitionsUtil.aggregate((Definitions)model, definitions, monitor); + return definitions; + } else { + error(monitor, "ContributionReadException", model, null); + } + } + } + + return definitions; + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", inputFactory, ce); + throw ce; + } catch (IOException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", inputFactory, ce); + throw ce; + } finally { + + try { + if (urlStream != null) { + urlStream.close(); + urlStream = null; + } + } catch (IOException ioe) { + //ignore + } + + monitor.popContext(); + } + } + + public void resolve(Definitions scaDefinitions, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + extensionProcessor.resolve(scaDefinitions, resolver, context); + } + + public String getArtifactType() { + return "/META-INF/definitions.xml"; + } + + public Class<Definitions> getModelType() { + return Definitions.class; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsExtensionPoint.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsExtensionPoint.java new file mode 100644 index 0000000000..3058b1f5b6 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsExtensionPoint.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.definitions.xml; + +import java.net.URL; +import java.util.List; + +import org.apache.tuscany.sca.definitions.Definitions; + +/** + * An extension point for built-in SCA intent/policySet definition files + * + * @version $Rev$ $Date$ + */ +public interface DefinitionsExtensionPoint { + String DEFINITIONS_FILE = "org.apache.tuscany.sca.definitions.xml.Definitions"; + + /** + * Add a definitions document + * + * @param url the URL of the definitions + */ + void addDefinitionsDocument(URL url); + + /** + * Remove a definitions document + * + * @param url the URL of the definitions + */ + void removeDefinitionsDocument(URL url); + + /** + * @param definitions + */ + void addDefinitions(Definitions definitions); + /** + * @param definitions + */ + void removeDefinitions(Definitions definitions); + + /** + * Get the list of definitions + * @return A list of definitions + */ + List<Definitions> getDefinitions(); + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsProcessor.java new file mode 100644 index 0000000000..0213713ced --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/DefinitionsProcessor.java @@ -0,0 +1,299 @@ +/* + * 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.definitions.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.util.ArrayList; +import java.util.List; + +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.assembly.Binding; +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.processor.StAXArtifactProcessorExtensionPoint; +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.definitions.Definitions; +import org.apache.tuscany.sca.definitions.DefinitionsFactory; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.policy.BindingType; +import org.apache.tuscany.sca.policy.ExternalAttachment; +import org.apache.tuscany.sca.policy.ImplementationType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentMap; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.Qualifier; + +/** + * Processor for SCA Definitions + * + * @version $Rev$ $Date$ + */ +public class DefinitionsProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<Definitions> { + private ExtensionPointRegistry registry; + private StAXArtifactProcessorExtensionPoint processors; + private StAXArtifactProcessor<Object> extensionProcessor; + private DefinitionsFactory definitionsFactory; + private PolicyFactory policyFactory; + + public static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + public static final String BINDING = "binding"; + public static final String IMPLEMENTATION = "implementation"; + public static final String DEFINITIONS = "definitions"; + public static final QName DEFINITIONS_QNAME = new QName(SCA11_NS, DEFINITIONS); + public static final String TARGET_NAMESPACE = "targetNamespace"; + public static final String NAME = "name"; + + public DefinitionsProcessor(ExtensionPointRegistry registry, + StAXArtifactProcessor<Object> extensionProcessor) { + this.registry = registry; + this.extensionProcessor = extensionProcessor; + this.processors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + FactoryExtensionPoint factoryExtensionPoint = registry.getExtensionPoint(FactoryExtensionPoint.class); + this.definitionsFactory = factoryExtensionPoint.getFactory(DefinitionsFactory.class); + this.policyFactory = factoryExtensionPoint.getFactory(PolicyFactory.class); + } + + public Definitions read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + QName name = null; + Definitions definitions = null; + String targetNamespace = null; + + while (reader.hasNext()) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: { + name = reader.getName(); + if (DEFINITIONS_QNAME.equals(name)) { + definitions = definitionsFactory.createDefinitions(); + targetNamespace = getURIString(reader, TARGET_NAMESPACE); + definitions.setTargetNamespace(targetNamespace); + } else { + Object extension = extensionProcessor.read(reader, context); + if (extension != null) { + if (extension instanceof Intent) { + Intent intent = (Intent)extension; + intent.setName(new QName(targetNamespace, intent.getName().getLocalPart())); + definitions.getIntents().add(intent); + for (Intent i : intent.getQualifiedIntents()) { + i.setName(new QName(targetNamespace, i.getName().getLocalPart())); + } + } else if (extension instanceof PolicySet) { + PolicySet policySet = (PolicySet)extension; + policySet.setName(new QName(targetNamespace, policySet.getName().getLocalPart())); + definitions.getPolicySets().add(policySet); + } else if (extension instanceof Binding) { + Binding binding = (Binding)extension; + definitions.getBindings().add(binding); + } else if (extension instanceof BindingType) { + definitions.getBindingTypes().add((BindingType)extension); + } else if (extension instanceof ImplementationType) { + definitions.getImplementationTypes().add((ImplementationType)extension); + } else if (extension instanceof ExternalAttachment) { + definitions.getExternalAttachments().add((ExternalAttachment)extension); + } + } + break; + } + } + + case XMLStreamConstants.CHARACTERS: + break; + + case END_ELEMENT: + name = reader.getName(); + if (DEFINITIONS_QNAME.equals(name)) { + return definitions; + } + break; + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + return definitions; + } + + public void write(Definitions definitions, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, + XMLStreamException { + + writeStartDocument(writer, SCA11_NS, DEFINITIONS, new XAttr(TARGET_NAMESPACE, definitions.getTargetNamespace())); + + for (Intent policyIntent : definitions.getIntents()) { + extensionProcessor.write(policyIntent, writer, context); + } + + for (PolicySet policySet : definitions.getPolicySets()) { + extensionProcessor.write(policySet, writer, context); + } + + for (Binding binding : definitions.getBindings()) { + extensionProcessor.write(binding, writer, context); + } + + for (BindingType bindingType : definitions.getBindingTypes()) { + extensionProcessor.write(bindingType, writer, context); + } + + for (ImplementationType implType : definitions.getImplementationTypes()) { + extensionProcessor.write(implType, writer, context); + } + + writeEndDocument(writer); + } + + public void resolve(Definitions scaDefns, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + + // start by adding all of the top level artifacts into the resolver as there + // are many cross artifact references in a definitions file and we don't want + // to be dependent on the order things appear + + List<Intent> intents = new ArrayList<Intent>(); + List<PolicySet> policySets = new ArrayList<PolicySet>(); + List<PolicySet> referredPolicySets = new ArrayList<PolicySet>(); + + for (Intent intent : scaDefns.getIntents()) { + intents.add(intent); + resolver.addModel(intent, context); + for (Intent i : intent.getQualifiedIntents()) { + intents.add(i); + resolver.addModel(i, context); + } + } + + for (PolicySet policySet : scaDefns.getPolicySets()) { + if (policySet.getReferencedPolicySets().isEmpty()) { + policySets.add(policySet); + } else { + referredPolicySets.add(policySet); + } + + resolver.addModel(policySet, context); + } + + for (BindingType bindingType : scaDefns.getBindingTypes()) { + resolver.addModel(bindingType, context); + } + + for (ImplementationType implType : scaDefns.getImplementationTypes()) { + resolver.addModel(implType, context); + } + + // now resolve everything to ensure that any references between + // artifacts are satisfied + + for (Intent policyIntent : intents) + extensionProcessor.resolve(policyIntent, resolver, context); + + for (PolicySet policySet : policySets) + extensionProcessor.resolve(policySet, resolver, context); + + for (PolicySet policySet : referredPolicySets) + extensionProcessor.resolve(policySet, resolver, context); + + for (Binding binding : scaDefns.getBindings()) { + extensionProcessor.resolve(binding, resolver, context); + } + + for (BindingType bindingType : scaDefns.getBindingTypes()) { + extensionProcessor.resolve(bindingType, resolver, context); + if (processors.getProcessor(bindingType.getType()) == null){ + Monitor.error(context.getMonitor(), + this, + "org.apache.tuscany.sca.definitions.xml.definitions-xml-validation-messages", + "BindingTypeNotFound", + bindingType.getType().toString()); + } + } + + for (ImplementationType implementationType : scaDefns.getImplementationTypes()) { + extensionProcessor.resolve(implementationType, resolver, context); + if (processors.getProcessor(implementationType.getType()) == null){ + Monitor.error(context.getMonitor(), + this, + "org.apache.tuscany.sca.definitions.xml.definitions-xml-validation-messages", + "ImplementationTypeNotFound", + implementationType.getType().toString()); + } + } + + + // Flat intentMap structure by creating a policySet for each one + List<PolicySet> copy = new ArrayList<PolicySet>(scaDefns.getPolicySets()); + for (PolicySet policySet : copy) { + // Add PolicySets to model based on qualified intents. The policy builder will be responsible for assigning + // the correct policy set. + // For example, ManagedTransactionPolicySet will result in: + // ManagedTransactionPolicySet (original PolicySet, must exist for matching at build time) + // ManagedTransactionPolicySet.managedTransaction.global + // ManagedTransactionPolicySet.managedTransaction.local + + //process intent maps + for(IntentMap intentMap : policySet.getIntentMaps()) { + for(Qualifier qualifier : intentMap.getQualifiers()) { + // remove = true; + + PolicySet qualifiedPolicySet = policyFactory.createPolicySet(); + qualifiedPolicySet.setAppliesTo(policySet.getAppliesTo()); + qualifiedPolicySet.setAppliesToXPathExpression(policySet.getAttachToXPathExpression()); + qualifiedPolicySet.setAttachTo(policySet.getAttachTo()); + qualifiedPolicySet.setAttachToXPathExpression(policySet.getAttachToXPathExpression()); + + String qualifiedLocalName = policySet.getName().getLocalPart() + "." + qualifier.getIntent().getName().getLocalPart(); + qualifiedPolicySet.setName(new QName(policySet.getName().getNamespaceURI(), qualifiedLocalName)); + qualifiedPolicySet.getProvidedIntents().clear(); + qualifiedPolicySet.getProvidedIntents().add(qualifier.getIntent()); + qualifiedPolicySet.getPolicies().clear(); + qualifiedPolicySet.getPolicies().addAll(qualifier.getPolicies()); + + scaDefns.getPolicySets().add(qualifiedPolicySet); + } + } + +// if(remove) { +// scaDefns.getPolicySets().remove(policySet); +// } + } + } + + public QName getArtifactType() { + return DEFINITIONS_QNAME; + } + + public Class<Definitions> getModelType() { + return Definitions.class; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/Messages.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/Messages.java new file mode 100644 index 0000000000..38cc4a9de2 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/definitions/xml/Messages.java @@ -0,0 +1,27 @@ +/* + * 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.definitions.xml; + +/** + * Constants for resource bundle names + */ +public interface Messages { + String RESOURCE_BUNDLE = "org.apache.tuscany.sca.definitions.xml.definitions-xml-validation-messages"; +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/BindingTypeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/BindingTypeProcessor.java new file mode 100644 index 0000000000..70c71c5f1f --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/BindingTypeProcessor.java @@ -0,0 +1,65 @@ +/* + * 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.policy.xml; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.policy.BindingType; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * Processor for handling XML models of BindingType meta data definitions + * + * @version $Rev$ $Date$ + */ +public class BindingTypeProcessor extends ExtensionTypeProcessor { + + public BindingTypeProcessor(PolicyFactory policyFactory, + StAXArtifactProcessor<Object> extensionProcessor) { + super(policyFactory, extensionProcessor); + } + + public BindingTypeProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> extensionProcessor) { + super(modelFactories.getFactory(PolicyFactory.class), extensionProcessor); + } + + public QName getArtifactType() { + return BINDING_TYPE_QNAME; + } + + @Override + protected ExtensionType resolveExtensionType(ExtensionType extnType, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (extnType instanceof BindingType) { + BindingType bindingType = (BindingType)extnType; + return resolver.resolveModel(BindingType.class, bindingType, context); + } else { + return extnType; + } + + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExtensionTypeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExtensionTypeProcessor.java new file mode 100644 index 0000000000..95d8e67bf7 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExtensionTypeProcessor.java @@ -0,0 +1,250 @@ +/* + * 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.policy.xml; + +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.BindingType; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.ImplementationType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * Processor for handling XML models of ExtensionType meta data definitions + * + * @version $Rev$ $Date$ + */ +abstract class ExtensionTypeProcessor extends BaseStAXArtifactProcessor implements + StAXArtifactProcessor<ExtensionType>, PolicyConstants { + + private PolicyFactory policyFactory; + + + protected abstract ExtensionType resolveExtensionType(ExtensionType extnType, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException; + + public ExtensionTypeProcessor(PolicyFactory policyFactory, + StAXArtifactProcessor<Object> extensionProcessor) { + this.policyFactory = policyFactory; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + (Object[])messageParameters); + monitor.problem(problem); + } + } + + public ExtensionType read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + QName extType = getArtifactType(); + QName type = getQName(reader, "type"); + + if (type != null) { + ExtensionType extensionType = null; + if (BINDING_TYPE_QNAME.equals(extType)) { + extensionType = policyFactory.createBindingType(); + } else if (IMPLEMENTATION_TYPE_QNAME.equals(extType)) { + extensionType = policyFactory.createImplementationType(); + } else { + error(context.getMonitor(), "UnrecognizedExtensionType", reader, type); + return null; + //throw new ContributionReadException("Unrecognized ExtensionType - " + type); + } + extensionType.setType(type); + extensionType.setUnresolved(true); + + readAlwaysProvidedIntents(extensionType, reader); + readMayProvideIntents(extensionType, reader); + return extensionType; + + } else { + error(context.getMonitor(), "RequiredAttributeMissing", reader, extType); + //throw new ContributionReadException("Required attribute '" + TYPE + + //"' missing from BindingType Definition"); + } + return null; + } + + private void readAlwaysProvidedIntents(ExtensionType extnType, XMLStreamReader reader) { + String value = reader.getAttributeValue(null, ALWAYS_PROVIDES); + if (value != null) { + List<Intent> alwaysProvided = extnType.getAlwaysProvidedIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent intent = policyFactory.createIntent(); + intent.setName(qname); + alwaysProvided.add(intent); + } + } + } + + private void readMayProvideIntents(ExtensionType extnType, XMLStreamReader reader) { + String value = reader.getAttributeValue(null, MAY_PROVIDE); + if (value != null) { + List<Intent> mayProvide = extnType.getMayProvidedIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent intent = policyFactory.createIntent(); + intent.setName(qname); + mayProvide.add(intent); + } + } + } + + public void write(ExtensionType extnType, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, + XMLStreamException { + + // Write an <sca:bindingType or sca:implementationType> + if (extnType instanceof BindingType) { + writer.writeStartElement(SCA11_NS, BINDING_TYPE); + } else if (extnType instanceof ImplementationType) { + writer.writeStartElement(SCA11_NS, IMPLEMENTATION_TYPE); + } + + writeAlwaysProvidesIntentsAttribute(extnType, writer); + writeMayProvideIntentsAttribute(extnType, writer); + + writer.writeEndElement(); + } + + private void writeMayProvideIntentsAttribute(ExtensionType extnType, XMLStreamWriter writer) + throws XMLStreamException { + StringBuffer sb = new StringBuffer(); + for (Intent intent : extnType.getMayProvidedIntents()) { + writer.writeNamespace(intent.getName().getPrefix(), intent.getName().getNamespaceURI()); + sb.append(intent.getName().getPrefix() + COLON + intent.getName().getLocalPart()); + sb.append(WHITE_SPACE); + } + + if (sb.length() > 0) { + writer.writeAttribute(MAY_PROVIDE, sb.toString()); + } + } + + private void writeAlwaysProvidesIntentsAttribute(ExtensionType extnType, XMLStreamWriter writer) + throws XMLStreamException { + StringBuffer sb = new StringBuffer(); + for (Intent intent : extnType.getAlwaysProvidedIntents()) { + writer.writeNamespace(intent.getName().getPrefix(), intent.getName().getNamespaceURI()); + sb.append(intent.getName().getPrefix() + COLON + intent.getName().getLocalPart()); + sb.append(WHITE_SPACE); + } + + if (sb.length() > 0) { + writer.writeAttribute(ALWAYS_PROVIDES, sb.toString()); + + } + } + + public void resolve(ExtensionType extnType, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + + if (extnType != null && extnType.isUnresolved()) { + resolveAlwaysProvidedIntents(extnType, resolver, context); + resolveMayProvideIntents(extnType, resolver, context); + extnType.setUnresolved(false); + //resolveExtensionType(extnType, resolver); + } + } + + private void resolveAlwaysProvidedIntents(ExtensionType extensionType, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (extensionType != null) { + // resolve all provided intents + List<Intent> alwaysProvided = new ArrayList<Intent>(); + for (Intent providedIntent : extensionType.getAlwaysProvidedIntents()) { + if (providedIntent.isUnresolved()) { + providedIntent = resolver.resolveModel(Intent.class, providedIntent, context); + if (!providedIntent.isUnresolved()) { + alwaysProvided.add(providedIntent); + } else { + error(context.getMonitor(), "AlwaysProvidedIntentNotFound", resolver, providedIntent, extensionType); + //throw new ContributionResolveException("Always Provided Intent - " + providedIntent + //+ " not found for ExtensionType " + //+ extensionType); + } + } else { + alwaysProvided.add(providedIntent); + } + } + extensionType.getAlwaysProvidedIntents().clear(); + extensionType.getAlwaysProvidedIntents().addAll(alwaysProvided); + } + } + + private void resolveMayProvideIntents(ExtensionType extensionType, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (extensionType != null) { + // resolve all provided intents + List<Intent> mayProvide = new ArrayList<Intent>(); + for (Intent providedIntent : extensionType.getMayProvidedIntents()) { + if (providedIntent.isUnresolved()) { + providedIntent = resolver.resolveModel(Intent.class, providedIntent, context); + if (!providedIntent.isUnresolved()) { + mayProvide.add(providedIntent); + } else { + error(context.getMonitor(), "MayProvideIntentNotFound", resolver, providedIntent, extensionType); + //throw new ContributionResolveException("May Provide Intent - " + providedIntent + //+ " not found for ExtensionType " + //+ extensionType); + } + } else { + mayProvide.add(providedIntent); + } + } + extensionType.getMayProvidedIntents().clear(); + extensionType.getMayProvidedIntents().addAll(mayProvide); + } + } + + public Class<ExtensionType> getModelType() { + return ExtensionType.class; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExternalAttachmentProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExternalAttachmentProcessor.java new file mode 100644 index 0000000000..2cf9d02ee4 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ExternalAttachmentProcessor.java @@ -0,0 +1,296 @@ +/*
+ * 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.policy.xml;
+
+import static org.apache.tuscany.sca.policy.xml.PolicyConstants.SCA11_NS;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpression;
+import javax.xml.xpath.XPathExpressionException;
+
+import org.apache.tuscany.sca.common.xml.xpath.XPathHelper;
+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.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.policy.ExternalAttachment;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+
+/**
+ * Processor for handling XML models of ExternalAttachment definitions
+ *
+ * @version $Rev: 961010 $ $Date: 2010-07-06 13:34:54 -0700 (Tue, 06 Jul 2010) $
+ */
+public class ExternalAttachmentProcessor extends BaseStAXArtifactProcessor
+ implements StAXArtifactProcessor<ExternalAttachment>, PolicyConstants {
+
+
+ private PolicyFactory policyFactory;
+ private XPathHelper xpathHelper;
+
+ public ExternalAttachmentProcessor(ExtensionPointRegistry registry) {
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.policyFactory = factories.getFactory(PolicyFactory.class);
+ this.xpathHelper = XPathHelper.getInstance(registry);
+ }
+
+ public Class<ExternalAttachment> getModelType() {
+ return ExternalAttachment.class;
+ }
+
+ public void resolve(ExternalAttachment attachment, ModelResolver resolver,
+ ProcessorContext context) throws ContributionResolveException {
+ if (attachment != null && attachment.isUnresolved()) {
+ resolveIntents(attachment, resolver, context);
+ resolvePolicySets(attachment, resolver, context);
+
+ attachment.setUnresolved(false);
+ }
+
+ }
+
+ private void resolvePolicySets(ExternalAttachment attachment,
+ ModelResolver resolver, ProcessorContext context) {
+ List<PolicySet> referredPolicySets = new ArrayList<PolicySet>();
+ for (PolicySet referredPolicySet : attachment.getPolicySets()) {
+ if (referredPolicySet.isUnresolved()) {
+ PolicySet resolved = resolver.resolveModel(PolicySet.class, referredPolicySet, context);
+ if (!resolved.isUnresolved() || resolved != referredPolicySet) {
+ referredPolicySets.add(resolved);
+ } else {
+ error(context.getMonitor(), "ReferredPolicySetNotFound", attachment, referredPolicySet, attachment);
+ return;
+ }
+ } else {
+ referredPolicySets.add(referredPolicySet);
+ }
+ }
+ attachment.getPolicySets().clear();
+ attachment.getPolicySets().addAll(referredPolicySets);
+
+ }
+
+ private void resolveIntents(ExternalAttachment attachment,
+ ModelResolver resolver, ProcessorContext context) {
+ if (attachment != null) {
+ //resolve all provided intents
+ List<Intent> providedIntents = new ArrayList<Intent>();
+ for (Intent providedIntent : attachment.getIntents()) {
+ if (providedIntent.isUnresolved()) {
+ Intent resolved = resolver.resolveModel(Intent.class, providedIntent, context);
+ if (!resolved.isUnresolved() || resolved != providedIntent) {
+ providedIntents.add(resolved);
+ } else {
+ error(context.getMonitor(), "ProvidedIntentNotFound", attachment, providedIntent, attachment);
+ return;
+ }
+ } else {
+ providedIntents.add(providedIntent);
+ }
+ }
+ attachment.getIntents().clear();
+ attachment.getIntents().addAll(providedIntents);
+ }
+
+ }
+
+ public QName getArtifactType() {
+ return EXTERNAL_ATTACHMENT_QNAME;
+ }
+
+ public ExternalAttachment read(XMLStreamReader reader, ProcessorContext context)
+ throws ContributionReadException, XMLStreamException {
+ ExternalAttachment attachment = policyFactory.createExternalAttachment();
+
+ readPolicySets(attachment, reader);
+ readIntents(attachment, reader, context);
+ readAttachTo(attachment, reader, context);
+
+ return attachment;
+ }
+
+ private void readIntents(ExternalAttachment attachment,
+ XMLStreamReader reader, ProcessorContext context) {
+ String value = reader.getAttributeValue(null, INTENTS);
+ if (value != null) {
+ List<Intent> intents = attachment.getIntents();
+ for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) {
+ QName qname = getQNameValue(reader, tokens.nextToken());
+ Intent intent = policyFactory.createIntent();
+ intent.setName(qname);
+ intents.add(intent);
+ }
+ }
+
+ }
+
+ private void readAttachTo(ExternalAttachment attachment,
+ XMLStreamReader reader, ProcessorContext context) {
+ Monitor monitor = context.getMonitor();
+
+ String attachTo = reader.getAttributeValue(null, ATTACH_TO);
+ if ( attachTo != null ) {
+ try {
+ XPath path = xpathHelper.newXPath();
+ NamespaceContext nsContext = xpathHelper.getNamespaceContext(attachTo, reader.getNamespaceContext());
+ path.setXPathFunctionResolver(new PolicyXPathFunctionResolver(nsContext));
+
+ attachTo = PolicyXPathFunction.normalize(attachTo,getSCAPrefix(nsContext));
+ XPathExpression expression = xpathHelper.compile(path, nsContext, attachTo);
+ attachment.setAttachTo(attachTo);
+ attachment.setAttachToXPathExpression(expression);
+ } catch (XPathExpressionException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error(monitor, "ContributionReadException", attachment, ce);
+ }
+ }
+
+ }
+
+ private String getSCAPrefix(NamespaceContext nsContext) {
+
+ Iterator<String> iter = nsContext.getPrefixes(SCA11_NS);
+ while (iter.hasNext()) {
+ String prefix = iter.next();
+ if (!prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
+ return prefix;
+ }
+ }
+
+ return "__sca";
+ }
+ /**
+ * Reads policy sets associated with an external attachment element.
+ * @param subject
+ * @param operation
+ * @param reader
+ */
+ private void readPolicySets(ExternalAttachment attachment, XMLStreamReader reader) {
+
+
+ String value = reader.getAttributeValue(null, POLICY_SETS);
+ if (value != null) {
+ List<PolicySet> policySets = attachment.getPolicySets();
+ for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) {
+ QName qname = getQNameValue(reader, tokens.nextToken());
+ PolicySet policySet = policyFactory.createPolicySet();
+ policySet.setName(qname);
+ policySets.add(policySet);
+ }
+ }
+ }
+ public void write(ExternalAttachment attachment, XMLStreamWriter writer,
+ ProcessorContext context) throws ContributionWriteException,
+ XMLStreamException {
+ writePolicySets(attachment, writer, context);
+ writeIntents(attachment, writer, context);
+ writeAttachTo(attachment, writer, context);
+
+ }
+
+ private void writeAttachTo(ExternalAttachment attachment,
+ XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException {
+ if ( attachment.getAttachTo() != null ) {
+ writer.writeAttribute(PolicyConstants.ATTACH_TO, attachment.getAttachTo());
+ }
+
+ }
+
+ private void writeIntents(ExternalAttachment attachment,
+ XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException {
+ if (!attachment.getIntents().isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ for (Intent intent : attachment.getIntents()) {
+ sb.append(getQualifiedName(intent.getName(), writer));
+ sb.append(" ");
+ }
+ // Remove the last space
+ sb.deleteCharAt(sb.length() - 1);
+ writer.writeAttribute(PolicyConstants.INTENTS, sb.toString());
+ }
+
+ }
+
+ private void writePolicySets(ExternalAttachment attachment,
+ XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException {
+ if ( !attachment.getPolicySets().isEmpty()) {
+ StringBuffer sb = new StringBuffer();
+ for (PolicySet ps : attachment.getPolicySets()) {
+ sb.append(getQualifiedName(ps.getName(), writer));
+ sb.append(" ");
+ }
+ // Remove the last space
+ sb.deleteCharAt(sb.length() - 1);
+ writer.writeAttribute(PolicyConstants.POLICY_SETS, sb.toString());
+ }
+
+ }
+
+ private String getQualifiedName(QName name, XMLStreamWriter writer) throws XMLStreamException {
+ String local = name.getLocalPart();
+ String prefix = writer.getPrefix(name.getNamespaceURI());
+ if (prefix != null && prefix.length() > 0) {
+ return prefix + ':' + local;
+ } else {
+ return local;
+ }
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ Messages.RESOURCE_BUNDLE,
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ImplementationTypeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ImplementationTypeProcessor.java new file mode 100644 index 0000000000..ec4e17385f --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/ImplementationTypeProcessor.java @@ -0,0 +1,65 @@ +/* + * 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.policy.xml; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.ImplementationType; +import org.apache.tuscany.sca.policy.PolicyFactory; + +/** + * Processor for handling XML models of ImplementationType meta data definitions + * + * @version $Rev$ $Date$ + */ +public class ImplementationTypeProcessor extends ExtensionTypeProcessor { + + public ImplementationTypeProcessor(PolicyFactory policyFactory, + StAXArtifactProcessor<Object> extensionProcessor) { + super(policyFactory, extensionProcessor); + } + + public ImplementationTypeProcessor(FactoryExtensionPoint modelFactories, + StAXArtifactProcessor<Object> extensionProcessor) { + super(modelFactories.getFactory(PolicyFactory.class), extensionProcessor); + } + + public QName getArtifactType() { + return IMPLEMENTATION_TYPE_QNAME; + } + + @Override + protected ExtensionType resolveExtensionType(ExtensionType extnType, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (extnType instanceof ImplementationType) { + ImplementationType implType = (ImplementationType)extnType; + return resolver.resolveModel(ImplementationType.class, implType, context); + } else { + return extnType; + } + + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/IntentProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/IntentProcessor.java new file mode 100644 index 0000000000..c7eb7f49d8 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/IntentProcessor.java @@ -0,0 +1,446 @@ +/* + * 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.policy.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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.FactoryExtensionPoint; +import org.apache.tuscany.sca.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.Intent.Type; + +/** + * Processor for handling XML models of PolicyIntent definitions + * + * @version $Rev$ $Date$ + */ +public class IntentProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<Intent>, + PolicyConstants { + + private PolicyFactory policyFactory; + + + public IntentProcessor(FactoryExtensionPoint modelFactories) { + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + } + + public IntentProcessor(PolicyFactory policyFactory) { + this.policyFactory = policyFactory; + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + messageParameters); + monitor.problem(problem); + } + } + + private void warn(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.WARNING, + model, + message, + messageParameters); + monitor.problem(problem); + } + } + + public Intent read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + Intent intent = null; + String intentLocalName = reader.getAttributeValue(null, NAME); + if (intentLocalName == null) { + error(context.getMonitor(), "IntentNameMissing", reader); + return null; + } + + String intentType = reader.getAttributeValue(null, INTENT_TYPE); + if (intentType == null) { + intentType = Intent.Type.interaction.name(); + } + + intent = policyFactory.createIntent(); + + // [rfeng] the target namespace is not available, set the local part for now + // This will be changed in the definitions processor + intent.setName(new QName(intentLocalName)); + intent.setType(Type.valueOf(intentType)); + + readRequiredIntents(intent, reader, context); + readExcludedIntents(intent, reader); + + readConstrainedTypes(intent, reader); + + String mutuallyExclusiveString = reader.getAttributeValue(null, MUTUALLY_EXCLUSIVE); + if (mutuallyExclusiveString != null && + mutuallyExclusiveString.equals("true")){ + intent.setMutuallyExclusive(true); + } else { + intent.setMutuallyExclusive(false); + } + + Intent current = intent; + int event = reader.getEventType(); + QName name = null; + while (reader.hasNext()) { + event = reader.getEventType(); + switch (event) { + case START_ELEMENT: { + name = reader.getName(); + if (DESCRIPTION_QNAME.equals(name)) { + String text = reader.getElementText(); + if (text != null) { + text = text.trim(); + } + current.setDescription(text); + } else if (INTENT_QUALIFIER_QNAME.equals(name)) { + String qualifierName = reader.getAttributeValue(null, NAME); + String defaultQ = reader.getAttributeValue(null, DEFAULT); + boolean isDefault = defaultQ == null ? false : Boolean.parseBoolean(defaultQ); + String qualifiedIntentName = intentLocalName + QUALIFIER + qualifierName; + Intent qualified = policyFactory.createIntent(); + qualified.setUnresolved(false); + qualified.setType(intent.getType()); + qualified.setName(new QName(qualifiedIntentName)); + if (isDefault) { + if (intent.getDefaultQualifiedIntent() == null){ + intent.setDefaultQualifiedIntent(qualified); + } else { + Monitor.error(context.getMonitor(), + this, + Messages.RESOURCE_BUNDLE, + "MultipleDefaultQualifiers", + intent.getName().toString()); + } + } + + // check that the qualifier is unique + if ( !intent.getQualifiedIntents().contains(qualified)){ + intent.getQualifiedIntents().add(qualified); + } else { + Monitor.error(context.getMonitor(), + this, + Messages.RESOURCE_BUNDLE, + "QualifierIsNotUnique", + intent.getName().toString(), + qualifierName); + } + + qualified.setQualifiableIntent(intent); + current = qualified; + } + break; + } + case END_ELEMENT: { + name = reader.getName(); + if (INTENT_QUALIFIER_QNAME.equals(name)) { + current = intent; + } + break; + } + } + if (event == END_ELEMENT && POLICY_INTENT_QNAME.equals(reader.getName())) { + break; + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + // REVIEW: [rfeng] What's going to happen if there is only one qualified intent + if (intent.getQualifiedIntents().size() == 1) { + intent.setDefaultQualifiedIntent(intent.getQualifiedIntents().get(0)); + } + + // set all qualified intents as excluding one another if the qualifiable + // intent is set to be mutually exclusive + if (intent.isMutuallyExclusive()){ + for (Intent qualifiedIntent : intent.getQualifiedIntents()){ + for (Intent excludedIntent : intent.getQualifiedIntents()){ + if (qualifiedIntent != excludedIntent){ + qualifiedIntent.getExcludedIntents().add(excludedIntent); + } + } + } + } + + return intent; + } + + public void write(Intent intent, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + // Write an <sca:intent> + writer.writeStartElement(PolicyConstants.SCA11_NS, INTENT); + writer.writeNamespace(intent.getName().getPrefix(), intent.getName().getNamespaceURI()); + writer.writeAttribute(PolicyConstants.NAME, intent.getName().getPrefix() + COLON + + intent.getName().getLocalPart()); + if (intent.getRequiredIntents() != null && intent.getRequiredIntents().size() > 0) { + StringBuffer sb = new StringBuffer(); + for (Intent requiredIntents : intent.getRequiredIntents()) { + sb.append(requiredIntents.getName()); + sb.append(" "); + } + writer.writeAttribute(PolicyConstants.REQUIRES, sb.toString()); + } + + if (intent.getExcludedIntents() != null && intent.getExcludedIntents().size() > 0) { + StringBuffer sb = new StringBuffer(); + for (Intent excludedIntents : intent.getExcludedIntents()) { + sb.append(excludedIntents.getName()); + sb.append(" "); + } + writer.writeAttribute(PolicyConstants.EXCLUDES, sb.toString()); + } + + if (intent.getConstrainedTypes() != null && intent.getConstrainedTypes().size() > 0) { + StringBuffer sb = new StringBuffer(); + for (ExtensionType contrainedArtifact : intent.getConstrainedTypes()) { + sb.append(contrainedArtifact.getType().getPrefix()); + sb.append(':').append(contrainedArtifact.getType().getLocalPart()); + sb.append(" "); + } + writer.writeAttribute(CONSTRAINS, sb.toString()); + } + + if (intent.getDescription() != null && intent.getDescription().length() > 0) { + writer.writeStartElement(PolicyConstants.SCA11_NS, DESCRIPTION); + writer.writeCData(intent.getDescription()); + writer.writeEndElement(); + } + + writer.writeEndElement(); + } + + private void resolveContrainedTypes(Intent intent, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + Collection<ExtensionType> resolvedTypes = new HashSet<ExtensionType>(); + for (ExtensionType extensionType : intent.getConstrainedTypes()) { + if (ExtensionType.BINDING_BASE.equals(extensionType.getType()) || ExtensionType.IMPLEMENTATION_BASE + .equals(extensionType.getType())) { + // HACK: Mark sca:binding and sca:implementation as resolved + extensionType.setUnresolved(false); + resolvedTypes.add(extensionType); + } else { + ExtensionType resolved = resolver.resolveModel(ExtensionType.class, extensionType, context); + if (!resolved.isUnresolved() || resolved != extensionType) { + resolvedTypes.add(resolved); + } else { + warn(context.getMonitor(), "ConstrainedTypeNotFound", intent, extensionType, intent); + } + } + } + intent.getConstrainedTypes().clear(); + intent.getConstrainedTypes().addAll(resolvedTypes); + } + + private void resolveProfileIntent(Intent intent, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + Monitor monitor = context.getMonitor(); + // FIXME: Need to check for cyclic references first i.e an A requiring B + // and then B requiring A... + if (intent != null && !intent.getRequiredIntents().isEmpty()) { + // resolve all required intents + List<Intent> requiredIntents = new ArrayList<Intent>(); + for (Intent required : intent.getRequiredIntents()) { + if (required.isUnresolved()) { + Intent resolved = resolver.resolveModel(Intent.class, required, context); + // At this point, when the required intent is not resolved, it does not mean + // its undeclared, chances are that their dependency are not resolved yet. + // Lets try to resolve them first. + if (resolved.isUnresolved()) { + if (((resolved).getRequiredIntents()).contains(intent)) { + error(monitor, "CyclicReferenceFound", resolver, required, intent); + return; + } + } + + if (!resolved.isUnresolved() || resolved != required) { + requiredIntents.add(resolved); + } else { + error(monitor, "RequiredIntentNotFound", resolver, required, intent); + return; + //throw new ContributionResolveException("Required Intent - " + requiredIntent + //+ " not found for Intent " + policyIntent); + } + } else { + requiredIntents.add(required); + } + } + intent.getRequiredIntents().clear(); + intent.getRequiredIntents().addAll(requiredIntents); + } + } + + private void resolveQualifiedIntent(Intent qualifed, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + if (qualifed != null) { + //resolve the qualifiable intent + Intent parent = qualifed.getQualifiableIntent(); + if (parent == null) { + return; + } + if (parent.isUnresolved()) { + Intent resolved = resolver.resolveModel(Intent.class, parent, context); + // At this point, when the qualifiable intent is not resolved, it does not mean + // its undeclared, chances are that their dependency are not resolved yet. + // Lets try to resolve them first. + + if (!resolved.isUnresolved() || resolved != qualifed) { + qualifed.setQualifiableIntent(resolved); + } else { + error(context.getMonitor(), "QualifiableIntentNotFound", resolver, parent, qualifed); + //throw new ContributionResolveException("Qualifiable Intent - " + qualifiableIntent + //+ " not found for Intent " + policyIntent); + } + } + } + } + + public void resolve(Intent intent, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException { + if (intent != null && intent.isUnresolved()) { + resolveProfileIntent(intent, resolver, context); + resolveExcludedIntents(intent, resolver, context); + resolveQualifiedIntent(intent, resolver, context); + resolveContrainedTypes(intent, resolver, context); + intent.setUnresolved(false); + } + } + + public QName getArtifactType() { + return POLICY_INTENT_QNAME; + } + + private void readConstrainedTypes(Intent policyIntent, XMLStreamReader reader) throws ContributionReadException { + String value = reader.getAttributeValue(null, CONSTRAINS); + if (value != null) { + List<ExtensionType> constrainedTypes = policyIntent.getConstrainedTypes(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + ExtensionType extensionType = policyFactory.createExtensionType(); + extensionType.setType(qname); + constrainedTypes.add(extensionType); + } + } + } + + private void readRequiredIntents(Intent intent, XMLStreamReader reader, ProcessorContext context) { + String value = reader.getAttributeValue(null, REQUIRES); + if (value != null) { + List<Intent> requiredIntents = intent.getRequiredIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent required = policyFactory.createIntent(); + required.setName(qname); + required.setUnresolved(true); + requiredIntents.add(required); + } + + // Check that a profile intent does not have "." in its name + if (requiredIntents.size() > 0) { + if (intent.getName().getLocalPart().contains(".")){ + Monitor.error(context.getMonitor(), + this, + Messages.RESOURCE_BUNDLE, + "ProfileIntentNameWithPeriod", + intent.getName().toString()); + } + } + } + } + + private void readExcludedIntents(Intent intent, XMLStreamReader reader) { + String value = reader.getAttributeValue(null, EXCLUDES); + if (value != null) { + List<Intent> excludedIntents = intent.getExcludedIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent excluded = policyFactory.createIntent(); + excluded.setName(qname); + excluded.setUnresolved(true); + excludedIntents.add(excluded); + } + } + } + + private void resolveExcludedIntents(Intent policyIntent, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (policyIntent != null) { + // resolve all excluded intents + List<Intent> excludedIntents = new ArrayList<Intent>(); + for (Intent excludedIntent : policyIntent.getExcludedIntents()) { + if (excludedIntent.isUnresolved()) { + Intent resolvedExcludedIntent = resolver.resolveModel(Intent.class, excludedIntent, context); + if (!resolvedExcludedIntent.isUnresolved() || resolvedExcludedIntent != excludedIntent) { + excludedIntents.add(resolvedExcludedIntent); + } else { + error(context.getMonitor(), "ExcludedIntentNotFound", resolver, excludedIntent, policyIntent); + return; + //throw new ContributionResolveException("Excluded Intent " + excludedIntent + //+ " not found for intent " + policyIntent); + } + } else { + excludedIntents.add(excludedIntent); + } + } + policyIntent.getExcludedIntents().clear(); + policyIntent.getExcludedIntents().addAll(excludedIntents); + } + } + + public Class<Intent> getModelType() { + return Intent.class; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/Messages.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/Messages.java new file mode 100644 index 0000000000..ee8b5274cc --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/Messages.java @@ -0,0 +1,27 @@ +/* + * 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.policy.xml; + +/** + * Constants for resource bundle names + */ +public interface Messages { + String RESOURCE_BUNDLE = "org.apache.tuscany.sca.policy.xml.policy-xml-validation-messages"; +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyConstants.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyConstants.java new file mode 100644 index 0000000000..2498f3df67 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyConstants.java @@ -0,0 +1,78 @@ +/* + * 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.policy.xml; + +import javax.xml.namespace.QName; + +/** + * constants related to policy framework + * + * @version $Rev$ $Date$ + */ +public interface PolicyConstants { + String WHITE_SPACE = " "; + String COLON = ":"; + String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + String TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1"; + String INTENT = "intent"; + String POLICY_SET = "policySet"; + String POLICY_SET_REFERENCE = "policySetReference"; + String INTENT_MAP = "intentMap"; + String NAME = "name"; + String TARGET_NAMESPACE = "targetNamespace"; + String SCA_DEFINITIONS = "definitions"; + String CONSTRAINS = "constrains"; + String DESCRIPTION = "description"; + String PROVIDES = "provides"; + String APPLIES_TO = "appliesTo"; + String ATTACH_TO = "attachTo"; + String ALWAYS_APPLIES_TO = "alwaysAppliesTo"; + String QUALIFIER = "."; + String INTENT_QUALIFIER = "qualifier"; + String INTENT_MAP_QUALIFIER = "qualifier"; + String REQUIRES = "requires"; + String EXCLUDES = "excludes"; + String DEFAULT = "default"; + String EXTERNAL_ATTACHMENT = "externalAttachment"; + String INTENTS = "intents"; + String POLICY_SETS = "policySets"; + String MUTUALLY_EXCLUSIVE = "mutuallyExclusive"; + + String ALWAYS_PROVIDES = "alwaysProvides"; + String MAY_PROVIDE = "mayProvide"; + String INTENT_TYPE = "intentType"; + String IMPLEMENTATION_TYPE = "implementationType"; + String BINDING_TYPE = "bindingType"; + QName IMPLEMENTATION_TYPE_QNAME = new QName(SCA11_NS, IMPLEMENTATION_TYPE); + QName BINDING_TYPE_QNAME = new QName(SCA11_NS, BINDING_TYPE); + String BINDING = "binding"; + String IMPLEMENTATION = "implementation"; + + QName POLICY_INTENT_QNAME = new QName(SCA11_NS, INTENT); + QName POLICY_SET_QNAME = new QName(SCA11_NS, POLICY_SET); + QName POLICY_INTENT_MAP_QNAME = new QName(SCA11_NS, INTENT_MAP); + QName SCA_DEFINITIONS_QNAME = new QName(SCA11_NS, SCA_DEFINITIONS); + QName DESCRIPTION_QNAME = new QName(SCA11_NS, DESCRIPTION); + QName POLICY_INTENT_MAP_QUALIFIER_QNAME = new QName(SCA11_NS, INTENT_MAP_QUALIFIER); + QName POLICY_SET_REFERENCE_QNAME = new QName(SCA11_NS, POLICY_SET_REFERENCE); + QName INTENT_QUALIFIER_QNAME = new QName(SCA11_NS, INTENT_QUALIFIER); + QName EXTERNAL_ATTACHMENT_QNAME = new QName(SCA11_NS, EXTERNAL_ATTACHMENT); + String QUALIFIED_INTENT_CONSTRAINS_ERROR = " - Qualified Intents must not specify 'constrains' attribute"; + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java new file mode 100644 index 0000000000..6bf797d957 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java @@ -0,0 +1,578 @@ +/* + * 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.policy.xml; + +import static javax.xml.stream.XMLStreamConstants.END_ELEMENT; +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.apache.tuscany.sca.policy.xml.PolicyConstants.SCA11_NS; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.StringTokenizer; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathExpressionException; + +import org.apache.tuscany.sca.common.xml.xpath.XPathHelper; +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.monitor.Monitor; +import org.apache.tuscany.sca.monitor.Problem; +import org.apache.tuscany.sca.monitor.Problem.Severity; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentMap; +import org.apache.tuscany.sca.policy.PolicyExpression; +import org.apache.tuscany.sca.policy.PolicyFactory; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.Qualifier; + +/** + * Processor for handling XML models of PolicySet definitions + * + * @version $Rev$ $Date$ + */ +public class PolicySetProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<PolicySet>, + PolicyConstants { + + private PolicyFactory policyFactory; + private StAXArtifactProcessor<Object> extensionProcessor; + private XPathHelper xpathHelper; + + // private XPathFactory xpathFactory; + + public PolicySetProcessor(ExtensionPointRegistry registry, StAXArtifactProcessor<Object> extensionProcessor) { + FactoryExtensionPoint modelFactories = registry.getExtensionPoint(FactoryExtensionPoint.class); + this.policyFactory = modelFactories.getFactory(PolicyFactory.class); + this.extensionProcessor = extensionProcessor; + this.xpathHelper = XPathHelper.getInstance(registry); + } + + /** + * Report a exception. + * + * @param problems + * @param message + * @param model + */ + private void error(Monitor monitor, String message, Object model, Exception ex) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + ex); + monitor.problem(problem); + } + } + + /** + * Report a error. + * + * @param problems + * @param message + * @param model + */ + private void error(Monitor monitor, String message, Object model, Object... messageParameters) { + if (monitor != null) { + Problem problem = + monitor.createProblem(this.getClass().getName(), + Messages.RESOURCE_BUNDLE, + Severity.ERROR, + model, + message, + (Object[])messageParameters); + monitor.problem(problem); + } + } + + public PolicySet read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, + XMLStreamException { + PolicySet policySet = null; + Monitor monitor = context.getMonitor(); + String policySetName = reader.getAttributeValue(null, NAME); + String appliesTo = reader.getAttributeValue(null, APPLIES_TO); + if (policySetName == null || appliesTo == null) { + if (policySetName == null) + error(monitor, "PolicySetNameMissing", reader); + if (appliesTo == null) + error(monitor, "PolicySetAppliesToMissing", reader); + return policySet; + } + + policySet = policyFactory.createPolicySet(); + policySet.setName(new QName(policySetName)); + + //TODO: with 1.0 version of specs the applies to xpath is given related to the immediate + //parent whereas the runtime evaluates the xpath aginst the composite element. What the runtime + //is doing is what the future version of the specs could be tending towards. When that happens + //this 'if' must be deleted + if (appliesTo != null && !appliesTo.startsWith("/")) { + appliesTo = "//" + appliesTo; + } + + policySet.setAppliesTo(appliesTo); + + if (appliesTo != null) { + try { + XPath path = xpathHelper.newXPath(); + NamespaceContext nsContext = xpathHelper.getNamespaceContext(appliesTo, reader.getNamespaceContext()); + // path.setXPathFunctionResolver(new PolicyXPathFunctionResolver(context)); + XPathExpression expression = xpathHelper.compile(path, nsContext, appliesTo); + policySet.setAppliesToXPathExpression(expression); + } catch (XPathExpressionException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", policySet, ce); + //throw ce; + } + } + + String attachTo = reader.getAttributeValue(null, ATTACH_TO); + if (attachTo != null) { + try { + XPath path = xpathHelper.newXPath(); + NamespaceContext nsContext = xpathHelper.getNamespaceContext(attachTo, reader.getNamespaceContext()); + path.setXPathFunctionResolver(new PolicyXPathFunctionResolver(nsContext)); + + attachTo = PolicyXPathFunction.normalize(attachTo,getSCAPrefix(nsContext)); + XPathExpression expression = xpathHelper.compile(path, nsContext, attachTo); + policySet.setAttachTo(attachTo); + policySet.setAttachToXPathExpression(expression); + } catch (XPathExpressionException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", policySet, ce); + //throw ce; + } + + } + + readProvidedIntents(policySet, reader); + + int event = reader.getEventType(); + QName name = null; + reader.next(); + while (reader.hasNext()) { + event = reader.getEventType(); + switch (event) { + case START_ELEMENT: { + name = reader.getName(); + if (POLICY_INTENT_MAP_QNAME.equals(name)) { + Intent mappedIntent = policyFactory.createIntent(); + String provides = reader.getAttributeValue(null, PROVIDES); + if (provides != null) { + mappedIntent.setName(getQName(reader, PROVIDES)); + if (policySet.getProvidedIntents().contains(mappedIntent)) { + readIntentMap(reader, policySet, mappedIntent, context); + } else { + error(monitor, "IntentNotSpecified", policySet, policySetName); + } + } else { + error(monitor, "IntentMapProvidesMissing", reader, policySetName); + } + } else if (POLICY_SET_REFERENCE_QNAME.equals(name)) { + PolicySet referredPolicySet = policyFactory.createPolicySet(); + String referencename = reader.getAttributeValue(null, NAME); + if (referencename != null) { + referredPolicySet.setName(getQName(reader, NAME)); + policySet.getReferencedPolicySets().add(referredPolicySet); + } else { + error(monitor, "PolicySetReferenceNameMissing", reader, policySetName); + } + } /*else if ( WS_POLICY_QNAME.equals(name) ) { + OMElement policyElement = loadElement(reader); + org.apache.neethi.Policy wsPolicy = PolicyEngine.getPolicy(policyElement); + policySet.getPolicies().add(wsPolicy); + } */else { + Object extension = extensionProcessor.read(reader, context); + if (extension != null) { + PolicyExpression exp = policyFactory.createPolicyExpression(); + exp.setName(name); + exp.setPolicy(extension); + // check that all the policies in the policy set are + // expressed in the same language. Compare against the + // first expression we added + if ((policySet.getPolicies().size() > 0) && (!policySet.getPolicies().get(0).getName() + .equals(name))) { + error(monitor, "PolicyLanguageMissmatch", reader, policySet.getName(), policySet + .getPolicies().get(0).getName(), name); + } else { + policySet.getPolicies().add(exp); + } + } + } + break; + } + } + if (event == END_ELEMENT) { + if (POLICY_SET_QNAME.equals(reader.getName())) { + break; + } + } + + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + return policySet; + } + + private String getSCAPrefix(NamespaceContext nsContext) { + + Iterator<String> iter = nsContext.getPrefixes(SCA11_NS); + while (iter.hasNext()) { + String prefix = iter.next(); + if (!prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) { + return prefix; + } + } + + return "__sca"; + } + + public void readIntentMap(XMLStreamReader reader, PolicySet policySet, Intent mappedIntent, ProcessorContext context) + throws ContributionReadException { + Monitor monitor = context.getMonitor(); + QName name = reader.getName(); + if (POLICY_INTENT_MAP_QNAME.equals(name)) { + + IntentMap intentMap = policyFactory.createIntentMap(); + QName intentName = getQName(reader, INTENT_MAP); + intentMap.setProvidedIntent(mappedIntent); + + if (!policySet.getIntentMaps().contains(intentMap)) { + policySet.getIntentMaps().add(intentMap); + } else { + Monitor.error(context.getMonitor(), this, Messages.RESOURCE_BUNDLE, "IntentMapIsNotUnique", policySet + .getName().toString(), mappedIntent.getName().getLocalPart()); + } + + String qualifierName = null; + String qualfiedIntentName = null; + Intent qualifiedIntent = null; + + Qualifier qualifier = null; + + int event = reader.getEventType(); + try { + reader.next(); + while (reader.hasNext()) { + event = reader.getEventType(); + switch (event) { + case START_ELEMENT: { + name = reader.getName(); + if (POLICY_INTENT_MAP_QUALIFIER_QNAME.equals(name)) { + qualifierName = getString(reader, NAME); + if (qualifierName != null) { + qualfiedIntentName = + mappedIntent.getName().getLocalPart() + QUALIFIER + qualifierName; + qualifiedIntent = policyFactory.createIntent(); + qualifiedIntent.setName(new QName(mappedIntent.getName().getNamespaceURI(), + qualfiedIntentName)); + qualifier = policyFactory.createQualifier(); + qualifier.setIntent(qualifiedIntent); + intentMap.getQualifiers().add(qualifier); + + } else { + error(monitor, "QualifierNameMissing", reader, policySet.getName()); + } + } else if (POLICY_INTENT_MAP_QNAME.equals(name)) { + QName providedIntent = getQName(reader, PROVIDES); + if (qualifierName.equals(providedIntent.getLocalPart())) { + readIntentMap(reader, policySet, qualifiedIntent, context); + } else { + error(monitor, + "IntentMapDoesNotMatch", + providedIntent, + providedIntent, + qualifierName, + policySet); + //throw new ContributionReadException("Intent provided by IntentMap " + + //providedIntent + " does not match parent qualifier " + qualifierName + + //" in policyset - " + policySet); + } + } else { + Object extension = extensionProcessor.read(reader, context); + if (extension != null && qualifier != null) { + PolicyExpression exp = policyFactory.createPolicyExpression(); + exp.setName(name); + exp.setPolicy(extension); + qualifier.getPolicies().add(exp); + } + } + break; + } + } + if (event == END_ELEMENT && POLICY_INTENT_MAP_QNAME.equals(reader.getName())) { + break; + } + //Read the next element + if (reader.hasNext()) { + reader.next(); + } + } + } catch (XMLStreamException e) { + ContributionReadException ce = new ContributionReadException(e); + error(monitor, "ContributionReadException", reader, ce); + throw ce; + } + } + } + + public void write(PolicySet policySet, XMLStreamWriter writer, ProcessorContext context) + throws ContributionWriteException, XMLStreamException { + + // Write an <sca:policySet> + writer.writeStartElement(SCA11_NS, POLICY_SET); + writer.writeNamespace(policySet.getName().getPrefix(), policySet.getName().getNamespaceURI()); + writer.writeAttribute(NAME, policySet.getName().getPrefix() + COLON + policySet.getName().getLocalPart()); + + if (policySet.getAppliesTo() != null){ + writer.writeAttribute(APPLIES_TO, policySet.getAppliesTo()); + } + + if (policySet.getAttachTo() != null){ + writer.writeAttribute(ATTACH_TO, policySet.getAttachTo()); + } + + writeProvidedIntents(policySet, writer); + + writer.writeEndElement(); + } + + private void readProvidedIntents(PolicySet policySet, XMLStreamReader reader) { + String value = reader.getAttributeValue(null, PROVIDES); + if (value != null) { + List<Intent> providedIntents = policySet.getProvidedIntents(); + for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) { + QName qname = getQNameValue(reader, tokens.nextToken()); + Intent intent = policyFactory.createIntent(); + intent.setName(qname); + providedIntents.add(intent); + } + } + } + + private void writeProvidedIntents(PolicySet policySet, XMLStreamWriter writer) throws XMLStreamException { + if (!policySet.getProvidedIntents().isEmpty()) { + StringBuffer sb = new StringBuffer(); + for (Intent providedIntents : policySet.getProvidedIntents()) { + sb.append(getQualifiedName(providedIntents.getName(), writer)); + sb.append(" "); + } + // Remove the last space + sb.deleteCharAt(sb.length() - 1); + writer.writeAttribute(PolicyConstants.PROVIDES, sb.toString()); + } + } + + private String getQualifiedName(QName name, XMLStreamWriter writer) throws XMLStreamException { + String local = name.getLocalPart(); + String prefix = writer.getPrefix(name.getNamespaceURI()); + if (prefix != null && prefix.length() > 0) { + return prefix + ':' + local; + } else { + return local; + } + } + + private void resolvePolicies(PolicySet policySet, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + boolean unresolved = false; + if (policySet != null) { + for (Object o : policySet.getPolicies()) { + extensionProcessor.resolve(o, resolver, context); + /*if ( o instanceof Policy && ((Policy)o).isUnresolved() ) { + unresolved = true; + }*/ + } + policySet.setUnresolved(unresolved); + } + } + + public QName getArtifactType() { + return POLICY_SET_QNAME; + } + + public Class<PolicySet> getModelType() { + return PolicySet.class; + } + + private void resolveProvidedIntents(PolicySet policySet, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (policySet != null) { + //resolve all provided intents + List<Intent> providedIntents = new ArrayList<Intent>(); + for (Intent providedIntent : policySet.getProvidedIntents()) { + if (providedIntent.isUnresolved()) { + Intent resolved = resolver.resolveModel(Intent.class, providedIntent, context); + if (!resolved.isUnresolved() || resolved != providedIntent) { + providedIntents.add(resolved); + } else { + error(context.getMonitor(), "ProvidedIntentNotFound", policySet, providedIntent, policySet); + return; + //throw new ContributionResolveException("Provided Intent - " + providedIntent + //+ " not found for PolicySet " + policySet); + } + } else { + providedIntents.add(providedIntent); + } + } + policySet.getProvidedIntents().clear(); + policySet.getProvidedIntents().addAll(providedIntents); + } + } + + private void resolveIntentsInMappedPolicies(PolicySet policySet, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + Monitor monitor = context.getMonitor(); + for (IntentMap intentMap : policySet.getIntentMaps()) { + Intent intent = intentMap.getProvidedIntent(); + if (intent.isUnresolved()) { + Intent resolved = resolver.resolveModel(Intent.class, intent, context); + if (!resolved.isUnresolved() || resolved != intent) { + intentMap.setProvidedIntent(resolved); + } else { + error(monitor, "MappedIntentNotFound", policySet, intent, policySet); + return; + //throw new ContributionResolveException("Mapped Intent - " + mappedIntent + //+ " not found for PolicySet " + policySet); + } + } + for (Qualifier qualifier : intentMap.getQualifiers()) { + intent = qualifier.getIntent(); + if (intent.isUnresolved()) { + Intent resolved = resolver.resolveModel(Intent.class, intent, context); + if (!resolved.isUnresolved() || resolved != intent) { + qualifier.setIntent(resolved); + } else { + error(monitor, "MappedIntentNotFound", policySet, intent, policySet); + return; + //throw new ContributionResolveException("Mapped Intent - " + mappedIntent + //+ " not found for PolicySet " + policySet); + } + } + for (PolicyExpression exp : qualifier.getPolicies()) { + // FIXME: How to resolve the policies? + } + } + // validate that the intent map has a qualifier for each + // intent qualifier. The above code has already checked that the + // qualifiers that are there are resolved + Intent providedIntent = intentMap.getProvidedIntent(); + if (intentMap.getQualifiers().size() != providedIntent.getQualifiedIntents().size()) { + String missingQualifiers = ""; + for (Intent loopQualifiedIntent : providedIntent.getQualifiedIntents()) { + boolean found = false; + for (Qualifier loopQualifier : intentMap.getQualifiers()) { + if (loopQualifier.getIntent().getName().equals(loopQualifiedIntent.getName())) { + found = true; + break; + } + } + if (!found) { + missingQualifiers += loopQualifiedIntent.getName().getLocalPart() + " "; + } + } + if (missingQualifiers.length() > 0) { + Monitor.error(context.getMonitor(), + this, + Messages.RESOURCE_BUNDLE, + "IntentMapMissingQualifiers", + policySet.getName().toString(), + providedIntent.getName().getLocalPart(), + missingQualifiers); + } + } + } + + } + + private void resolveReferredPolicySets(PolicySet policySet, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + + List<PolicySet> referredPolicySets = new ArrayList<PolicySet>(); + for (PolicySet referredPolicySet : policySet.getReferencedPolicySets()) { + if (referredPolicySet.isUnresolved()) { + PolicySet resolved = resolver.resolveModel(PolicySet.class, referredPolicySet, context); + if (!resolved.isUnresolved() || resolved != referredPolicySet) { + referredPolicySets.add(resolved); + } else { + error(context.getMonitor(), "ReferredPolicySetNotFound", policySet, referredPolicySet, policySet); + return; + //throw new ContributionResolveException("Referred PolicySet - " + referredPolicySet + //+ "not found for PolicySet - " + policySet); + } + } else { + referredPolicySets.add(referredPolicySet); + } + } + policySet.getReferencedPolicySets().clear(); + policySet.getReferencedPolicySets().addAll(referredPolicySets); + } + + private void includeReferredPolicySets(PolicySet policySet, PolicySet referredPolicySet) { + for (PolicySet furtherReferredPolicySet : referredPolicySet.getReferencedPolicySets()) { + includeReferredPolicySets(referredPolicySet, furtherReferredPolicySet); + } + policySet.getPolicies().addAll(referredPolicySet.getPolicies()); + policySet.getIntentMaps().addAll(referredPolicySet.getIntentMaps()); + } + + public void resolve(PolicySet policySet, ModelResolver resolver, ProcessorContext context) + throws ContributionResolveException { + if (policySet != null && policySet.isUnresolved()) { + resolveProvidedIntents(policySet, resolver, context); + resolveIntentsInMappedPolicies(policySet, resolver, context); + resolveReferredPolicySets(policySet, resolver, context); + + for (PolicySet referredPolicySet : policySet.getReferencedPolicySets()) { + includeReferredPolicySets(policySet, referredPolicySet); + } + + if (policySet.isUnresolved()) { + //resolve the policy attachments + resolvePolicies(policySet, resolver, context); + + /*if ( !policySet.isUnresolved() ) { + resolver.addModel(policySet); + }*/ + } + + policySet.setUnresolved(false); + } + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java new file mode 100644 index 0000000000..8e2d7f9e60 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java @@ -0,0 +1,295 @@ +/* + * 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.policy.xml; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathFunction; +import javax.xml.xpath.XPathFunctionException; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * The SCA-defined XPath function + */ +public class PolicyXPathFunction implements XPathFunction { + private static Logger logger = Logger.getLogger(PolicyXPathFunction.class.getName()); + + static final QName InterfaceRef = new QName(PolicyConstants.SCA11_NS, "InterfaceRef"); + static final QName OperationRef = new QName(PolicyConstants.SCA11_NS, "OperationRef"); + static final QName MessageRef = new QName(PolicyConstants.SCA11_NS, "MessageRef"); + static final QName IntentRefs = new QName(PolicyConstants.SCA11_NS, "IntentRefs"); + static final QName URIRef = new QName(PolicyConstants.SCA11_NS, "URIRef"); + + static final Set<QName> functions = + new HashSet<QName>(Arrays.asList(InterfaceRef, OperationRef, MessageRef, IntentRefs, URIRef)); + + private NamespaceContext namespaceContext; + private final QName functionName; + + public PolicyXPathFunction(NamespaceContext namespaceContext, QName functionName) { + super(); + this.namespaceContext = namespaceContext; + this.functionName = functionName; + } + + private Node getContextNode(List args) { + if (args.size() >= 2) { + NodeList nodeList = (NodeList)args.get(1); + if (nodeList.getLength() > 0) { + return nodeList.item(0); + } + } + return null; + } + + public Object evaluate(List args) throws XPathFunctionException { + if (logger.isLoggable(Level.FINE)) { + logger.fine(functionName + "(" + args + ")"); + } + + String arg = (String)args.get(0); + Node node = getContextNode(args); + /** + * If the xpath expression that contains the function does not select any nodes + * (eg IntentRefs('someIntent')), the context node passed in will be a Document. + * In this case we need to iterate over every Node in the Document and evaluate it. + * + * If the xpath expression does select nodes (eg //sca:component[IntentRefs('someIntent')]) + * then xpath will call evaluate for each node and we only need to return the result for that + * node. + */ + if ( node instanceof Document ) + return evaluateDocument(arg, (Document)node); + else + return evaluateNode(arg, node); + } + + public Object evaluateNode(String arg, Node node) { + if (InterfaceRef.equals(functionName)) { + return evaluateInterface(arg, node); + } else if (OperationRef.equals(functionName)) { + String[] params = arg.split("/"); + if (params.length != 2) { + throw new IllegalArgumentException("Invalid argument: " + arg); + } + String interfaceName = params[0]; + String operationName = params[1]; + return evaluateOperation(interfaceName, operationName, node); + } else if (MessageRef.equals(functionName)) { + String[] params = arg.split("/"); + if (params.length != 3) { + throw new IllegalArgumentException("Invalid argument: " + arg); + } + String interfaceName = params[0]; + String operationName = params[1]; + String messageName = params[2]; + return evaluateMessage(interfaceName, operationName, messageName, node); + } else if (URIRef.equals(functionName)) { + return evaluateURI(arg, node); + } else if (IntentRefs.equals(functionName)) { + String[] intents = arg.split("(\\s)+"); + return evaluateIntents(intents, node); + } else { + return Boolean.FALSE; + } + } + + private class NodeListImpl implements NodeList { + + private ArrayList<Node> list; + + public NodeListImpl() { + this.list = new ArrayList<Node>(); + } + public int getLength() { + return this.list.size(); + } + + public Node item(int index) { + return this.list.get(index); + } + public boolean add(Node node) { + return this.list.add(node); + + } + + } + private Object evaluateDocument(String arg, Document doc) { + NodeListImpl retList = new NodeListImpl(); + NodeList elements = doc.getElementsByTagName("*"); + for ( int i=0; i < elements.getLength(); i++) { + Object node = evaluateNode(arg, elements.item(i)); + if ( node != null ) + retList.add((Node)node); + } + return retList; + } + + private Boolean evaluateInterface(String interfaceName, Node node) { + return Boolean.FALSE; + } + + private Boolean evaluateOperation(String interfaceName, String operationName, Node node) { + return Boolean.FALSE; + } + + private Boolean evaluateMessage(String interfaceName, String operationName, String messageName, Node node) { + return Boolean.FALSE; + } + + private Boolean evaluateURI(String uri, Node node) { + return Boolean.FALSE; + } + + /** + * Evaluates a single node for the given intents. + * @param intents + * @param node + * @return + */ + private Object evaluateIntents(String[] intents, Node node) { + if ( node == null ) + return false; + + if ( node.getAttributes() != null ) { + for ( int i=0; i < node.getAttributes().getLength(); i++) { + Node attr = node.getAttributes().item(i); + + if ( "requires".equalsIgnoreCase(attr.getNodeName())) { + + for ( int j = 0; j < intents.length; j++ ) { + // Check negative intents + if ( intents[j].startsWith("!")) { + if ( matchIntent(intents[j].substring(1), attr, node.getNamespaceURI())) + return null; + } else if ( !matchIntent(intents[j], attr, node.getNamespaceURI())){ + return null; + } + } + return node; + } + + } + } + + return null; + } + + + + /** + * Determine whether the given intent is present in the "requires" attribute + * @param intent + * @param node + * @param namespaceURI + * @return + */ + private boolean matchIntent(String intent, Node node, String namespaceURI) { + String[] requires = node.getNodeValue().split("(\\s)+"); + QName intentName = getStringAsQName(intent); + + + for ( int i=0; i < requires.length; i++ ) { + QName nodeName = null; + int idx = requires[i].indexOf(':'); + + // No prefix specified + if ( idx == -1 ) { + nodeName = new QName(namespaceURI, requires[i]); + } else { + String prefix = requires[i].substring(0, idx); + String name = requires[i].substring(idx + 1); + String ns = node.lookupNamespaceURI(prefix); + nodeName = new QName(ns, name, prefix); + } + if ( intentName.equals(nodeName)) + return true; + } + return false; + } + + + private QName getStringAsQName(String intent) { + int idx = intent.indexOf(':'); + if (idx == -1) + return new QName(namespaceContext.getNamespaceURI(XMLConstants.DEFAULT_NS_PREFIX), intent); + + String prefix = intent.substring(0, idx); + intent = intent.substring(idx + 1); + + return new QName(namespaceContext.getNamespaceURI(prefix), intent, prefix); + + } + + + private static Pattern FUNCTION; + static { + String functionPattern = "(URIRef|InterfaceRef|OperationRef|MessageRef|IntentRefs)\\s*\\(([^\\)]*)\\)"; + FUNCTION = Pattern.compile(functionPattern); + } + + /** Adds the node as an argument to the XPath function. + * Required in order to have access to the NodeList within the function + */ + public static String normalize(String attachTo, String scaPrefix) { + // Get rid of any whitespace + attachTo = attachTo.trim(); + + Matcher matcher = FUNCTION.matcher(attachTo); + boolean result = matcher.find(); + if (result) { + StringBuffer sb = new StringBuffer(); + do { + String function = matcher.group(1); + String args = matcher.group(2); + if ( (matcher.start() == 0) || (attachTo.charAt( matcher.start() -1) != ':' )) { + function = scaPrefix + ":" + function; + } + String replacement = null; + if (args.trim().length() > 0) { + replacement = function + "(" + args + "," + "self::node())"; + } else { + replacement = function + "(self::node())"; + } + matcher.appendReplacement(sb, replacement); + result = matcher.find(); + } while (result); + + matcher.appendTail(sb); + return sb.toString(); + } + return attachTo; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolver.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolver.java new file mode 100644 index 0000000000..ca44667903 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolver.java @@ -0,0 +1,72 @@ +/* + * 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.policy.xml; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import javax.xml.xpath.XPathFunction; +import javax.xml.xpath.XPathFunctionResolver; + +/** + * A resolver that handles SCA-defined XPath functions + * + * Interface Related Functions + * <ul> + * <li>InterfaceRef( InterfaceName ) + * <li>OperationRef( InterfaceName/OperationName ) + * <li>MessageRef( InterfaceName/OperationName/MessageName ) + * </ul> + * + * Intent Related Functions + * <ul> + * <li>IntentRefs( IntentList ) + * </ul> + * + * URI Based Function + * <ul> + * <li>URIRef( URI ) + * </ul> + */ +public class PolicyXPathFunctionResolver implements XPathFunctionResolver { + private NamespaceContext namespaceContext; + + public PolicyXPathFunctionResolver(NamespaceContext namespaceContext) { + super(); + this.namespaceContext = namespaceContext; + } + + public XPathFunction resolveFunction(QName functionName, int arity) { + if (functionName == null) { + throw new NullPointerException("Function name is null"); + } + if (PolicyXPathFunction.functions.contains(functionName)) { + if (arity >= 1) { + // We are relaxing the arity here so that we can pass in the context node + // by modifying the original xpath so that sca functions take self::node() + // as the 2nd argument + return new PolicyXPathFunction(namespaceContext, functionName); + } else { + throw new IllegalArgumentException("Invalid number of arguments: " + arity); + } + } + return null; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/sca-policy-1.1-intents-definitions-cd04.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/sca-policy-1.1-intents-definitions-cd04.xml new file mode 100644 index 0000000000..0d6c5ac714 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/sca-policy-1.1-intents-definitions-cd04.xml @@ -0,0 +1,249 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright(C) OASIS(R) 2005,2010. All Rights Reserved.
+ OASIS trademark, IPR and other policies apply. -->
+<sca:definitions xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ targetNamespace="http://docs.oasis-open.org/ns/opencsa/sca/200912">
+
+ <!-- Security related intents -->
+ <sca:intent name="serverAuthentication" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ Communication through the binding requires that the
+ server is authenticated by the client
+ </sca:description>
+ <sca:qualifier name="transport" default="true"/>
+ <sca:qualifier name="message"/>
+ </sca:intent>
+
+ <sca:intent name="clientAuthentication" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ Communication through the binding requires that the
+ client is authenticated by the server
+ </sca:description>
+ <sca:qualifier name="transport" default="true"/>
+ <sca:qualifier name="message"/>
+ </sca:intent>
+
+ <sca:intent name="authentication" requires="sca:clientAuthentication">
+ <sca:description>
+ A convenience intent to help migration
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="mutualAuthentication"
+ requires="sca:clientAuthentication sca:serverAuthentication">
+ <sca:description>
+ Communication through the binding requires that the
+ client and server to authenticate each other
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="confidentiality" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ Communication through the binding prevents unauthorized
+ users from reading the messages
+ </sca:description>
+ <sca:qualifier name="transport" default="true"/>
+ <sca:qualifier name="message"/>
+ </sca:intent>
+
+ <sca:intent name="integrity" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ Communication through the binding prevents tampering
+ with the messages sent between the client and the service.
+ </sca:description>
+ <sca:qualifier name="transport" default="true"/>
+ <sca:qualifier name="message"/>
+ </sca:intent>
+
+ <sca:intent name="authorization" constrains="sca:implementation"
+ intentType="implementation">
+ <sca:description>
+ Ensures clients are authorized to use services.
+ </sca:description>
+ </sca:intent>
+
+
+ <!-- Reliable messaging related intents -->
+ <sca:intent name="atLeastOnce" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ This intent is used to indicate that a message sent
+ by a client is always delivered to the component.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="atMostOnce" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ This intent is used to indicate that a message that was
+ successfully sent by a client is not delivered more than
+ once to the component.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="exactlyOnce" requires="sca:atLeastOnce sca:atMostOnce"
+ constrains="sca:binding" intentType="interaction">
+ <sca:description>
+ This profile intent is used to indicate that a message sent
+ by a client is always delivered to the component. It also
+ indicates that duplicate messages are not delivered to the
+ component.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="ordered" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ This intent is used to indicate that all the messages are
+ delivered to the component in the order they were sent by
+ the client.
+ </sca:description>
+ </sca:intent>
+
+ <!-- Transaction related intents -->
+ <sca:intent name="managedTransaction" excludes="sca:noManagedTransaction"
+ mutuallyExclusive="true" constrains="sca:implementation"
+ intentType="implementation">
+ <sca:description>
+ A managed transaction environment is necessary in order to
+ run the component. The specific type of managed transaction
+ needed is not constrained.
+ </sca:description>
+ <sca:qualifier name="global" default="true">
+ <sca:description>
+ For a component marked with managedTransaction.global
+ a global transaction needs to be present before dispatching
+ any method on the component - using any transaction
+ propagated from the client or else beginning and completing
+ a new transaction.
+ </sca:description>
+ </sca:qualifier>
+ <sca:qualifier name="local">
+ <sca:description>
+ A component marked with managedTransaction.local needs to
+ run within a local transaction containment (LTC) that
+ is started and ended by the SCA runtime.
+ </sca:description>
+ </sca:qualifier>
+ </sca:intent>
+
+ <sca:intent name="noManagedTransaction" excludes="sca:managedTransaction"
+ constrains="sca:implementation" intentType="implementation">
+ <sca:description>
+ A component marked with noManagedTransaction needs to run without
+ a managed transaction, under neither a global transaction nor
+ an LTC. A transaction propagated to the hosting SCA runtime
+ is not joined by the hosting runtime on behalf of a
+ component marked with noManagedtransaction.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="transactedOneWay" excludes="sca:immediateOneWay"
+ constrains="sca:binding" intentType="implementation">
+ <sca:description>
+ For a reference marked as transactedOneWay any OneWay invocation
+ messages are transacted as part of a client global
+ transaction.
+ For a service marked as transactedOneWay any OneWay invocation
+ message are received from the transport binding in a
+ transacted fashion, under the service’s global transaction.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="immediateOneWay" excludes="sca:transactedOneWay"
+ constrains="sca:binding" intentType="implementation">
+ <sca:description>
+ For a reference indicates that any OneWay invocation messages
+ are sent immediately regardless of any client transaction.
+ For a service indicates that any OneWay invocation is
+ received immediately regardless of any target service
+ transaction.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="propagatesTransaction" excludes="sca:suspendsTransaction"
+ constrains="sca:binding" intentType="interaction">
+ <sca:description>
+ A service marked with propagatesTransaction is dispatched
+ under any propagated (client) transaction and the service binding
+ needs to be capable of receiving a transaction context.
+ A reference marked with propagatesTransaction propagates any
+ transaction context under which the client runs when the
+ reference is used for a request-response interaction and the
+ binding of a reference marked with propagatesTransaction needs to
+ be capable of propagating a transaction context.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="suspendsTransaction" excludes="sca:propagatesTransaction"
+ constrains="sca:binding" intentType="interaction">
+ <sca:description>
+ A service marked with suspendsTransaction is not dispatched
+ under any propagated (client) transaction.
+ A reference marked with suspendsTransaction does not propagate
+ any transaction context under which the client runs when the
+ reference is used.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="managedSharedTransaction"
+ requires="sca:managedTransaction.global sca:propagatesTransaction">
+ <sca:description>
+ Used to indicate that the component requires both the
+ managedTransaction.global and the propagatesTransactions
+ intents
+ </sca:description>
+ </sca:intent>
+
+ <!-- Miscellaneous intents -->
+ <sca:intent name="asyncInvocation" excludes="sca:propagatesTransaction"
+ constrains="sca:binding" intentType="interaction">
+ <sca:description>
+ Indicates that request/response operations for the
+ interface of this wire are "long running" and must be
+ treated as two separate message transmissions
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="EJB" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ Specifies that the EJB API is needed to communicate with
+ the service or reference.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="SOAP" constrains="sca:binding" intentType="interaction" mutuallyExclusive="true">
+ <sca:description>
+ Specifies that the SOAP messaging model is used for delivering
+ messages.
+ </sca:description>
+ <sca:qualifier name="v1_1" default="true"/>
+ <sca:qualifier name="v1_2"/>
+ </sca:intent>
+
+ <sca:intent name="JMS" constrains="sca:binding" intentType="interaction">
+ <sca:description>
+ Requires that the messages are delivered and received via the
+ JMS API.
+ </sca:description>
+ </sca:intent>
+
+ <sca:intent name="noListener" constrains="sca:binding"
+ intentType="interaction">
+ <sca:description>
+ This intent can only be used on a reference. Indicates that the
+ client is not able to handle new inbound connections. The binding
+ and callback binding are configured so that any
+ response or callback comes either through a back channel of the
+ connection from the client to the server or by having the client
+ poll the server for messages.
+ </sca:description>
+ </sca:intent>
+
+</sca:definitions>
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor new file mode 100644 index 0000000000..250cc1d568 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor @@ -0,0 +1,29 @@ +# 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.
+
+# Implementation class for the artifact processor extension
+org.apache.tuscany.sca.assembly.xml.ComponentTypeProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#componentType,model=org.apache.tuscany.sca.assembly.ComponentType
+org.apache.tuscany.sca.assembly.xml.CompositeProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#composite,model=org.apache.tuscany.sca.assembly.Composite
+org.apache.tuscany.sca.assembly.xml.SCABindingProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#binding.sca,model=org.apache.tuscany.sca.assembly.SCABinding
+org.apache.tuscany.sca.assembly.xml.EndpointProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#endpoint,model=org.apache.tuscany.sca.assembly.Endpoint
+org.apache.tuscany.sca.assembly.xml.EndpointReferenceProcessor;qname=http://tuscany.apache.org/xmlns/sca/1.1#endpointReference,model=org.apache.tuscany.sca.assembly.EndpointReference
+org.apache.tuscany.sca.definitions.xml.DefinitionsProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#definitions,model=org.apache.tuscany.sca.definitions.Definitions
+org.apache.tuscany.sca.policy.xml.BindingTypeProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#bindingType,model=org.apache.tuscany.sca.policy.BindingType
+org.apache.tuscany.sca.policy.xml.ImplementationTypeProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#implementationType,model=org.apache.tuscany.sca.policy.ImplementationType
+org.apache.tuscany.sca.policy.xml.IntentProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#intent,model=org.apache.tuscany.sca.policy.Intent
+org.apache.tuscany.sca.policy.xml.PolicySetProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#policySet,model=org.apache.tuscany.sca.policy.PolicySet
+org.apache.tuscany.sca.policy.xml.ExternalAttachmentProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200912#externalAttachment,model=org.apache.tuscany.sca.policy.ExternalAttachment
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor new file mode 100644 index 0000000000..f8d1e11ef3 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor @@ -0,0 +1,22 @@ +# 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. + +# Implementation class for the artifact processor extension +org.apache.tuscany.sca.assembly.xml.ComponentTypeDocumentProcessor;type=.componentType,model=org.apache.tuscany.sca.assembly.ComponentType +org.apache.tuscany.sca.assembly.xml.CompositeDocumentProcessor;type=.composite,model=org.apache.tuscany.sca.assembly.Composite +org.apache.tuscany.sca.definitions.xml.DefinitionsDocumentProcessor;type=/META-INF/definitions.xml,model=org.apache.tuscany.sca.definitions.Definitions +
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver new file mode 100644 index 0000000000..f8e4d5bbd4 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+org.apache.tuscany.sca.assembly.xml.CompositeModelResolver;model=org.apache.tuscany.sca.assembly.Composite
+org.apache.tuscany.sca.assembly.xml.ComponentTypeModelResolver;model=org.apache.tuscany.sca.assembly.ComponentType
+org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver;model=org.apache.tuscany.sca.policy.Intent
+
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions new file mode 100644 index 0000000000..7e75c402e3 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.Definitions @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+META-INF/sca-policy-1.1-intents-definitions-cd04.xml
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.DefinitionsExtensionPoint b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.DefinitionsExtensionPoint new file mode 100644 index 0000000000..45b3512614 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.definitions.xml.DefinitionsExtensionPoint @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+org.apache.tuscany.sca.definitions.xml.DefaultDefinitionsExtensionPoint
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties new file mode 100644 index 0000000000..8ad5f88892 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties @@ -0,0 +1,32 @@ +# +# +# 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. +# +# +NoCompositeNamespace = No namespace found: Composite = {0} +UnexpectedInterfaceElement = Unexpected <interface> element found. It should appear inside a <service> or <reference> element. +UnexpectedBindingElement = Unexpected <binding> element found. It should appear inside a <service> or <reference> element. +UnexpectedImplementationElement = Unexpected <implementation> element found. It should appear inside a <component> element. +PolicyImplValidationException = PolicyValidation exception when processing implementation of component {0} due to {1}. +PolicyServiceValidationException = PolicyValidation exceptions when processing service/reference {0} in {1}. Error is {2} +ContributionReadException = ContributionReadException occured due to : {0} +ContributionResolveException = ContributionResolveException occured due to : {0} +ContributionWriteException = ContributionWriteException occured due to : {0} +XMLStreamException = XMLStreamException occured due to : {0} +DuplicateCompositeName = [ASM_6001] More than one composite with the same name {0} found in contribution {1} +PropertyTypeNotFound = The type {0} specified on property {1} of {2} can't be found in any loaded contribution (makes sure the .xsd file is in a contribution, that the contribution is being loaded and that contribution imports and exports are correct) diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/definitions/xml/definitions-xml-validation-messages.properties b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/definitions/xml/definitions-xml-validation-messages.properties new file mode 100644 index 0000000000..de27c0bd31 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/definitions/xml/definitions-xml-validation-messages.properties @@ -0,0 +1,24 @@ +# +# +# 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. +# +# +ContributionReadException = ContributionReadException occured due to : +PrivilegedActionException = Privileged Action Exception occured due to FilePermission in security policy file: +ImplementationTypeNotFound = [POL50001] An extension to support the implementation type {0} can't be found in the domain +BindingTypeNotFound = An extension to support the binding type {0} can't be found in the domain
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/policy/xml/policy-xml-validation-messages.properties b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/policy/xml/policy-xml-validation-messages.properties new file mode 100644 index 0000000000..08ef6bb5e9 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/policy/xml/policy-xml-validation-messages.properties @@ -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. +# +# +ReferredPolicySetNotFound = Referred PolicySet - {0} not found for PolicySet - {1} +MappedIntentNotFound = Mapped Intent - {0} not found for PolicySet {1} +ProvidedIntentNotFound = Provided Intent - {0} not found for PolicySet {1} +UnableToMapPolicies = Unable to map policies for default qualifier in IntentMap for - {0} in policy set - {1} +IntentMapDoesNotMatch = Intent provided by IntentMap {0} does not match parent qualifier {1} in policyset - {2} +IntentNotSpecified = [POL30021] Intent Map provides for Intent not specified as provided by parent PolicySet - {0} +ContrainsAttributeMissing = Constrains attribute missing from Policy Intent Definition {0} +RequiredIntentNotFound = [POL30015] Required Intent - {0} not found for ProfileIntent {1} +QualifiableIntentNotFound = Qualifiable Intent - {0} not found for QualifiedIntent {1} +ErrorInPolicyIntentDefinition = Error in PolicyIntent Definition - {0} {1} +ExcludedIntentNotFound = [POL30016] Excluded Intent {0} not found for intent {1} +UnrecognizedIntentAttachPointType = Unrecognized IntentAttachPointType - {0} +RequiredAttributeMissing = Required attribute {0} missing from extension type definition +AlwaysProvidedIntentNotFound = Always Provided Intent - {0} not found for ExtensionType {1} +MayProvideIntentNotFound = May Provide Intent - {0} not found for ExtensionType {1} +ContributionReadException = ContributionReadException occurred due to: {0} +CyclicReferenceFound = Cyclic reference detected in required attributes of ProfileIntents {0} and {1} +IntentNameMissing = Required attribute "name" missing for Intent Definition +PolicySetReferenceNameMissing = Required attribute "name" missing for PolicySetReference in PolicySet : {0} +PolicySetNameMissing = Required attribute "name" missing for PolicySet Definition +PolicySetAppliesToMissing = Required attribute "appliesTo" missing for PolicySet Definition +IntentMapProvidesMissing = Required attribute "provides" missing for IntentMap in PolicySet : {0} +QualifierNameMissing = Required attribute "name" missing for qualifier definition in PolicySet : {0} +ConstrainedTypeNotFound = Unable to find the extension type {0} constrained by intent: {1} +MultipleDefaultQualifiers = [POL30004] Intent {0} has more than one qualifier marked as the default qualifier +QualifierIsNotUnique = [POL30005] The intent {0} has more than one qualifier with the name {1} +ProfileIntentNameWithPeriod = [POL30006] The profile intent name {0} must not have the character "." in it +IntentMapIsNotUnique = [POL30010] The policy set {0} has more than one intent map with the name {1} +IntentMapMissingQualifiers = [POL30020] The policy set {0} intent map {1} has missing qualifiers: {2} The intent map qualifiers must match the provided intent qualifiers. +PolicyLanguageMissmatch = Policy set {0} contains policy expressions from more than on language, languages {1} and {2} found diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessorTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessorTestCase.java new file mode 100644 index 0000000000..3f4a74ba03 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessorTestCase.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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.monitor.Monitor; +import org.junit.BeforeClass; +import org.junit.Test; + +public class CompositeProcessorTestCase { + private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + + private static final String OASIS_COMPOSITE = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" " + + "xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.1\" " + + "targetNamespace=\"http://store\" " + + "name=\"store\">" + + "<component name=\"Catalog\">" + + " <implementation.java class=\"services.FruitsCatalogImpl\"/>" + + "</component>" + + "</composite>"; + + private static final String OSOA_COMPOSITE = + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + + "<composite xmlns=\"http://www.osoa.org/xmlns/sca/1.0\" " + + "xmlns:tuscany=\"http://tuscany.apache.org/xmlns/sca/1.0\" " + + "targetNamespace=\"http://store\" " + + "name=\"store\">" + + "<component name=\"Catalog\">" + + " <implementation.java class=\"services.FruitsCatalogImpl\"/>" + + "</component>" + + "</composite>"; + + private static XMLInputFactory inputFactory; + private static XMLOutputFactory outputFactory; + private static StAXArtifactProcessor<Object> staxProcessor; + private static Monitor monitor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + monitor = context.getMonitor(); + inputFactory = XMLInputFactory.newInstance(); + outputFactory = XMLOutputFactory.newInstance(); + outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); + StAXArtifactProcessorExtensionPoint staxProcessors = + extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory); + } + + @Test + public void testReadOASISSpecVersion() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(OASIS_COMPOSITE)); + Object result = staxProcessor.read(reader, context); + assertNotNull(result); + if( result instanceof Composite) { + Composite composite = (Composite) result; + assertEquals(SCA11_NS, composite.getSpecVersion()); + } + reader.close(); + } + + @Test + public void testReadOSOASpecVersion() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(OSOA_COMPOSITE)); + Object result = staxProcessor.read(reader, context); + assertNotNull(result); + if( result instanceof Composite) { + throw new Exception("Error, unsupported OSOA namespace being parsed as valid !"); + } + reader.close(); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/MultiplicityReadWriteTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/MultiplicityReadWriteTestCase.java new file mode 100644 index 0000000000..0d5e69bd61 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/MultiplicityReadWriteTestCase.java @@ -0,0 +1,88 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Multiplicity; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.junit.Before; +import org.junit.Test; + +/** + * Test writing SCA XML assemblies. + * + * TUSCANY-2662 + * + * @version $Rev$ $Date$ + */ +public class MultiplicityReadWriteTestCase { + private XMLInputFactory inputFactory; + private XMLOutputFactory outputFactory; + private ExtensibleStAXArtifactProcessor staxProcessor; + private ProcessorContext context; + + @Before + public void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + outputFactory = XMLOutputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory); + } + + + @Test + public void testReadWriteComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("Multiplicity.composite"); + Composite composite = staxProcessor.read(is, Composite.class, context); + + verifyComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + bos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + + verifyComposite(composite); + + } + + + private void verifyComposite(Composite composite) { + assertEquals(composite.getComponents().get(0).getReferences().get(0).getMultiplicity(), Multiplicity.ZERO_N); + assertEquals(composite.getReferences().get(0).getMultiplicity(), Multiplicity.ONE_N); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadAllTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadAllTestCase.java new file mode 100644 index 0000000000..155c0c5a47 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadAllTestCase.java @@ -0,0 +1,151 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.InputStream; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; + +import org.apache.tuscany.sca.assembly.Callback; +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.ComponentReference; +import org.apache.tuscany.sca.assembly.ComponentService; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeReference; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.assembly.Property; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.policy.PolicySubject; +import org.junit.BeforeClass; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +/** + * Test reading SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class ReadAllTestCase { + private static StAXArtifactProcessor<Object> staxProcessor; + private static XMLInputFactory inputFactory; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + inputFactory = XMLInputFactory.newInstance(); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null); + } + + @Test + public void testReadComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("TestAllCalculator.composite"); + Composite composite = (Composite)staxProcessor.read(inputFactory.createXMLStreamReader(is), context); + assertNotNull(composite); + assertEquals(composite.getName(), new QName("http://calc", "TestAllCalculator")); + assertTrue(composite.isLocal()); + assertFalse(composite.getAutowire() == Boolean.TRUE); + assertEquals(((PolicySubject)composite).getRequiredIntents().get(0).getName(), new QName("http://test", + "confidentiality")); + assertEquals(((PolicySubject)composite).getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + + Composite include = composite.getIncludes().get(0); + assertEquals(include.getName(), new QName("http://calc", "TestAllDivide")); + + CompositeService calcCompositeService = (CompositeService)composite.getServices().get(0); + assertEquals(calcCompositeService.getName(), "CalculatorService"); + assertTrue(calcCompositeService.getPromotedService().isUnresolved()); + assertEquals(calcCompositeService.getPromotedService().getName(), + "CalculatorService"); + assertEquals(calcCompositeService.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcCompositeService.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + // TODO test operations + Callback calcServiceCallback = calcCompositeService.getCallback(); + assertNotNull(calcServiceCallback); + assertEquals(calcServiceCallback.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcServiceCallback.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + // TODO test operations + + Component calcComponent = composite.getComponents().get(0); + assertEquals(calcComponent.getName(), "CalculatorServiceComponent"); + assertEquals(calcComponent.getAutowire(), Boolean.FALSE); + assertEquals(calcComponent.getRequiredIntents().get(0).getName(), new QName("http://test", + "confidentiality")); + assertEquals(calcComponent.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + + ComponentService calcComponentService = calcComponent.getServices().get(0); + assertEquals(calcComponentService.getName(), "CalculatorService"); + assertEquals(calcComponentService.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcComponentService.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + // TODO test operations + + ComponentReference calcComponentReference = calcComponent.getReferences().get(0); + assertEquals(calcComponentReference.getName(), "addService"); + assertEquals(calcComponentReference.getAutowire(), Boolean.FALSE); + assertEquals(calcComponentReference.isWiredByImpl(), false); + assertEquals(calcComponentReference.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcComponentReference.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + // TODO test operations + + Property property = calcComponent.getProperties().get(0); + assertEquals(property.getName(), "round"); + Document doc = (Document) property.getValue(); + Element element = doc.getDocumentElement(); + String value = element.getTextContent(); + assertEquals(value, "true"); + assertEquals(property.getXSDType(), new QName("http://www.w3.org/2001/XMLSchema", "boolean")); + assertEquals(property.isMany(), false); + + CompositeReference calcCompositeReference = (CompositeReference)composite.getReferences().get(0); + assertEquals(calcCompositeReference.getName(), "MultiplyService"); + assertTrue(calcCompositeReference.getPromotedReferences().get(0).isUnresolved()); + assertEquals(calcCompositeReference.getPromotedReferences().get(0).getName(), + "CalculatorServiceComponent/multiplyService"); + assertEquals(calcCompositeReference.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcCompositeReference.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + // TODO test operations + Callback calcCallback = calcCompositeReference.getCallback(); + assertEquals(calcCompositeReference.getRequiredIntents().get(0).getName(), + new QName("http://test", "confidentiality")); + assertEquals(calcCompositeReference.getPolicySets().get(0).getName(), new QName("http://test", "SecureReliablePolicy")); + assertNotNull(calcCallback); + // TODO test operations + + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadDocumentTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadDocumentTestCase.java new file mode 100644 index 0000000000..473e483d31 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadDocumentTestCase.java @@ -0,0 +1,192 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.net.URI; +import java.net.URL; +import java.util.HashMap; + +import javax.xml.XMLConstants; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.stream.XMLInputFactory; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.ValidatorHandler; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.DefaultValidatingXMLInputFactory; +import org.apache.tuscany.sca.contribution.processor.DefaultValidationSchemaExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ValidationSchemaExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.DefaultFactoryExtensionPoint; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.BeforeClass; +import org.junit.Test; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +/** + * Test reading SCA XML assembly documents. + * + * @version $Rev$ $Date$ + */ +public class ReadDocumentTestCase { + private static final String TUSCANY_11_XSD = "tuscany-sca-1.1.xsd"; + + private static URLArtifactProcessor<Object> documentProcessor; + private static ModelResolver resolver; + private static XMLInputFactory inputFactory; + private static StAXArtifactProcessor<Object> staxProcessor; + private static ValidatorHandler handler; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + URLArtifactProcessorExtensionPoint documentProcessors = + extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + documentProcessor = new ExtensibleURLArtifactProcessor(documentProcessors); + + StAXArtifactProcessorExtensionPoint staxProcessors = + extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + inputFactory = XMLInputFactory.newInstance(); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null); + + resolver = new DefaultModelResolver(); + handler = getValidationHandler(); + + } + + @Test + public void testValidateAssembly() throws Exception { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + URL url = getClass().getResource("Calculator.composite"); + XMLReader reader = parserFactory.newSAXParser().getXMLReader(); + reader.setFeature("http://xml.org/sax/features/namespaces", true); + reader.setContentHandler(handler); + reader.parse(new InputSource(url.openStream())); + + } + + private static ValidatorHandler getValidationHandler() throws SAXException { + SchemaFactory schemaFactory; + try { + schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + schemaFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + } catch (Error e) { + // Some old JDKs don't support XMLSchema validation + return null; + } catch (Exception e) { + // Some old JDKs don't support XMLSchema validation + return null; + } + Schema schema = schemaFactory.newSchema(ReadDocumentTestCase.class.getClassLoader().getResource(TUSCANY_11_XSD)); + ValidatorHandler handler = schema.newValidatorHandler(); + return handler; + } + + @Test + public void testValidateImplementation() throws Exception { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + URL url = getClass().getResource("Calculator.composite"); + XMLReader reader = parserFactory.newSAXParser().getXMLReader(); + reader.setFeature("http://xml.org/sax/features/namespaces", true); + reader.setContentHandler(handler); + reader.parse(new InputSource(url.openStream())); + } + + @Test + public void testReadImplementation() throws Exception { + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); + ValidationSchemaExtensionPoint schemas = new DefaultValidationSchemaExtensionPoint(registry, new HashMap<String, String>()); + schemas.addSchema(getClass().getClassLoader().getResource(TUSCANY_11_XSD).toString()); + XMLInputFactory validatingInputFactory = new DefaultValidatingXMLInputFactory(inputFactory, schemas); + DefaultFactoryExtensionPoint factories = new DefaultFactoryExtensionPoint(registry); + factories.addFactory(validatingInputFactory); + + CompositeDocumentProcessor compositeDocumentProcessor = + new CompositeDocumentProcessor(factories, staxProcessor); + + URL url = getClass().getResource("Calculator.composite"); + URI uri = URI.create("Calculator.composite"); + Composite composite = (Composite)compositeDocumentProcessor.read(null, uri, url, context); + assertNotNull(composite); + } + + @Test + public void testValidateBinding() throws Exception { + SAXParserFactory parserFactory = SAXParserFactory.newInstance(); + URL url = getClass().getResource("RMIBindingTest.composite"); + XMLReader reader = parserFactory.newSAXParser().getXMLReader(); + reader.setFeature("http://xml.org/sax/features/namespaces", true); + reader.setContentHandler(handler); + reader.parse(new InputSource(url.openStream())); + } + + @Test + public void testReadBinding() throws Exception { + + ExtensionPointRegistry registry = new DefaultExtensionPointRegistry(); + ValidationSchemaExtensionPoint schemas = new DefaultValidationSchemaExtensionPoint(registry, new HashMap<String, String>()); + schemas.addSchema(getClass().getClassLoader().getResource(TUSCANY_11_XSD).toString()); + XMLInputFactory validatingInputFactory = new DefaultValidatingXMLInputFactory(inputFactory, schemas); + DefaultFactoryExtensionPoint factories = new DefaultFactoryExtensionPoint(registry); + factories.addFactory(validatingInputFactory); + CompositeDocumentProcessor compositeDocumentProcessor = + new CompositeDocumentProcessor(factories, staxProcessor); + + URL url = getClass().getResource("RMIBindingTest.composite"); + URI uri = URI.create("RMIBindingTest.composite"); + Composite composite = (Composite)compositeDocumentProcessor.read(null, uri, url, context); + assertNotNull(composite); + } + + @Test + public void testResolveComposite() throws Exception { + URL url = getClass().getResource("Calculator.composite"); + URI uri = URI.create("Calculator.composite"); + Composite nestedComposite = (Composite)documentProcessor.read(null, uri, url, context); + assertNotNull(nestedComposite); + resolver.addModel(nestedComposite, context); + + url = getClass().getResource("TestAllCalculator.composite"); + uri = URI.create("TestAllCalculator.composite"); + Composite composite = (Composite)documentProcessor.read(null, uri, url, context); + + documentProcessor.resolve(composite, resolver, context); + + assertEquals(composite.getComponents().get(2).getImplementation(), nestedComposite); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadTestCase.java new file mode 100644 index 0000000000..05d320b211 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadTestCase.java @@ -0,0 +1,85 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertNotNull; + +import java.io.InputStream; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test reading SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class ReadTestCase { + + private static XMLInputFactory inputFactory; + private static StAXArtifactProcessor<Object> staxProcessor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, XMLInputFactory.newInstance(), XMLOutputFactory.newInstance()); + } + + + @Test + public void testReadComponentType() throws Exception { + InputStream is = getClass().getResourceAsStream("CalculatorImpl.componentType"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + assertNotNull(staxProcessor.read(reader, context)); + is.close(); + } + + @Test + public void testReadComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("Calculator.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + assertNotNull(staxProcessor.read(reader, context)); + is.close(); + + } + + @Test + public void testReadCompositeAndWireIt() throws Exception { + InputStream is = getClass().getResourceAsStream("Calculator.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + assertNotNull(staxProcessor.read(reader, context)); + is.close(); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyAttributeTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyAttributeTestCase.java new file mode 100644 index 0000000000..cbe3cfa09c --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyAttributeTestCase.java @@ -0,0 +1,157 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Extension; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.Test; + +/** + * Test reading SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class ReadWriteAnyAttributeTestCase { + + private static final String XML = "<?xml version='1.0' encoding='UTF-8'?>"+ + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" " + + "targetNamespace=\"http://calc\" " + + "name=\"Calculator\">"+ + "<component name=\"AddServiceComponent\" xmlns:test=\"http://test\" test:customAttribute=\"customValue\">"+ + "<implementation.java class=\"calculator.AddServiceImpl\" />"+ + "</component>"+ + "</composite>"; + + private XMLInputFactory inputFactory; + private ExtensibleStAXArtifactProcessor staxProcessor; + private ProcessorContext context; + + /** + * Initialize the test environment + * This takes care to register attribute processors when provided + * + * @param attributeProcessor + * @throws Exception + */ + private void init(StAXAttributeProcessor<?> attributeProcessor) throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + + if(attributeProcessor != null) { + StAXAttributeProcessorExtensionPoint staxAttributeProcessors = extensionPoints.getExtensionPoint(StAXAttributeProcessorExtensionPoint.class); + staxAttributeProcessors.addArtifactProcessor(attributeProcessor); + } + + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, XMLInputFactory.newInstance(), XMLOutputFactory.newInstance()); + } + + /** + * Read and Write a composite that has a extended attribute + * and a particular attribute processor + * @throws Exception + */ + @Test + public void testReadWriteCompositeWithAttributeProcessor() throws Exception { + init(new TestAttributeProcessor()); + + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(XML)); + Composite composite = (Composite) staxProcessor.read(reader, context); + assertNotNull(composite); + reader.close(); + + verifyComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + + // used for debug comparison + // System.out.println(XML); + // System.out.println(bos.toString()); + + //assertEquals(XML, bos.toString()); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + verifyComposite(composite); + } + + /** + * Read and Write a composite that has a extended attribute + * but no particular processor for it + * @throws Exception + */ + @Test + public void testDefaultReadWriteComposite() throws Exception { + init(null); + + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(XML)); + Composite composite = (Composite) staxProcessor.read(reader, context); + assertNotNull(composite); + reader.close(); + + verifyComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + + // used for debug comparison + // System.out.println(XML); + // System.out.println(bos.toString()); + + // assertEquals(XML, bos.toString()); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + verifyComposite(composite); + } + + private void verifyComposite(Composite c) { + assertEquals("Calculator", c.getName().getLocalPart()); + assertEquals(1, c.getComponents().size()); + Component component = c.getComponents().get(0); + assertEquals("AddServiceComponent", component.getName()); + assertEquals(1, component.getAttributeExtensions().size()); + Extension extension = component.getAttributeExtensions().get(0); + assertEquals("customAttribute", extension.getQName().getLocalPart()); + assertEquals("http://test", extension.getQName().getNamespaceURI()); + assertEquals("customValue", extension.getValue()); + } +}
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyElementTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyElementTestCase.java new file mode 100644 index 0000000000..ddbd70e567 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteAnyElementTestCase.java @@ -0,0 +1,205 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.StringReader; + +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.Extension; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.junit.After; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; + +public class ReadWriteAnyElementTestCase { + private static final String XML_RECURSIVE_EXTENDED_ELEMENT = + "<?xml version='1.0' encoding='UTF-8'?>" + + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" targetNamespace=\"http://temp\" name=\"RecursiveExtendedElement\">" + + "<unknownElement>" + + "<subUnknownElement1 attribute=\"anyAttribute\" />" + + "<subUnknownElement2 />" + + "</unknownElement>" + + "</composite>"; + + private static final String XML_UNKNOWN_IMPL = + "<?xml version='1.0' encoding='UTF-8'?>" + + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" targetNamespace=\"http://temp\" name=\"aaaa\" autowire=\"false\">" + + "<component name=\"unknownImpl\">" + + "<implementation.unknown class=\"raymond\" />" + + "<service name=\"service\">" + + "<binding.ws />" + + "</service>" + + "</component>" + + "</composite>"; + + private static final String XML_UNKNOWN_IMPL_WITH_INVALID_ATTRIBUTE = + "<?xml version='1.0' encoding='UTF-8'?>" + + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" targetNamespace=\"http://temp\" name=\"aaaa\" autowire=\"false\">" + + "<component name=\"unknownImpl\">" + + "<implementation.unknown class=\"raymond\" />" + + "<service name=\"service\" requires=\"\">" + + "<binding.ws />" + + "</service>" + + "</component>" + + "</composite>"; + + + private ValidatingXMLInputFactory inputFactory; + private ExtensibleStAXArtifactProcessor staxProcessor; + private ProcessorContext context; + + @Before + public void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class); + + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, XMLOutputFactory.newInstance()); + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testReadWriteExtendedRecursiveElement() throws Exception { + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(XML_RECURSIVE_EXTENDED_ELEMENT)); + ValidatingXMLInputFactory.setMonitor(reader, context.getMonitor()); + Composite composite = (Composite)staxProcessor.read(reader, context); + assertNotNull(composite); + reader.close(); + + verifyExtendedElementComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + + // used for debug comparison +// System.out.println(XML_RECURSIVE_EXTENDED_ELEMENT); +// System.out.println(bos.toString()); + + // assertEquals(XML_RECURSIVE_EXTENDED_ELEMENT, bos.toString()); + bos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + verifyExtendedElementComposite(composite); + } + + private void verifyExtendedElementComposite(Composite composite) throws XMLStreamException { + + assertEquals("RecursiveExtendedElement", composite.getName().getLocalPart()); + assertEquals(1, composite.getExtensions().size()); + Extension ext1 = (Extension) composite.getExtensions().get(0); + assertEquals("unknownElement", ext1.getQName().getLocalPart()); + assertEquals("http://docs.oasis-open.org/ns/opencsa/sca/200912", ext1.getQName().getNamespaceURI()); + + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader((String)ext1.getValue())); + reader.next(); + assertEquals("unknownElement", reader.getLocalName()); + reader.next(); + assertEquals("subUnknownElement1", reader.getLocalName()); + assertEquals(1, reader.getAttributeCount()); + assertEquals("attribute", reader.getAttributeLocalName(0)); + assertEquals("anyAttribute", reader.getAttributeValue(0)); + + reader.close(); + + } + + @Test + public void testReadWriteUnknwonImpl() throws Exception { + + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(XML_UNKNOWN_IMPL)); + Composite composite = (Composite)staxProcessor.read(reader, context); + assertNotNull(composite); + reader.close(); + + verifyUnknownImplComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + + // used for debug comparison + // System.out.println(XML_UNKNOWN_IMPL); + // System.out.println(bos.toString()); + + // assertEquals(XML_UNKNOWN_IMPL, bos.toString()); + bos.close(); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + verifyUnknownImplComposite(composite); + } + + private void verifyUnknownImplComposite(Composite composite) { + + assertEquals("aaaa", composite.getName().getLocalPart()); + assertEquals(1, composite.getComponents().size()); + Component component = composite.getComponents().get(0); + assertEquals("unknownImpl", component.getName()); + assertEquals(1, component.getServices().size()); + assertEquals("service", component.getServices().get(0).getName()); + assertEquals(1, component.getExtensions().size()); + Extension ext = (Extension) component.getExtensions().get(0); + assertEquals("http://docs.oasis-open.org/ns/opencsa/sca/200912", ext.getQName().getNamespaceURI()); + assertEquals("implementation.unknown", ext.getQName().getLocalPart()); + + } + + // @Test + @Ignore() + public void testReadWriteInvalidAttribute() throws Exception { + + XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(XML_UNKNOWN_IMPL_WITH_INVALID_ATTRIBUTE)); + Composite composite = (Composite)staxProcessor.read(reader, context); + assertNotNull(composite); + reader.close(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + + // used for debug comparison + // System.out.println(XML_UNKNOWN_IMPL); + // System.out.println(bos.toString()); + + assertEquals(XML_UNKNOWN_IMPL, bos.toString()); + bos.close(); + } +}
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteLocalCompositeTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteLocalCompositeTestCase.java new file mode 100644 index 0000000000..b3ccdd8201 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ReadWriteLocalCompositeTestCase.java @@ -0,0 +1,109 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + + +/** + * Test reading SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class ReadWriteLocalCompositeTestCase { + + private XMLInputFactory inputFactory; + private ExtensibleStAXArtifactProcessor staxProcessor; + private ProcessorContext context; + + private static final String LOCAL_COMPOSITE_XML = "<?xml version='1.0' encoding='UTF-8'?>"+ + "<composite xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" targetNamespace=\"http://localcalc\" name=\"LocalCalculator\" local=\"true\">"+ + "</composite>"; + + @Before + public void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + + StAXAttributeProcessorExtensionPoint staxAttributeProcessors = extensionPoints.getExtensionPoint(StAXAttributeProcessorExtensionPoint.class); + staxAttributeProcessors.addArtifactProcessor(new TestAttributeProcessor()); + + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, XMLInputFactory.newInstance(), XMLOutputFactory.newInstance()); + } + + @After + public void tearDown() throws Exception { + + } + + @Test + public void testReadComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("local.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite composite = (Composite) staxProcessor.read(reader, context); + assertNotNull(composite); + assertTrue(composite.isLocal()); + is.close(); + } + + @Test + public void testWriteComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("local.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite composite = (Composite) staxProcessor.read(reader, context); + assertNotNull(composite); + assertTrue(composite.isLocal()); + is.close(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + System.out.println(bos.toString()); + + // assertEquals(LOCAL_COMPOSITE_XML, bos.toString()); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + assertNotNull(composite); + assertTrue(composite.isLocal()); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolvePolicyTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolvePolicyTestCase.java new file mode 100644 index 0000000000..df588e3504 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolvePolicyTestCase.java @@ -0,0 +1,143 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.net.URI; +import java.net.URL; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.ExtensibleURLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.policy.PolicySubject; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test reading SCA XML assembly documents. + * + * @version $Rev$ $Date$ + */ +public class ResolvePolicyTestCase { + + private static URLArtifactProcessor<Object> documentProcessor; + private static ModelResolver resolver; + private static URLArtifactProcessor<Definitions> policyDefinitionsProcessor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + resolver = new DefaultModelResolver(); + + URLArtifactProcessorExtensionPoint documentProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + documentProcessor = new ExtensibleURLArtifactProcessor(documentProcessors); + policyDefinitionsProcessor = documentProcessors.getProcessor(Definitions.class); + + // Create StAX processors + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessors.addArtifactProcessor(new TestPolicyProcessor()); + } + + private void preResolvePolicyTests(Composite composite) { + assertNull(((PolicySubject)composite).getRequiredIntents().get(0).getDescription()); + assertTrue(((PolicySubject)composite).getPolicySets().get(0).getProvidedIntents().isEmpty()); + + assertNull(composite.getServices().get(0).getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getServices().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNull(composite.getServices().get(0).getCallback().getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getServices().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().isEmpty()); + + assertNull(composite.getComponents().get(0).getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getComponents().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNull(composite.getComponents().get(0).getServices().get(0).getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getComponents().get(0).getServices().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNull(composite.getComponents().get(0).getReferences().get(0).getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getComponents().get(0).getReferences().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + + assertNull(composite.getReferences().get(0).getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getReferences().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNull(composite.getReferences().get(0).getCallback().getRequiredIntents().get(0).getDescription()); + assertTrue(composite.getReferences().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().isEmpty()); + } + + private void postResolvePolicyTests(Composite composite) { + assertNotNull(((PolicySubject)composite).getRequiredIntents().get(0).getDescription()); + assertFalse(((PolicySubject)composite).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(((PolicySubject)composite).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + + assertNotNull(composite.getServices().get(0).getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getServices().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getServices().get(0).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + assertNotNull(composite.getServices().get(0).getCallback().getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getServices().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getServices().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + + assertNotNull(composite.getComponents().get(0).getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getComponents().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getComponents().get(0).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + assertNotNull(composite.getComponents().get(0).getServices().get(0).getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getComponents().get(0).getServices().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getComponents().get(0).getServices().get(0).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + assertNotNull(composite.getComponents().get(0).getReferences().get(0).getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getComponents().get(0).getReferences().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getComponents().get(0).getReferences().get(0).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + + assertNotNull(composite.getReferences().get(0).getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getReferences().get(0).getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getReferences().get(0).getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + assertNotNull(composite.getReferences().get(0).getCallback().getRequiredIntents().get(0).getDescription()); + assertFalse(composite.getReferences().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().isEmpty()); + assertNotNull(composite.getReferences().get(0).getCallback().getPolicySets().get(0).getProvidedIntents().get(1).getDescription()); + + + } + + @Test + public void testResolveComposite() throws Exception { + URL url = getClass().getResource("Calculator.composite"); + URI uri = URI.create("Calculator.composite"); + Composite nestedComposite = (Composite)documentProcessor.read(null, uri, url, context); + assertNotNull(nestedComposite); + resolver.addModel(nestedComposite, context); + + url = getClass().getResource("TestAllCalculator.composite"); + uri = URI.create("TestAllCalculator.composite"); + Composite composite = (Composite)documentProcessor.read(null, uri, url, context); + + documentProcessor.resolve(composite, resolver, context); + + assertEquals(composite.getComponents().get(2).getImplementation(), nestedComposite); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolveTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolveTestCase.java new file mode 100644 index 0000000000..28e679da4a --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/ResolveTestCase.java @@ -0,0 +1,82 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.InputStream; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.junit.BeforeClass; +import org.junit.Test; + + +/** + * Test resolving SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class ResolveTestCase { + + private static XMLInputFactory inputFactory; + private static StAXArtifactProcessorExtensionPoint staxProcessors; + private static ModelResolver resolver; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + resolver = new DefaultModelResolver(); + } + + @Test + public void testResolveComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("Calculator.composite"); + StAXArtifactProcessor<Composite> compositeReader = staxProcessors.getProcessor(Composite.class); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite nestedComposite = compositeReader.read(reader, context); + is.close(); + assertNotNull(nestedComposite); + resolver.addModel(nestedComposite, context); + + is = getClass().getResourceAsStream("TestAllCalculator.composite"); + reader = inputFactory.createXMLStreamReader(is); + Composite composite = compositeReader.read(reader, context); + is.close(); + + compositeReader.resolve(composite, resolver, context); + + assertEquals(composite.getComponents().get(2).getImplementation(), nestedComposite); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/StripURISpacesTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/StripURISpacesTestCase.java new file mode 100644 index 0000000000..8d9bc72389 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/StripURISpacesTestCase.java @@ -0,0 +1,78 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertEquals; + +import java.io.InputStream; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.CompositeService; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test reading SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class StripURISpacesTestCase { + + private static XMLInputFactory inputFactory; + private static StAXArtifactProcessor<Object> staxProcessor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, XMLInputFactory.newInstance(), XMLOutputFactory.newInstance()); + } + + + + @Test + public void testReadComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("CalculatorURISpaces.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite composite = (Composite)staxProcessor.read(reader, context); + assertNotNull(composite); + is.close(); + + CompositeService compositeService = (CompositeService)composite.getServices().get(0); + assertNotNull(compositeService); + + // Promoted component name with leading and training spaces removed + assertEquals("CalculatorServiceComponent", compositeService.getPromotedComponent().getName()); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestAttributeProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestAttributeProcessor.java new file mode 100644 index 0000000000..b6f4c11ac2 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestAttributeProcessor.java @@ -0,0 +1,62 @@ +/* + * 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.assembly.xml; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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.StAXAttributeProcessor; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; + +/** + * A Policy Processor used for testing. + * + * @version $Rev$ $Date$ + */ +public class TestAttributeProcessor extends BaseStAXArtifactProcessor implements StAXAttributeProcessor<String> { + private static final QName ATTRIBUTE = new QName("http://test", "customAttribute"); + + public QName getArtifactType() { + return ATTRIBUTE; + } + + public String read(QName attributeName, XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException { + return reader.getAttributeValue(attributeName.getNamespaceURI(), attributeName.getLocalPart()); + } + + public void write(String value, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + writer.setPrefix(ATTRIBUTE.getPrefix(), ATTRIBUTE.getNamespaceURI()); + writer.writeAttribute(ATTRIBUTE.getLocalPart(), value); + } + + public Class<String> getModelType() { + return String.class; + } + + public void resolve(String arg0, ModelResolver arg1, ProcessorContext context) throws ContributionResolveException { + + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestPolicyProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestPolicyProcessor.java new file mode 100644 index 0000000000..cfec8dee7a --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestPolicyProcessor.java @@ -0,0 +1,83 @@ +/* + * 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.assembly.xml; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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.policy.PolicyExpression; + +/** + * A PolicyExpression Processor used for testing. + * + * @version $Rev$ $Date$ + */ +public class TestPolicyProcessor implements StAXArtifactProcessor<PolicyExpression> { + + public QName getArtifactType() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public PolicyExpression read(XMLStreamReader arg0, ProcessorContext context) throws ContributionReadException, XMLStreamException { + return new MockPolicyImplOne(); + } + + public void write(PolicyExpression arg0, XMLStreamWriter arg1, ProcessorContext context) throws ContributionWriteException, + XMLStreamException { + } + + public Class<PolicyExpression> getModelType() { + return PolicyExpression.class; + } + + public void resolve(PolicyExpression arg0, ModelResolver arg1, ProcessorContext context) throws ContributionResolveException { + } + + public class MockPolicyImplOne implements PolicyExpression { + public <T> T getPolicy() { + return null; + } + + public void setName(QName name) { + } + + public <T> void setPolicy(T policy) { + } + + public QName getName() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public boolean isUnresolved() { + return false; + } + + public void setUnresolved(boolean unresolved) { + } + + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingFactoryImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingFactoryImpl.java new file mode 100644 index 0000000000..5e3fa15b69 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingFactoryImpl.java @@ -0,0 +1,35 @@ +/* + * 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.assembly.xml; + +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.assembly.SCABindingFactory; + +/** + * A factory for the SCA binding model. + * + * @version $Rev$ $Date$ + */ +public class TestSCABindingFactoryImpl implements SCABindingFactory { + public SCABinding createSCABinding() { + return new TestSCABindingImpl(); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingImpl.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingImpl.java new file mode 100644 index 0000000000..f83a2ebd14 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/TestSCABindingImpl.java @@ -0,0 +1,162 @@ +/* + * 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.assembly.xml; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.OperationSelector; +import org.apache.tuscany.sca.assembly.SCABinding; +import org.apache.tuscany.sca.assembly.WireFormat; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.PolicySubject; + +/** + * A test cheel for the SCA binding. + * + * @version $Rev$ $Date$ + */ +public class TestSCABindingImpl implements SCABinding, PolicySubject { + private String name; + private String uri; + private List<Object> extensions = new ArrayList<Object>(); + + private List<Intent> requiredIntents = new ArrayList<Intent>(); + private List<PolicySet> policySets = new ArrayList<PolicySet>(); + private ExtensionType bindingType = new TestSCABindingType(); + + /** + * Constructs a new SCA binding. + */ + protected TestSCABindingImpl() { + } + + public String getName() { + return name; + } + + public String getURI() { + return uri; + } + + public void setName(String name) { + this.name = name; + } + + public void setURI(String uri) { + this.uri = uri; + } + + public List<Object> getExtensions() { + return extensions; + } + + public boolean isUnresolved() { + return false; + } + + public void setUnresolved(boolean unresolved) { + } + + /** + * @see java.lang.Object#clone() + */ + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public List<PolicySet> getPolicySets() { + // TODO Auto-generated method stub + return policySets; + } + + public List<Intent> getRequiredIntents() { + // TODO Auto-generated method stub + return requiredIntents; + } + + public ExtensionType getExtensionType() { + // TODO Auto-generated method stub + return bindingType; + } + + public void setExtensionType(ExtensionType type) { + this.bindingType = type; + } + + public QName getType() { + return TYPE; + } + + private class TestSCABindingType implements ExtensionType { + private QName name = new QName("http://docs.oasis-open.org/ns/opencsa/sca/200912","binding"); + public QName getBaseType() { + return BINDING_BASE; + } + + public QName getType() { + return name; + } + + public void setType(QName type) { + } + + public List<Intent> getAlwaysProvidedIntents() { + return Collections.emptyList(); + } + + public List<Intent> getMayProvidedIntents() { + return Collections.emptyList(); + } + + public boolean isUnresolved() { + return false; + } + + public void setUnresolved(boolean unresolved) { + } + } + + public WireFormat getRequestWireFormat() { + return null; + } + + public void setRequestWireFormat(WireFormat wireFormat) { + } + + public WireFormat getResponseWireFormat() { + return null; + } + + public void setResponseWireFormat(WireFormat wireFormat) { + } + + public OperationSelector getOperationSelector() { + return null; + } + + public void setOperationSelector(OperationSelector operationSelector) { + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WireTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WireTestCase.java new file mode 100644 index 0000000000..543aaf9893 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WireTestCase.java @@ -0,0 +1,109 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.SCABindingFactory; +import org.apache.tuscany.sca.contribution.processor.ContributionReadException; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.definitions.Definitions; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test the wiring of SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class WireTestCase { + + private static XMLInputFactory inputFactory; + private static StAXArtifactProcessor<Object> staxProcessor; + private static ModelResolver resolver; + private static URLArtifactProcessor<Definitions> policyDefinitionsProcessor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null); + resolver = new DefaultModelResolver(); + + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + SCABindingFactory scaBindingFactory = new TestSCABindingFactoryImpl(); + modelFactories.addFactory(scaBindingFactory); + + URLArtifactProcessorExtensionPoint documentProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + policyDefinitionsProcessor = documentProcessors.getProcessor(Definitions.class); + } + + @Test + public void testResolveComposite() throws Exception { + Composite nestedComposite = readComposite("Calculator.composite"); + assertNotNull(nestedComposite); + resolver.addModel(nestedComposite, context); + + Composite composite = readComposite("TestAllCalculator.composite"); + + URL url = getClass().getResource("test_definitions.xml"); + URI uri = URI.create("test_definitions.xml"); + Definitions scaDefns = (Definitions)policyDefinitionsProcessor.read(null, uri, url, context); + assertNotNull(scaDefns); + + policyDefinitionsProcessor.resolve(scaDefns, resolver, context); + + staxProcessor.resolve(composite, resolver, context); + + assertEquals(composite.getComponents().get(2).getImplementation(), nestedComposite); + } + + private Composite readComposite(String resource) throws XMLStreamException, ContributionReadException, IOException { + InputStream is = getClass().getResourceAsStream(resource); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite composite = (Composite)staxProcessor.read(reader, context); + is.close(); + return composite; + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteAllTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteAllTestCase.java new file mode 100644 index 0000000000..11d146e55e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteAllTestCase.java @@ -0,0 +1,137 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URI; +import java.net.URL; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; + +import org.apache.tuscany.sca.assembly.ComponentType; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.assembly.SCABindingFactory; +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.definitions.Definitions; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test writing SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class WriteAllTestCase { + private static XMLInputFactory inputFactory; + private static XMLOutputFactory outputFactory; + private static ExtensibleStAXArtifactProcessor staxProcessor; + private static ModelResolver resolver; + private static URLArtifactProcessor<Definitions> policyDefinitionsProcessor; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + inputFactory = XMLInputFactory.newInstance(); + outputFactory = XMLOutputFactory.newInstance(); + StAXArtifactProcessorExtensionPoint staxProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory); + resolver = new DefaultModelResolver(); + + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + SCABindingFactory scaBindingFactory = new TestSCABindingFactoryImpl(); + modelFactories.addFactory(scaBindingFactory); + + URLArtifactProcessorExtensionPoint documentProcessors = extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + policyDefinitionsProcessor = documentProcessors.getProcessor(Definitions.class); + } + + @Test + public void testReadWriteComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("TestAllCalculator.composite"); + Composite composite = staxProcessor.read(is, Composite.class, context); + + verifyComposite(composite); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + bos.close(); + System.out.println("Writtent ouput is:\n" + bos); + + ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); + composite = staxProcessor.read(bis, Composite.class, context); + + verifyComposite(composite); + + } + + @Test + public void testReadWireWriteComposite() throws Exception { + InputStream is = getClass().getResourceAsStream("TestAllCalculator.composite"); + Composite composite = staxProcessor.read(is, Composite.class, context); + + URL url = getClass().getResource("test_definitions.xml"); + URI uri = URI.create("test_definitions.xml"); + Definitions scaDefns = (Definitions)policyDefinitionsProcessor.read(null, uri, url, context); + assertNotNull(scaDefns); + policyDefinitionsProcessor.resolve(scaDefns, resolver, context); + + staxProcessor.resolve(composite, resolver, context); + // compositeBuilder.build(composite, null, monitor); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(composite, bos, context); + } + + @Test + public void testReadWriteComponentType() throws Exception { + InputStream is = getClass().getResourceAsStream("CalculatorImpl.componentType"); + ComponentType componentType = staxProcessor.read(is, ComponentType.class, context); + staxProcessor.resolve(componentType, resolver, context); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + staxProcessor.write(componentType, bos, context); + } + + + private void verifyComposite(Composite composite) { + assertEquals(composite.getProperties().get(0).getName(),"prop1"); + assertEquals(composite.getProperties().get(0).isMany(), true); + assertEquals(composite.getProperties().get(1).getName(),"prop2"); + assertEquals(composite.getProperties().get(1).isMustSupply(), true); + assertEquals(composite.getProperties().get(0).getXSDType(), new QName("http://foo", "MyComplexType")); + assertEquals(composite.getProperties().get(1).getXSDElement(), new QName("http://foo", "MyComplexPropertyValue1")); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteNamespacesTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteNamespacesTestCase.java new file mode 100644 index 0000000000..6371e87040 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/assembly/xml/WriteNamespacesTestCase.java @@ -0,0 +1,100 @@ +/* + * 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.assembly.xml; + +import static org.junit.Assert.assertEquals; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.apache.tuscany.sca.assembly.Component; +import org.apache.tuscany.sca.assembly.Composite; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test writing SCA XML assemblies. + * + * @version $Rev$ $Date$ + */ +public class WriteNamespacesTestCase { + private static StAXArtifactProcessor<Composite> compositeProcessor; + private static XMLOutputFactory outputFactory; + private static XMLInputFactory inputFactory; + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + + FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + outputFactory = modelFactories.getFactory(XMLOutputFactory.class); + //outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE); + inputFactory = modelFactories.getFactory(XMLInputFactory.class); + + StAXArtifactProcessorExtensionPoint artifactProcessors = extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + compositeProcessor = artifactProcessors.getProcessor(Composite.class); + } + + @Test + public void testReadWriteComposite() throws Exception { + + // Read + InputStream is = getClass().getResourceAsStream("NestedCalculator.composite"); + XMLStreamReader reader = inputFactory.createXMLStreamReader(is); + Composite composite = compositeProcessor.read(reader, context); + Component component = composite.getComponents().get(0); + Composite implementation = (Composite)component.getImplementation(); + QName qname = implementation.getName(); + + // Write + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + XMLStreamWriter writer = outputFactory.createXMLStreamWriter(bos); + compositeProcessor.write(composite, writer, context); + writer.close(); + System.out.println("Writtent ouput is:\n" + bos); + + // Read again + is = new ByteArrayInputStream(bos.toByteArray()); + reader = inputFactory.createXMLStreamReader(is); + composite = compositeProcessor.read(reader, context); + + // Compare + component = composite.getComponents().get(0); + implementation = (Composite)component.getImplementation(); + + assertEquals(qname, implementation.getName()); + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/MockPolicy.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/MockPolicy.java new file mode 100644 index 0000000000..58e6e534b9 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/MockPolicy.java @@ -0,0 +1,39 @@ +/* + * 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.definitions.xml; + +import javax.xml.namespace.QName; + +/** + * Mocked Policy + */ +public class MockPolicy { + public QName getName() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public boolean isUnresolved() { + return false; + } + + public void setUnresolved(boolean unresolved) { + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/ReadDocumentTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/ReadDocumentTestCase.java new file mode 100644 index 0000000000..f99b81f73f --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/ReadDocumentTestCase.java @@ -0,0 +1,230 @@ +/* + * 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.definitions.xml; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.net.URI; +import java.net.URL; +import java.util.Hashtable; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.definitions.Definitions; +import org.apache.tuscany.sca.policy.BindingType; +import org.apache.tuscany.sca.policy.ImplementationType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentMap; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.Qualifier; +import org.junit.BeforeClass; +import org.junit.Test; + +/** + * Test reading SCA XML assembly documents. + * + * @version $Rev$ $Date$ + */ +public class ReadDocumentTestCase { + + private static URLArtifactProcessor<Definitions> policyDefinitionsProcessor = null; + private static Definitions definitions; + private static Map<QName, Intent> intentTable = new Hashtable<QName, Intent>(); + private static Map<QName, PolicySet> policySetTable = new Hashtable<QName, PolicySet>(); + private static Map<QName, BindingType> bindingTypesTable = new Hashtable<QName, BindingType>(); + private static Map<QName, ImplementationType> implTypesTable = new Hashtable<QName, ImplementationType>(); + public static final String scaNamespace = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + public static final String namespace = "http://test"; + + private static final QName secureWsPolicy = new QName(namespace, "SecureWSPolicy"); + private static final QName confidentiality = new QName(namespace, "confidentiality"); + private static final QName integrity = new QName(namespace, "integrity"); + private static final QName messageProtection = new QName(namespace, "messageProtection"); + private static final QName confidentiality_transport = new QName(namespace, "confidentiality.transport"); + private static final QName confidentiality_message = new QName(namespace, "confidentiality.message"); + private static final QName secureReliablePolicy = new QName(namespace, "SecureReliablePolicy"); + private static final QName secureMessagingPolicies = new QName(namespace, "SecureMessagingPolicies"); + private static final QName securityPolicy = new QName(namespace, "SecurityPolicy"); + private static final QName basicAuthMsgProtSecurity = new QName(namespace, "BasicAuthMsgProtSecurity"); + private static final QName wsBinding = new QName(scaNamespace, "binding.ws"); + private static final QName javaImpl = new QName(scaNamespace, "implementation.java"); + private static ProcessorContext context; + + @BeforeClass + public static void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + context = new ProcessorContext(extensionPoints); + + // Create StAX processors + StAXArtifactProcessorExtensionPoint staxProcessors = + extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessors.addArtifactProcessor(new TestPolicyProcessor()); + + URLArtifactProcessorExtensionPoint documentProcessors = + extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class); + policyDefinitionsProcessor = documentProcessors.getProcessor(Definitions.class); + + URL url = ReadDocumentTestCase.class.getResource("test_definitions.xml"); + URI uri = URI.create("test_definitions.xml"); + definitions = policyDefinitionsProcessor.read(null, uri, url, context); + + for (Intent intent : definitions.getIntents()) { + intentTable.put(intent.getName(), intent); + for (Intent i : intent.getQualifiedIntents()) { + intentTable.put(i.getName(), i); + } + } + + for (PolicySet policySet : definitions.getPolicySets()) { + policySetTable.put(policySet.getName(), policySet); + } + + for (BindingType bindingType : definitions.getBindingTypes()) { + bindingTypesTable.put(bindingType.getType(), bindingType); + } + + for (ImplementationType implType : definitions.getImplementationTypes()) { + implTypesTable.put(implType.getType(), implType); + } + } + + @Test + public void testReadSCADefinitions() throws Exception { + assertNotNull(definitions); + + assertNotNull(intentTable.get(confidentiality)); + assertNotNull(intentTable.get(messageProtection)); + assertNotNull(intentTable.get(confidentiality_transport)); + assertTrue(intentTable.get(confidentiality).getDescription().length() > 0); + + assertNotNull(policySetTable.get(secureReliablePolicy)); + assertTrue(policySetTable.get(secureReliablePolicy).getProvidedIntents().size() == 2); + assertTrue(policySetTable.get(secureReliablePolicy).getPolicies().size() == 2); + + assertNotNull(policySetTable.get(secureMessagingPolicies)); + assertEquals(2, policySetTable.get(secureMessagingPolicies).getIntentMaps().get(0).getQualifiers().size()); + //assertTrue(policySetTable.get(secureWsPolicy).getPolicies().get(0) instanceof org.apache.neethi.Policy); + + assertEquals(bindingTypesTable.size(), 1); + assertNotNull(bindingTypesTable.get(wsBinding)); + assertEquals(implTypesTable.size(), 1); + assertNotNull(implTypesTable.get(javaImpl)); + } + + private boolean isRealizedBy(PolicySet policySet, Intent intent) { + if (intent.getName().getLocalPart().indexOf('.') == -1) { + return policySet.getProvidedIntents().contains(intent); + } + for (IntentMap map : policySet.getIntentMaps()) { + for (Qualifier q : map.getQualifiers()) { + if (q.getIntent().equals(intent)) { + return true; + } + } + } + return false; + } + + private int getNumberOfQualifiedPolicies(PolicySet policySet) { + int count = 0; + for(IntentMap intentMap: policySet.getIntentMaps()) { + for(Qualifier q: intentMap.getQualifiers()) { + count += q.getPolicies().size(); + } + } + return count; + } + + @Test + public void testResolveSCADefinitions() throws Exception { + Intent i1 = intentTable.get(messageProtection); + assertTrue(!i1.getRequiredIntents().isEmpty()); + assertNull(i1.getRequiredIntents().get(0).getDescription()); + + QName confidentiality_transport = new QName(namespace, "confidentiality.transport"); + Intent i2 = intentTable.get(confidentiality_transport); + assertNotNull(i2.getQualifiableIntent()); + + PolicySet secureReliablePolicySet = policySetTable.get(secureReliablePolicy); + PolicySet secureMessagingPolicySet = policySetTable.get(secureMessagingPolicies); + PolicySet securityPolicySet = policySetTable.get(securityPolicy); + + assertEquals(secureReliablePolicySet.getProvidedIntents().get(1).getName(), integrity); + assertNull(secureReliablePolicySet.getProvidedIntents().get(1).getDescription()); + assertTrue(secureMessagingPolicySet.isUnresolved()); + assertEquals(3, getNumberOfQualifiedPolicies(securityPolicySet)); + + //testing to ensure that inclusion of referred policy sets has not happened + PolicySet basicAuthMsgProtSecurityPolicySet = policySetTable.get(basicAuthMsgProtSecurity); + assertTrue(basicAuthMsgProtSecurityPolicySet.getPolicies().isEmpty()); + assertTrue(basicAuthMsgProtSecurityPolicySet.getIntentMaps().isEmpty()); + + BindingType wsBindingType = bindingTypesTable.get(wsBinding); + assertNull(wsBindingType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNull(wsBindingType.getMayProvidedIntents().get(0).getDescription()); + + ImplementationType javaImplType = implTypesTable.get(javaImpl); + assertNull(javaImplType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNull(javaImplType.getMayProvidedIntents().get(0).getDescription()); + + ModelResolver resolver = new DefaultModelResolver(); + policyDefinitionsProcessor.resolve(definitions, resolver, context); + //builder.build(scaDefinitions); + + //testing if policy intents have been linked have property been linked up + assertNotNull(i1.getRequiredIntents().get(0).getDescription()); + // assertNotNull(i2.getQualifiableIntent().getDescription()); + assertEquals(secureReliablePolicySet.getProvidedIntents().get(1).getName(), integrity); + assertNotNull(secureReliablePolicySet.getProvidedIntents().get(1).getDescription()); + + //testing if policysets have been properly linked up with intents + assertFalse(secureMessagingPolicySet.isUnresolved()); + assertTrue(isRealizedBy(secureMessagingPolicySet, intentTable.get(confidentiality))); + assertTrue(isRealizedBy(secureMessagingPolicySet, intentTable.get(confidentiality_transport))); + + //testing if intent maps have been properly mapped to policies + assertFalse(securityPolicySet.isUnresolved()); + assertTrue(isRealizedBy(securityPolicySet, intentTable.get(confidentiality))); + assertTrue(isRealizedBy(securityPolicySet, intentTable.get(confidentiality_message))); + + //testing for inclusion of referred policysets + assertFalse(basicAuthMsgProtSecurityPolicySet.getPolicies().isEmpty()); + assertFalse(basicAuthMsgProtSecurityPolicySet.getIntentMaps().get(0).getQualifiers().isEmpty()); + assertTrue(isRealizedBy(basicAuthMsgProtSecurityPolicySet, intentTable.get(confidentiality_transport))); + + assertNotNull(wsBindingType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNotNull(wsBindingType.getMayProvidedIntents().get(0).getDescription()); + + assertNotNull(javaImplType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNotNull(javaImplType.getMayProvidedIntents().get(0).getDescription()); + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/TestPolicyProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/TestPolicyProcessor.java new file mode 100644 index 0000000000..a148e33029 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/definitions/xml/TestPolicyProcessor.java @@ -0,0 +1,58 @@ +/* + * 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.definitions.xml; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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; + +/** + * A PolicyProcessor used for testing. + * + * @version $Rev$ $Date$ + */ +public class TestPolicyProcessor implements StAXArtifactProcessor<MockPolicy> { + public QName getArtifactType() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public MockPolicy read(XMLStreamReader arg0, ProcessorContext context) throws ContributionReadException, XMLStreamException { + return new MockPolicy(); + } + + public void write(MockPolicy arg0, XMLStreamWriter arg1, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + } + + public Class<MockPolicy> getModelType() { + return MockPolicy.class; + } + + public void resolve(MockPolicy arg0, ModelResolver arg1, ProcessorContext context) throws ContributionResolveException { + + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java new file mode 100644 index 0000000000..d2b0775361 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java @@ -0,0 +1,161 @@ +/* + * 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.policy.xml; + +import static org.apache.tuscany.sca.policy.xml.PolicyXPathFunction.normalize; + +import java.util.Collections; +import java.util.Iterator; + +import javax.xml.namespace.NamespaceContext; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathExpression; +import javax.xml.xpath.XPathFactory; + +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; + +/** + * + */ +public class PolicyXPathFunctionResolverTestCase { + private static XPath xpath; + + /** + * @throws java.lang.Exception + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + XPathFactory factory = XPathFactory.newInstance(); + xpath = factory.newXPath(); + xpath.setNamespaceContext(new NamespaceContextImpl()); + xpath.setXPathFunctionResolver(new PolicyXPathFunctionResolver(xpath.getNamespaceContext())); + } + + @Test + public void testIntentsRef() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + String str = "//sca:composite/sca:component[IntentRefs('sca:confidentiality')]"; + str = normalize(str, "sca"); + // Test the rewrite of xpath so that the self:node() is passed into the SCA function + XPathExpression exp = xpath.compile(str); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + Assert.assertEquals(1, nodes.getLength()); + } + + @Test + public void testIntentsRef2() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + String str = " //sca:composite/sca:component[sca:IntentRefs('sca:confidentiality')]"; + str = normalize(str, "sca"); + // Test the rewrite of xpath so that the self:node() is passed into the SCA function + XPathExpression exp = xpath.compile(str); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + Assert.assertEquals(1, nodes.getLength()); + } + + @Test + public void testIntentsRef3() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + String str = " IntentRefs('sca:confidentiality') "; + str = normalize(str, "sca"); + // Test the rewrite of xpath so that the self:node() is passed into the SCA function + XPathExpression exp = xpath.compile(str); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + Assert.assertEquals(1, nodes.getLength()); + } + @Test + public void testURIRef() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + XPathExpression exp = xpath.compile(normalize("sca:composite/sca:component[sca:URIRef('AddServiceComponent')]","sca")); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + // Assert.assertEquals(1, nodes.getLength()); + } + + @Test + public void testInterfaceRef() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:service[sca:InterfaceRef('AddService')]","sca")); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + // Assert.assertEquals(1, nodes.getLength()); + } + + @Test + public void testOperationRef() throws Exception { + InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite")); + XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:reference[sca:OperationRef('AddService/add')]","sca")); + Object result = exp.evaluate(xml, XPathConstants.NODESET); + Assert.assertTrue(result instanceof NodeList); + NodeList nodes = (NodeList)result; + // Assert.assertEquals(1, nodes.getLength()); + } + + + /** + * @throws java.lang.Exception + */ + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + private static class NamespaceContextImpl implements NamespaceContext { + + private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + + public String getNamespaceURI(String prefix) { + if ("sca".equals(prefix)) { + return SCA11_NS; + } else { + return null; + } + } + + public String getPrefix(String namespaceURI) { + if (SCA11_NS.equals(namespaceURI)) { + return "sca"; + } + return null; + } + + public Iterator getPrefixes(String namespaceURI) { + if (SCA11_NS.equals(namespaceURI)) { + return Collections.singleton("sca").iterator(); + } + return null; + } + + } + +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/ReadDocumentTestCase.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/ReadDocumentTestCase.java new file mode 100644 index 0000000000..b91308cfb0 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/ReadDocumentTestCase.java @@ -0,0 +1,307 @@ +/* + * 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.policy.xml; + +import static javax.xml.stream.XMLStreamConstants.START_ELEMENT; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.InputStream; +import java.net.URL; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.ProcessorContext; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; +import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; +import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver; +import org.apache.tuscany.sca.contribution.resolver.ModelResolver; +import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry; +import org.apache.tuscany.sca.policy.BindingType; +import org.apache.tuscany.sca.policy.ExtensionType; +import org.apache.tuscany.sca.policy.ExternalAttachment; +import org.apache.tuscany.sca.policy.ImplementationType; +import org.apache.tuscany.sca.policy.Intent; +import org.apache.tuscany.sca.policy.IntentMap; +import org.apache.tuscany.sca.policy.PolicySet; +import org.apache.tuscany.sca.policy.Qualifier; +import org.junit.Before; +import org.junit.Test; + +/** + * Test reading SCA XML assembly documents. + * + * @version $Rev$ $Date$ + */ +public class ReadDocumentTestCase { + + private ModelResolver resolver; + private StAXArtifactProcessor<Object> staxProcessor; + private ProcessorContext context; + + private static final QName elementToProcess = + new QName("http://docs.oasis-open.org/ns/opencsa/sca/200912", "implementationType"); + + private Map<QName, Intent> intentTable = new Hashtable<QName, Intent>(); + private Map<QName, PolicySet> policySetTable = new Hashtable<QName, PolicySet>(); + private Map<QName, BindingType> bindingTypesTable = new Hashtable<QName, BindingType>(); + private Map<QName, ImplementationType> implTypesTable = new Hashtable<QName, ImplementationType>(); + private Map<QName, ExternalAttachment> attachmentsTable = new Hashtable<QName, ExternalAttachment>(); + + private static final String scaNamespace = "http://docs.oasis-open.org/ns/opencsa/sca/200912"; + private static final String namespace = "http://test"; + + private static final QName confidentiality = new QName(namespace, "confidentiality"); + private static final QName integrity = new QName(namespace, "integrity"); + private static final QName messageProtection = new QName(namespace, "messageProtection"); + private static final QName confidentiality_transport = new QName(namespace, "confidentiality.transport"); + private static final QName confidentiality_message = new QName(namespace, "confidentiality.message"); + private static final QName secureReliablePolicy = new QName(namespace, "SecureReliablePolicy"); + private static final QName secureMessagingPolicies = new QName(namespace, "SecureMessagingPolicies"); + private static final QName securityPolicy = new QName(namespace, "SecurityPolicy"); + private static final QName basicAuthMsgProtSecurity = new QName(namespace, "BasicAuthMsgProtSecurity"); + private static final QName wsBinding = new QName(scaNamespace, "binding.ws"); + private static final QName javaImpl = new QName(scaNamespace, "implementation.java"); + private static final QName testPolicySetOne = new QName(namespace, "TestPolicySetOne"); + + @Before + public void setUp() throws Exception { + DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); + resolver = new DefaultModelResolver(); + context = new ProcessorContext(extensionPoints); + XMLInputFactory inputFactory = XMLInputFactory.newInstance(); + + StAXArtifactProcessorExtensionPoint staxProcessors = + extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class); + staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, null); + staxProcessors.addArtifactProcessor(new TestPolicyProcessor()); + + URL url = getClass().getResource("test_definitions.xml"); + InputStream urlStream = url.openStream(); + XMLStreamReader reader = inputFactory.createXMLStreamReader(urlStream); + reader.next(); + + //position on the right element qname to get processed + while (reader.hasNext()) { + reader.next(); + int event = reader.getEventType(); + if (event == START_ELEMENT && reader.getName().equals(elementToProcess)) { + break; + } + } + while (true) { + int event = reader.getEventType(); + switch (event) { + case START_ELEMENT: { + Object artifact = staxProcessor.read(reader, context); + if (artifact instanceof PolicySet) { + PolicySet policySet = (PolicySet)artifact; + policySet.setName(new QName(namespace, policySet.getName().getLocalPart())); + policySetTable.put(policySet.getName(), policySet); + } else if (artifact instanceof Intent) { + Intent intent = (Intent)artifact; + intent.setName(new QName(namespace, intent.getName().getLocalPart())); + intentTable.put(intent.getName(), intent); + for (Intent i : intent.getQualifiedIntents()) { + i.setName(new QName(namespace, i.getName().getLocalPart())); + intentTable.put(i.getName(), i); + resolver.addModel(i, context); + } + } else if (artifact instanceof BindingType) { + BindingType bindingType = (BindingType)artifact; + bindingTypesTable.put(bindingType.getType(), bindingType); + } else if (artifact instanceof ImplementationType) { + ImplementationType implType = (ImplementationType)artifact; + implTypesTable.put(implType.getType(), implType); + } else if ( artifact instanceof ExternalAttachment) { + ExternalAttachment attachment = (ExternalAttachment)artifact; + attachmentsTable.put(attachment.getPolicySets().get(0).getName(), attachment); + } + + if (artifact != null) { + resolver.addModel(artifact, context); + } + + break; + } + } + if (reader.hasNext()) { + reader.next(); + } else { + break; + } + } + urlStream.close(); + } + + @Test + public void testReadSCADefinitions() throws Exception { + assertNotNull(intentTable.get(confidentiality)); + assertNotNull(intentTable.get(messageProtection)); + assertNotNull(intentTable.get(confidentiality_transport)); + assertTrue(intentTable.get(confidentiality).getDescription().length() > 0); + + assertNotNull(policySetTable.get(secureReliablePolicy)); + assertTrue(policySetTable.get(secureReliablePolicy).getProvidedIntents().size() == 2); + assertTrue(policySetTable.get(secureReliablePolicy).getPolicies().size() == 2); + + assertNotNull(policySetTable.get(secureMessagingPolicies)); + assertEquals(2, policySetTable.get(secureMessagingPolicies).getIntentMaps().get(0).getQualifiers().get(0).getPolicies().size()); + + assertEquals(bindingTypesTable.size(), 1); + assertNotNull(bindingTypesTable.get(wsBinding)); + assertEquals(implTypesTable.size(), 1); + assertNotNull(implTypesTable.get(javaImpl)); + + // Test external attachments + assertEquals(1, attachmentsTable.size()); + assertNotNull(attachmentsTable.get(policySetTable.get(testPolicySetOne).getName())); + } + + private int getNumberOfQualifiedPolicies(PolicySet policySet) { + int count = 0; + for(IntentMap intentMap: policySet.getIntentMaps()) { + for(Qualifier q: intentMap.getQualifiers()) { + count += q.getPolicies().size(); + } + } + return count; + } + + @Test + public void testResolution() throws Exception { + assertTrue(!intentTable.get(messageProtection).getRequiredIntents().isEmpty()); + Intent profileIntent = intentTable.get(new QName(namespace, "messageProtection")); + assertNull(profileIntent.getRequiredIntents().get(0).getDescription()); + + QName confidentiality_transport = new QName(namespace, "confidentiality.transport"); + assertTrue(intentTable.get(confidentiality_transport) instanceof Intent); + Intent qualifiedIntent = (Intent)intentTable.get(new QName(namespace, "confidentiality.transport")); + assertNull(qualifiedIntent.getDescription()); + assertNotNull(qualifiedIntent.getQualifiableIntent().getDescription()); + + PolicySet secureReliablePolicySet = policySetTable.get(secureReliablePolicy); + PolicySet secureMessagingPolicySet = policySetTable.get(secureMessagingPolicies); + PolicySet securityPolicySet = policySetTable.get(securityPolicy); + + assertEquals(secureReliablePolicySet.getProvidedIntents().get(1).getName(), integrity); + assertNull(secureReliablePolicySet.getProvidedIntents().get(1).getDescription()); + assertTrue(secureMessagingPolicySet.isUnresolved()); + assertEquals(2, getNumberOfQualifiedPolicies(securityPolicySet)); + + //testing to ensure that inclusion of referred policy sets has not happened + PolicySet basicAuthMsgProtSecurityPolicySet = policySetTable.get(basicAuthMsgProtSecurity); + assertTrue(basicAuthMsgProtSecurityPolicySet.getPolicies().isEmpty()); + assertTrue(basicAuthMsgProtSecurityPolicySet.getIntentMaps().isEmpty()); + + ExtensionType wsBindingType = bindingTypesTable.get(wsBinding); + assertNull(wsBindingType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNull(wsBindingType.getMayProvidedIntents().get(0).getDescription()); + + ExtensionType javaImplType = implTypesTable.get(javaImpl); + assertNull(javaImplType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNull(javaImplType.getMayProvidedIntents().get(0).getDescription()); + + ExternalAttachment attachment = attachmentsTable.values().iterator().next(); + PolicySet psOne = policySetTable.get(testPolicySetOne); + assertEquals(psOne, attachment.getPolicySets().get(0)); + + List<Intent> intents = new ArrayList<Intent>(intentTable.values()); + + for (Intent intent : intents) { + staxProcessor.resolve(intent, resolver, context); + } + + for (PolicySet policySet : policySetTable.values()) { + if (policySet.getReferencedPolicySets().isEmpty()) + staxProcessor.resolve(policySet, resolver, context); + } + + for (PolicySet policySet : policySetTable.values()) { + if (!policySet.getReferencedPolicySets().isEmpty()) + staxProcessor.resolve(policySet, resolver, context); + } + + for (ExtensionType bindingType : bindingTypesTable.values()) { + staxProcessor.resolve(bindingType, resolver, context); + } + + for (ExtensionType implType : implTypesTable.values()) { + staxProcessor.resolve(implType, resolver, context); + } + + for ( ExternalAttachment ea : attachmentsTable.values()) { + staxProcessor.resolve(ea, resolver, context); + } + + //testing if policy intents have been linked have property been linked up + assertNotNull(profileIntent.getRequiredIntents().get(0).getDescription()); + assertNotNull(qualifiedIntent.getQualifiableIntent().getDescription()); + assertEquals(secureReliablePolicySet.getProvidedIntents().get(1).getName(), integrity); + assertNotNull(secureReliablePolicySet.getProvidedIntents().get(1).getDescription()); + + //testing if policysets have been properly linked up with intents + assertFalse(secureMessagingPolicySet.isUnresolved()); + assertTrue(isRealizedBy(secureMessagingPolicySet, intentTable.get(confidentiality))); + assertTrue(isRealizedBy(secureMessagingPolicySet, intentTable.get(confidentiality_transport))); + + //testing if intent maps have been properly mapped to policies + assertFalse(securityPolicySet.isUnresolved()); + assertTrue(isRealizedBy(securityPolicySet, intentTable.get(confidentiality))); + assertTrue(isRealizedBy(securityPolicySet, intentTable.get(confidentiality_message))); + + //testing for inclusion of referred policysets + assertFalse(basicAuthMsgProtSecurityPolicySet.getPolicies().isEmpty()); + assertFalse(basicAuthMsgProtSecurityPolicySet.getIntentMaps().isEmpty()); + assertTrue(isRealizedBy(basicAuthMsgProtSecurityPolicySet, intentTable.get(confidentiality_transport))); + + assertNotNull(wsBindingType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNotNull(wsBindingType.getMayProvidedIntents().get(0).getDescription()); + + assertNotNull(javaImplType.getAlwaysProvidedIntents().get(0).getDescription()); + assertNotNull(javaImplType.getMayProvidedIntents().get(0).getDescription()); + + + } + + private boolean isRealizedBy(PolicySet policySet, Intent intent) { + if (intent.getName().getLocalPart().indexOf('.') == -1) { + return policySet.getProvidedIntents().contains(intent); + } + for (IntentMap map : policySet.getIntentMaps()) { + for (Qualifier q : map.getQualifiers()) { + if (q.getIntent().equals(intent)) { + return true; + } + } + } + return false; + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/TestPolicyProcessor.java b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/TestPolicyProcessor.java new file mode 100644 index 0000000000..aea2c3adb8 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/TestPolicyProcessor.java @@ -0,0 +1,83 @@ +/* + * 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.policy.xml; + +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +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.policy.PolicyExpression; + +/** + * + * @version $Rev$ $Date$ + */ +public class TestPolicyProcessor implements StAXArtifactProcessor<PolicyExpression> { + + public QName getArtifactType() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public PolicyExpression read(XMLStreamReader arg0, ProcessorContext context) throws ContributionReadException, XMLStreamException { + return new MockPolicyImplOne(); + } + + public void write(PolicyExpression arg0, XMLStreamWriter arg1, ProcessorContext context) throws ContributionWriteException, XMLStreamException { + } + + public Class<PolicyExpression> getModelType() { + // TODO Auto-generated method stub + return PolicyExpression.class; + } + + public void resolve(PolicyExpression arg0, ModelResolver arg1, ProcessorContext context) throws ContributionResolveException { + + } + + public class MockPolicyImplOne implements PolicyExpression { + public <T> T getPolicy() { + return null; + } + + public void setName(QName name) { + } + + public <T> void setPolicy(T policy) { + } + + public QName getName() { + return new QName("http://schemas.xmlsoap.org/ws/2004/09/policy", "PolicyAttachment"); + } + + public boolean isUnresolved() { + return false; + } + + public void setUnresolved(boolean unresolved) { + } + + } +} diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Calculator.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Calculator.composite new file mode 100644 index 0000000000..be0c1eb737 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Calculator.composite @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:x="http://x"
+ xmlns:calc="http://calc" + targetNamespace="http://calc"
+ name="Calculator">
+
+ <service name="CalculatorService" promote="CalculatorServiceComponent">
+ <interface.java interface="calculator.CalculatorService"/>
+ </service>
+
+ <component name="CalculatorServiceComponent">
+ <implementation.java class="calculator.CalculatorServiceImpl"/>
+ <reference name="addService" multiplicity="0..1" target="AddServiceComponent"/>
+ <reference name="subtractService" target="SubtractServiceComponent"/>
+ <reference name="multiplyService" target="MultiplyServiceComponent"/>
+ <reference name="divideService" target="DivideServiceComponent"/>
+ </component>
+
+ <component name="AddServiceComponent">
+ <implementation.java class="calculator.AddServiceImpl"/>
+ </component>
+
+ <component name="SubtractServiceComponent">
+ <implementation.java class="calculator.SubtractServiceImpl"/>
+ </component>
+
+ <component name="MultiplyServiceComponent">
+ <implementation.java class="calculator.MultiplyServiceImpl"/>
+ </component>
+
+ <component name="DivideServiceComponent">
+ <implementation.java class="calculator.DivideServiceImpl"/>
+ </component>
+
+ <x:unknownElement uknAttr="attribute1">
+ <y:subUnknownElement1 xmlns:y="http://y" uknAttr1="attribute2"/>
+ <x:subUnknownElement2 />
+ </x:unknownElement>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorImpl.componentType b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorImpl.componentType new file mode 100644 index 0000000000..83fa64cef4 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorImpl.componentType @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> +<componentType xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + + <service name="CalculatorService"> + <interface.java interface="calculator.CalculatorService" /> + </service> + + <reference name="divideService"> + <interface.java interface="calculator.DivideService" /> + </reference> + +</componentType> + diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorURISpaces.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorURISpaces.composite new file mode 100644 index 0000000000..287810b156 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/CalculatorURISpaces.composite @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:x="http://x" + xmlns:calc="http://calc" + targetNamespace="http://calc" + name="Calculator"> + + <service name="CalculatorService" promote=" CalculatorServiceComponent "> + <interface.java interface="calculator.CalculatorService"/> + </service> + + <component name="CalculatorServiceComponent"> + <implementation.java class="calculator.CalculatorServiceImpl"/> + <reference name="addService" multiplicity="0..1" target="AddServiceComponent"/> + <reference name="subtractService" target="SubtractServiceComponent"/> + <reference name="multiplyService" target="MultiplyServiceComponent"/> + <reference name="divideService" target="DivideServiceComponent"/> + </component> + + <component name="AddServiceComponent"> + <implementation.java class="calculator.AddServiceImpl"/> + </component> + + <component name="SubtractServiceComponent"> + <implementation.java class="calculator.SubtractServiceImpl"/> + </component> + + <component name="MultiplyServiceComponent"> + <implementation.java class="calculator.MultiplyServiceImpl"/> + </component> + + <component name="DivideServiceComponent"> + <implementation.java class="calculator.DivideServiceImpl"/> + </component> + + <x:unknownElement uknAttr="attribute1"> + <y:subUnknownElement1 xmlns:y="http://y" uknAttr1="attribute2"/> + <x:subUnknownElement2 /> + </x:unknownElement> + +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Multiplicity.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Multiplicity.composite new file mode 100644 index 0000000000..0d344ac937 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/Multiplicity.composite @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + targetNamespace="http://temp" + name="composite1"> + <component name="data7"> + <implementation.java class="temp.EchoImpl"/> + <service name="Echo"> + <interface.wsdl interface="http://echo.webservice#wsdl.interface(Echo)"/> + </service> + <reference multiplicity="0..n" name="reference" requires=""/> + </component> + + <reference multiplicity="1..n" name="reference" promote="" requires=""/> +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/NestedCalculator.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/NestedCalculator.composite new file mode 100644 index 0000000000..5606e653bb --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/NestedCalculator.composite @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"
+ xmlns:calc="http://calc" + targetNamespace="http://calc"
+ name="Calculator">
+
+ <component name="CalculatorServiceComponent">
+ <implementation.composite xmlns:n="http://inner" name="n:InnerCalculator"/>
+ </component>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/RMIBindingTest.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/RMIBindingTest.composite new file mode 100644 index 0000000000..9140403fc4 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/RMIBindingTest.composite @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + --> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.1" + targetNamespace="http://helloWorldRMI" + name="HelloWorldRmiComposite"> + + <service name="HelloWorldRmiService" promote="HelloWorldServiceComponent"> + <interface.java interface="helloworld.HelloWorldService"/> + <tuscany:binding.rmi uri="rmi://localhost:8099/HelloWorldRemoteService" /> + </service> + + <component name="HelloWorldServiceComponent"> + <implementation.java class="helloworld.HelloWorldImpl"/> + </component> + + <component name="HelloWorldRmiServiceComponent"> + <implementation.java class="helloworld.HelloWorldRmiImpl"/> + <reference name="extService"></reference> + </component> + + <reference name="HelloWorldRmiReference" promote="HelloWorldRmiServiceComponent/extService"> + <interface.java interface="helloworld.HelloWorldService"/> + <tuscany:binding.rmi uri="rmi://localhost:8099/HelloWorldRemoteService" /> + </reference> + +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllCalculator.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllCalculator.composite new file mode 100644 index 0000000000..195dfcf106 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllCalculator.composite @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
+<composite autowire="false" local="true" name="TestAllCalculator" policySets="sns:SecureReliablePolicy"
+ requires="cns:confidentiality" targetNamespace="http://calc" xmlns:tns="http://calc"
+ xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://docs.oasis-open.org/ns/opencsa/sca/200912 http://docs.oasis-open.org/ns/opencsa/sca/200912 " + xmlns:ext="http://extension"
+ xmlns:cns="http://test" xmlns:sns="http://test">
+
+ <include name="tns:TestAllDivide"/>
+ <ext:testExtension/> +
+ <service name="CalculatorService" promote="CalculatorServiceComponent/CalculatorService" requires="cns:confidentiality"
+ policySets="sns:SecureReliablePolicy"> + <ext:testExtension/>
+ <interface.java interface="calculator.CalculatorService" callbackInterface="calculator.CalculatorCallback" />
+ <operation name="add" policySets="sns:SecureReliablePolicy" requires="cns:confidentiality" />
+
+ <binding.ws name="CalculatorWS" policySets="sns:SecureReliablePolicy" port="" requires="cns:confidentiality" uri="http://calc/ws">
+ </binding.ws>
+
+ <callback policySets="sns:SecureReliablePolicy" requires="cns:confidentiality">
+ <ext:testExtension/> + <binding.ws name="CalculatorCallbackWS" policySets="" port="" requires="" uri="http://calc/callback/ws">
+ </binding.ws>
+ </callback>
+ </service>
+
+ <component name="CalculatorServiceComponent" autowire="false"
+ policySets="sns:SecureReliablePolicy" requires="cns:confidentiality">
+ <ext:testExtension/> + <service name="CalculatorService" policySets="sns:SecureReliablePolicy" requires="cns:confidentiality">
+ <interface.java interface="calculator.CalculatorService" callbackInterface="calculator.CalculatorCallback" />
+ </service>
+
+ <reference name="addService" target="AddServiceComponent/AddService" autowire="false" multiplicity="1..1"
+ policySets="sns:SecureReliablePolicy" requires="cns:confidentiality" wiredByImpl="false">
+ <ext:testExtension/> + <interface.java interface="calculator.AddService" callbackInterface="calculator.AddCallback" />
+ </reference>
+ <reference name="subtractService" target="SubtractServiceComponent" />
+ <reference name="multiplyService" />
+ <reference name="divideService" target="DivideServiceComponent" />
+
+ <property name="round" type="xsd:boolean" many="false">true</property>
+
+ <implementation.java class="calculator.CalculatorServiceImpl" policySets="" requires="" />
+ </component>
+
+ <component name="AddServiceComponent">
+ <service name="AddService">
+ <interface.java interface="calculator.AddService" />
+ </service>
+ <implementation.java class="calculator.AddServiceImpl" />
+ </component>
+
+ <component name="NestedCompositeComponent"> + <service name="CalculatorService"> + <interface.java interface="calculator.CalculatorService" /> + </service> + <implementation.composite name="tns:Calculator" /> + </component> + + <component name="SubtractServiceComponent">
+ <implementation.java class="calculator.SubtractServiceImpl" />
+ </component>
+
+ <component name="MultiplyServiceComponent">
+ <implementation.java class="calculator.MultiplyServiceImpl" />
+ </component>
+
+ <component name="DivideServiceComponent">
+ <implementation.java class="calculator.DivideServiceImpl" />
+ </component>
+
+ <reference name="MultiplyService" promote="CalculatorServiceComponent/multiplyService" policySets="sns:SecureReliablePolicy"
+ requires="cns:confidentiality">
+ <interface.java interface="calculator.MultiplyService" callbackInterface="calculator.MultiplyCallback" />
+
+ <binding.ws name="MultiplyWS" port="" policySets="sns:SecureReliablePolicy" requires="cns:confidentiality" uri="http://calc/ws">
+ </binding.ws>
+
+ <callback policySets="sns:SecureReliablePolicy" requires="cns:confidentiality">
+ <binding.ws name="MultiplyCallbackWS" port="" uri="http://calc/callback/ws" policySets="sns:SecureReliablePolicy"
+ requires="cns:confidentiality">
+ </binding.ws>
+ </callback>
+ </reference>
+
+ <property name="prop1" xmlns:foo="http://foo" many="true" type="foo:MyComplexType">
+ <value xsi:type="foo:MyComplexType" attr="bar">
+ <foo:a>AValue</foo:a>
+ <bar:b xmlns:bar="http://bar">InterestingURI</bar:b>
+ </value>
+ <value xsi:type="foo:MyComplexType" attr="zing">
+ <foo:a>BValue</foo:a>
+ <bar:b xmlns:bar="http://bar">BoringURI</bar:b>
+ </value>
+ </property>
+
+ <property name="prop2" xmlns:foo="http://foo" mustSupply="true" element="foo:MyComplexPropertyValue1">
+ <foo:MyComplexPropertyValue1>123</foo:MyComplexPropertyValue1>
+ </property>
+ <property name="prop3" xmlns:foo="http://foo" mustSupply="true" value="123"/>
+ <property name="prop4">123</property>
+ <property name="prop5"><value>123</value></property>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllDivide.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllDivide.composite new file mode 100644 index 0000000000..42e6c1c3ec --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllDivide.composite @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite autowire="false" + local="true" + name="TestAllDivide" + policySets="" requires="" + targetNamespace="http://calc" + xmlns:tns="http://calc" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://docs.oasis-open.org/ns/opencsa/sca/200912 http://docs.oasis-open.org/ns/opencsa/sca/200912 "> + + <!-- + <include name="tns:CompleteDivide"/> + --> + <service name="DivideService" policySets="" promote="CalculatorDivideComponent/DivideService" requires=""> + <interface.java interface="calculator.DivideService" callbackInterface="calculator.DivideCallback"/> + <operation name="divide" policySets="" requires=""/> + + <binding.ws name="CalculatorWS" policySets="" port="" requires="" uri="http://calc/ws"> + <operation name="divide" policySets="" requires=""/> + </binding.ws> + + <callback policySets="" requires=""> + <binding.ws name="CalculatorCallbackWS" policySets="" port="" requires="" uri="http://calc/callback/ws"> + <operation name="divideCallback" policySets="" requires=""/> + </binding.ws> + </callback> + </service> + + <component name="CalculatorDivideComponent" autowire="false" policySets="" requires=""> + <service name="DivideService" policySets="" requires=""> + <interface.java interface="calculator.DivideService" callbackInterface="calculator.DivideCallback"/> + </service> + <implementation.java class="calculator.DivideImpl" policySets="" requires=""/> + </component> + +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllPolicyCalculator.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllPolicyCalculator.composite new file mode 100644 index 0000000000..424cec3e8a --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/TestAllPolicyCalculator.composite @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+-->
+
+<composite autowire="false" local="true" name="TestAllCalculator"
+ requires="cns:tuscanyIntent_1" targetNamespace="http://calc" xmlns:tns="http://calc"
+ xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://docs.oasis-open.org/ns/opencsa/sca/200912 http://docs.oasis-open.org/ns/opencsa/sca/200912 " + xmlns:ext="http://extension"
+ xmlns:cns="http://test" xmlns:sns="http://test">
+
+ <include name="tns:TestAllDivide"/>
+ <ext:testExtension/> +
+ <service name="CalculatorService" promote="CalculatorServiceComponent/CalculatorService" requires="cns:tuscanyIntent_2 cns:tuscanyIntent_1"> + <ext:testExtension/>
+ <interface.java interface="calculator.CalculatorService" callbackInterface="calculator.CalculatorCallback" />
+ <operation name="add" requires="cns:tuscanyIntent_6"/>
+
+ <binding.ws name="CalculatorWS" port="" requires="cns:tuscanyIntent_3" uri="http://calc/ws">
+ </binding.ws>
+
+ <callback requires="cns:tuscanyIntent_4">
+ <ext:testExtension/> + <binding.ws name="CalculatorCallbackWS" policySets="" port="" requires="cns:tuscanyIntent_5" uri="http://calc/callback/ws">
+ </binding.ws>
+ </callback>
+ </service>
+
+ <component name="CalculatorServiceComponent" autowire="false"
+ requires="cns:tuscanyIntent_2 cns:tuscanyIntent_3">
+ <ext:testExtension/> + <service name="CalculatorService" requires="cns:tuscanyIntent_3">
+ <interface.java interface="calculator.CalculatorService" callbackInterface="calculator.CalculatorCallback" />
+ <binding.ws name="CalculatorCallbackWS" policySets="" port="" requires="cns:tuscanyIntent_4" uri="http://calc/callback/ws">
+ </binding.ws>
+ <callback>
+ </callback>
+ </service>
+
+ <reference name="addService" target="AddServiceComponent/AddService" autowire="false" multiplicity="1..1"
+ requires="cns:tuscanyIntent_3 cns:tuscanyIntent_2.qualified" wiredByImpl="false">
+ <ext:testExtension/> + <interface.java interface="calculator.AddService" callbackInterface="calculator.AddCallback" />
+ <binding.ws name="addServiceWSRef" policySets="" port="" requires="cns:tuscanyIntent_4" uri="http://calc/callback/ws">
+ </binding.ws>
+ </reference>
+ <reference name="subtractService" target="SubtractServiceComponent" />
+ <reference name="multiplyService" />
+ <reference name="divideService" target="DivideServiceComponent" />
+
+ <property name="round" type="xsd:boolean" many="false">true</property>
+
+ <implementation.java class="calculator.CalculatorServiceImpl" policySets="" requires="cns:tuscanyIntent_4" />
+ </component>
+
+ <component name="AddServiceComponent">
+ <service name="AddService">
+ <interface.java interface="calculator.AddService" />
+ </service>
+ <implementation.java class="calculator.AddServiceImpl" />
+ </component>
+
+ <component name="NestedCompositeComponent"> + <service name="CalculatorService"> + <interface.java interface="calculator.CalculatorService" /> + </service> + <implementation.composite name="tns:Calculator" /> + </component> + + <component name="SubtractServiceComponent">
+ <implementation.java class="calculator.SubtractServiceImpl" />
+ </component>
+
+ <component name="MultiplyServiceComponent">
+ <implementation.java class="calculator.MultiplyServiceImpl" />
+ </component>
+
+ <component name="DivideServiceComponent">
+ <implementation.java class="calculator.DivideServiceImpl" />
+ </component>
+
+ <reference name="MultiplyService" promote="CalculatorServiceComponent/multiplyService"
+ requires="cns:tuscanyIntent_2">
+ <interface.java interface="calculator.MultiplyService" callbackInterface="calculator.MultiplyCallback" />
+
+ <binding.ws name="MultiplyWS" port="" requires="cns:tuscanyIntent_3" uri="http://calc/ws">
+ </binding.ws>
+
+ <callback policySets="sns:SecureReliablePolicy" requires="cns:tuscanyIntent_3">
+ <binding.ws name="MultiplyCallbackWS" port="" uri="http://calc/callback/ws"
+ requires="cns:tuscanyIntent_4">
+ </binding.ws>
+ </callback>
+ </reference>
+
+ <property name="prop1" xmlns:foo="http://foo">
+ <value xsi:type="foo:MyComplexType" attr="bar">
+ <foo:a>AValue</foo:a>
+ <bar:b xmlns:bar="http://bar">InterestingURI</bar:b>
+ </value>
+ <value xsi:type="foo:MyComplexType" attr="zing">
+ <foo:a>BValue</foo:a>
+ <bar:b xmlns:bar="http://bar">BoringURI</bar:b>
+ </value>
+ </property>
+
+</composite>
diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/another_test_definitions.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/another_test_definitions.xml new file mode 100644 index 0000000000..489d6abed1 --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/another_test_definitions.xml @@ -0,0 +1,96 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> +<sca:definitions xmlns="http://test" + targetNamespace="http://test" + xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + +<!-- simple intent --> + <sca:intent name="tuscanyIntent_1" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + <sca:qualifier name="qualified" default="true"/> + </sca:intent> + + <sca:intent name="tuscanyIntent_2" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + <sca:qualifier name="qualified" default="true"/> + </sca:intent> + + <sca:intent name="tuscanyIntent_3" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_4" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + +<sca:intent name="tuscanyIntent_5" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_6" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_7" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_8" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_9" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> + + <sca:intent name="tuscanyIntent_10" + constrains="sca:binding"> + <sca:description> + Sample Intent + </sca:description> + </sca:intent> +</sca:definitions>
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/local.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/local.composite new file mode 100644 index 0000000000..279f7d534e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/local.composite @@ -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. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + xmlns:calc="http://localcalc" + xmlns:test="http://testlocal" + targetNamespace="http://localcalc" + name="LocalCalculator" + local="true"> + +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/test_definitions.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/test_definitions.xml new file mode 100644 index 0000000000..2cfbd6bcff --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/assembly/xml/test_definitions.xml @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> +<definitions xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" targetNamespace="http://test" + xmlns:test="http://test" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + + <!-- Extension Types Metadata --> + <implementationType type="sca:implementation.java" alwaysProvides="test:logging" mayProvide="test:tracing" /> + <bindingType type="sca:binding.ws" alwaysProvides="test:confidentiality" mayProvide="test:integrity" /> + + <!-- Intents and Policysets to assume targetnamespace --> + <intent name="TestIntentOne" constrains="sca:binding"> + <description> + Test Intent + </description> + </intent> + + <intent name="TestIntentTwo" constrains="sca:binding" requires="test:TestIntentOne"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <policySet name="TestPolicySetOne" provides="test:TestIntentOne" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <!-- POLICY SETS --> + <policySet name="SecureReliablePolicy" provides="test:confidentiality.transport test:integrity" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="SecureMessagingPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" alternative" --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecurityPolicy" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy attachment for body encryption --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy attachment for whole message encryption --> + </wsp:PolicyAttachment> + </qualifier> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy attachment for transport encryption --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="BasicAuthMsgProtSecurity" provides="test:authentication test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + <policySetReference name="test:AuthenticationPolicies" /> + <policySetReference name="test:ConfidentialityPolicies" /> + </policySet> + + <policySet name="AuthenticationPolicies" provides="test:authentication" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "basic + authentication" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="ConfidentialityPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" + alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" + alternative" --> + ... + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecureWSPolicy" provides="test:confidentiality" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" + xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:Policy> + <wsp:ExactlyOne> + <wsp:All> + <sp:SecurityToken> + <sp:TokenType>sp:X509v3</sp:TokenType> + </sp:SecurityToken> + <sp:UsernameToken /> + <sp:SignedParts /> + <sp:EncryptedParts> + <sp:Body /> + </sp:EncryptedParts> + <sp:TransportBinding> + <sp:IncludeTimeStamp /> + </sp:TransportBinding> + </wsp:All> + </wsp:ExactlyOne> + </wsp:Policy> + </policySet> + + <!-- profile intent --> + <intent name="reliableMessageProtection" constrains="sca:binding" requires="test:messageProtection"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <intent name="messageProtection" constrains="sca:binding" requires="test:confidentiality test:integrity"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <!-- simple intent --> + <intent name="confidentiality" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized users from reading the messages. + </description> + <qualifier name="transport" /> + <qualifier name="message" default="true" /> + </intent> + + <intent name="integrity" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized modification of the messages. + </description> + </intent> + + <intent name="authentication" constrains="sca:binding"> + <description> + Communitcation thro this binding required + Authentication. + </description> + </intent> + + <intent name="logging" constrains="sca:implementation"> + <description> + All messages to and from this implementation must be logged + </description> + </intent> + + <intent name="tracing" constrains="sca:implementation.java"> + <description> + Need to figure out some description for this + </description> + </intent> + +</definitions>
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/definitions/xml/test_definitions.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/definitions/xml/test_definitions.xml new file mode 100644 index 0000000000..dc7f5c422c --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/definitions/xml/test_definitions.xml @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> +<definitions xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" targetNamespace="http://test" + xmlns:test="http://test" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + + <!-- Extension Types Metadata --> + <implementationType type="sca:implementation.java" alwaysProvides="test:logging" mayProvide="test:tracing" /> + <bindingType type="sca:binding.ws" alwaysProvides="test:confidentiality" mayProvide="test:integrity" /> + + <!-- Intents and Policysets to assume targetnamespace --> + <intent name="TestIntentOne" constrains="sca:binding"> + <description> + Test Intent + </description> + </intent> + + <intent name="TestIntentTwo" constrains="sca:binding" requires="test:TestIntentOne"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <policySet name="TestPolicySetOne" provides="test:TestIntentOne" appliesTo="sca:binding.ws" + attachTo = "//sca:component[@name='CalculatorServiceComponent']/sca:reference[@name='addService']" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <!-- POLICY SETS --> + <policySet name="SecureReliablePolicy" provides="test:confidentiality.transport test:integrity" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="SecureMessagingPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" alternative" --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecurityPolicy" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy attachment for body encryption --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy attachment for whole message encryption --> + </wsp:PolicyAttachment> + </qualifier> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy attachment for transport encryption --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="BasicAuthMsgProtSecurity" provides="test:authentication test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + <policySetReference name="test:AuthenticationPolicies" /> + <policySetReference name="test:ConfidentialityPolicies" /> + </policySet> + + <policySet name="AuthenticationPolicies" provides="test:authentication" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "basic + authentication" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="ConfidentialityPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" + alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" + alternative" --> + ... + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecureWSPolicy" provides="test:confidentiality" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" + xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:Policy> + <wsp:ExactlyOne> + <wsp:All> + <sp:SecurityToken> + <sp:TokenType>sp:X509v3</sp:TokenType> + </sp:SecurityToken> + <sp:UsernameToken /> + <sp:SignedParts /> + <sp:EncryptedParts> + <sp:Body /> + </sp:EncryptedParts> + <sp:TransportBinding> + <sp:IncludeTimeStamp /> + </sp:TransportBinding> + </wsp:All> + </wsp:ExactlyOne> + </wsp:Policy> + </policySet> + + <!-- profile intent --> + <intent name="reliableMessageProtection" constrains="sca:binding" requires="test:messageProtection"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <intent name="messageProtection" constrains="sca:binding" requires="test:confidentiality test:integrity"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <!-- simple intent --> + <intent name="confidentiality" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized users from reading the messages. + </description> + <qualifier name="transport" /> + <qualifier name="message" default="true" /> + </intent> + + <intent name="integrity" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized modification of the messages. + </description> + </intent> + + <intent name="authentication" constrains="sca:binding"> + <description> + Communitcation thro this binding required + Authentication. + </description> + </intent> + + <intent name="logging" constrains="sca:implementation"> + <description> + All messages to and from this implementation must be logged + </description> + </intent> + + <intent name="tracing" constrains="sca:implementation.java"> + <description> + Need to figure out some description for this + </description> + </intent> + +</definitions>
\ No newline at end of file diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/Calculator.composite b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/Calculator.composite new file mode 100644 index 0000000000..0e7aad877e --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/Calculator.composite @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. +--> +<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" + targetNamespace="http://sample" + xmlns:sample="http://sample" + name="Calculator"> + + <component name="CalculatorServiceComponent" requires="confidentiality"> + <implementation.java class="calculator.CalculatorServiceImpl" xmlns:test="http://test" requiers="test:TestIntentOne"/> + <reference name="addService" target="AddServiceComponent" /> + <reference name="subtractService" target="SubtractServiceComponent" /> + <reference name="multiplyService" target="MultiplyServiceComponent" /> + <reference name="divideService" target="DivideServiceComponent" /> + </component> + + <component name="AddServiceComponent"> + <implementation.java class="calculator.AddServiceImpl"/> + </component> + + <component name="SubtractServiceComponent"> + <implementation.java class="calculator.SubtractServiceImpl"/> + </component> + + <component name="MultiplyServiceComponent"> + <implementation.java class="calculator.MultiplyServiceImpl"/> + </component> + + <component name="DivideServiceComponent"> + <implementation.java class="calculator.DivideServiceImpl"/> + </component> + +</composite> diff --git a/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/test_definitions.xml b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/test_definitions.xml new file mode 100644 index 0000000000..aea941a78f --- /dev/null +++ b/sca-java-2.x/branches/2.0-Beta2/modules/assembly-xml/src/test/resources/org/apache/tuscany/sca/policy/xml/test_definitions.xml @@ -0,0 +1,206 @@ +<?xml version="1.0" encoding="ASCII"?> +<!-- + * 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. +--> +<definitions xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" targetNamespace="http://test" + xmlns:test="http://test" xmlns:sca="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + + <!-- Extension Types Metadata --> + <implementationType type="sca:implementation.java" alwaysProvides="test:logging" mayProvide="test:tracing" /> + <bindingType type="sca:binding.ws" alwaysProvides="test:confidentiality" mayProvide="test:integrity" /> + + <!-- Intents and Policysets to assume targetnamespace --> + <intent name="TestIntentOne" constrains="sca:binding"> + <description> + Test Intent + </description> + </intent> + + <intent name="TestIntentTwo" constrains="sca:binding" requires="test:TestIntentOne"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <policySet name="TestPolicySetOne" provides="test:TestIntentOne" appliesTo="sca:binding.ws" + attachTo = "//sca:component[@name='CalculatorServiceComponent']/sca:reference[@name='addService']" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <!-- POLICY SETS --> + <policySet name="SecureReliablePolicy" provides="test:confidentiality.transport test:integrity" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "basic authentication" --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for + "reliability" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="SecureMessagingPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" alternative" --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecurityPolicy" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy attachment for body encryption --> + </wsp:PolicyAttachment> + </qualifier> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy attachment for transport encryption --> + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="BasicAuthMsgProtSecurity" provides="test:authentication test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912"> + <policySetReference name="test:AuthenticationPolicies" /> + <policySetReference name="test:ConfidentialityPolicies" /> + </policySet> + + <policySet name="AuthenticationPolicies" provides="test:authentication" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "basic + authentication" --> + </wsp:PolicyAttachment> + </policySet> + + <policySet name="ConfidentialityPolicies" provides="test:confidentiality" appliesTo="binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <intentMap provides="test:confidentiality"> + <qualifier name="transport"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "transport" + alternative --> + </wsp:PolicyAttachment> + <wsp:PolicyAttachment>...</wsp:PolicyAttachment> + </qualifier> + <qualifier name="message"> + <wsp:PolicyAttachment> + <!-- policy expression and policy subject for "message" + alternative" --> + ... + </wsp:PolicyAttachment> + </qualifier> + </intentMap> + </policySet> + + <policySet name="SecureWSPolicy" provides="test:confidentiality" appliesTo="sca:binding.ws" + xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" xmlns:sp="http://schemas.xmlsoap.org/ws/2002/12/secext" + xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"> + <wsp:Policy> + <wsp:ExactlyOne> + <wsp:All> + <sp:SecurityToken> + <sp:TokenType>sp:X509v3</sp:TokenType> + </sp:SecurityToken> + <sp:UsernameToken /> + <sp:SignedParts /> + <sp:EncryptedParts> + <sp:Body /> + </sp:EncryptedParts> + <sp:TransportBinding> + <sp:IncludeTimeStamp /> + </sp:TransportBinding> + </wsp:All> + </wsp:ExactlyOne> + </wsp:Policy> + </policySet> + + <!-- profile intent --> + <intent name="reliableMessageProtection" constrains="sca:binding" requires="test:messageProtection"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <intent name="messageProtection" constrains="sca:binding" requires="test:confidentiality test:integrity"> + <description> + Protect messages from unauthorized reading or modification + </description> + </intent> + + <!-- simple intent --> + <intent name="confidentiality" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized users from reading the messages. + </description> + <qualifier name="transport" /> + <qualifier name="message" default="true" /> + </intent> + + <intent name="integrity" constrains="sca:binding"> + <description> + Communitcation thro this binding must prevent + unauthorized modification of the messages. + </description> + </intent> + + <intent name="authentication" constrains="sca:binding"> + <description> + Communitcation thro this binding required + Authentication. + </description> + </intent> + + <intent name="logging" constrains="sca:implementation"> + <description> + All messages to and from this implementation must be logged + </description> + </intent> + + <intent name="tracing" constrains="sca:implementation.java"> + <description> + Need to figure out some description for this + </description> + </intent> + + <externalAttachment policySets="test:TestPolicySetOne" attachTo="IntentRefs('test:testIntentOne')"/> + +</definitions>
\ No newline at end of file |