summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor
diff options
context:
space:
mode:
Diffstat (limited to 'sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor')
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java48
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java532
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java46
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java96
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java43
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java45
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java63
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java79
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java324
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java291
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java319
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java465
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java123
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedArtifactProcessor.java41
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedURLArtifactProcessor.java30
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java283
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java259
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java148
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ProcessorContext.java127
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java62
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java57
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.java64
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java56
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java52
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java66
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java48
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java43
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java40
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java49
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java409
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java63
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/ContributionContentProcessor.java349
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java79
-rw-r--r--sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java96
34 files changed, 4895 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java
new file mode 100644
index 0000000000..9ac3aebaf6
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ArtifactProcessor.java
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * Base interface for artifact processors.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ArtifactProcessor<M> {
+
+ /**
+ * Resolve references from this model to other models. For example references
+ * from a composite to another one, or references from a composite to a WSDL
+ * model.
+ *
+ * @param model The model to resolve
+ * @param resolver The resolver to use to resolve referenced models
+ * @param context The context for the processor
+ */
+ void resolve(M model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException;
+
+ /**
+ * Returns the type of model handled by this artifact processor.
+ *
+ * @return The type of model handled by this artifact processor
+ */
+ Class<M> getModelType();
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java
new file mode 100644
index 0000000000..82902a11fe
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/BaseStAXArtifactProcessor.java
@@ -0,0 +1,532 @@
+/*
+ * 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;
+
+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.List;
+
+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 org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Extensible;
+import org.apache.tuscany.sca.assembly.Extension;
+import org.apache.tuscany.sca.common.xml.stax.StAXHelper;
+
+
+/**
+ * A base class with utility methods for the other artifact processors in this module.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.inheritfrom
+ */
+public abstract class BaseStAXArtifactProcessor {
+ private static String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912";
+ private static String SCA11_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1";
+
+ /**
+ * The StAXHelper without states
+ */
+ private static final StAXHelper helper = new StAXHelper(null, null, null);
+ /**
+ * Returns a QName from a string.
+ * @param reader
+ * @param value
+ * @return
+ */
+ protected QName getQNameValue(XMLStreamReader reader, String value) {
+ return StAXHelper.getValueAsQName(reader, value);
+ }
+
+ /**
+ * Returns the boolean value of an attribute.
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected boolean getBoolean(XMLStreamReader reader, String name) {
+ Boolean attr = StAXHelper.getAttributeAsBoolean(reader, name);
+ if (attr == null) {
+ return false;
+ } else {
+ return attr.booleanValue();
+ }
+ }
+
+ /**
+ * Returns the QName value of an attribute.
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected QName getQName(XMLStreamReader reader, String name) {
+ return StAXHelper.getAttributeAsQName(reader, name);
+ }
+
+ /**
+ * Returns the value of an attribute as a list of QNames.
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected List<QName> getQNames(XMLStreamReader reader, String name) {
+ return StAXHelper.getAttributeAsQNames(reader, name);
+ }
+
+ /**
+ * Returns the string value of an attribute.
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected String getString(XMLStreamReader reader, String name) {
+ return StAXHelper.getAttributeAsString(reader, name);
+ }
+
+ /**
+ * Returns the string value of an attribute.
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected String getURIString(XMLStreamReader reader, String name) {
+ return StAXHelper.getAttributeAsURIString(reader, name);
+ }
+
+ /**
+ * Test if an attribute is explicitly set
+ * @param reader
+ * @param name
+ * @return
+ */
+ protected boolean isSet(XMLStreamReader reader, String name) {
+ return StAXHelper.isAttributePresent(reader, name);
+ }
+
+ /**
+ * Returns the value of xsi:type attribute
+ * @param reader The XML stream reader
+ * @return The QName of the type, if the attribute is not present, null is
+ * returned.
+ */
+ protected QName getXSIType(XMLStreamReader reader) {
+ return StAXHelper.getXSIType(reader);
+ }
+
+ /**
+ * Parse the next child element.
+ * @param reader
+ * @return
+ * @throws XMLStreamException
+ */
+ protected boolean nextChildElement(XMLStreamReader reader) throws XMLStreamException {
+ while (reader.hasNext()) {
+ int event = reader.next();
+ if (event == END_ELEMENT) {
+ return false;
+ }
+ if (event == START_ELEMENT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Advance the stream to the next END_ELEMENT event skipping any nested
+ * content.
+ * @param reader the reader to advance
+ * @throws XMLStreamException if there was a problem reading the stream
+ */
+ protected void skipToEndElement(XMLStreamReader reader) throws XMLStreamException {
+ StAXHelper.skipToEndElement(reader);
+ }
+
+ /**
+ *
+ * @param writer
+ * @param uri
+ * @throws XMLStreamException
+ */
+ private String setPrefix(XMLStreamWriter writer, String uri) throws XMLStreamException {
+ if (uri == null) {
+ return null;
+ }
+ String prefix = writer.getPrefix(uri);
+ if (prefix != null) {
+ return null;
+ } else {
+
+ // Find an available prefix and bind it to the given URI
+ NamespaceContext nsc = writer.getNamespaceContext();
+ for (int i=1; ; i++) {
+ prefix = "ns" + i;
+ if (nsc.getNamespaceURI(prefix) == null) {
+ break;
+ }
+ }
+ writer.setPrefix(prefix, uri);
+ return prefix;
+ }
+
+ }
+
+ /**
+ * Start an element.
+ * @param uri
+ * @param name
+ * @param attrs
+ * @throws XMLStreamException
+ */
+ protected void writeStart(XMLStreamWriter writer, String uri, String name, XAttr... attrs)
+ throws XMLStreamException {
+ helper.writeStartElement(writer, "", name, uri);
+ writeAttributes(writer, attrs);
+ }
+
+ /**
+ * Start an element.
+ * @param qname
+ * @param attrs
+ * @throws XMLStreamException
+ */
+ protected void writeStart(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException {
+ writeStart(writer, qname.getNamespaceURI(), qname.getLocalPart(), attrs);
+ }
+
+ /**
+ * End an element.
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void writeEnd(XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeEndElement();
+ }
+
+ /**
+ * Start a document.
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void writeStartDocument(XMLStreamWriter writer, String uri, String name, XAttr... attrs) throws XMLStreamException {
+ writer.writeStartDocument();
+ writer.setDefaultNamespace(uri);
+ writeStart(writer, uri, name, attrs);
+ // writer.writeDefaultNamespace(uri);
+ }
+
+ /**
+ * Start a document.
+ * @param writer
+ * @param qname
+ * @param attrs
+ * @throws XMLStreamException
+ */
+ protected void writeStartDocument(XMLStreamWriter writer, QName qname, XAttr... attrs) throws XMLStreamException {
+ writeStartDocument(writer, qname.getNamespaceURI(), qname.getLocalPart(), attrs);
+ }
+
+ /**
+ * End a document.
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void writeEndDocument(XMLStreamWriter writer) throws XMLStreamException {
+ writer.writeEndDocument();
+ }
+
+ /**
+ * Write attributes to the current element.
+ * @param writer
+ * @param attrs
+ * @throws XMLStreamException
+ */
+ protected void writeAttributes(XMLStreamWriter writer, XAttr... attrs) throws XMLStreamException {
+ for (XAttr attr : attrs) {
+ if (attr != null)
+ attr.write(writer);
+ }
+ }
+
+ /**
+ *
+ * @param reader
+ * @param extensible
+ * @param extensionAttributeProcessor
+ * @param extensionAttributeProcessor
+ * @param extensionFactory
+ * @param context TODO
+ * @param elementName
+ * @throws ContributionReadException
+ * @throws XMLStreamException
+ */
+ protected void readExtendedAttributes(XMLStreamReader reader,
+ Extensible extensible,
+ StAXAttributeProcessor extensionAttributeProcessor,
+ AssemblyFactory extensionFactory, ProcessorContext context) throws ContributionReadException,
+ XMLStreamException {
+ QName elementName = reader.getName();
+ for (int a = 0; a < reader.getAttributeCount(); a++) {
+ QName attributeName = reader.getAttributeName(a);
+ if (attributeName.getNamespaceURI() != null && attributeName.getNamespaceURI().length() > 0) {
+ if (!elementName.getNamespaceURI().equals(attributeName.getNamespaceURI())) {
+ Object attributeValue = extensionAttributeProcessor.read(attributeName, reader, context);
+ Extension attributeExtension;
+ if (attributeValue instanceof Extension) {
+ attributeExtension = (Extension)attributeValue;
+ } else {
+ attributeExtension = extensionFactory.createExtension();
+ attributeExtension.setQName(attributeName);
+ attributeExtension.setValue(attributeValue);
+ attributeExtension.setAttribute(true);
+ }
+ extensible.getAttributeExtensions().add(attributeExtension);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param writer
+ * @param extensibleElement
+ * @param extensionAttributeProcessor
+ * @param context TODO
+ * @param attributeModel
+ * @throws ContributionWriteException
+ * @throws XMLStreamException
+ */
+ protected void writeExtendedAttributes(XMLStreamWriter writer,
+ Extensible extensibleElement,
+ StAXAttributeProcessor extensionAttributeProcessor, ProcessorContext context)
+ throws ContributionWriteException, XMLStreamException {
+
+ for (Extension extension : extensibleElement.getAttributeExtensions()) {
+ if (extension.isAttribute()) {
+ extensionAttributeProcessor.write(extension, writer, context);
+ }
+ }
+ }
+
+ protected void readExtendedElement(XMLStreamReader reader,
+ Extensible extensible,
+ StAXArtifactProcessor extensionProcessor, ProcessorContext context)
+ throws ContributionReadException, XMLStreamException {
+
+ Object ext = extensionProcessor.read(reader, context);
+ if (extensible != null) {
+ extensible.getExtensions().add(ext);
+ }
+ }
+
+ protected void writeExtendedElements(XMLStreamWriter writer,
+ Extensible extensible,
+ StAXArtifactProcessor extensionProcessor, ProcessorContext context)
+ throws ContributionWriteException, XMLStreamException {
+
+ List <Object> otherExtensions = new ArrayList<Object>();
+
+ // write all generic extensions as elements
+ // to produce semanticaly equal xml output
+ for (Object ext : extensible.getExtensions()) {
+ if (ext instanceof Extension) {
+ extensionProcessor.write(ext, writer, context);
+ } else {
+ otherExtensions.add(ext);
+ }
+ }
+
+ //wrap xml extensibility into a extension wrapper element
+ if(otherExtensions.size() > 0) {
+
+ writeStart(writer, SCA11_NS, "extensions");
+
+ for (Object extension : otherExtensions) {
+ extensionProcessor.write(extension, writer, context);
+ }
+
+ writeEnd(writer);
+ }
+
+ }
+
+ /**
+ * Represents an XML attribute that needs to be written to a document.
+ */
+ public static class XAttr {
+
+ private static final String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200912";
+
+ private String uri = SCA11_NS;
+ private String name;
+ private Object value;
+
+ public XAttr(String uri, String name, String value) {
+ this.uri = uri;
+ this.name = name;
+ this.value = value;
+ }
+
+ public XAttr(String name, String value) {
+ this(null, name, value);
+ }
+
+ public XAttr(String uri, String name, List<?> values) {
+ this.uri = uri;
+ this.name = name;
+ this.value = values;
+ }
+
+ public XAttr(String name, List<?> values) {
+ this(null, name, values);
+ }
+
+ public XAttr(String uri, String name, Boolean value) {
+ this.uri = uri;
+ this.name = name;
+ this.value = value;
+ }
+
+ public XAttr(String name, Boolean value) {
+ this(null, name, value);
+ }
+
+ public XAttr(String uri, String name, Integer value) {
+ this.uri = uri;
+ this.name = name;
+ this.value = value;
+ }
+
+ public XAttr(String name, Integer value) {
+ this(null, name, value);
+ }
+
+ public XAttr(String uri, String name, Double value) {
+ this.uri = uri;
+ this.name = name;
+ this.value = value;
+ }
+
+ public XAttr(String name, Double value) {
+ this(null, name, value);
+ }
+
+ public XAttr(String uri, String name, QName value) {
+ this.uri = uri;
+ this.name = name;
+ this.value = value;
+ }
+
+ public XAttr(String name, QName value) {
+ this(null, name, value);
+ }
+
+ public String toString() {
+ return uri == null ? name + "=\"" + value + "\"" : "{" + uri + "}" + name + "=\"" + value + "\"";
+ }
+
+ /**
+ * Writes a string from a QName and registers a prefix for its namespace.
+ * @param reader
+ * @param value
+ * @return
+ */
+ private String writeQNameValue(XMLStreamWriter writer, QName qname) throws XMLStreamException {
+ if (qname != null) {
+ String prefix = helper.writeNamespace(writer, qname.getPrefix(), qname.getNamespaceURI());
+ if ("".equals(prefix)) {
+ return qname.getLocalPart();
+ } else {
+ return prefix + ":" + qname.getLocalPart();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Write to document
+ * @param writer
+ * @throws XMLStreamException
+ */
+ public void write(XMLStreamWriter writer) throws XMLStreamException {
+ String str;
+ if (value instanceof QName) {
+
+ // Write a QName
+ str = writeQNameValue(writer, (QName)value);
+
+ } else if (value instanceof Collection) {
+
+ // Write a list of values
+ Collection<?> values = (Collection<?>)value;
+ if (values.isEmpty()) {
+ return;
+ }
+ StringBuffer buffer = new StringBuffer();
+ for (Object v: values) {
+ if (v == null) {
+ // Skip null values
+ continue;
+ }
+
+ if (v instanceof XAttr) {
+ // Write an XAttr value
+ ((XAttr)v).write(writer);
+ continue;
+ }
+
+ if (buffer.length() != 0) {
+ buffer.append(' ');
+ }
+ if (v instanceof QName) {
+ // Write a QName value
+ buffer.append(writeQNameValue(writer, (QName)v));
+ } else {
+ // Write value as a string
+ buffer.append(String.valueOf(v));
+ }
+ }
+ str = buffer.toString();
+
+ } else {
+
+ // Write a string
+ if (value == null) {
+ return;
+ }
+ str = String.valueOf(value);
+ }
+ if (str.length() == 0 && (value instanceof Collection)) {
+ return;
+ }
+
+ helper.writeAttribute(writer, "", name, uri, str);
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java
new file mode 100644
index 0000000000..93cb8c7fc7
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionException.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.contribution.processor;
+
+/**
+ * Base class for exceptions raised by contribution services.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public class ContributionException extends Exception {
+
+ private static final long serialVersionUID = 4432880414927652578L;
+
+ protected ContributionException() {
+ super();
+ }
+
+ protected ContributionException(String message) {
+ super(message);
+ }
+
+ protected ContributionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContributionException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.java
new file mode 100644
index 0000000000..ced2ad1899
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionReadException.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.contribution.processor;
+
+
+/**
+ * Denotes an exception while reading artifacts inside an SCA contribution.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public class ContributionReadException extends ContributionException {
+ public static final int UNDEFINED = -1;
+ private static final long serialVersionUID = -7459051598906813461L;
+ private String resourceURI;
+ private int line = UNDEFINED;
+ private int column = UNDEFINED;
+
+ public ContributionReadException(String message) {
+ super(message);
+ }
+
+ public ContributionReadException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContributionReadException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns the location of the resource that was being read.
+ *
+ * @return the location of the resource that was being read
+ */
+ public String getResourceURI() {
+ return resourceURI;
+ }
+
+ /**
+ * Sets the location of the resource that was being read.
+ *
+ * @param resourceURI the location of the resource that was being read
+ */
+ public void setResourceURI(String resourceURI) {
+ this.resourceURI = resourceURI;
+ }
+
+ /**
+ * Returns the line inside the resource that was being read.
+ * @return the line inside the resource that was being read
+ */
+ public int getLine() {
+ return line;
+ }
+
+ /**
+ * Sets the line inside the resource that was being read.
+ * @param line the line inside the resource that was being read
+ */
+ public void setLine(int line) {
+ this.line = line;
+ }
+
+ /**
+ * Returns the column inside the resource that was being read.
+ * @return the column inside the resource that was being read
+ */
+ public int getColumn() {
+ return column;
+ }
+
+ /**
+ * Sets the column inside the resource that was being read.
+ * @param column the column inside the resource that was being read
+ */
+ public void setColumn(int column) {
+ this.column = column;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java
new file mode 100644
index 0000000000..af42c25734
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionResolveException.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+
+/**
+ * Denotes a problem while resolving models inside an SCA contribution.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public class ContributionResolveException extends ContributionException {
+ private static final long serialVersionUID = -7459051598906813461L;
+
+ public ContributionResolveException(String message) {
+ super(message);
+ }
+
+ public ContributionResolveException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContributionResolveException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java
new file mode 100644
index 0000000000..9db6292e3d
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionRuntimeException.java
@@ -0,0 +1,45 @@
+/*
+ * 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;
+
+/**
+ * Base class for runtime exceptions raised by contribution services.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public class ContributionRuntimeException extends RuntimeException {
+ private static final long serialVersionUID = 7711215366287498896L;
+
+ protected ContributionRuntimeException() {
+ super();
+ }
+
+ protected ContributionRuntimeException(String message) {
+ super(message);
+ }
+
+ protected ContributionRuntimeException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContributionRuntimeException(Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java
new file mode 100644
index 0000000000..4e1cd287bb
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ContributionWriteException.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tuscany.sca.contribution.processor;
+
+
+
+/**
+ * Denotes an exception while writing artifacts inside an SCA contribution.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public class ContributionWriteException extends ContributionException {
+ private static final long serialVersionUID = -7459051598906813461L;
+ private String resourceURI;
+
+ public ContributionWriteException(String message) {
+ super(message);
+ }
+
+ public ContributionWriteException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ContributionWriteException(Throwable cause) {
+ super(cause);
+ }
+
+ /**
+ * Returns the location of the resource that was being written.
+ *
+ * @return the location of the resource that was being written
+ */
+ public String getResourceURI() {
+ return resourceURI;
+ }
+
+ /**
+ * Sets the location of the resource that was being written.
+ *
+ * @param resourceURI the location of the resource that was being written
+ */
+ public void setResourceURI(String resourceURI) {
+ this.resourceURI = resourceURI;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java
new file mode 100644
index 0000000000..774971b8be
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultArtifactProcessorExtensionPoint.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.common.java.reflection.JavaIntrospectionHelper;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+
+/**
+ * The default implementation of an artifact processor extension point.
+ *
+ * @version $Rev$ $Date$
+ */
+abstract class DefaultArtifactProcessorExtensionPoint<P extends ArtifactProcessor<?>> {
+ protected final Map<Object, P> processorsByArtifactType = new HashMap<Object, P>();
+ protected final Map<Class<?>, P> processorsByModelType = new HashMap<Class<?>, P>();
+
+ protected ExtensionPointRegistry registry;
+ private JavaIntrospectionHelper introspectionHelper;
+
+ /**
+ * Constructs a new loader registry.
+ */
+ DefaultArtifactProcessorExtensionPoint(ExtensionPointRegistry registry) {
+ this.registry = registry;
+ this.introspectionHelper = JavaIntrospectionHelper.getInstance(registry);
+ }
+
+ /**
+ * Returns the processor associated with the given artifact type.
+ *
+ * @param artifactType An artifact type
+ * @return The processor associated with the given artifact type
+ */
+ public P getProcessor(Object artifactType) {
+ return processorsByArtifactType.get(artifactType);
+ }
+
+ /**
+ * Returns the processor associated with the given model type.
+ *
+ * @param modelType A model type
+ * @return The processor associated with the given model type
+ */
+ public <T> P getProcessor(Class<T> modelType) {
+ P processor = processorsByModelType.get(modelType);
+ if (processor != null) {
+ return processor;
+ }
+ List<Class<?>> classes = introspectionHelper.getAllInterfaces(modelType);
+ for (Class<?> c : classes) {
+ processor = processorsByModelType.get(c);
+ if (processor != null) {
+ return processor;
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java
new file mode 100644
index 0000000000..814c8c63ef
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXArtifactProcessorExtensionPoint.java
@@ -0,0 +1,324 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+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.extensibility.ServiceDeclaration;
+import org.apache.tuscany.sca.extensibility.ServiceDeclarationParser;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+
+/**
+ * The default implementation of an extension point for StAX artifact processors.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultStAXArtifactProcessorExtensionPoint extends
+ DefaultArtifactProcessorExtensionPoint<StAXArtifactProcessor<?>> implements StAXArtifactProcessorExtensionPoint {
+
+ private FactoryExtensionPoint modelFactories;
+ private boolean loaded;
+ private StAXArtifactProcessor<Object> extensibleStAXProcessor;
+ private StAXAttributeProcessor<Object> extensibleStAXAttributeProcessor;
+
+ /**
+ * Constructs a new extension point.
+ */
+ public DefaultStAXArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) {
+ super(extensionPoints);
+ this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class);
+ XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class);
+ this.extensibleStAXProcessor = new ExtensibleStAXArtifactProcessor(this, inputFactory, outputFactory);
+
+ StAXAttributeProcessorExtensionPoint attributeExtensionPoint =
+ extensionPoints.getExtensionPoint(StAXAttributeProcessorExtensionPoint.class);
+ this.extensibleStAXAttributeProcessor =
+ new ExtensibleStAXAttributeProcessor(attributeExtensionPoint, inputFactory, outputFactory);
+ }
+
+ public void addArtifactProcessor(StAXArtifactProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor);
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor);
+ }
+ }
+
+ public void removeArtifactProcessor(StAXArtifactProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType());
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.remove(artifactProcessor.getModelType());
+ }
+ }
+
+ @Override
+ public <T> StAXArtifactProcessor<T> getProcessor(Class<T> modelType) {
+ loadArtifactProcessors();
+ return (StAXArtifactProcessor<T>)super.getProcessor(modelType);
+ }
+
+ @Override
+ public StAXArtifactProcessor<?> getProcessor(Object artifactType) {
+ loadArtifactProcessors();
+ return super.getProcessor(artifactType);
+ }
+
+ /**
+ * Lazily load artifact processors registered in the extension point.
+ */
+ private synchronized void loadArtifactProcessors() {
+ if (loaded)
+ return;
+
+ // Get the processor service declarations
+ Collection<ServiceDeclaration> processorDeclarations;
+ try {
+ processorDeclarations =
+ registry.getServiceDiscovery().getServiceDeclarations(StAXArtifactProcessor.class.getName());
+ } catch (IOException e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+
+ for (ServiceDeclaration processorDeclaration : processorDeclarations) {
+ Map<String, String> attributes = processorDeclaration.getAttributes();
+
+ // Load a StAX artifact processor
+
+ // Get the model QName
+ QName artifactType = ServiceDeclarationParser.getQName(attributes.get("qname"));
+
+ // Get the model class name
+ String modelTypeName = attributes.get("model");
+
+ // Get the model factory class name
+ String factoryName = attributes.get("factory");
+
+ // Create a processor wrapper and register it
+ StAXArtifactProcessor<?> processor =
+ new LazyStAXArtifactProcessor(artifactType, modelTypeName, factoryName, processorDeclaration,
+ registry, modelFactories, extensibleStAXProcessor,
+ extensibleStAXAttributeProcessor);
+ addArtifactProcessor(processor);
+ }
+
+ loaded = true;
+ }
+
+ /**
+ * A wrapper around an Artifact processor class allowing lazy loading and
+ * initialization of artifact processors.
+ */
+ private static class LazyStAXArtifactProcessor implements StAXArtifactProcessor {
+
+ private ExtensionPointRegistry extensionPoints;
+ private QName artifactType;
+ private String modelTypeName;
+ private String factoryName;
+ private ServiceDeclaration processorDeclaration;
+ private StAXArtifactProcessor<?> processor;
+ private Class<?> modelType;
+ private StAXArtifactProcessor<Object> extensionProcessor;
+ private StAXAttributeProcessor<Object> extensionAttributeProcessor;
+
+ LazyStAXArtifactProcessor(QName artifactType,
+ String modelTypeName,
+ String factoryName,
+ ServiceDeclaration processorDeclaration,
+ ExtensionPointRegistry extensionPoints,
+ FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor<Object> extensionProcessor,
+ StAXAttributeProcessor<Object> extensionAttributeProcessor) {
+
+ this.extensionPoints = extensionPoints;
+ this.artifactType = artifactType;
+ this.modelTypeName = modelTypeName;
+ this.factoryName = factoryName;
+ this.processorDeclaration = processorDeclaration;
+ this.extensionProcessor = extensionProcessor;
+ this.extensionAttributeProcessor = extensionAttributeProcessor;
+ }
+
+ public QName getArtifactType() {
+ return artifactType;
+ }
+
+ private void error(Monitor monitor, String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private StAXArtifactProcessor getProcessor() {
+ if (processor == null) {
+
+ if (processorDeclaration.getClassName()
+ .equals("org.apache.tuscany.sca.assembly.xml.DefaultBeanModelProcessor")) {
+
+ // Specific initialization for the DefaultBeanModelProcessor
+ FactoryExtensionPoint modelFactories =
+ extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ try {
+ Class<StAXArtifactProcessor> processorClass =
+ (Class<StAXArtifactProcessor>)processorDeclaration.loadClass();
+ Object modelFactory;
+ if (factoryName != null) {
+ Class<?> factoryClass = (Class<?>)processorDeclaration.loadClass(factoryName);
+ modelFactory = modelFactories.getFactory(factoryClass);
+ } else {
+ modelFactory = null;
+ }
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class,
+ QName.class,
+ Class.class,
+ Object.class);
+ processor = constructor.newInstance(modelFactories, artifactType, getModelType(), modelFactory);
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+ } else {
+ FactoryExtensionPoint modelFactories =
+ extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+
+ // Load and instantiate the processor class
+ try {
+ Class<StAXArtifactProcessor> processorClass =
+ (Class<StAXArtifactProcessor>)processorDeclaration.loadClass();
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class);
+ processor = constructor.newInstance(modelFactories);
+ } catch (NoSuchMethodException e) {
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class);
+ processor = constructor.newInstance(extensionPoints);
+ } catch (NoSuchMethodException e1) {
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(modelFactories, extensionProcessor);
+ } catch (NoSuchMethodException e2) {
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class,
+ StAXArtifactProcessor.class,
+ StAXAttributeProcessor.class);
+ processor =
+ constructor.newInstance(modelFactories,
+ extensionProcessor,
+ extensionAttributeProcessor);
+ } catch (NoSuchMethodException e2a) {
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(extensionPoints, extensionProcessor);
+ } catch (NoSuchMethodException e3) {
+ try {
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class,
+ StAXArtifactProcessor.class,
+ StAXAttributeProcessor.class);
+ processor =
+ constructor.newInstance(extensionPoints,
+ extensionProcessor,
+ extensionAttributeProcessor);
+ } catch (NoSuchMethodException e3a) {
+
+ Constructor<StAXArtifactProcessor> constructor =
+ processorClass.getConstructor();
+ processor = constructor.newInstance();
+
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+ }
+ }
+ return processor;
+ }
+
+ public Object read(XMLStreamReader inputSource, ProcessorContext context) throws ContributionReadException,
+ XMLStreamException {
+ return getProcessor().read(inputSource, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void write(Object model, XMLStreamWriter outputSource, ProcessorContext context)
+ throws ContributionWriteException, XMLStreamException {
+ getProcessor().write(model, outputSource, context);
+ }
+
+ public Class<?> getModelType() {
+ if (modelTypeName != null && modelType == null) {
+ try {
+ modelType = processorDeclaration.loadClass(modelTypeName);
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+ }
+ return modelType;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ getProcessor().resolve(model, resolver, context);
+ }
+
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java
new file mode 100644
index 0000000000..36dec73898
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultStAXAttributeProcessorExtensionPoint.java
@@ -0,0 +1,291 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.Collection;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+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.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
+import org.apache.tuscany.sca.extensibility.ServiceDeclarationParser;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+
+/**
+ * The default implementation of an extension point for StAX artifact processors.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultStAXAttributeProcessorExtensionPoint extends
+ DefaultArtifactProcessorExtensionPoint<StAXAttributeProcessor<?>> implements StAXAttributeProcessorExtensionPoint {
+
+ private FactoryExtensionPoint modelFactories;
+ private StAXAttributeProcessor<Object> extensibleStAXAttributeProcessor;
+ private boolean loaded;
+ private Monitor monitor = null;
+
+ /**
+ * Constructs a new extension point.
+ */
+ public DefaultStAXAttributeProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) {
+ super(extensionPoints);
+ this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class);
+ XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class);
+ UtilityExtensionPoint utilities = this.registry.getExtensionPoint(UtilityExtensionPoint.class);
+ MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
+ if (monitorFactory != null) {
+ this.monitor = monitorFactory.createMonitor();
+ }
+ this.extensibleStAXAttributeProcessor = new ExtensibleStAXAttributeProcessor(this, inputFactory, outputFactory);
+ }
+
+ /**
+ * 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-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public void addArtifactProcessor(StAXAttributeProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ processorsByArtifactType.put((Object)artifactProcessor.getArtifactType(), artifactProcessor);
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor);
+ }
+ }
+
+ public void removeArtifactProcessor(StAXAttributeProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType());
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.remove(artifactProcessor.getModelType());
+ }
+ }
+
+ @Override
+ public <T> StAXAttributeProcessor<T> getProcessor(Class<T> modelType) {
+ loadArtifactProcessors();
+ return (StAXAttributeProcessor<T>)super.getProcessor(modelType);
+ }
+
+ @Override
+ public StAXAttributeProcessor<?> getProcessor(Object artifactType) {
+ loadArtifactProcessors();
+ return super.getProcessor(artifactType);
+ }
+
+ /**
+ * Lazily load artifact processors registered in the extension point.
+ */
+ private synchronized void loadArtifactProcessors() {
+ if (loaded)
+ return;
+
+ // Get the processor service declarations
+ Collection<ServiceDeclaration> processorDeclarations;
+ try {
+ processorDeclarations =
+ registry.getServiceDiscovery().getServiceDeclarations(StAXAttributeProcessor.class.getName());
+ } catch (IOException e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ error("IllegalStateException", extensibleStAXAttributeProcessor, ie);
+ throw ie;
+ }
+
+ for (ServiceDeclaration processorDeclaration : processorDeclarations) {
+ Map<String, String> attributes = processorDeclaration.getAttributes();
+
+ // Load a StAX artifact processor
+
+ // Get the model QName
+ QName artifactType = ServiceDeclarationParser.getQName(attributes.get("qname"));
+
+ // Get the model class name
+ String modelTypeName = attributes.get("model");
+
+ // Get the model factory class name
+ String factoryName = attributes.get("factory");
+
+ // Create a processor wrapper and register it
+ StAXAttributeProcessor<?> processor =
+ new LazyStAXAttributeProcessor(artifactType, modelTypeName, factoryName, processorDeclaration,
+ registry, modelFactories, extensibleStAXAttributeProcessor);
+ addArtifactProcessor(processor);
+ }
+
+ loaded = true;
+ }
+
+ /**
+ * A wrapper around an Artifact processor class allowing lazy loading and
+ * initialization of artifact processors.
+ */
+ private static class LazyStAXAttributeProcessor implements StAXAttributeProcessor {
+
+ private ExtensionPointRegistry extensionPoints;
+ private QName artifactType;
+ private String modelTypeName;
+ private String factoryName;
+ private ServiceDeclaration processorDeclaration;
+ private StAXAttributeProcessor<?> processor;
+ private Class<?> modelType;
+ private StAXAttributeProcessor<Object> extensionProcessor;
+
+ LazyStAXAttributeProcessor(QName artifactType,
+ String modelTypeName,
+ String factoryName,
+ ServiceDeclaration processorDeclaration,
+ ExtensionPointRegistry extensionPoints,
+ FactoryExtensionPoint modelFactories,
+ StAXAttributeProcessor<Object> extensionProcessor) {
+
+ this.extensionPoints = extensionPoints;
+ this.artifactType = artifactType;
+ this.modelTypeName = modelTypeName;
+ this.factoryName = factoryName;
+ this.processorDeclaration = processorDeclaration;
+ this.extensionProcessor = extensionProcessor;
+ }
+
+ public QName getArtifactType() {
+ return artifactType;
+ }
+
+ @SuppressWarnings("unchecked")
+ private StAXAttributeProcessor getProcessor() {
+ if (processor == null) {
+ FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+
+ // Load and instantiate the processor class
+ try {
+ Class<StAXAttributeProcessor> processorClass =
+ (Class<StAXAttributeProcessor>)processorDeclaration.loadClass();
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class);
+ processor = constructor.newInstance(modelFactories);
+ } catch (NoSuchMethodException e) {
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class);
+ processor = constructor.newInstance(extensionPoints);
+ } catch (NoSuchMethodException e1) {
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(modelFactories, extensionProcessor);
+ } catch (NoSuchMethodException e2) {
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(extensionPoints, extensionProcessor);
+ } catch (NoSuchMethodException e3) {
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class);
+ processor = constructor.newInstance(modelFactories);
+ } catch (NoSuchMethodException e4) {
+ try {
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class);
+ processor = constructor.newInstance(extensionPoints);
+ } catch (NoSuchMethodException e4a) {
+
+ Constructor<StAXAttributeProcessor> constructor =
+ processorClass.getConstructor();
+ processor = constructor.newInstance();
+
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+
+ }
+ return processor;
+ }
+
+ public Object read(QName attributeName, XMLStreamReader inputSource, ProcessorContext context)
+ throws ContributionReadException, XMLStreamException {
+ return getProcessor().read(attributeName, inputSource, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void write(Object model, XMLStreamWriter outputSource, ProcessorContext context)
+ throws ContributionWriteException, XMLStreamException {
+ getProcessor().write(model, outputSource, context);
+ }
+
+ public Class<?> getModelType() {
+ if (modelTypeName != null && modelType == null) {
+ try {
+ modelType = processorDeclaration.loadClass(modelTypeName);
+ } catch (Exception e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+ }
+ return modelType;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ getProcessor().resolve(model, resolver, context);
+ }
+
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java
new file mode 100644
index 0000000000..812695575d
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultURLArtifactProcessorExtensionPoint.java
@@ -0,0 +1,319 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+
+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.extensibility.ServiceDeclaration;
+
+/**
+ * The default implementation of a URL artifact processor extension point.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultURLArtifactProcessorExtensionPoint extends
+ DefaultArtifactProcessorExtensionPoint<URLArtifactProcessor<?>> implements URLArtifactProcessorExtensionPoint {
+
+ private StAXArtifactProcessor<?> staxProcessor;
+ private boolean loaded;
+
+ /**
+ * Constructs a new extension point.
+ */
+ public DefaultURLArtifactProcessorExtensionPoint(ExtensionPointRegistry extensionPoints) {
+ super(extensionPoints);
+ FactoryExtensionPoint modelFactories = this.registry.getExtensionPoint(FactoryExtensionPoint.class);
+ XMLInputFactory inputFactory = modelFactories.getFactory(XMLInputFactory.class);
+ XMLOutputFactory outputFactory = modelFactories.getFactory(XMLOutputFactory.class);
+ StAXArtifactProcessorExtensionPoint staxProcessors =
+ extensionPoints.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ staxProcessor = new ExtensibleStAXArtifactProcessor(staxProcessors, inputFactory, outputFactory);
+ }
+
+ public void addArtifactProcessor(URLArtifactProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ Pattern pattern = Pattern.compile(wildcard2regex(artifactProcessor.getArtifactType()));
+ processorsByArtifactType.put(pattern, artifactProcessor);
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.put(artifactProcessor.getModelType(), artifactProcessor);
+ }
+ }
+
+ public void removeArtifactProcessor(URLArtifactProcessor<?> artifactProcessor) {
+ if (artifactProcessor.getArtifactType() != null) {
+ String regex = wildcard2regex(artifactProcessor.getArtifactType());
+ for (Object key : processorsByArtifactType.keySet()) {
+ if ((key instanceof Pattern) && ((Pattern)key).pattern().equals(regex)) {
+ processorsByArtifactType.remove(key);
+ }
+ }
+ processorsByArtifactType.remove((Object)artifactProcessor.getArtifactType());
+ }
+ if (artifactProcessor.getModelType() != null) {
+ processorsByModelType.remove(artifactProcessor.getModelType());
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public <T> URLArtifactProcessor<T> getProcessor(Class<T> modelType) {
+ loadProcessors();
+ return (URLArtifactProcessor<T>)super.getProcessor(modelType);
+ }
+
+ public Collection<URLArtifactProcessor<?>> getProcessors(Object artifactType) {
+ loadProcessors();
+ String uri = (String)artifactType;
+ if (uri.endsWith("/")) {
+ // Ignore directories
+ return Collections.emptyList();
+ }
+ if (!uri.startsWith("/")) {
+ uri = "/" + uri;
+ }
+ List<URLArtifactProcessor<?>> processors = new ArrayList<URLArtifactProcessor<?>>();
+ for (Map.Entry<Object, URLArtifactProcessor<?>> e : processorsByArtifactType.entrySet()) {
+ Pattern pattern = (Pattern)e.getKey();
+ if (pattern.matcher(uri).matches()) {
+ processors.add(e.getValue());
+ }
+ }
+ return processors;
+ }
+
+ @SuppressWarnings("unchecked")
+ public URLArtifactProcessor<?> getProcessor(Object artifactType) {
+ Collection<URLArtifactProcessor<?>> processors = getProcessors(artifactType);
+ return processors.isEmpty() ? null : processors.iterator().next();
+ }
+
+ private static String wildcard2regex(String pattern) {
+ String wildcard = pattern;
+ if (wildcard.endsWith("/")) {
+ // Directory: xyz/ --> xyz/**
+ wildcard = wildcard + "**";
+ }
+ if (wildcard.startsWith(".")) {
+ // File extension: .xyz --> **/*.xyz
+ wildcard = "**/*" + wildcard;
+ } else if (wildcard.indexOf('/') == -1) {
+ // File name: abc.txt --> **/abc.txt
+ wildcard = "**/" + wildcard;
+ } else if (!(wildcard.startsWith("/") || wildcard.startsWith("**"))) {
+ wildcard = '/' + wildcard;
+ }
+ StringBuffer regex = new StringBuffer();
+ char[] chars = wildcard.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ switch (chars[i]) {
+ case '*':
+ if (i < chars.length - 1 && chars[i + 1] == '*') {
+ // Next char is '*'
+ if (i < chars.length - 2) {
+ if (chars[i + 2] == '/') {
+ // The wildcard is **/, it matches zero or more directories
+ regex.append("(.*/)*");
+ i += 2; // Skip */
+ } else {
+ // ** can only be followed by /
+ throw new IllegalArgumentException("** can only be used as the name for a directory");
+ }
+ } else {
+ regex.append(".*");
+ i++; // Skip next *
+ }
+ } else {
+ // Non-directory
+ regex.append("[^/]*");
+ }
+ break;
+ case '?':
+ regex.append("[^/]");
+ break;
+ case '\\':
+ case '|':
+ case '(':
+ case ')':
+ // case '[':
+ // case ']':
+ // case '{':
+ // case '}':
+ case '^':
+ case '$':
+ case '+':
+ case '.':
+ case '<':
+ case '>':
+ regex.append("\\").append(chars[i]);
+ break;
+ default:
+ regex.append(chars[i]);
+ break;
+ }
+ }
+ return regex.toString();
+ }
+
+ /**
+ * Lazily load artifact processors registered in the extension point.
+ */
+ private synchronized void loadProcessors() {
+ if (loaded)
+ return;
+
+ // Get the processor service declarations
+ Collection<ServiceDeclaration> processorDeclarations;
+ try {
+ processorDeclarations =
+ registry.getServiceDiscovery().getServiceDeclarations(URLArtifactProcessor.class.getName());
+ } catch (IOException e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+
+ for (ServiceDeclaration processorDeclaration : processorDeclarations) {
+ Map<String, String> attributes = processorDeclaration.getAttributes();
+ // Load a URL artifact processor
+ String artifactType = attributes.get("type");
+ String modelTypeName = attributes.get("model");
+
+ // Create a processor wrapper and register it
+ URLArtifactProcessor<?> processor =
+ new LazyURLArtifactProcessor(artifactType, modelTypeName, processorDeclaration, registry,
+ staxProcessor);
+ addArtifactProcessor(processor);
+ }
+
+ loaded = true;
+ }
+
+ /**
+ * A wrapper around an Artifact processor class allowing lazy loading and
+ * initialization of artifact processors.
+ */
+ private static class LazyURLArtifactProcessor implements ExtendedURLArtifactProcessor {
+
+ private ExtensionPointRegistry extensionPoints;
+ private String artifactType;
+ private String modelTypeName;
+ private ServiceDeclaration processorDeclaration;
+ private URLArtifactProcessor<?> processor;
+ private Class<?> modelType;
+ private StAXArtifactProcessor<?> staxProcessor;
+
+ LazyURLArtifactProcessor(String artifactType,
+ String modelTypeName,
+ ServiceDeclaration processorDeclaration,
+ ExtensionPointRegistry extensionPoints,
+ StAXArtifactProcessor<?> staxProcessor) {
+ this.artifactType = artifactType;
+ this.modelTypeName = modelTypeName;
+ this.processorDeclaration = processorDeclaration;
+ this.extensionPoints = extensionPoints;
+ this.staxProcessor = staxProcessor;
+ }
+
+ public String getArtifactType() {
+ return artifactType;
+ }
+
+ @SuppressWarnings("unchecked")
+ private URLArtifactProcessor getProcessor() {
+ if (processor == null) {
+ try {
+ FactoryExtensionPoint modelFactories =
+ extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ Class<URLArtifactProcessor> processorClass =
+ (Class<URLArtifactProcessor>)processorDeclaration.loadClass();
+ try {
+ Constructor<URLArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class);
+ processor = constructor.newInstance(modelFactories);
+ } catch (NoSuchMethodException e) {
+ try {
+ Constructor<URLArtifactProcessor> constructor =
+ processorClass.getConstructor(FactoryExtensionPoint.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(modelFactories, staxProcessor);
+ } catch (NoSuchMethodException e2) {
+ Constructor<URLArtifactProcessor> constructor =
+ processorClass.getConstructor(ExtensionPointRegistry.class,
+ StAXArtifactProcessor.class);
+ processor = constructor.newInstance(extensionPoints, staxProcessor);
+ }
+ }
+ } catch (Throwable e) {
+ IllegalStateException ie = new IllegalStateException("Exception during getProcessor() for " +
+ processorDeclaration.getClassName(), e);
+ throw ie;
+ }
+ }
+ return processor;
+ }
+
+ public Object read(URL contributionURL, URI artifactURI, URL artifactURL, ProcessorContext context) throws ContributionReadException {
+ return getProcessor().read(contributionURL, artifactURI, artifactURL, context);
+ }
+
+ public Class<?> getModelType() {
+ if (modelTypeName != null && modelType == null) {
+ try {
+ modelType = processorDeclaration.loadClass(modelTypeName);
+ } catch (ClassNotFoundException e) {
+ IllegalStateException ie = new IllegalStateException(e);
+ throw ie;
+ }
+ }
+ return modelType;
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+ getProcessor().resolve(model, resolver, context);
+ } // end method resolve
+
+ /**
+ * Preresolve phase, for ExtendedURLArtifactProcessors only
+ */
+ @SuppressWarnings("unchecked")
+ public void preResolve( Object model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+ URLArtifactProcessor<?> processor = getProcessor();
+ if( processor instanceof ExtendedURLArtifactProcessor ) {
+ ((ExtendedURLArtifactProcessor)processor).preResolve(model, resolver, context);
+ } // end if
+ } // end method resolve
+
+ } // end class LazyURLArtifactProcessor
+} // end class DefaultURLArtifactProcessorExtensionPoint
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java
new file mode 100644
index 0000000000..cf8c8fbf17
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidatingXMLInputFactory.java
@@ -0,0 +1,465 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.stream.EventFilter;
+import javax.xml.stream.StreamFilter;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLReporter;
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.util.XMLEventAllocator;
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+
+import org.apache.tuscany.sca.assembly.xsd.Constants;
+import org.apache.tuscany.sca.common.xml.XMLDocumentHelper;
+import org.apache.tuscany.sca.common.xml.stax.StAXHelper;
+import org.apache.tuscany.sca.core.DefaultExtensionPointRegistry;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.extensibility.ClassLoaderContext;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSInput;
+import org.w3c.dom.ls.LSResourceResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Default implementation of an XMLInputFactory that creates validating
+ * XMLStreamReaders.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultValidatingXMLInputFactory extends ValidatingXMLInputFactory implements LSResourceResolver {
+ private ExtensionPointRegistry registry;
+ private XMLInputFactory inputFactory;
+ private DocumentBuilderFactory documentBuilderFactory;
+ private DOMImplementationLS ls;
+ private ValidationSchemaExtensionPoint schemas;
+ private MonitorFactory monitorFactory;
+ private boolean initialized;
+ private boolean hasSchemas;
+ private Schema aggregatedSchema;
+ private StAXHelper helper;
+
+ public DefaultValidatingXMLInputFactory(ExtensionPointRegistry registry) {
+ this.registry = registry;
+ FactoryExtensionPoint factoryExtensionPoint = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.inputFactory = factoryExtensionPoint.getFactory(XMLInputFactory.class);
+ this.documentBuilderFactory = factoryExtensionPoint.getFactory(DocumentBuilderFactory.class);
+ this.schemas = registry.getExtensionPoint(ValidationSchemaExtensionPoint.class);
+ this.monitorFactory = registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(MonitorFactory.class);
+ this.helper = StAXHelper.getInstance(registry);
+ }
+
+ /**
+ * Constructs a new XMLInputFactory.
+ *
+ * @param inputFactory
+ * @param schemas
+ */
+ // FOR Test only
+ public DefaultValidatingXMLInputFactory(XMLInputFactory inputFactory, ValidationSchemaExtensionPoint schemas) {
+ this.inputFactory = inputFactory;
+ this.schemas = schemas;
+ this.registry = new DefaultExtensionPointRegistry();
+ }
+
+ /**
+ * Report a exception.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void error(Monitor monitor, String message, Object model, Throwable ex) {
+ Monitor.error(monitor, this, "contribution-validation-messages", message, ex);
+ }
+
+ private void warn(Monitor monitor, String message, Object model, Throwable ex) {
+ Monitor.warning(monitor, this, "contribution-validation-messages", message, ex);
+ }
+
+ public static final QName XSD = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "schema");
+
+ private Collection<? extends Source> aggregate(URL... urls) throws IOException, XMLStreamException {
+ if (urls.length == 1) {
+ return Collections.singletonList(new SAXSource(XMLDocumentHelper.getInputSource(urls[0])));
+ }
+ Map<String, Collection<URL>> map = new HashMap<String, Collection<URL>>();
+
+ for (URL url : urls) {
+ String tns = helper.readAttribute(url, XSD, "targetNamespace");
+ Collection<URL> collection = map.get(tns);
+ if (collection == null) {
+ collection = new HashSet<URL>();
+ map.put(tns, collection);
+ }
+ collection.add(url);
+ }
+ List<Source> sources = new ArrayList<Source>();
+ for (Map.Entry<String, Collection<URL>> e : map.entrySet()) {
+ if (e.getValue().size() == 1) {
+ sources.add(new SAXSource(XMLDocumentHelper.getInputSource(e.getValue().iterator().next())));
+ } else {
+ StringBuffer xsd = new StringBuffer("<schema xmlns=\"http://www.w3.org/2001/XMLSchema\"");
+ if (e.getKey() != null) {
+ xsd.append(" targetNamespace=\"").append(e.getKey()).append("\"");
+ }
+ xsd.append(">");
+ for (URL url : e.getValue()) {
+ xsd.append("<include schemaLocation=\"").append(url).append("\"/>");
+ }
+ xsd.append("</schema>");
+ SAXSource source = new SAXSource(new InputSource(new StringReader(xsd.toString())));
+ sources.add(source);
+ }
+ }
+ return sources;
+ }
+
+ /**
+ * Initialize the registered schemas and create an aggregated schema for
+ * validation.
+ *
+ * @param monitor TODO
+ */
+ private synchronized void initializeSchemas(Monitor monitor) {
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+
+ // Load the XSDs registered in the validation schema extension point
+ try {
+ List<String> uris = schemas.getSchemas();
+ int n = uris.size();
+ if (n == 0) {
+ return;
+ } else {
+ hasSchemas = true;
+ }
+
+ // For bundleresource: URL(s), this URL constructor
+ // can require org.osgi.framework.AdminPermission
+ final List<String> urisCopy = uris;
+
+ URL[] urls = null;
+ try {
+ urls = AccessController.doPrivileged(new PrivilegedExceptionAction<URL[]>() {
+ public URL[] run() throws MalformedURLException {
+ URL[] urlsTemp = new URL[urisCopy.size()];
+ for (int i = 0; i < urlsTemp.length; i++) {
+ urlsTemp[i] = new URL(urisCopy.get(i));
+ }
+ return urlsTemp;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ warn(monitor, "PrivilegedActionException", schemas, (MalformedURLException)e.getException());
+ throw (MalformedURLException)e.getException();
+ }
+
+ final Collection<? extends Source> sources = aggregate(urls);
+
+ final SchemaFactory schemaFactory = newSchemaFactory();
+
+ DOMImplementation impl = null;
+ try {
+ impl = documentBuilderFactory.newDocumentBuilder().getDOMImplementation();
+ } catch (ParserConfigurationException e) {
+ // Ignore
+ }
+ if (impl instanceof DOMImplementationLS) {
+ ls = (DOMImplementationLS)impl;
+ schemaFactory.setResourceResolver(this);
+ }
+ // Allow privileged access to check files. Requires FilePermission
+ // in security policy.
+ try {
+ aggregatedSchema = AccessController.doPrivileged(new PrivilegedExceptionAction<Schema>() {
+ public Schema run() throws SAXException {
+ return schemaFactory.newSchema(sources.toArray(new Source[sources.size()]));
+ }
+ });
+
+ } catch (PrivilegedActionException e) {
+ warn(monitor, "PrivilegedActionException", schemaFactory, (SAXException)e.getException());
+ hasSchemas = false;
+ throw (SAXException)e.getException();
+ }
+
+ } catch (SAXException e) {
+ // IllegalStateException ie = new IllegalStateException(e);
+ // error("IllegalStateException", schemas, ie);
+ // throw ie;
+ } catch (Throwable e) {
+ // FIXME Log this, some old JDKs don't support XMLSchema validation
+ warn(monitor, e.getMessage(), schemas, e);
+ hasSchemas = false;
+ }
+ }
+
+ /**
+ * For OSGi: Create a SchemaFactory in the context of service provider
+ * classloaders
+ *
+ * @return
+ */
+ private SchemaFactory newSchemaFactory() {
+
+ SchemaFactory retVal = AccessController.doPrivileged(new PrivilegedAction<SchemaFactory>() {
+ public SchemaFactory run() {
+ ClassLoader cl = ClassLoaderContext.setContextClassLoader(getClass().getClassLoader(),
+ registry.getServiceDiscovery(),
+ SchemaFactory.class,
+ TransformerFactory.class,
+ SAXParserFactory.class,
+ DocumentBuilderFactory.class
+ );
+
+ try {
+ // Create an aggregated validation schemas from all the XSDs
+ return SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+ } finally {
+ if (cl != null) {
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ }
+ }
+ });
+
+ return retVal;
+ }
+
+ @Override
+ public XMLEventReader createFilteredReader(XMLEventReader arg0, EventFilter arg1) throws XMLStreamException {
+ return inputFactory.createFilteredReader(arg0, arg1);
+ }
+
+ @Override
+ public XMLStreamReader createFilteredReader(XMLStreamReader arg0, StreamFilter arg1) throws XMLStreamException {
+ return inputFactory.createFilteredReader(arg0, arg1);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(InputStream arg0, String arg1) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0, arg1);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(InputStream arg0) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(Reader arg0) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(Source arg0) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(String arg0, InputStream arg1) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0, arg1);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(String arg0, Reader arg1) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0, arg1);
+ }
+
+ @Override
+ public XMLEventReader createXMLEventReader(XMLStreamReader arg0) throws XMLStreamException {
+ return inputFactory.createXMLEventReader(arg0);
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(InputStream arg0, String arg1) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema,
+ monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0, arg1);
+ }
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(InputStream arg0) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0);
+ }
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(Reader arg0) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0);
+ }
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(Source arg0) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0), aggregatedSchema, monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0);
+ }
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(String arg0, InputStream arg1) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema,
+ monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0, arg1);
+ }
+ }
+
+ @Override
+ public XMLStreamReader createXMLStreamReader(String arg0, Reader arg1) throws XMLStreamException {
+ Monitor monitor = monitorFactory.getContextMonitor();
+ initializeSchemas(monitor);
+ if (hasSchemas) {
+ return new ValidatingXMLStreamReader(inputFactory.createXMLStreamReader(arg0, arg1), aggregatedSchema,
+ monitor);
+ } else {
+ return inputFactory.createXMLStreamReader(arg0, arg1);
+ }
+ }
+
+ @Override
+ public XMLEventAllocator getEventAllocator() {
+ return inputFactory.getEventAllocator();
+ }
+
+ @Override
+ public Object getProperty(String arg0) throws IllegalArgumentException {
+ return inputFactory.getProperty(arg0);
+ }
+
+ @Override
+ public XMLReporter getXMLReporter() {
+ return inputFactory.getXMLReporter();
+ }
+
+ @Override
+ public XMLResolver getXMLResolver() {
+ return inputFactory.getXMLResolver();
+ }
+
+ @Override
+ public boolean isPropertySupported(String arg0) {
+ return inputFactory.isPropertySupported(arg0);
+ }
+
+ @Override
+ public void setEventAllocator(XMLEventAllocator arg0) {
+ inputFactory.setEventAllocator(arg0);
+ }
+
+ @Override
+ public void setProperty(String arg0, Object arg1) throws IllegalArgumentException {
+ inputFactory.setProperty(arg0, arg1);
+ }
+
+ @Override
+ public void setXMLReporter(XMLReporter arg0) {
+ inputFactory.setXMLReporter(arg0);
+ }
+
+ @Override
+ public void setXMLResolver(XMLResolver arg0) {
+ inputFactory.setXMLResolver(arg0);
+ }
+
+ public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
+ String key = null;
+ if ("http://www.w3.org/2001/XMLSchema".equals(type)) {
+ key = namespaceURI;
+ } else if ("http://www.w3.org/TR/REC-xml".equals(type)) {
+ key = publicId;
+ }
+ URL url = Constants.CACHED_XSDS.get(key);
+ if (url != null && !Constants.SCA11_NS.equals(namespaceURI)) {
+ systemId = url.toString();
+ } else if (url != null && systemId == null) {
+ systemId = url.toString();
+ }
+
+ LSInput input = ls.createLSInput();
+ input.setBaseURI(baseURI);
+ input.setPublicId(publicId);
+ input.setSystemId(systemId);
+ return input;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java
new file mode 100644
index 0000000000..4cb83cd5ef
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/DefaultValidationSchemaExtensionPoint.java
@@ -0,0 +1,123 @@
+/*
+ * 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;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.extensibility.ServiceDeclaration;
+
+/**
+ * Default implementation of an extension point for XML schemas.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultValidationSchemaExtensionPoint implements ValidationSchemaExtensionPoint {
+ private boolean enabled = true;
+ private List<String> schemas = new ArrayList<String>();
+ private boolean loaded;
+ private ExtensionPointRegistry registry;
+
+ public DefaultValidationSchemaExtensionPoint(ExtensionPointRegistry registry, Map<String, String> attributes) {
+ super();
+ this.registry = registry;
+ if (attributes != null) {
+ String attr = attributes.get("enabled");
+ if (attr != null) {
+ enabled = Boolean.parseBoolean(attr);
+ }
+ }
+ }
+
+ public void addSchema(String uri) {
+ schemas.add(uri);
+ }
+
+ public void removeSchema(String uri) {
+ schemas.remove(uri);
+ }
+
+ /**
+ * Load schema declarations from META-INF/services/
+ * org.apache.tuscany.sca.contribution.processor.ValidationSchema files
+ */
+ private synchronized void loadSchemas() {
+ if (loaded || (!enabled))
+ return;
+
+ // Get the schema declarations
+ Collection<ServiceDeclaration> schemaDeclarations;
+ try {
+ schemaDeclarations =
+ registry.getServiceDiscovery()
+ .getServiceDeclarations("org.apache.tuscany.sca.contribution.processor.ValidationSchema");
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+
+ // TODO - temp fix to ensure that the schema tuscany-sca.xsd always comes first
+ String tuscanyScaXsd = null;
+
+ // Find each schema
+ for (ServiceDeclaration schemaDeclaration : schemaDeclarations) {
+ URL url = schemaDeclaration.getResource(schemaDeclaration.getClassName());
+ if (url == null) {
+ throw new IllegalArgumentException(new FileNotFoundException(schemaDeclaration.getClassName()));
+ }
+
+ if (url.toString().contains("tuscany-sca-1.1.xsd")) {
+ tuscanyScaXsd = url.toString();
+ } else {
+ schemas.add(url.toString());
+ }
+ }
+
+ if (tuscanyScaXsd != null) {
+ schemas.add(0, tuscanyScaXsd);
+ }
+
+ loaded = true;
+ }
+
+ public List<String> getSchemas() {
+ if (enabled) {
+ loadSchemas();
+ return schemas;
+ } else {
+ return Collections.emptyList();
+ }
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedArtifactProcessor.java
new file mode 100644
index 0000000000..ca579110ae
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedArtifactProcessor.java
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+
+/**
+ * Interface for extended Artifact Processors which require a pre-resolve phase prior to the resolve phase
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ExtendedArtifactProcessor<M> extends ArtifactProcessor<M> {
+
+ /**
+ * Pre-resolve references from this model to other models. Used for models where initial setup of
+ * the resolve phase is required. An example is Contribution models with imports and exports which must
+ * be set up prior to the main resolve phase
+ *
+ * @param model The model to resolve
+ * @param resolver The resolver to use to resolve referenced models
+ * @param context The context
+ */
+ void preResolve(M model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException;
+
+} // end interface
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedURLArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedURLArtifactProcessor.java
new file mode 100644
index 0000000000..2639a21e41
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtendedURLArtifactProcessor.java
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+
+/**
+ * An extended artifact processor that can read models from a URL.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ExtendedURLArtifactProcessor<M> extends ExtendedArtifactProcessor<M>, URLArtifactProcessor<M> {
+
+} // end interface
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java
new file mode 100644
index 0000000000..b50f9a71be
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXArtifactProcessor.java
@@ -0,0 +1,283 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+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.Extension;
+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;
+
+/**
+ * Implementation of an extensible StAX artifact processor.
+ *
+ * Takes a StAXArtifactProcessorExtensionPoint and delegates to the proper
+ * StAXArtifactProcessor by element QName
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExtensibleStAXArtifactProcessor implements StAXArtifactProcessor<Object> {
+ private static final Logger logger = Logger.getLogger(ExtensibleStAXArtifactProcessor.class.getName());
+ private static final String XMLSCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+ public static final QName ANY_ELEMENT = new QName(XMLSCHEMA_NS, "any");
+
+ private XMLInputFactory inputFactory;
+ private XMLOutputFactory outputFactory;
+ private StAXArtifactProcessorExtensionPoint processors;
+
+ /**
+ * Constructs a new ExtensibleStAXArtifactProcessor.
+ * @param processors
+ * @param inputFactory
+ * @param outputFactory
+ */
+ public ExtensibleStAXArtifactProcessor(StAXArtifactProcessorExtensionPoint processors,
+ XMLInputFactory inputFactory,
+ XMLOutputFactory outputFactory) {
+ super();
+ this.processors = processors;
+ this.inputFactory = inputFactory;
+ this.outputFactory = outputFactory;
+ if (this.outputFactory != null) {
+ this.outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+ }
+ }
+
+ public ExtensibleStAXArtifactProcessor(ExtensionPointRegistry registry) {
+ super();
+ this.processors = registry.getExtensionPoint(StAXArtifactProcessorExtensionPoint.class);
+ FactoryExtensionPoint factories = registry.getExtensionPoint(FactoryExtensionPoint.class);
+ this.inputFactory = factories.getFactory(XMLInputFactory.class);
+ this.outputFactory = factories.getFactory(XMLOutputFactory.class);
+ if (this.outputFactory != null) {
+ this.outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+ }
+ }
+
+ /**
+ * Report a warning.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void warning(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "contribution-validation-messages",
+ Severity.WARNING,
+ model,
+ message,
+ (Object[])messageParameters);
+ 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(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * 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(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public Object read(XMLStreamReader source, ProcessorContext context) throws ContributionReadException, XMLStreamException {
+ Monitor monitor = context.getMonitor();
+ // Delegate to the processor associated with the element QName
+ int event = source.getEventType();
+ if (event == XMLStreamConstants.START_DOCUMENT) {
+ while (source.next() != XMLStreamReader.START_ELEMENT);
+ }
+ QName name = source.getName();
+ StAXArtifactProcessor<?> processor = (StAXArtifactProcessor<?>)processors.getProcessor(name);
+ if (processor == null) {
+ Location location = source.getLocation();
+ error(monitor, "ElementCannotBeProcessed", processors, name, location);
+
+ StAXArtifactProcessor anyElementProcessor = processors.getProcessor(ANY_ELEMENT);
+ if (anyElementProcessor != null) {
+ return anyElementProcessor.read(source, context);
+ } else {
+ return null;
+ }
+ }
+ return processor.read(source, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void write(Object model, XMLStreamWriter outputSource, ProcessorContext context) throws ContributionWriteException, XMLStreamException {
+ // Delegate to the processor associated with the model type
+ if (model != null) {
+ StAXArtifactProcessor processor = processors.getProcessor(model.getClass());
+ if (processor != null) {
+ processor.write(model, outputSource, context);
+ } else {
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("No StAX processor is configured to handle " + model.getClass());
+ }
+ StAXArtifactProcessor anyElementProcessor = processors.getProcessor(ANY_ELEMENT);
+ if ((model instanceof Extension) && anyElementProcessor != null) {
+ anyElementProcessor.write(model, outputSource, context);
+ }
+ }
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+
+ // Delegate to the processor associated with the model type
+ if (model != null) {
+ StAXArtifactProcessor processor = processors.getProcessor(model.getClass());
+ if (processor != null) {
+ processor.resolve(model, resolver, context);
+ }
+ }
+ }
+
+ /**
+ * Read a model from an InputStream.
+ * @param is The artifact InputStream
+ * @param type Model type
+ * @param context TODO
+ * @return The model
+ * @throws ContributionReadException
+ */
+ public <M> M read(InputStream is, Class<M> type, ProcessorContext context) throws ContributionReadException {
+ Monitor monitor = context.getMonitor();
+ try {
+ XMLStreamReader reader;
+ try {
+ reader = inputFactory.createXMLStreamReader(is);
+ try {
+ reader.nextTag();
+ QName name = reader.getName();
+ Object mo = read(reader, context);
+ if (type.isInstance(mo)) {
+ return type.cast(mo);
+ } else {
+ error(monitor, "UnrecognizedElementException", reader, name);
+ UnrecognizedElementException e = new UnrecognizedElementException(name);
+ throw e;
+ }
+ } catch (ContributionReadException e) {
+ Location location = reader.getLocation();
+ e.setLine(location.getLineNumber());
+ e.setColumn(location.getColumnNumber());
+ error(monitor, "ContributionReadException", reader, e);
+ throw e;
+ } finally {
+ try {
+ reader.close();
+ } catch (XMLStreamException e) {
+ // ignore
+ }
+ }
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ } catch (XMLStreamException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error(monitor, "ContributionReadException", inputFactory, ce);
+ throw ce;
+ }
+ }
+
+ /**
+ * Write a model to an OutputStream.
+ * @param model
+ * @param os
+ * @param context
+ * @throws ContributionWriteException
+ */
+ public void write(Object model, OutputStream os, ProcessorContext context) throws ContributionWriteException {
+ try {
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
+ write(model, writer, context);
+ writer.flush();
+ writer.close();
+ } catch (XMLStreamException e) {
+ ContributionWriteException cw = new ContributionWriteException(e);
+ error(context.getMonitor(), "ContributionWriteException", outputFactory, cw);
+ throw cw;
+ }
+ }
+
+ public QName getArtifactType() {
+ return null;
+ }
+
+ public Class<Object> getModelType() {
+ return null;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java
new file mode 100644
index 0000000000..5bf7e88779
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleStAXAttributeProcessor.java
@@ -0,0 +1,259 @@
+/*
+ * 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;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.Location;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLOutputFactory;
+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.Extension;
+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;
+
+/**
+ * Implementation of an extensible StAX attribute processor.
+ *
+ * Takes a StAXAttributeProcessorExtensionPoint and delegates to the proper
+ * StAXAttributeProcessor by attribute QName
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExtensibleStAXAttributeProcessor implements StAXAttributeProcessor<Object> {
+
+ private static final Logger logger = Logger.getLogger(ExtensibleStAXAttributeProcessor.class.getName());
+ private static final String XMLSCHEMA_NS = "http://www.w3.org/2001/XMLSchema";
+ public static final QName ANY_ATTRIBUTE = new QName(XMLSCHEMA_NS, "anyAttribute");
+
+ private XMLInputFactory inputFactory;
+ private XMLOutputFactory outputFactory;
+ private StAXAttributeProcessorExtensionPoint processors;
+ /**
+ * Constructs a new ExtensibleStAXArtifactProcessor.
+ * @param processors
+ * @param inputFactory
+ * @param outputFactory
+ */
+ public ExtensibleStAXAttributeProcessor(StAXAttributeProcessorExtensionPoint processors,
+ XMLInputFactory inputFactory,
+ XMLOutputFactory outputFactory) {
+ super();
+ this.processors = processors;
+ this.inputFactory = inputFactory;
+ this.outputFactory = outputFactory;
+ if (this.outputFactory != null) {
+ this.outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+ }
+ }
+
+ /**
+ * Report a warning.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void warning(Monitor monitor, String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "contribution-validation-messages",
+ Severity.WARNING,
+ model,
+ message,
+ (Object[])messageParameters);
+ 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(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * 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(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ public Object read(QName attributeName, XMLStreamReader source, ProcessorContext context) throws ContributionReadException,
+ XMLStreamException {
+ // Delegate to the processor associated with the attribute QName
+ int event = source.getEventType();
+ if (event == XMLStreamConstants.START_DOCUMENT) {
+ while (source.next() != XMLStreamReader.START_ELEMENT);
+ }
+
+ StAXAttributeProcessor<?> processor = null;
+
+ //lookup for registered attribute processors
+ processor = (StAXAttributeProcessor<?>)processors.getProcessor(attributeName);
+ if (processor == null) {
+ Location location = source.getLocation();
+ // Skip xsi:type, xsi:nil and xsi:schemaLocation etc
+ if (!W3C_XML_SCHEMA_INSTANCE_NS_URI.equals(attributeName.getNamespaceURI())) {
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("Attribute " + attributeName + " cannot be processed. (" + location + ")");
+ }
+ warning(context.getMonitor(), "AttributeCannotBeProcessed", processors, attributeName, location);
+ }
+ } else {
+ return processor.read(attributeName, source, context);
+ }
+
+ //handle extension attributes without processors
+ processor = (StAXAttributeProcessor<?>)processors.getProcessor(ANY_ATTRIBUTE);
+ if (processor == null) {
+ Location location = source.getLocation();
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("Could not find Default Attribute processor !");
+ }
+ warning(context.getMonitor(), "DefaultAttributeProcessorNotAvailable", processors, ANY_ATTRIBUTE, location);
+ }
+
+ return processor == null ? null : processor.read(attributeName, source, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void write(Object model, XMLStreamWriter outputSource, ProcessorContext context) throws ContributionWriteException, XMLStreamException {
+
+ if (model == null) {
+ return;
+ }
+
+ // Delegate to the processor associated with the model type
+ StAXAttributeProcessor processor = processors.getProcessor(model.getClass());
+ if (processor == null) {
+ if (!Extension.class.isInstance(model)) {
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("No StAX processor is configured to handle " + model.getClass());
+ }
+ warning(context.getMonitor(), "NoStaxProcessor", processors, model.getClass());
+ }
+ } else {
+ processor.write(model, outputSource, context);
+ return;
+ }
+
+ //handle extension attributes without processors
+ processor = (StAXAttributeProcessor<?>)processors.getProcessor(ANY_ATTRIBUTE);
+ if (processor == null) {
+ if (logger.isLoggable(Level.WARNING)) {
+ logger.warning("No Default StAX processor is configured to handle " + model.getClass());
+ }
+ warning(context.getMonitor(), "NoDefaultStaxProcessor", processors, model.getClass());
+ } else {
+ processor.write(model, outputSource, context);
+ return;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+
+ // Delegate to the processor associated with the model type
+ if (model != null) {
+ StAXAttributeProcessor processor = processors.getProcessor(model.getClass());
+ if (processor != null) {
+ processor.resolve(model, resolver, context);
+ }
+ }
+ }
+
+ /**
+ * Read a model from an InputStream.
+ * @param is The artifact InputStream
+ * @param type Model type
+ * @return The model
+ * @throws ContributionReadException
+ */
+ public <M> M read(InputStream is, Class<M> type) throws ContributionReadException {
+ return null;
+ }
+
+ /**
+ * Write a model to an OutputStream.
+ * @param model
+ * @param os
+ * @throws ContributionWriteException
+ */
+ public void write(Object model, OutputStream os, ProcessorContext context) throws ContributionWriteException {
+ try {
+ XMLStreamWriter writer = outputFactory.createXMLStreamWriter(os);
+ write(model, writer, context);
+ writer.flush();
+ writer.close();
+ } catch (XMLStreamException e) {
+ ContributionWriteException cw = new ContributionWriteException(e);
+ error(context.getMonitor(), "ContributionWriteException", outputFactory, cw);
+ throw cw;
+ }
+ }
+
+ public QName getArtifactType() {
+ return null;
+ }
+
+ public Class<Object> getModelType() {
+ return Object.class;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java
new file mode 100644
index 0000000000..2491e22a29
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ExtensibleURLArtifactProcessor.java
@@ -0,0 +1,148 @@
+/*
+ * 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;
+
+import java.net.URI;
+import java.net.URL;
+
+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;
+
+/**
+ * Implementation of an extensible URL artifact processor.
+ *
+ * Takes a URLArtifactProcessorExtensionPoint and delegates to the proper URLArtifactProcessor
+ * by either fileName or fileExtention
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExtensibleURLArtifactProcessor implements URLArtifactProcessor<Object> {
+
+ private URLArtifactProcessorExtensionPoint processors;
+
+ /**
+ * Constructs a new ExtensibleURLArtifactProcessor.
+ *
+ * @param processors
+ */
+ public ExtensibleURLArtifactProcessor(URLArtifactProcessorExtensionPoint processors) {
+ this.processors = processors;
+ }
+
+ /**
+ * 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(),
+ "contribution-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object read(URL contributionURL, URI sourceURI, URL sourceURL, ProcessorContext context) throws ContributionReadException {
+ URLArtifactProcessor<Object> processor = null;
+ if (sourceURI != null) {
+ //try to retrieve a processor for the specific URI
+ String uri = sourceURI.toString();
+ if (!uri.startsWith("/")) {
+ uri = "/" + uri;
+ }
+ // Register the URI as the artifact type starts with /
+ processor = (URLArtifactProcessor<Object>)processors.getProcessor(uri);
+ }
+
+ /*
+ if (processor == null) {
+ // Delegate to the processor associated with file extension
+ String fileName = getFileName(sourceURL);
+
+ //try to retrieve a processor for the specific filename
+ processor = (URLArtifactProcessor<Object>)processors.getProcessor(fileName);
+ }
+
+ if (processor == null) {
+ //try to find my file type (extension)
+ String extension = sourceURL.getPath();
+
+ int extensionStart = extension.lastIndexOf('.');
+ //handle files without extension (e.g NOTICE)
+ if (extensionStart > 0) {
+ // File extensions are registered as .<extension>
+ extension = extension.substring(extensionStart);
+ processor = (URLArtifactProcessor<Object>)processors.getProcessor(extension);
+ }
+ }
+ */
+
+ if (processor == null) {
+ return null;
+ }
+ if (context != null && context.getMonitor() != null){
+ context.getMonitor().setArtifactName(null); //Reset Artifact Name in Monitor
+ }
+ return processor.read(contributionURL, sourceURI, sourceURL, context);
+ }
+
+ @SuppressWarnings("unchecked")
+ public void resolve(Object model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+
+ // Delegate to the processor associated with the model type
+ if (model != null) {
+ URLArtifactProcessor processor = processors.getProcessor(model.getClass());
+ if (processor != null) {
+ processor.resolve(model, resolver, context);
+ }
+ }
+ }
+
+ public <M> M read(URL contributionURL, URI artifactURI, URL artifactUrl, ProcessorContext context, Class<M> type)
+ throws ContributionReadException {
+ Object mo = read(contributionURL, artifactURI, artifactUrl, context);
+ if (type.isInstance(mo)) {
+ return type.cast(mo);
+ } else {
+ UnrecognizedElementException e = new UnrecognizedElementException(null);
+ e.setResourceURI(artifactURI.toString());
+ error(context.getMonitor(), "UnrecognizedElementException", processors, artifactURI.toString());
+ throw e;
+ }
+ }
+
+ public String getArtifactType() {
+ return "";
+ }
+
+ public Class<Object> getModelType() {
+ return Object.class;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ProcessorContext.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ProcessorContext.java
new file mode 100644
index 0000000000..d464af40f2
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ProcessorContext.java
@@ -0,0 +1,127 @@
+/*
+ * 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;
+
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.Contribution;
+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;
+
+/**
+ * Context for contribution processors
+ * @tuscany.spi.extension.asclient
+ */
+public class ProcessorContext {
+ protected Contribution contribution;
+ protected Artifact artifact;
+ protected Monitor monitor;
+ protected Object parentModel;
+
+ /**
+ * @param contribution
+ * @param monitor
+ */
+ public ProcessorContext(Contribution contribution, Monitor monitor) {
+ super();
+ this.contribution = contribution;
+ this.monitor = monitor;
+ }
+
+ public ProcessorContext(Monitor monitor) {
+ super();
+ this.monitor = monitor;
+ }
+
+ public ProcessorContext(ExtensionPointRegistry registry) {
+ super();
+ MonitorFactory monitorFactory =
+ registry.getExtensionPoint(UtilityExtensionPoint.class).getUtility(MonitorFactory.class);
+ this.monitor = monitorFactory.createMonitor();
+ }
+
+ public ProcessorContext() {
+ super();
+ this.monitor = new DefaultMonitorFactory().createMonitor();
+ }
+
+ /**
+ * Get the current contribution
+ * @return The current contribution
+ */
+ public Contribution getContribution() {
+ return contribution;
+ }
+
+ /**
+ * Set the current contribution
+ * @param contribution
+ * @return
+ */
+ public Contribution setContribution(Contribution contribution) {
+ Contribution old = this.contribution;
+ this.contribution = contribution;
+ return old;
+ }
+
+ public Monitor getMonitor() {
+ return monitor;
+ }
+
+ public Monitor setMonitor(Monitor monitor) {
+ Monitor old = this.monitor;
+ this.monitor = monitor;
+ return old;
+ }
+
+ public Object getParentModel() {
+ return parentModel;
+ }
+
+ public Object setParentModel(Object parentMObject) {
+ Object old = this.parentModel;
+ this.parentModel = parentMObject;
+ return old;
+ }
+
+ /**
+ * Get the current artifact
+ * @return The current artifact
+ */
+ public Artifact getArtifact() {
+ return artifact;
+ }
+
+ /**
+ * Set the current artifact. This should be called by URLArtifactProcessor to set the document
+ * context (such as the URI of the composite file).
+ *
+ * @param artifact The new artifact
+ * @return The old artifact
+ */
+ public Artifact setArtifact(Artifact artifact) {
+ Artifact old = this.artifact;
+ this.artifact = artifact;
+ return old;
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.java
new file mode 100644
index 0000000000..cbdb5c38a0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessor.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.contribution.processor;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+
+/**
+ * An artifact processor that can read models from a StAX XMLStreamReader.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.inheritfrom
+ */
+public interface StAXArtifactProcessor<M> extends ArtifactProcessor<M> {
+
+ /**
+ * Reads a model from an XMLStreamReader.
+ *
+ * @param reader The XMLStreamReader
+ * @param context The context
+ * @return A model representation of the input.
+ */
+ M read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException;
+
+ /**
+ * Writes a model to an XMLStreamWriter.
+ *
+ * @param model A model representing the source
+ * @param writer The XML stream writer
+ * @param context TODO
+ * @throws ContributionWriteException
+ * @throws XMLStreamException
+ */
+ void write(M model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException;
+
+ /**
+ * Returns the type of artifact handled by this artifact processor.
+ *
+ * @return The type of artifact handled by this artifact processor
+ */
+ QName getArtifactType();
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java
new file mode 100644
index 0000000000..a5c66bc1ee
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXArtifactProcessorExtensionPoint.java
@@ -0,0 +1,57 @@
+/*
+ * 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;
+
+/**
+ * An extension point for StAX artifact processors.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public interface StAXArtifactProcessorExtensionPoint {
+ /**
+ * Add an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to add
+ */
+ void addArtifactProcessor(StAXArtifactProcessor<?> artifactProcessor);
+
+ /**
+ * Remove an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to remove
+ */
+ void removeArtifactProcessor(StAXArtifactProcessor<?> artifactProcessor);
+
+ /**
+ * Returns the processor associated with the given artifact type.
+ *
+ * @param artifactType An artifact type
+ * @return The processor associated with the given artifact type
+ */
+ <T> StAXArtifactProcessor<T> getProcessor(Object artifactType);
+
+ /**
+ * Returns the processor associated with the given model type.
+ *
+ * @param modelType A model type
+ * @return The processor associated with the given model type
+ */
+ <T> StAXArtifactProcessor<T> getProcessor(Class<T> modelType);
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.java
new file mode 100644
index 0000000000..e9fca5fc4c
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessor.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.contribution.processor;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+
+
+/**
+ * An artifact processor that can read attributes from a StAX XMLStreamReader.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public interface StAXAttributeProcessor<M> extends ArtifactProcessor<M>{
+
+ /**
+ * Reads a model from an XMLStreamReader.
+ * @param reader The XMLStreamReader
+ * @param context The context
+ *
+ * @return A model representation of the input.
+ */
+ M read(QName attributeName, XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException;
+
+ /**
+ * Writes a model to an XMLStreamWriter.
+ *
+ * @param model A model representing the source
+ * @param writer The XML stream writer
+ * @param context The context
+ * @throws ContributionWriteException
+ * @throws XMLStreamException
+ */
+ void write(M model, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException;
+
+ /**
+ * Returns the type of artifact handled by this artifact processor.
+ *
+ * @return The type of artifact handled by this artifact processor
+ */
+ QName getArtifactType();
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java
new file mode 100644
index 0000000000..dbc0a2c7bc
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/StAXAttributeProcessorExtensionPoint.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+/**
+ * An extension point for StAX artifact processors.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface StAXAttributeProcessorExtensionPoint {
+ /**
+ * Add an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to add
+ */
+ void addArtifactProcessor(StAXAttributeProcessor<?> artifactProcessor);
+
+ /**
+ * Remove an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to remove
+ */
+ void removeArtifactProcessor(StAXAttributeProcessor<?> artifactProcessor);
+
+ /**
+ * Returns the processor associated with the given artifact type.
+ *
+ * @param artifactType An artifact type
+ * @return The processor associated with the given artifact type
+ */
+ <T> StAXAttributeProcessor<T> getProcessor(Object artifactType);
+
+ /**
+ * Returns the processor associated with the given model type.
+ *
+ * @param modelType A model type
+ * @return The processor associated with the given model type
+ */
+ <T> StAXAttributeProcessor<T> getProcessor(Class<T> modelType);
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java
new file mode 100644
index 0000000000..035a753649
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessor.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import java.net.URI;
+import java.net.URL;
+
+
+/**
+ * An artifact processor that can read models from a URL.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.inheritfrom
+ */
+public interface URLArtifactProcessor<M> extends ArtifactProcessor<M> {
+
+ /**
+ * Reads a model from a URL.
+ *
+ * @param contributionURL Contribution location URL
+ * @param artifactURI Artifact URI
+ * @param artifactURL Artifact location URL
+ * @param context The context
+ * @return A model representation of the input.
+ */
+ M read(URL contributionURL, URI artifactURI, URL artifactURL, ProcessorContext context) throws ContributionReadException;
+
+ /**
+ * Returns the type of artifact handled by this artifact processor.
+ *
+ * @return The type of artifact handled by this artifact processor
+ */
+ String getArtifactType();
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java
new file mode 100644
index 0000000000..e5b3492767
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/URLArtifactProcessorExtensionPoint.java
@@ -0,0 +1,66 @@
+/*
+ * 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;
+
+import java.util.Collection;
+
+/**
+ * An extension point for URL artifact processors.
+ *
+ * @version $Rev$ $Date$
+ * @tuscany.spi.extension.asclient
+ */
+public interface URLArtifactProcessorExtensionPoint {
+ /**
+ * Add an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to add
+ */
+ void addArtifactProcessor(URLArtifactProcessor<?> artifactProcessor);
+
+ /**
+ * Remove an artifact processor.
+ *
+ * @param artifactProcessor The artifact processor to remove
+ */
+ void removeArtifactProcessor(URLArtifactProcessor<?> artifactProcessor);
+
+ /**
+ * Returns the processor associated with the given artifact type.
+ *
+ * @param artifactType An artifact type
+ * @return The processor associated with the given artifact type
+ */
+ <T> URLArtifactProcessor<T> getProcessor(Object artifactType);
+
+ /**
+ * Returns the processor associated with the given model type.
+ *
+ * @param modelType A model type
+ * @return The processor associated with the given model type
+ */
+ <T> URLArtifactProcessor<T> getProcessor(Class<T> modelType);
+
+ /**
+ * Return a collection of artifact processors that match the artifactType
+ * @param artifactType
+ * @return A collection of processors
+ */
+ Collection<URLArtifactProcessor<?>> getProcessors(Object artifactType);
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java
new file mode 100644
index 0000000000..4c6f0b7282
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnrecognizedElementException.java
@@ -0,0 +1,48 @@
+/*
+ * 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;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Exception that indicates an element was encountered that could not be handled.
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnrecognizedElementException extends ContributionReadException {
+ private static final long serialVersionUID = 2549543622209829032L;
+ private final QName element;
+
+ /**
+ * Constructor that indicates which element could not be handled.
+ * @param element the element that could not be handled
+ */
+ public UnrecognizedElementException(QName element) {
+ super("Unrecognized element: " + element);
+ this.element = element;
+ }
+
+ /**
+ * Returns the element that could not be handled.
+ * @return the element that could not be handled.
+ */
+ public QName getElement() {
+ return element;
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java
new file mode 100644
index 0000000000..8a166e42f0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedContentTypeException.java
@@ -0,0 +1,43 @@
+/*
+ * 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;
+
+
+/**
+ * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain.
+ * The Content-Type value supplied will be returned as the message text for this exception.
+ *
+ * FIXME Don't use as it's deprecated and replaced by UnsupportedPackageTypeException.
+ *
+ * @version $Rev$ $Date$
+ */
+@Deprecated
+public class UnsupportedContentTypeException extends ContributionException {
+ private static final long serialVersionUID = -1831797280021355672L;
+
+ /**
+ * Constructs a new UnsupportedContentTypeException.
+ *
+ * @param message
+ */
+ public UnsupportedContentTypeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java
new file mode 100644
index 0000000000..ce94cef6a0
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/UnsupportedPackageTypeException.java
@@ -0,0 +1,40 @@
+/*
+ * 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;
+
+
+/**
+ * Exception thrown to indicate that a Content-Type is not supported by this SCA Domain.
+ * The Content-Type value supplied will be returned as the message text for this exception.
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnsupportedPackageTypeException extends ContributionException {
+ private static final long serialVersionUID = -1831797280021355672L;
+
+ /**
+ * Constructs a new UnsupportedPackageTypeException.
+ *
+ * @param message
+ */
+ public UnsupportedPackageTypeException(String message) {
+ super(message);
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java
new file mode 100644
index 0000000000..0ad8259287
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLInputFactory.java
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * Base marker class for validating XML input factories.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class ValidatingXMLInputFactory extends XMLInputFactory {
+
+ /**
+ * Allows the monitor to be set in lieu of the context being passed
+ * into the create methods. The base definitions of the create methods
+ * don't allow for this.
+ *
+ * @param reader the XMLStreamReader instance
+ * @param monitor the current monitor object
+ *
+ * @tuscany.spi.extension.asclient
+ */
+ public static void setMonitor(XMLStreamReader reader, Monitor monitor) {
+ if (reader instanceof ValidatingXMLStreamReader) {
+ ((ValidatingXMLStreamReader)reader).setMonitor(monitor);
+ }
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java
new file mode 100644
index 0000000000..6de25d4eeb
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidatingXMLStreamReader.java
@@ -0,0 +1,409 @@
+/*
+ * 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;
+
+import java.util.logging.Logger;
+
+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.util.StreamReaderDelegate;
+import javax.xml.validation.Schema;
+import javax.xml.validation.ValidatorHandler;
+
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.AttributesImpl;
+
+/**
+ *
+ * A validating XMLStreamReader that reports XMLSchema validation errors.
+ *
+ * @version $Rev$ $Date$
+ */
+class ValidatingXMLStreamReader extends StreamReaderDelegate implements XMLStreamReader {
+
+ private static final Logger logger = Logger.getLogger(ValidatingXMLStreamReader.class.getName());
+
+ private ValidatorHandler handler;
+ private Schema schema;
+ private Monitor monitor;
+
+ /**
+ * Constructs a new ValidatingXMLStreamReader.
+ *
+ * @param reader
+ * @param schema
+ * @throws XMLStreamException
+ */
+ ValidatingXMLStreamReader(XMLStreamReader reader, Schema schema, Monitor monitor) throws XMLStreamException {
+ super(reader);
+ this.monitor = monitor;
+ this.schema = schema;
+ }
+
+ void setMonitor(Monitor monitor) {
+ this.monitor = monitor;
+ }
+
+ private synchronized ValidatorHandler getHandler() throws XMLStreamException {
+ if (schema == null || handler!=null) {
+ return handler;
+ }
+ handler = schema.newValidatorHandler();
+ handler.setDocumentLocator(new LocatorAdapter());
+ try {
+ handler.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
+ } catch (SAXException e) {
+ XMLStreamException xse = new XMLStreamException(e);
+ error("XMLStreamException", handler, xse);
+ throw xse;
+ }
+
+ // These validation errors are just warnings for us as we want to support
+ // running from an XML document with XSD validation errors, as long as we can
+ // get the metadata we need from the document
+ handler.setErrorHandler(new ErrorHandler() {
+ private String getMessage(SAXParseException e) {
+ return "XMLSchema validation problem in: " + getArtifactName( e.getSystemId() ) + ", line: " + e.getLineNumber() + ", column: " + e.getColumnNumber() + "\n" + e.getMessage();
+ }
+
+ public void error(SAXParseException exception) throws SAXException {
+ if (ValidatingXMLStreamReader.this.monitor == null)
+ logger.warning(getMessage(exception));
+ else
+ ValidatingXMLStreamReader.this.error("SchemaError", ValidatingXMLStreamReader.this.getClass(), getArtifactName( exception.getSystemId() ),
+ exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage());
+ }
+
+ public void fatalError(SAXParseException exception) throws SAXException {
+ if (ValidatingXMLStreamReader.this.monitor == null)
+ logger.warning(getMessage(exception));
+ else
+ ValidatingXMLStreamReader.this.error("SchemaFatalError", ValidatingXMLStreamReader.this.getClass(), getArtifactName( exception.getSystemId() ),
+ exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage());
+ }
+
+ public void warning(SAXParseException exception) throws SAXException {
+ if (ValidatingXMLStreamReader.this.monitor == null)
+ logger.warning(getMessage(exception));
+ else
+ ValidatingXMLStreamReader.this.warning("SchemaWarning", ValidatingXMLStreamReader.this.getClass(), getArtifactName( exception.getSystemId() ),
+ exception.getLineNumber(), exception.getColumnNumber(), exception.getMessage());
+ }
+
+ private String getArtifactName( String input ) {
+ String artifactName = null;
+ if( ValidatingXMLStreamReader.this.monitor != null ) {
+ artifactName = ValidatingXMLStreamReader.this.monitor.getArtifactName();
+ }
+ if (artifactName == null){
+ artifactName = input;
+ }
+ return artifactName;
+ }
+ });
+ return handler;
+ }
+
+ /**
+ * Report a warning.
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ private void warning(String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem = monitor.createProblem(this.getClass().getName(), "contribution-validation-messages", Severity.WARNING, model, message, (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * 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-validation-messages", Severity.ERROR, model, message, (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ @Override
+ public int next() throws XMLStreamException {
+ if (getHandler() == null) {
+ return super.next();
+ }
+
+ int event = super.getEventType();
+ try {
+ if (event == START_DOCUMENT) {
+ // We need to trigger the startDocument()
+ handler.startDocument();
+ }
+ event = super.next();
+ validate(event);
+ } catch (SAXException e) {
+ XMLStreamException xse = new XMLStreamException(e.getMessage(), e);
+ error("XMLStreamException", handler, xse);
+ throw xse;
+ }
+ return event;
+ }
+
+ private void validate(int event) throws SAXException {
+ switch (event) {
+ case START_DOCUMENT:
+ handler.startDocument();
+ break;
+ case START_ELEMENT:
+ handleStartElement();
+ break;
+ case PROCESSING_INSTRUCTION:
+ handler.processingInstruction(super.getPITarget(), super.getPIData());
+ break;
+ case CHARACTERS:
+ case CDATA:
+ case SPACE:
+ case ENTITY_REFERENCE:
+ handler.characters(super.getTextCharacters(), super.getTextStart(), super.getTextLength());
+ break;
+ case END_ELEMENT:
+ handleEndElement();
+ break;
+ case END_DOCUMENT:
+ handler.endDocument();
+ break;
+ }
+ }
+
+ @Override
+ public int nextTag() throws XMLStreamException {
+ if (getHandler() == null) {
+ return super.nextTag();
+ }
+ while (true) {
+ int event = super.getEventType();
+ try {
+ if (event == START_DOCUMENT) {
+ // We need to trigger the startDocument()
+ handler.startDocument();
+ }
+ event = super.next();
+ validate(event);
+ } catch (SAXException e) {
+ XMLStreamException xse = new XMLStreamException(e);
+ error("XMLStreamException", handler, xse);
+ throw xse;
+ }
+
+ if ((event == CHARACTERS && isWhiteSpace()) // skip whitespace
+ || (event == CDATA && isWhiteSpace())
+ // skip whitespace
+ || event == SPACE
+ || event == PROCESSING_INSTRUCTION
+ || event == COMMENT) {
+ continue;
+ }
+ if (event != START_ELEMENT && event != END_ELEMENT) {
+ throw new XMLStreamException("expected start or end tag", getLocation());
+ }
+ return event;
+ }
+ }
+
+ @Override
+ public String getElementText() throws XMLStreamException {
+ if (getHandler() == null) {
+ return super.getElementText();
+ }
+
+ if (getEventType() != START_ELEMENT) {
+ return super.getElementText();
+ }
+ StringBuffer text = new StringBuffer();
+
+ for (;;) {
+ int event = next();
+ switch (event) {
+ case END_ELEMENT:
+ return text.toString();
+
+ case COMMENT:
+ case PROCESSING_INSTRUCTION:
+ continue;
+
+ case CHARACTERS:
+ case CDATA:
+ case SPACE:
+ case ENTITY_REFERENCE:
+ text.append(getText());
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ @Override
+ public NamespaceContext getNamespaceContext(){
+ return super.getNamespaceContext();
+ }
+
+ /**
+ * Handle a start element event.
+ *
+ * @throws SAXException
+ */
+ private void handleStartElement() throws SAXException {
+
+ // send startPrefixMapping events immediately before startElement event
+ int nsCount = super.getNamespaceCount();
+ for (int i = 0; i < nsCount; i++) {
+ String prefix = super.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.startPrefixMapping(prefix, super.getNamespaceURI(i));
+ }
+
+ // fire startElement
+ QName qname = super.getName();
+ String prefix = qname.getPrefix();
+ String rawname;
+ if (prefix == null || prefix.length() == 0) {
+ rawname = qname.getLocalPart();
+ } else {
+ rawname = prefix + ':' + qname.getLocalPart();
+ }
+ Attributes attrs = getAttributes();
+ handler.startElement(qname.getNamespaceURI(), qname.getLocalPart(), rawname, attrs);
+ }
+
+ /**
+ * Handle an endElement event.
+ *
+ * @throws SAXException
+ */
+ private void handleEndElement() throws SAXException {
+
+ // fire endElement
+ QName qname = super.getName();
+ handler.endElement(qname.getNamespaceURI(), qname.getLocalPart(), qname.toString());
+
+ // send endPrefixMapping events immediately after endElement event
+ // we send them in the opposite order to that returned but this is not
+ // actually required by SAX
+ int nsCount = super.getNamespaceCount();
+ for (int i = nsCount - 1; i >= 0; i--) {
+ String prefix = super.getNamespacePrefix(i);
+ if (prefix == null) { // true for default namespace
+ prefix = "";
+ }
+ handler.endPrefixMapping(prefix);
+ }
+ }
+
+ /**
+ * Get the attributes associated with the current START_ELEMENT event.
+ *
+ * @return the StAX attributes converted to org.xml.sax.Attributes
+ */
+ private Attributes getAttributes() {
+ AttributesImpl attrs = new AttributesImpl();
+
+ // add namespace declarations
+ for (int i = 0; i < super.getNamespaceCount(); i++) {
+ String prefix = super.getNamespacePrefix(i);
+ String uri = super.getNamespaceURI(i);
+ if (prefix == null) {
+ attrs.addAttribute("", "", "xmlns", "CDATA", uri);
+ } else {
+ attrs.addAttribute("", "", "xmlns:" + prefix, "CDATA", uri);
+ }
+ }
+
+ // Regular attributes
+ for (int i = 0; i < super.getAttributeCount(); i++) {
+ String uri = super.getAttributeNamespace(i);
+ if (uri == null) {
+ uri = "";
+ }
+ String localName = super.getAttributeLocalName(i);
+ String prefix = super.getAttributePrefix(i);
+ String qname;
+ if (prefix == null || prefix.length() == 0) {
+ qname = localName;
+ } else {
+ qname = prefix + ':' + localName;
+ }
+ String type = super.getAttributeType(i);
+ String value = super.getAttributeValue(i);
+
+ attrs.addAttribute(uri, localName, qname, type, value);
+ }
+
+ return attrs;
+ }
+
+ /**
+ * Adapter for mapping Locator information.
+ */
+ private final class LocatorAdapter implements Locator {
+
+ private LocatorAdapter() {
+ }
+
+ public int getColumnNumber() {
+ Location location = getLocation();
+ return location == null ? 0 : location.getColumnNumber();
+ }
+
+ public int getLineNumber() {
+ Location location = getLocation();
+ return location == null ? 0 : location.getLineNumber();
+ }
+
+ public String getPublicId() {
+ Location location = getLocation();
+ return location == null ? "" : location.getPublicId();
+ }
+
+ public String getSystemId() {
+ Location location = getLocation();
+ return location == null ? "" : location.getSystemId();
+ }
+ }
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java
new file mode 100644
index 0000000000..67ec55b72e
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/ValidationSchemaExtensionPoint.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.contribution.processor;
+
+import java.util.List;
+
+
+/**
+ * An extension point for XML schemas used for validation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ValidationSchemaExtensionPoint {
+ /**
+ * Set the flag to control if schema validation should be enabled
+ * @param enabled
+ */
+ void setEnabled(boolean enabled);
+
+ /**
+ * Test the schema validation is enabled
+ * @return
+ */
+ boolean isEnabled();
+
+ /**
+ * Add a schema.
+ *
+ * @param uri the URI of the schema
+ */
+ void addSchema(String uri);
+
+ /**
+ * Remove a schema.
+ *
+ * @param uri the URI of the schema
+ */
+ void removeSchema(String uri);
+
+ /**
+ * Returns the list of schemas registered in the extension point.
+ * @return the list of schemas
+ */
+ List<String> getSchemas();
+
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/ContributionContentProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/ContributionContentProcessor.java
new file mode 100644
index 0000000000..58abc98d21
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/impl/ContributionContentProcessor.java
@@ -0,0 +1,349 @@
+/*
+ * 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.impl;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+import java.util.ListIterator;
+
+import org.apache.tuscany.sca.assembly.Composite;
+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.ContributionMetadata;
+import org.apache.tuscany.sca.contribution.DefaultExport;
+import org.apache.tuscany.sca.contribution.DefaultImport;
+import org.apache.tuscany.sca.contribution.Export;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.java.JavaExport;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ExtendedURLArtifactProcessor;
+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.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessorExtensionPoint;
+import org.apache.tuscany.sca.contribution.resolver.DefaultModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ExtensibleModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolverExtensionPoint;
+import org.apache.tuscany.sca.contribution.scanner.ContributionScanner;
+import org.apache.tuscany.sca.contribution.scanner.ContributionScannerExtensionPoint;
+import org.apache.tuscany.sca.contribution.scanner.impl.DirectoryContributionScanner;
+import org.apache.tuscany.sca.contribution.scanner.impl.JarContributionScanner;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * URLArtifactProcessor that handles contribution files and the artifacts they contain
+ * and returns a contribution model.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ContributionContentProcessor implements ExtendedURLArtifactProcessor<Contribution> {
+ private ContributionFactory contributionFactory;
+ private ModelResolverExtensionPoint modelResolvers;
+ private FactoryExtensionPoint modelFactories;
+ private URLArtifactProcessor<Object> artifactProcessor;
+ private StAXArtifactProcessor<Object> extensionProcessor;
+ private ContributionScannerExtensionPoint scanners;
+ // Marks pre-resolve phase completed
+ private boolean preResolved = false;
+
+ public ContributionContentProcessor(ExtensionPointRegistry extensionPoints,
+ StAXArtifactProcessor<Object> extensionProcessor) {
+ this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ this.modelResolvers = extensionPoints.getExtensionPoint(ModelResolverExtensionPoint.class);
+ URLArtifactProcessorExtensionPoint artifactProcessors =
+ extensionPoints.getExtensionPoint(URLArtifactProcessorExtensionPoint.class);
+ this.artifactProcessor = new ExtensibleURLArtifactProcessor(artifactProcessors);
+ this.extensionProcessor = extensionProcessor;
+ this.contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ this.scanners = extensionPoints.getExtensionPoint(ContributionScannerExtensionPoint.class);
+ }
+
+ public String getArtifactType() {
+ return ".contribution/content";
+ }
+
+ public Class<Contribution> getModelType() {
+ return Contribution.class;
+ }
+
+ private File toFile(URL url) {
+ if ("file".equalsIgnoreCase(url.getProtocol())) {
+ try {
+ return new File(url.toURI());
+ } catch (URISyntaxException e) {
+ return new File(url.getPath());
+ } catch (IllegalArgumentException e) {
+ // Hack for file:./a.txt or file:../a/c.wsdl
+ return new File(url.getPath());
+ }
+ }
+ return null;
+ }
+
+ public Contribution read(URL parentURL, URI contributionURI, URL contributionURL, ProcessorContext context)
+ throws ContributionReadException {
+
+ // Create contribution model
+ Contribution contribution = contributionFactory.createContribution();
+ contribution.setURI(contributionURI.toString());
+ if (contributionURL != null) {
+ contribution.setLocation(contributionURL.toString());
+ }
+ ModelResolver modelResolver = new ExtensibleModelResolver(contribution, modelResolvers, modelFactories);
+ contribution.setModelResolver(modelResolver);
+ contribution.setUnresolved(true);
+
+ Monitor monitor = context.getMonitor();
+ monitor.pushContext("Contribution: " + contribution.getURI());
+
+ Contribution old = context.setContribution(contribution);
+ try {
+ if (contributionURL != null) {
+ // Create a contribution scanner
+ ContributionScanner scanner = scanners.getContributionScanner(contributionURL.getProtocol());
+ if (scanner == null) {
+ File file = toFile(contributionURL);
+ if (file != null && file.isDirectory()) {
+ scanner = new DirectoryContributionScanner(contributionFactory);
+ } else {
+ scanner = new JarContributionScanner(contributionFactory);
+ }
+ }
+
+ // Scan the contribution and list the artifacts contained in it
+ boolean contributionMetadata = false;
+ List<Artifact> artifacts = scanner.scan(contribution);
+ for (Artifact artifact : artifacts) {
+ // Add the deployed artifact model to the contribution
+ modelResolver.addModel(artifact, context);
+
+ monitor.pushContext("Artifact: " + artifact.getURI());
+
+ Artifact oldArtifact = context.setArtifact(artifact);
+ try {
+ // Read each artifact
+ URL artifactLocationURL = null;
+ try {
+ artifactLocationURL = new URL(artifact.getLocation());
+ } catch (MalformedURLException e) {
+ //ignore
+ }
+
+ Object model =
+ artifactProcessor.read(contributionURL,
+ URI.create(artifact.getURI()),
+ artifactLocationURL,
+ context);
+ if (model != null) {
+ artifact.setModel(model);
+
+ // Add the loaded model to the model resolver
+ modelResolver.addModel(model, context);
+
+ // Merge contribution metadata into the contribution model
+ if (model instanceof ContributionMetadata) {
+ contributionMetadata = true;
+ ContributionMetadata c = (ContributionMetadata)model;
+ contribution.getImports().addAll(c.getImports());
+ contribution.getExports().addAll(c.getExports());
+ contribution.getDeployables().addAll(c.getDeployables());
+ contribution.getExtensions().addAll(c.getExtensions());
+ contribution.getAttributeExtensions().addAll(c.getAttributeExtensions());
+ }
+ }
+ } finally {
+ monitor.popContext();
+ context.setArtifact(oldArtifact);
+ }
+ }
+
+ List<Artifact> contributionArtifacts = contribution.getArtifacts();
+ contributionArtifacts.addAll(artifacts);
+
+ // If no sca-contribution.xml file was provided then just consider
+ // all composites in the contribution as deployables
+ if (!contributionMetadata) {
+ for (Artifact artifact : artifacts) {
+ if (artifact.getModel() instanceof Composite) {
+ contribution.getDeployables().add((Composite)artifact.getModel());
+ }
+ }
+
+ // Add default contribution import and export
+ DefaultImport defaultImport = contributionFactory.createDefaultImport();
+ defaultImport.setModelResolver(new DefaultModelResolver());
+ contribution.getImports().add(defaultImport);
+ DefaultExport defaultExport = contributionFactory.createDefaultExport();
+ contribution.getExports().add(defaultExport);
+ } else {
+ if (contribution.getDeployables().size() > 0) {
+ // Update the deployable Composite objects with the correct Composite object for the artifact
+ for (Artifact a : contribution.getArtifacts()) {
+ if (a.getModel() instanceof Composite) {
+ for (ListIterator<Composite> lit = contribution.getDeployables().listIterator(); lit.hasNext();) {
+ if (lit.next().getName().equals(((Composite)a.getModel()).getName())) {
+ lit.set((Composite)a.getModel());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ } finally {
+ monitor.popContext();
+ context.setContribution(old);
+ }
+
+ return contribution;
+ }
+
+ /**
+ * A pre-resolution step, which is required for Contributions to handle the resolution of imports and exports so that
+ * at resolve time, imports can be followed to exports and anything exported that is required can be resolved on demand
+ * without the need to have already resolved the whole of the Contribution containing the export
+ * @param contribution - the Contribution
+ * @param resolver - the Resolver to use
+ * @throws ContributionResolveException
+ */
+ public void preResolve(Contribution contribution, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ // Resolve the contribution model itself
+ ModelResolver contributionResolver = contribution.getModelResolver();
+ contribution.setUnresolved(false);
+ contributionResolver.addModel(contribution, context);
+
+ // Resolve Exports
+ resolveExports(contribution, contributionResolver, context);
+ // Resolve Imports
+ resolveImports(contribution, contributionResolver, context);
+
+ preResolved = true;
+ } // end method preResolve
+
+ public void resolve(Contribution contribution, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+
+ Monitor monitor = context.getMonitor();
+ Contribution old = context.setContribution(contribution);
+ try {
+ monitor.pushContext("Contribution: " + contribution.getURI());
+
+ if (!preResolved)
+ preResolve(contribution, resolver, context);
+ ModelResolver contributionResolver = contribution.getModelResolver();
+
+ // Validate Java Exports: [JCI100007] A Java package that is specified on an export
+ // element MUST be contained within the contribution containing the export element.
+ for (Export export : contribution.getExports()) {
+ if (export instanceof JavaExport) {
+ boolean available = false;
+ String packageName = ((JavaExport)export).getPackage();
+ for (Artifact artifact : contribution.getArtifacts()) {
+ if (packageName.equals(artifact.getURI().replace("/", ".")))
+ available = true;
+ }
+ if (!available) {
+ String message = context.getMonitor().getMessageString(ContributionContentProcessor.class.getName(),
+ "contribution-xml-validation-messages",
+ "ExportedPackageNotFound");
+ message = message.replace("{0}", packageName);
+
+ throw new ContributionResolveException(message);
+ }
+ }
+ }
+
+ // Resolve all artifact models
+ for (Artifact artifact : contribution.getArtifacts()) {
+ Object model = artifact.getModel();
+ if (model != null) {
+ Artifact oldArtifact = context.setArtifact(artifact);
+ try {
+ artifactProcessor.resolve(model, contributionResolver, context);
+ } catch (Throwable e) {
+ throw new ContributionResolveException(e);
+ } finally {
+ context.setArtifact(oldArtifact);
+ }
+ }
+ }
+
+ // Resolve deployable composites
+ List<Composite> deployables = contribution.getDeployables();
+ Artifact oldArtifact = context.setArtifact(contribution);
+ try {
+ for (int i = 0, n = deployables.size(); i < n; i++) {
+ Composite deployable = deployables.get(i);
+ Composite resolved =
+ (Composite)contributionResolver.resolveModel(Composite.class, deployable, context);
+ if (resolved != deployable) {
+ deployables.set(i, resolved);
+ }
+ } // end for
+ } finally {
+ context.setArtifact(oldArtifact);
+ }
+ } finally {
+ monitor.popContext();
+ context.setContribution(old);
+ } // end try
+ } // end method resolve
+
+ /**
+ * Resolves the Exports of the contribution
+ * @param contribution
+ * @param resolver
+ */
+ private void resolveExports(Contribution contribution, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ for (Export export : contribution.getExports()) {
+ if (export instanceof DefaultExport) {
+ // Initialize the default export's resolver
+ export.setModelResolver(resolver);
+ } else {
+ extensionProcessor.resolve(export, resolver, context);
+ } // end if
+ } // end for
+
+ } // end method resolveExports
+
+ /**
+ * Resolves the Imports of the contribution
+ * @param contribution
+ * @param resolver
+ */
+ private void resolveImports(Contribution contribution, ModelResolver resolver, ProcessorContext context)
+ throws ContributionResolveException {
+ for (Import import_ : contribution.getImports()) {
+ extensionProcessor.resolve(import_, resolver, context);
+ } // end for
+ } // end method resolveImports
+
+} // end class ContributionContentProcessor
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java
new file mode 100644
index 0000000000..f589c6b911
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyAttributeProcessor.java
@@ -0,0 +1,79 @@
+/*
+ * 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.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.ExtensibleStAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.processor.ProcessorContext;
+import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * A Policy Processor used for testing.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnyAttributeProcessor extends BaseStAXArtifactProcessor implements StAXAttributeProcessor<Extension> {
+
+ private AssemblyFactory assemblyFactory;
+
+ public AnyAttributeProcessor(FactoryExtensionPoint modelFactories) {
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ }
+
+ public QName getArtifactType() {
+ return ExtensibleStAXAttributeProcessor.ANY_ATTRIBUTE;
+ }
+
+ public Class<Extension> getModelType() {
+ return Extension.class;
+ }
+
+ public Extension read(QName attributeName, XMLStreamReader reader, ProcessorContext context) 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, ProcessorContext context) 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 model, ModelResolver modelResolver, ProcessorContext context) throws ContributionResolveException {
+
+ }
+}
diff --git a/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.java
new file mode 100644
index 0000000000..db4feeec48
--- /dev/null
+++ b/sca-java-2.x/branches/2.0/modules/contribution/src/main/java/org/apache/tuscany/sca/contribution/processor/xml/AnyElementProcessor.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.contribution.processor.xml;
+
+import java.io.StringReader;
+
+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.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.ExtensibleStAXArtifactProcessor;
+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;
+
+public class AnyElementProcessor implements StAXArtifactProcessor<Extension> {
+ private AssemblyFactory assemblyFactory;
+ private StAXHelper helper;
+
+ public AnyElementProcessor(ExtensionPointRegistry extensionPoints, StAXArtifactProcessor<Object> extensionProcessor) {
+ FactoryExtensionPoint modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ this.helper = StAXHelper.getInstance(extensionPoints);
+ }
+
+ public QName getArtifactType() {
+ return ExtensibleStAXArtifactProcessor.ANY_ELEMENT;
+ }
+
+ public Class<Extension> getModelType() {
+ return Extension.class;
+ }
+
+ /**
+ * Reads the contetns of the unknown elements and generates a custom
+ * implementation of XMLStreamReader i.e. XMLEventsStreamReader
+ *
+ * @param reader
+ * @return
+ * @throws XMLStreamException
+ */
+ public Extension read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException, XMLStreamException {
+ QName name = reader.getName();
+ String xml = helper.saveAsString(reader);
+ Extension ext = assemblyFactory.createExtension();
+ ext.setQName(name);
+ ext.setValue(xml);
+
+ return ext;
+ }
+
+ /**
+ * Writes unknown portions back to the writer
+ *
+ * @param model
+ * @param writer
+ */
+ public void write(Extension model, XMLStreamWriter writer, ProcessorContext context) throws XMLStreamException {
+ Object value = model.getValue();
+ if (!(value instanceof String)) {
+ return;
+ }
+ String xml = (String) value;
+ XMLStreamReader reader = helper.createXMLStreamReader(new StringReader(xml));
+ // Position the reader to the root element
+ reader.nextTag();
+ helper.save(reader, writer);
+ }
+
+ public void resolve(Extension model, ModelResolver resolver, ProcessorContext context) throws ContributionResolveException {
+ }
+}