summaryrefslogtreecommitdiffstats
path: root/branches/2.0-M2/modules/contribution-xml
diff options
context:
space:
mode:
Diffstat (limited to 'branches/2.0-M2/modules/contribution-xml')
-rw-r--r--branches/2.0-M2/modules/contribution-xml/LICENSE205
-rw-r--r--branches/2.0-M2/modules/contribution-xml/META-INF/MANIFEST.MF27
-rw-r--r--branches/2.0-M2/modules/contribution-xml/NOTICE6
-rw-r--r--branches/2.0-M2/modules/contribution-xml/pom.xml52
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java80
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java161
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLDocumentStreamReader.java482
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLEventsStreamReader.java444
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLFragmentStreamReader.java53
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java50
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java131
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java221
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.java72
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor20
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor19
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor20
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver18
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties24
-rw-r--r--branches/2.0-M2/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java145
19 files changed, 2230 insertions, 0 deletions
diff --git a/branches/2.0-M2/modules/contribution-xml/LICENSE b/branches/2.0-M2/modules/contribution-xml/LICENSE
new file mode 100644
index 0000000000..8aa906c321
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-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/branches/2.0-M2/modules/contribution-xml/META-INF/MANIFEST.MF b/branches/2.0-M2/modules/contribution-xml/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..d80ced9e24
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/META-INF/MANIFEST.MF
@@ -0,0 +1,27 @@
+Manifest-Version: 1.0
+Private-Package: org.apache.tuscany.sca.contribution.processor.xml;ver
+ sion="2.0.0"
+Tool: Bnd-0.0.255
+Bundle-Name: Apache Tuscany SCA XML Contribution Model
+Created-By: 1.6.0_07 (Sun Microsystems Inc.)
+Bundle-Vendor: The Apache Software Foundation
+Bundle-Version: 2.0.0
+Bnd-LastModified: 1225397199187
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Apache Tuscany SCA XML Contribution Model
+Import-Package: javax.xml.namespace,
+ javax.xml.parsers,
+ javax.xml.stream,
+ javax.xml.stream.events,
+ org.apache.tuscany.sca.assembly;version="2.0.0",
+ org.apache.tuscany.sca.contribution;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.monitor;version="2.0.0",
+ org.apache.tuscany.sca.policy;version="2.0.0",
+ org.w3c.dom
+Bundle-SymbolicName: org.apache.tuscany.sca.contribution.xml
+Bundle-DocURL: http://www.apache.org/
+
diff --git a/branches/2.0-M2/modules/contribution-xml/NOTICE b/branches/2.0-M2/modules/contribution-xml/NOTICE
new file mode 100644
index 0000000000..25bb89c9b2
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/NOTICE
@@ -0,0 +1,6 @@
+${pom.name}
+Copyright (c) 2005 - 2009 The Apache Software Foundation
+
+This product includes software developed by
+The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/branches/2.0-M2/modules/contribution-xml/pom.xml b/branches/2.0-M2/modules/contribution-xml/pom.xml
new file mode 100644
index 0000000000..bdc22067aa
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/pom.xml
@@ -0,0 +1,52 @@
+<?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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-modules</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+ <artifactId>tuscany-contribution-xml</artifactId>
+ <name>Apache Tuscany SCA XML Contribution Model</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-contribution</artifactId>
+ <version>2.0-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.codehaus.woodstox</groupId>
+ <artifactId>wstx-asl</artifactId>
+ <version>3.2.4</version>
+ <scope>runtime</scope>
+ <exclusions>
+ <exclusion>
+ <groupId>stax</groupId>
+ <artifactId>stax-api</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java
new file mode 100644
index 0000000000..aad7747522
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java
@@ -0,0 +1,80 @@
+/*
+ * 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.contribution.processor.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.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Extension;
+import org.apache.tuscany.sca.contribution.Constants;
+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.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * A Policy Processor used for testing.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnyAttributeProcessor extends BaseStAXArtifactProcessor implements StAXAttributeProcessor<Extension> {
+ private static final QName ANY_ATTRIBUTE = new QName(Constants.XMLSCHEMA_NS, "anyAttribute");
+
+ private AssemblyFactory assemblyFactory;
+
+ public AnyAttributeProcessor(FactoryExtensionPoint modelFactories, Monitor monitor) {
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ }
+
+ public QName getArtifactType() {
+ return ANY_ATTRIBUTE;
+ }
+
+ public Class<Extension> getModelType() {
+ return Extension.class;
+ }
+
+ public Extension read(QName attributeName, XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+ String attributeValue = reader.getAttributeValue(attributeName.getNamespaceURI(), attributeName.getLocalPart());
+ Extension ext = assemblyFactory.createExtension();
+ ext.setQName(attributeName);
+ ext.setAttribute(true);
+ ext.setValue(attributeValue);
+ return ext;
+ }
+
+ public void write(Extension attributeExtension, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+ writer.writeAttribute(attributeExtension.getQName().getPrefix(),
+ attributeExtension.getQName().getNamespaceURI(),
+ attributeExtension.getQName().getLocalPart(),
+ attributeExtension.getValue().toString()); //for extended attributes, we can assume values
+ // are just the string representation fo the attribute
+ }
+
+ public void resolve(Extension arg0, ModelResolver arg1) throws ContributionResolveException {
+
+ }
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java
new file mode 100644
index 0000000000..68c46a2301
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.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.contribution.processor.xml;
+
+import static javax.xml.stream.XMLStreamConstants.CDATA;
+import static javax.xml.stream.XMLStreamConstants.CHARACTERS;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.stream.events.XMLEvent;
+
+import org.apache.tuscany.sca.contribution.Constants;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+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;
+
+public class AnyElementProcessor implements StAXArtifactProcessor<Object> {
+ private static final QName ANY_ELEMENT = new QName(Constants.XMLSCHEMA_NS, "anyElement");
+
+ private XMLInputFactory xmlInputFactory;
+ @SuppressWarnings("unused")
+ private Monitor monitor;
+
+
+ public AnyElementProcessor(FactoryExtensionPoint modelFactories, Monitor monitor) {
+ xmlInputFactory = modelFactories.getFactory(XMLInputFactory.class);
+ this.monitor = monitor;
+ }
+
+ public QName getArtifactType() {
+ return ANY_ELEMENT;
+ }
+
+ public Class<Object> getModelType() {
+ return Object.class;
+ }
+
+ /**
+ * Reads the contetns of the unknown elements and generates a custom
+ * implementation of XMLStreamReader i.e. XMLEventsStreamReader
+ *
+ * @param reader
+ * @return
+ * @throws XMLStreamException
+ */
+ @SuppressWarnings("unchecked")
+ public Object read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+
+ // Custom variables
+ String currentElement = null;
+ List eventsList = new ArrayList();
+
+ Map<String, NamespaceContext> eventContext = new HashMap<String, NamespaceContext>();
+
+ try {
+ // Cast the block of unknown elements into document
+ XMLDocumentStreamReader docReader = new XMLDocumentStreamReader(reader);
+
+ XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(docReader);
+
+ while (xmlEventReader.hasNext()) {
+ XMLEvent event = xmlEventReader.nextEvent();
+
+ // Populate the eventContext map with the current element's name
+ // and corresponding NamesapceContext
+ if (currentElement != null && !(eventContext.containsKey(currentElement))) {
+ eventContext.put(currentElement, reader.getNamespaceContext());
+ }
+
+ // Populate the list with the XMLEvents
+ eventsList.add(event);
+ if (event.isStartElement()) {
+ currentElement = reader.getName().getLocalPart();
+ }
+ if (event.isEndDocument()) {
+ return new XMLEventsStreamReader(eventsList, eventContext);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ /**
+ * Writes unknown portions back to the writer
+ *
+ * @param model
+ * @param writer
+ */
+ public void write(Object model, XMLStreamWriter writer) throws XMLStreamException {
+ if (!(model instanceof XMLStreamReader)) {
+ return;
+ }
+ XMLStreamReader reader = (XMLStreamReader)model;
+
+ int event = reader.getEventType();
+ while (reader.hasNext()) {
+ switch (event) {
+ case START_ELEMENT:
+
+ writer.writeStartElement(reader.getPrefix(), reader.getLocalName(), reader.getNamespaceURI());
+ for (int i = 1; i <= reader.getAttributeCount(); i++) {
+ writer.writeAttribute(reader.getAttributePrefix(i), reader.getAttributeNamespace(i), reader
+ .getAttributeLocalName(i), reader.getAttributeValue(i));
+ }
+ break;
+
+ case CHARACTERS:
+ writer.writeCharacters(reader.getText());
+ break;
+
+ case CDATA:
+ writer.writeCData(reader.getText());
+ break;
+
+ case END_ELEMENT:
+ writer.writeEndElement();
+ break;
+ }
+ if (reader.hasNext()) {
+ event = reader.next();
+ }
+ }
+ }
+
+ public void resolve(Object model, ModelResolver resolver) throws ContributionResolveException {
+
+ }
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLDocumentStreamReader.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLDocumentStreamReader.java
new file mode 100644
index 0000000000..7e8b3a9d9e
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLDocumentStreamReader.java
@@ -0,0 +1,482 @@
+/*
+ * 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.contribution.processor.xml;
+
+import java.util.NoSuchElementException;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+/**
+ * This class is derived from Apache Axis2 class
+ * org.apache.axis2.util.StreamWrapper</a>. It's used wrap a XMLStreamReader to
+ * create a XMLStreamReader representing a document and it will produce
+ * START_DOCUMENT, END_DOCUMENT events.
+ *
+ * @version $Rev: 659153 $ $Date: 2008-05-22 09:43:58 -0700 (Thu, 22 May 2008) $
+ */
+public class XMLDocumentStreamReader implements XMLStreamReader {
+ private static final int STATE_COMPLETE_AT_NEXT = 2; // The wrapper
+ // will produce
+ // END_DOCUMENT
+
+ private static final int STATE_COMPLETED = 3; // Done
+
+ private static final int STATE_INIT = 0; // The wrapper will produce
+ // START_DOCUMENT
+
+ private static final int STATE_SWITCHED = 1; // The real reader will
+ // produce events
+
+ private XMLStreamReader realReader;
+ private boolean fragment;
+ private int level = 0;
+
+ private int state = STATE_INIT;
+
+ public XMLDocumentStreamReader(XMLStreamReader realReader) {
+ if (realReader == null) {
+ throw new UnsupportedOperationException("Reader cannot be null");
+ }
+
+ this.realReader = realReader;
+
+ if (realReader instanceof XMLFragmentStreamReader) {
+ ((XMLFragmentStreamReader)realReader).init();
+ }
+
+ // If the real reader is positioned at START_DOCUMENT, always use
+ // the real reader
+ if (realReader.getEventType() == START_DOCUMENT) {
+ fragment = false;
+ state = STATE_SWITCHED;
+ }
+ }
+
+ public void close() throws XMLStreamException {
+ realReader.close();
+ }
+
+ public int getAttributeCount() {
+ if (isDelegating()) {
+ return realReader.getAttributeCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeLocalName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeLocalName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public QName getAttributeName(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeName(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeNamespace(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeNamespace(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeType(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeType(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(int i) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getAttributeValue(String s, String s1) {
+ if (isDelegating()) {
+ return realReader.getAttributeValue(s, s1);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getCharacterEncodingScheme() {
+ return realReader.getCharacterEncodingScheme();
+ }
+
+ public String getElementText() throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getElementText();
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public String getEncoding() {
+ return realReader.getEncoding();
+ }
+
+ public int getEventType() {
+ int event = -1;
+ switch (state) {
+ case STATE_SWITCHED:
+ case STATE_COMPLETE_AT_NEXT:
+ event = realReader.getEventType();
+ break;
+ case STATE_INIT:
+ event = START_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ event = END_DOCUMENT;
+ break;
+ }
+ return event;
+ }
+
+ public String getLocalName() {
+ if (isDelegating()) {
+ return realReader.getLocalName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Location getLocation() {
+ if (isDelegating()) {
+ return realReader.getLocation();
+ } else {
+ return null;
+ }
+ }
+
+ public QName getName() {
+ if (isDelegating()) {
+ return realReader.getName();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ return realReader.getNamespaceContext();
+ }
+
+ public int getNamespaceCount() {
+ if (isDelegating()) {
+ return realReader.getNamespaceCount();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespacePrefix(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespacePrefix(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI() {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(int i) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(i);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getNamespaceURI(String s) {
+ if (isDelegating()) {
+ return realReader.getNamespaceURI(s);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPIData() {
+ if (isDelegating()) {
+ return realReader.getPIData();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPITarget() {
+ if (isDelegating()) {
+ return realReader.getPITarget();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getPrefix() {
+ if (isDelegating()) {
+ return realReader.getPrefix();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public Object getProperty(String s) throws IllegalArgumentException {
+ if (isDelegating()) {
+ return realReader.getProperty(s);
+ } else {
+ throw new IllegalArgumentException();
+ }
+ }
+
+ public String getText() {
+ if (isDelegating()) {
+ return realReader.getText();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (isDelegating()) {
+ return realReader.getTextCharacters();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextCharacters(int i, char[] chars, int i1, int i2) throws XMLStreamException {
+ if (isDelegating()) {
+ return realReader.getTextCharacters(i, chars, i1, i2);
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextLength() {
+ if (isDelegating()) {
+ return realReader.getTextLength();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public int getTextStart() {
+ if (isDelegating()) {
+ return realReader.getTextStart();
+ } else {
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getVersion() {
+ if (isDelegating()) {
+ return realReader.getVersion();
+ } else {
+ return null;
+ }
+ }
+
+ public boolean hasName() {
+ if (isDelegating()) {
+ return realReader.hasName();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ if (state == STATE_COMPLETE_AT_NEXT) {
+ return true;
+ } else if (state == STATE_COMPLETED) {
+ return false;
+ } else if (state == STATE_SWITCHED) {
+ return realReader.hasNext();
+ } else {
+ return true;
+ }
+ }
+
+ public boolean hasText() {
+ if (isDelegating()) {
+ return realReader.hasText();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isAttributeSpecified(int i) {
+ if (isDelegating()) {
+ return realReader.isAttributeSpecified(i);
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isCharacters() {
+ if (isDelegating()) {
+ return realReader.isCharacters();
+ } else {
+ return false;
+ }
+ }
+
+ private boolean isDelegating() {
+ return state == STATE_SWITCHED || state == STATE_COMPLETE_AT_NEXT;
+ }
+
+ public boolean isEndElement() {
+ if (isDelegating()) {
+ return realReader.isEndElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStandalone() {
+ if (isDelegating()) {
+ return realReader.isStandalone();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isStartElement() {
+ if (isDelegating()) {
+ return realReader.isStartElement();
+ } else {
+ return false;
+ }
+ }
+
+ public boolean isWhiteSpace() {
+ if (isDelegating()) {
+ return realReader.isWhiteSpace();
+ } else {
+ return false;
+ }
+ }
+
+ public int next() throws XMLStreamException {
+ int returnEvent;
+
+ switch (state) {
+ case STATE_SWITCHED:
+ returnEvent = realReader.next();
+ if (returnEvent == END_DOCUMENT) {
+ state = STATE_COMPLETED;
+ } else if (!realReader.hasNext()) {
+ state = STATE_COMPLETE_AT_NEXT;
+ }
+ if (fragment && returnEvent == END_ELEMENT) {
+ level--;
+ if (level == -1) {
+ // We are now at the end of the top-level element in the fragment
+ state = STATE_COMPLETE_AT_NEXT;
+ }
+ }
+ if (fragment && returnEvent == START_ELEMENT) {
+ level++;
+ }
+ break;
+ case STATE_INIT:
+ state = STATE_SWITCHED;
+ returnEvent = realReader.getEventType();
+ if (returnEvent == START_ELEMENT) {
+ // The real reader is positioned at the top-level element in the fragment
+ level = 0;
+ fragment = true;
+ }
+ break;
+ case STATE_COMPLETE_AT_NEXT:
+ state = STATE_COMPLETED;
+ returnEvent = END_DOCUMENT;
+ break;
+ case STATE_COMPLETED:
+ // oops - no way we can go beyond this
+ throw new NoSuchElementException("End of stream has reached.");
+ default:
+ throw new UnsupportedOperationException();
+ }
+
+ return returnEvent;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ if (isDelegating()) {
+ int returnEvent = realReader.nextTag();
+ if (fragment && returnEvent == END_ELEMENT) {
+ level--;
+ if (level == 0) {
+ // We are now at the end of the top-level element in the fragment
+ state = STATE_COMPLETE_AT_NEXT;
+ }
+ }
+ if (fragment && returnEvent == START_ELEMENT) {
+ level++;
+ }
+ return returnEvent;
+ } else {
+ throw new XMLStreamException();
+ }
+ }
+
+ public void require(int i, String s, String s1) throws XMLStreamException {
+ if (isDelegating()) {
+ realReader.require(i, s, s1);
+ }
+ }
+
+ public boolean standaloneSet() {
+ if (isDelegating()) {
+ return realReader.standaloneSet();
+ } else {
+ return false;
+ }
+ }
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLEventsStreamReader.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLEventsStreamReader.java
new file mode 100644
index 0000000000..eecdee5ba6
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLEventsStreamReader.java
@@ -0,0 +1,444 @@
+/*
+ * 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.contribution.processor.xml;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.events.Attribute;
+import javax.xml.stream.events.Namespace;
+import javax.xml.stream.events.ProcessingInstruction;
+import javax.xml.stream.events.XMLEvent;
+
+
+public class XMLEventsStreamReader implements XMLStreamReader {
+
+ @SuppressWarnings("unused")
+ private ArrayList<XMLEvent> events = null;
+ private HashMap<String, NamespaceContext> eventContext = null;
+
+ private int state;
+ private java.util.Iterator<XMLEvent> iterator;
+ private XMLEvent current;
+
+ public XMLEventsStreamReader(List<XMLEvent> events,Map<String, NamespaceContext> map) {
+ this.events = (ArrayList<XMLEvent>) events;
+ this.eventContext = (HashMap<String, NamespaceContext>) map;
+ this.iterator = events.iterator();
+ this.current = iterator.next();
+ this.state = current.getEventType();
+ }
+
+ public void close() throws XMLStreamException {
+ this.events = null;
+ this.eventContext = null;
+ this.iterator = null;
+ this.current = null;
+ }
+
+ private void checkElementState() {
+ if (getEventType() != START_ELEMENT && getEventType() != END_ELEMENT) {
+ throw new IllegalStateException();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public int getAttributeCount() {
+ checkElementState();
+ int count = 0;
+ Iterator<Attribute> iterator = current.asStartElement().getAttributes();
+ while (iterator.hasNext()) {
+ count++;
+ iterator.next();
+ }
+ return count;
+ }
+
+ /*
+ * Custom method to get attribute from the specified index
+ */
+ @SuppressWarnings("unchecked")
+ private Attribute getAttribute(int index) {
+ checkElementState();
+ int count = 0;
+ Attribute attribute = null;
+ Iterator<Attribute> iterator = current.asStartElement().getAttributes();
+ while (iterator.hasNext()) {
+ count++;
+ if (count == index) {
+ attribute = iterator.next();
+ } else {
+ iterator.next();
+ }
+ }
+ return attribute;
+ }
+
+
+ public String getAttributeLocalName(int index) {
+ checkElementState();
+ return getAttribute(index).getName().getLocalPart();
+ }
+
+ public QName getAttributeName(int index) {
+ checkElementState();
+ return getAttribute(index).getName();
+ }
+
+ public String getAttributeNamespace(int index) {
+ checkElementState();
+ return getAttributeName(index).getNamespaceURI();
+ }
+
+ public String getAttributePrefix(int index) {
+ checkElementState();
+ return getAttributeName(index).getPrefix();
+ }
+
+ public String getAttributeType(int index) {
+ checkElementState();
+ return getAttribute(index).getDTDType();
+ }
+
+ public String getAttributeValue(int index) {
+ checkElementState();
+ return getAttribute(index).getValue();
+ }
+
+ @SuppressWarnings("unchecked")
+ public String getAttributeValue(String namespaceURI, String localName) {
+ checkElementState();
+ Iterator<Attribute> iterator = current.asStartElement().getAttributes();
+ Attribute attribute;
+ while (iterator.hasNext()) {
+ attribute = iterator.next();
+ if (attribute.getName().getNamespaceURI().equalsIgnoreCase(
+ namespaceURI)
+ && attribute.getName().getLocalPart().equalsIgnoreCase(
+ localName)) {
+ return attribute.getValue();
+ }
+ }
+ return null;
+
+ }
+
+ public String getCharacterEncodingScheme() {
+ return "UTF-8";
+ }
+
+ public String getElementText() throws XMLStreamException {
+ checkElementState();
+ int eventType = getEventType();
+ String elementText = null;
+
+ if (eventType == START_ELEMENT) {
+ elementText = current.asStartElement().getName().getLocalPart();
+ } else if (eventType == END_ELEMENT) {
+ elementText = current.asEndElement().getName().getLocalPart();
+ }
+ return elementText;
+ }
+
+ public String getEncoding() {
+ return "UTF-8";
+ }
+
+ public int getEventType() {
+ return state;
+ }
+
+ public String getLocalName() {
+ checkElementState();
+ switch (current.getEventType()) {
+ case START_ELEMENT:
+ return current.asStartElement().getName().getLocalPart();
+ case END_ELEMENT:
+ return current.asEndElement().getName().getLocalPart();
+ }
+ return null;
+ }
+
+ public Location getLocation() {
+ return current.getLocation();
+ }
+
+ public QName getName() {
+ checkElementState();
+ switch (current.getEventType()) {
+ case START_ELEMENT:
+ return current.asStartElement().getName();
+ case END_ELEMENT:
+ return current.asEndElement().getName();
+ }
+ return null;
+ }
+
+ public NamespaceContext getNamespaceContext() {
+ checkElementState();
+ //return new TuscanyNamespaceContext(eventContext.get(getLocalName()));
+ return eventContext.get(getLocalName());
+ }
+
+ @SuppressWarnings("unchecked")
+ public int getNamespaceCount() {
+ int count = 0;
+ Iterator<Namespace> itr = current.asStartElement().getNamespaces();
+ while (itr.hasNext()) {
+ count++;
+ itr.next();
+ }
+ return count;
+ }
+
+ @SuppressWarnings("unchecked")
+ public String getNamespacePrefix(int index) {
+ Iterator<Namespace> itr = current.asStartElement().getNamespaces();
+ int level = 0;
+ Namespace ns = null;
+ while (itr.hasNext()) {
+ ns = itr.next();
+ if (level == index) {
+ return ns.getPrefix();
+ }
+ level++;
+ }
+ return null;
+ }
+
+ public String getNamespaceURI() {
+ checkElementState();
+ switch (current.getEventType()) {
+ case START_ELEMENT:
+ return current.asStartElement().getName().getNamespaceURI();
+ case END_ELEMENT:
+ return current.asEndElement().getName().getNamespaceURI();
+ }
+ return null;
+ }
+
+ public String getNamespaceURI(String prefix) {
+ return getNamespaceContext().getNamespaceURI(prefix);
+ }
+
+ @SuppressWarnings("unchecked")
+ public String getNamespaceURI(int index) {
+ Iterator<Namespace> itr = current.asStartElement().getNamespaces();
+ int level = 0;
+ Namespace ns = null;
+ while (itr.hasNext()) {
+ ns = itr.next();
+ if (level == index) {
+ return ns.getNamespaceURI();
+ }
+ level++;
+ }
+ return null;
+ }
+
+ public String getPIData() {
+ if (current.isProcessingInstruction()) {
+ ProcessingInstruction pi = (ProcessingInstruction) current;
+ return pi.getData();
+ } else {
+ throw new IllegalStateException(current.toString());
+ }
+ }
+
+ public String getPITarget() {
+ if (current.isProcessingInstruction()) {
+ ProcessingInstruction pi = (ProcessingInstruction) current;
+ return pi.getTarget();
+ } else {
+ throw new IllegalStateException(current.toString());
+ }
+ }
+
+ public String getPrefix() {
+ checkElementState();
+ if (current.isStartElement()) {
+ return current.asStartElement().getName().getPrefix();
+ }
+ return null;
+ }
+
+ /*
+ * FIXME: Implementation pending...
+ *
+ * @see (non-Javadoc)
+ * javax.xml.stream.util.StreamReaderDelegate#getProperty(java.lang.String)
+ */
+ public Object getProperty(String name) throws IllegalArgumentException {
+ // TODO Auto-generated method stub
+
+ return null;
+ }
+
+ public String getText() {
+ if (current.isCharacters()) {
+ return current.asCharacters().getData();
+ } else {
+ throw new IllegalStateException(current.toString());
+ }
+ }
+
+ public char[] getTextCharacters() {
+ if (current.isCharacters()) {
+ return current.asCharacters().getData().toCharArray();
+ } else {
+ throw new IllegalStateException(current.toString());
+ }
+ }
+
+ /*
+ * FIXME: Implementation pending... (non-Javadoc)
+ *
+ * @see javax.xml.stream.util.StreamReaderDelegate#getTextCharacters(int,
+ * char[], int, int)
+ */
+ public int getTextCharacters(int sourceStart, char[] target,
+ int targetStart, int length) throws XMLStreamException {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /*
+ * FIXME:Implementaion can be improved (non-Javadoc)
+ *
+ * @see javax.xml.stream.util.StreamReaderDelegate#getTextLength()
+ */
+ public int getTextLength() {
+ if (current.isCharacters()) {
+ return current.asCharacters().getData().length();
+ } else {
+ throw new IllegalStateException(current.toString());
+ }
+ }
+
+ /*
+ * FIXME: Implementation pending... (non-Javadoc)
+ *
+ * @see javax.xml.stream.util.StreamReaderDelegate#getTextStart()
+ */
+ public int getTextStart() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ /*
+ * FIXME: Implementation pending... (non-Javadoc)
+ *
+ * @see javax.xml.stream.util.StreamReaderDelegate#getTextStart()
+ */
+ public String getVersion() {
+ // TODO Auto-generated method stub
+
+ return null;
+ }
+
+ public boolean hasName() {
+ return false;
+ }
+
+ public boolean hasNext() throws XMLStreamException {
+ return iterator.hasNext() || state != END_DOCUMENT;
+
+ }
+
+ public boolean hasText() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ /*
+ * FIXME: Implementation pending... (non-Javadoc)
+ *
+ * @see javax.xml.stream.util.StreamReaderDelegate#getTextStart()
+ */
+ public boolean isAttributeSpecified(int index) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isCharacters() {
+ return current.isCharacters();
+ }
+
+ public boolean isEndElement() {
+ return current.isEndElement();
+ }
+
+ public boolean isStandalone() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public boolean isStartElement() {
+ return current.isStartElement();
+ }
+
+ public boolean isWhiteSpace() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public int next() throws XMLStreamException {
+ if (!hasNext()) {
+ throw new IllegalStateException("No more events");
+ }
+ if (!iterator.hasNext()) {
+ state = END_DOCUMENT;
+ current = null;
+ return state;
+ }
+ current = iterator.next();
+ state = current.getEventType();
+ return state;
+ }
+
+ public int nextTag() throws XMLStreamException {
+ return iterator.next().getEventType();
+ }
+
+ public void require(int type, String namespaceURI, String localName)
+ throws XMLStreamException {
+ boolean require = false;
+ String uri = getNamespaceURI();
+ String name = getLocalName();
+ if (state == type && namespaceURI.equals(uri) && localName.equals(name)) {
+ require = true;
+ }
+ if (require != true) {
+ throw new XMLStreamException();
+ }
+ }
+
+ public boolean standaloneSet() {
+ return false;
+ }
+
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLFragmentStreamReader.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLFragmentStreamReader.java
new file mode 100644
index 0000000000..66361e1d76
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/XMLFragmentStreamReader.java
@@ -0,0 +1,53 @@
+/*
+ * 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.contribution.processor.xml;
+
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamReader;
+
+public interface XMLFragmentStreamReader extends XMLStreamReader {
+ QName NIL_QNAME = new QName("http://www.w3.org/2001/XMLSchema-instance", "nil", "xsi");
+ String NIL_VALUE_TRUE = "true";
+
+ /**
+ * this will help to handle Text within the current element. user should
+ * pass the element text to the property list as this ELEMENT_TEXT as the
+ * key. This key deliberately has a space in it so that it is not a valid
+ * XML name
+ */
+ String ELEMENT_TEXT = "Element Text";
+
+ /**
+ * Extra method to query the state of the pullparser
+ */
+ boolean isDone();
+
+ /**
+ * add the parent namespace context to this parser
+ */
+ void setParentNamespaceContext(NamespaceContext nsContext);
+
+ /**
+ * Initiate the parser - this will do whatever the needed tasks to initiate
+ * the parser and must be called before attempting any specific parsing
+ * using this parser
+ */
+ void init();
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java
new file mode 100644
index 0000000000..ff7bf7068a
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionGeneratedMetadataDocumentProcessor.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.contribution.xml;
+
+import javax.xml.stream.XMLInputFactory;
+
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * URLArtifactProcessor that handles sca-contribution-generated.xml files.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionGeneratedMetadataDocumentProcessor extends ContributionMetadataDocumentProcessor {
+
+ public ContributionGeneratedMetadataDocumentProcessor(XMLInputFactory inputFactory,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ super(inputFactory, staxProcessor, monitor);
+ }
+
+ public ContributionGeneratedMetadataDocumentProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ super(modelFactories, staxProcessor, monitor);
+ }
+
+ @Override
+ public String getArtifactType() {
+ return "sca-contribution-generated.xml";
+ }
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java
new file mode 100644
index 0000000000..f080f23797
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataDocumentProcessor.java
@@ -0,0 +1,131 @@
+/*
+ * 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.contribution.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.contribution.ContributionMetadata;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+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.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+
+/**
+ * URLArtifactProcessor that handles sca-contribution.xml files.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionMetadataDocumentProcessor implements URLArtifactProcessor<ContributionMetadata>{
+ private final StAXArtifactProcessor staxProcessor;
+ private final XMLInputFactory inputFactory;
+ private final Monitor monitor;
+
+ public ContributionMetadataDocumentProcessor(XMLInputFactory inputFactory,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ this.inputFactory = inputFactory;
+ this.staxProcessor = staxProcessor;
+ this.monitor = monitor;
+ }
+
+ public ContributionMetadataDocumentProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class);
+ this.staxProcessor = staxProcessor;
+ this.monitor = monitor;
+ }
+
+ /**
+ * Report a exception.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-xml-validation-messages", Severity.ERROR, model, message, ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public String getArtifactType() {
+ return "sca-contribution.xml";
+ }
+
+ public Class<ContributionMetadata> getModelType() {
+ return ContributionMetadata.class;
+ }
+
+ public ContributionMetadata read(URL contributionURL, URI uri, URL url) throws ContributionReadException {
+ InputStream urlStream = null;
+ try {
+
+ // Create a stream reader
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ urlStream = connection.getInputStream();
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream);
+ reader.nextTag();
+
+ // Read the contribution model
+ ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader);
+
+ return contribution;
+
+ } catch (XMLStreamException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("XMLStreamException", inputFactory, ex);
+ throw ex;
+ } catch (IOException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("IOException", inputFactory, ex);
+ throw ex;
+ } finally {
+ try {
+ if (urlStream != null) {
+ urlStream.close();
+ urlStream = null;
+ }
+ } catch (IOException ioe) {
+ //ignore
+ }
+ }
+ }
+
+ public void resolve(ContributionMetadata contribution, ModelResolver resolver) throws ContributionResolveException {
+ staxProcessor.resolve(contribution, resolver);
+ }
+
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java
new file mode 100644
index 0000000000..804af17719
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessor.java
@@ -0,0 +1,221 @@
+/*
+ * 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.contribution.xml;
+
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+
+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.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.ContributionMetadata;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+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.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;
+
+/**
+ * Processor for contribution metadata
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionMetadataProcessor extends BaseStAXArtifactProcessor implements StAXArtifactProcessor<ContributionMetadata> {
+ private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200903";
+
+ private static final QName CONTRIBUTION_QNAME = new QName(SCA11_NS, "contribution");
+ private static final QName DEPLOYABLE_QNAME = new QName(SCA11_NS, "deployable");
+
+ private final AssemblyFactory assemblyFactory;
+ private final ContributionFactory contributionFactory;
+
+ private final StAXArtifactProcessor<Object> extensionProcessor;
+ private Monitor monitor;
+
+ public ContributionMetadataProcessor(AssemblyFactory assemblyFactory,
+ ContributionFactory contributionFactory,
+ StAXArtifactProcessor<Object> extensionProcessor,
+ Monitor monitor) {
+ this.assemblyFactory = assemblyFactory;
+ this.contributionFactory = contributionFactory;
+ this.extensionProcessor = extensionProcessor;
+ this.monitor = monitor;
+ }
+
+ /**
+ * Report a error.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-xml-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ public ContributionMetadataProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor<Object> extensionProcessor,
+ Monitor monitor) {
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ this.contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ this.extensionProcessor = extensionProcessor;
+ this.monitor = monitor;
+ }
+
+
+ public QName getArtifactType() {
+ return CONTRIBUTION_QNAME;
+ }
+
+ public Class<ContributionMetadata> getModelType() {
+ return ContributionMetadata.class;
+ }
+
+ public ContributionMetadata read(XMLStreamReader reader) throws ContributionReadException {
+ ContributionMetadata contribution = null;
+ QName name = null;
+
+ try {
+ while (reader.hasNext()) {
+ int event = reader.getEventType();
+ switch (event) {
+ case START_ELEMENT:
+ name = reader.getName();
+
+ if (CONTRIBUTION_QNAME.equals(name)) {
+
+ // Read <contribution>
+ contribution = this.contributionFactory.createContributionMetadata();
+ contribution.setUnresolved(true);
+
+ } else if (DEPLOYABLE_QNAME.equals(name)) {
+
+ // Read <deployable>
+ QName compositeName = getQName(reader, "composite");
+ if (compositeName == null) {
+ error("AttributeCompositeMissing", reader);
+ //throw new ContributionReadException("Attribute 'composite' is missing");
+ } else {
+ if (contribution != null) {
+ Composite composite = assemblyFactory.createComposite();
+ composite.setName(compositeName);
+ composite.setUnresolved(true);
+ contribution.getDeployables().add(composite);
+ }
+ }
+ } else {
+
+ // Read an extension element
+ Object extension = extensionProcessor.read(reader);
+ if (extension != null && contribution != null) {
+ if (extension instanceof Import) {
+ contribution.getImports().add((Import)extension);
+ } else if (extension instanceof Export) {
+ contribution.getExports().add((Export)extension);
+ }
+ }
+ }
+ break;
+
+ case XMLStreamConstants.END_ELEMENT:
+ if (CONTRIBUTION_QNAME.equals(reader.getName())) {
+ return contribution;
+ }
+ break;
+ }
+
+ //Read the next element
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+ }
+ catch (XMLStreamException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("XMLStreamException", reader, ex);
+ }
+
+ return contribution;
+ }
+
+ public void write(ContributionMetadata contribution, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+
+ // Write <contribution>
+ writeStartDocument(writer, CONTRIBUTION_QNAME.getNamespaceURI(), CONTRIBUTION_QNAME.getLocalPart());
+
+ // Write <import>
+ for (Import imp: contribution.getImports()) {
+ extensionProcessor.write(imp, writer);
+ }
+
+ // Write <export>
+ for (Export export: contribution.getExports()) {
+ extensionProcessor.write(export, writer);
+ }
+
+ // Write <deployable>
+ for (Composite deployable: contribution.getDeployables()) {
+ writeStart(writer, DEPLOYABLE_QNAME.getNamespaceURI(), DEPLOYABLE_QNAME.getLocalPart(),
+ new XAttr("composite", deployable.getName()));
+ writeEnd(writer);
+ }
+
+ writeEndDocument(writer);
+ }
+
+ public void resolve(ContributionMetadata contribution, ModelResolver resolver) throws ContributionResolveException {
+
+ // Resolve imports and exports
+ for (Export export: contribution.getExports()) {
+ extensionProcessor.resolve(export, resolver);
+ }
+ for (Import import_: contribution.getImports()) {
+ extensionProcessor.resolve(import_, resolver);
+ }
+
+ // Resolve deployable composites
+ List<Composite> deployables = contribution.getDeployables();
+ for (int i = 0, n = deployables.size(); i < n; i++) {
+ Composite deployable = deployables.get(i);
+ Composite resolved = (Composite)resolver.resolveModel(Composite.class, deployable);
+ if (resolved != deployable) {
+ deployables.set(i, resolved);
+ }
+ }
+
+ contribution.setUnresolved(false);
+ }
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.java b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.java
new file mode 100644
index 0000000000..ddc768b61c
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/java/org/apache/tuscany/sca/contribution/xml/ContributionModelResolver.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.contribution.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * A Model Resolver for Contribution models.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionModelResolver implements ModelResolver {
+
+ private Map<String, Contribution> map = new HashMap<String, Contribution>();
+
+ public ContributionModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ }
+
+ public void addModel(Object resolved) {
+ Contribution contribution = (Contribution)resolved;
+ map.put(contribution.getURI(), contribution);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(((Contribution)resolved).getURI());
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ // Lookup a contribution for the given URI
+ String uri = ((Contribution)unresolved).getURI();
+ if (uri != null) {
+ Contribution resolved = (Contribution) map.get(uri);
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+ return unresolved;
+ } else {
+
+ // If no URI was specified, just return the first contribution
+ if (!map.isEmpty()) {
+ Contribution resolved = map.values().iterator().next();
+ return modelClass.cast(resolved);
+ } else {
+ return unresolved;
+ }
+ }
+ }
+
+}
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
new file mode 100644
index 0000000000..4c7416d38e
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor
@@ -0,0 +1,20 @@
+# 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.contribution.xml.ContributionMetadataProcessor;qname=http://docs.oasis-open.org/ns/opencsa/sca/200903#contribution,model=org.apache.tuscany.sca.contribution.ContributionMetadata
+org.apache.tuscany.sca.contribution.processor.xml.AnyElementProcessor;qname=http://www.w3.org/2001/XMLSchema#anyElement,model=java.lang.Object
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor
new file mode 100644
index 0000000000..b4a13295bc
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor
@@ -0,0 +1,19 @@
+# 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 attribute processor extension
+org.apache.tuscany.sca.contribution.processor.xml.AnyAttributeProcessor;qname=http://www.w3.org/2001/XMLSchema#anyAttribute,model=org.apache.tuscany.sca.assembly.Extension
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor
new file mode 100644
index 0000000000..23adab56b9
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor
@@ -0,0 +1,20 @@
+# 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.contribution.xml.ContributionMetadataDocumentProcessor;type=sca-contribution.xml,model=org.apache.tuscany.sca.contribution.ContributionMetadata
+org.apache.tuscany.sca.contribution.xml.ContributionGeneratedMetadataDocumentProcessor;type=sca-contribution-generated.xml
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver
new file mode 100644
index 0000000000..68030bf6e6
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/resources/META-INF/services/org.apache.tuscany.sca.contribution.resolver.ModelResolver
@@ -0,0 +1,18 @@
+# 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.contribution.xml.ContributionModelResolver;model=org.apache.tuscany.sca.contribution.Contribution
diff --git a/branches/2.0-M2/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties b/branches/2.0-M2/modules/contribution-xml/src/main/resources/contribution-xml-validation-messages.properties
new file mode 100644
index 0000000000..4827fd5e94
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/main/resources/contribution-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.
+#
+#
+XMLStreamException = XMLStreamException occured due to : {0}
+IOException = IOException occured due to : {0}
+AttributeCompositeMissing = Attribute 'composite' is missing
+
diff --git a/branches/2.0-M2/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java b/branches/2.0-M2/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java
new file mode 100644
index 0000000000..35e8b57136
--- /dev/null
+++ b/branches/2.0-M2/modules/contribution-xml/src/test/java/org/apache/tuscany/sca/contribution/xml/ContributionMetadataProcessorTestCase.java
@@ -0,0 +1,145 @@
+/*
+ * 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.contribution.xml;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+
+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.contribution.ContributionMetadata;
+import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor;
+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.UtilityExtensionPoint;
+import org.apache.tuscany.sca.monitor.DefaultMonitorFactory;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test the contribution metadata processor.
+ *
+ * @version $Rev$ $Date$
+ */
+
+public class ContributionMetadataProcessorTestCase {
+
+ private static final String VALID_XML =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<contribution xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200903\" xmlns:ns=\"http://ns\">"
+ + "<deployable composite=\"ns:Composite1\"/>"
+ + "<deployable composite=\"ns:Composite2\"/>"
+ + "</contribution>";
+
+ private static final String INVALID_XML =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<contribution xmlns=\"http://docs.oasis-open.org/ns/opencsa/sca/200903\" xmlns:ns=\"http://ns\">"
+ + "<deployable composite=\"ns:Composite1\"/>"
+ + "<deployable/>"
+ + "</contribution>";
+
+ private static XMLInputFactory inputFactory;
+ private static XMLOutputFactory outputFactory;
+ private static StAXArtifactProcessor<Object> staxProcessor;
+ private static Monitor monitor;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ ExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry();
+
+ inputFactory = XMLInputFactory.newInstance();
+ outputFactory = XMLOutputFactory.newInstance();
+
+ // Create a monitor
+ UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
+ MonitorFactory monitorFactory = new DefaultMonitorFactory();
+ if (monitorFactory != null) {
+ monitor = monitorFactory.createMonitor();
+ utilities.addUtility(monitorFactory);
+ }
+ StAXArtifactProcessorExtensionPoint staxProcessors =
+ extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory, null);
+ }
+
+ @Test
+ public void testRead() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML));
+ ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader);
+ assertNotNull(contribution);
+ assertEquals(2, contribution.getDeployables().size());
+ }
+
+ @Test
+ public void testReadInvalid() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(INVALID_XML));
+ /*try {
+ staxProcessor.read(reader);
+ fail("InvalidException should have been thrown");
+ } catch (ContributionReadException e) {
+ assertTrue(true);
+ }*/
+ staxProcessor.read(reader);
+ Problem problem = monitor.getLastProblem();
+ assertNotNull(problem);
+ assertEquals("AttributeCompositeMissing", problem.getMessageId());
+ }
+
+ @Test
+ public void testWrite() throws Exception {
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(new StringReader(VALID_XML));
+ ContributionMetadata contribution = (ContributionMetadata)staxProcessor.read(reader);
+
+ validateContribution(contribution);
+
+ //write the contribution metadata contents
+ StringWriter stringWriter = new StringWriter();
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(stringWriter);
+ staxProcessor.write(contribution, writer);
+ stringWriter.close();
+
+ reader = inputFactory.createXMLStreamReader(new StringReader(stringWriter.toString()));
+ contribution = (ContributionMetadata)staxProcessor.read(reader);
+
+ validateContribution(contribution);
+ }
+
+ private void validateContribution(ContributionMetadata contribution) {
+ QName deployable;
+
+ assertNotNull(contribution);
+ assertEquals(2, contribution.getDeployables().size());
+ deployable = new QName("http://ns", "Composite1");
+ assertEquals(deployable, contribution.getDeployables().get(0).getName());
+ deployable = new QName("http://ns", "Composite2");
+ assertEquals(deployable, contribution.getDeployables().get(1).getName());
+ }
+
+}