summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org
diff options
context:
space:
mode:
authorlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:09:18 +0000
committerlresende <lresende@13f79535-47bb-0310-9956-ffa450edef68>2009-11-11 23:09:18 +0000
commit4e13586bc791d71c41760cf4d0a5cc908973de3e (patch)
tree82e905f91d993f3a642168854371789150dfb2e8 /sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org
parentcde3d2629677a07aa09e3c7fbe117b680c0f5df7 (diff)
Moving 2.x branches
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@835134 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org')
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java906
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java130
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java95
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java381
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java202
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java83
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java1047
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java101
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeDocumentProcessor.java127
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeModelResolver.java83
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeProcessor.java273
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java254
-rw-r--r--sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java252
13 files changed, 3934 insertions, 0 deletions
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java
new file mode 100644
index 0000000000..03a087a5ec
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java
@@ -0,0 +1,906 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static javax.xml.XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI;
+import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
+import static javax.xml.stream.XMLStreamConstants.CDATA;
+import static javax.xml.stream.XMLStreamConstants.CHARACTERS;
+import static javax.xml.stream.XMLStreamConstants.COMMENT;
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MANY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MULTIPLICITY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.NAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ONE_N;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ONE_ONE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SCA11_NS;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.VALUE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.VALUE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ZERO_N;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ZERO_ONE;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.dom.DOMSource;
+
+import org.apache.tuscany.sca.assembly.AbstractContract;
+import org.apache.tuscany.sca.assembly.AbstractProperty;
+import org.apache.tuscany.sca.assembly.AbstractReference;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Base;
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Extensible;
+import org.apache.tuscany.sca.assembly.Extension;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Multiplicity;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.Problem;
+import org.apache.tuscany.sca.monitor.Problem.Severity;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * A base class with utility methods for the other artifact processors in this module.
+ *
+ * @version $Rev$ $Date$
+ */
+abstract class BaseAssemblyProcessor extends BaseStAXArtifactProcessor {
+
+ protected AssemblyFactory assemblyFactory;
+ protected PolicyFactory policyFactory;
+ protected StAXArtifactProcessor<Object> extensionProcessor;
+ protected PolicySubjectProcessor policyProcessor;
+ private DocumentBuilderFactory documentBuilderFactory;
+ private Monitor monitor;
+
+ /**
+ * Constructs a new BaseArtifactProcessor.
+ * @param assemblyFactory
+ * @param policyFactory
+ */
+ @SuppressWarnings("unchecked")
+ protected BaseAssemblyProcessor(AssemblyFactory assemblyFactory,
+ PolicyFactory policyFactory,
+ DocumentBuilderFactory documentBuilderFactory,
+ StAXArtifactProcessor extensionProcessor,
+ Monitor monitor) {
+ this.assemblyFactory = assemblyFactory;
+ this.policyFactory = policyFactory;
+ this.documentBuilderFactory = documentBuilderFactory;
+ this.extensionProcessor = (StAXArtifactProcessor<Object>)extensionProcessor;
+ this.policyProcessor = new PolicySubjectProcessor(policyFactory);
+ this.monitor = monitor;
+ }
+
+ /**
+ * @param modelFactories
+ * @param staxProcessor
+ * @param monitor
+ */
+ protected BaseAssemblyProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ this.assemblyFactory = modelFactories.getFactory(AssemblyFactory.class);
+ this.policyFactory = modelFactories.getFactory(PolicyFactory.class);
+ this.documentBuilderFactory = modelFactories.getFactory(DocumentBuilderFactory.class);
+ this.extensionProcessor = (StAXArtifactProcessor<Object>)staxProcessor;
+ this.policyProcessor = new PolicySubjectProcessor(policyFactory);
+ this.monitor = monitor;
+ }
+
+ /**
+ * Marshals warnings into the monitor
+ *
+ * @param message
+ * @param model
+ * @param messageParameters
+ */
+ protected void warning(String message, Object model, String... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "assembly-xml-validation-messages",
+ Severity.WARNING,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Marshals errors into the monitor
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ protected void error(String message, Object model, Object... messageParameters) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "assembly-xml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ (Object[])messageParameters);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Marshals exceptions into the monitor
+ *
+ * @param problems
+ * @param message
+ * @param model
+ */
+ protected void error(String message, Object model, Exception ex) {
+ if (monitor != null) {
+ Problem problem =
+ monitor.createProblem(this.getClass().getName(),
+ "assembly-xml-validation-messages",
+ Severity.ERROR,
+ model,
+ message,
+ ex);
+ monitor.problem(problem);
+ }
+ }
+
+ /**
+ * Start an element.
+ * @param writer
+ * @param name
+ * @param attrs
+ * @throws XMLStreamException
+ */
+ protected void writeStart(XMLStreamWriter writer, String name, XAttr... attrs) throws XMLStreamException {
+ writeStart(writer, SCA11_NS, name, attrs);
+ }
+
+ /**
+ * Start a document.
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void writeStartDocument(XMLStreamWriter writer, String name, XAttr... attrs) throws XMLStreamException {
+ writer.writeStartDocument();
+ writer.setDefaultNamespace(SCA11_NS);
+ writeStart(writer, SCA11_NS, name, attrs);
+ writer.writeDefaultNamespace(SCA11_NS);
+ }
+
+ /**
+ * Read list of reference targets
+ * @param reference
+ * @param reader
+ */
+ protected void readTargets(Reference reference, XMLStreamReader reader) {
+ String value = reader.getAttributeValue(null, TARGET);
+ ComponentService target = null;
+ if (value != null) {
+ for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) {
+ target = assemblyFactory.createComponentService();
+ target.setUnresolved(true);
+ target.setName(tokens.nextToken());
+ reference.getTargets().add(target);
+ }
+ }
+ }
+
+ /**
+ * Write a list of targets into an attribute
+ * @param reference
+ * @return
+ */
+ protected XAttr writeTargets(Reference reference) {
+ List<String> targets = new ArrayList<String>();
+ for (Service target : reference.getTargets()) {
+ targets.add(target.getName());
+ }
+ return new XAttr(TARGET, targets);
+ }
+
+ /**
+ * Read a multiplicity attribute.
+ * @param reference
+ * @param reader
+ */
+ protected void readMultiplicity(AbstractReference reference, XMLStreamReader reader) {
+ String value = reader.getAttributeValue(null, MULTIPLICITY);
+ if (ZERO_ONE.equals(value)) {
+ reference.setMultiplicity(Multiplicity.ZERO_ONE);
+ } else if (ONE_N.equals(value)) {
+ reference.setMultiplicity(Multiplicity.ONE_N);
+ } else if (ZERO_N.equals(value)) {
+ reference.setMultiplicity(Multiplicity.ZERO_N);
+ } else if (ONE_ONE.equals(value)) {
+ reference.setMultiplicity(Multiplicity.ONE_ONE);
+ }
+ }
+
+ protected XAttr writeMultiplicity(AbstractReference reference) {
+ Multiplicity multiplicity = reference.getMultiplicity();
+ if (multiplicity != null) {
+ String value = null;
+ if (Multiplicity.ZERO_ONE.equals(multiplicity)) {
+ value = ZERO_ONE;
+ } else if (Multiplicity.ONE_N.equals(multiplicity)) {
+ value = ONE_N;
+ } else if (Multiplicity.ZERO_N.equals(multiplicity)) {
+ value = ZERO_N;
+ } else if (Multiplicity.ONE_ONE.equals(multiplicity)) {
+ value = ONE_ONE;
+ return null;
+ }
+ return new XAttr(MULTIPLICITY, value);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the value of a constrainingType attribute.
+ * @param reader
+ * @return
+ */
+ protected ConstrainingType readConstrainingType(XMLStreamReader reader) {
+ QName constrainingTypeName = getQName(reader, Constants.CONSTRAINING_TYPE);
+ if (constrainingTypeName != null) {
+ ConstrainingType constrainingType = assemblyFactory.createConstrainingType();
+ constrainingType.setName(constrainingTypeName);
+ constrainingType.setUnresolved(true);
+ return constrainingType;
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Reads an abstract property element.
+ * @param property
+ * @param reader
+ * @throws XMLStreamException
+ * @throws ContributionReadException
+ */
+ protected void readAbstractProperty(AbstractProperty property, XMLStreamReader reader) throws XMLStreamException,
+ ContributionReadException {
+
+ property.setName(getString(reader, NAME));
+ property.setMany(getBoolean(reader, MANY));
+ property.setMustSupply(getBoolean(reader, MUST_SUPPLY));
+ property.setXSDElement(getQName(reader, ELEMENT));
+ property.setXSDType(getQName(reader, TYPE));
+
+ }
+
+ /**
+ * Resolve an implementation.
+ * @param implementation
+ * @param resolver
+ * @return
+ * @throws ContributionResolveException
+ */
+ protected Implementation resolveImplementation(Implementation implementation, ModelResolver resolver)
+ throws ContributionResolveException {
+ if (implementation != null) {
+ if (implementation.isUnresolved()) {
+ implementation = resolver.resolveModel(Implementation.class, implementation);
+
+ // Lazily resolve implementations
+ if (implementation.isUnresolved()) {
+ extensionProcessor.resolve(implementation, resolver);
+ if (!implementation.isUnresolved()) {
+ resolver.addModel(implementation);
+ }
+ }
+ }
+ }
+ return implementation;
+ }
+
+ /**
+ * Resolve interface, callback interface and bindings on a list of contracts.
+ * @param contracts the list of contracts
+ * @param resolver the resolver to use to resolve models
+ */
+ protected <C extends Contract> void resolveContracts(List<C> contracts, ModelResolver resolver)
+ throws ContributionResolveException {
+ resolveContracts(null, contracts, resolver);
+ }
+
+ /**
+ * Resolve interface, callback interface and bindings on a list of contracts.
+ * @param parent element for the contracts
+ * @param contracts the list of contracts
+ * @param resolver the resolver to use to resolve models
+ */
+ protected <C extends Contract> void resolveContracts(Base parent, List<C> contracts, ModelResolver resolver)
+ throws ContributionResolveException {
+
+ String parentName =
+ (parent instanceof Composite) ? ((Composite)parent).getName().toString() : (parent instanceof Component)
+ ? ((Component)parent).getName() : "UNKNOWN";
+
+ for (Contract contract : contracts) {
+ // Resolve the interface contract
+ InterfaceContract interfaceContract = contract.getInterfaceContract();
+ if (interfaceContract != null) {
+ extensionProcessor.resolve(interfaceContract, resolver);
+ }
+
+ // Resolve bindings
+ for (int i = 0, n = contract.getBindings().size(); i < n; i++) {
+ Binding binding = contract.getBindings().get(i);
+ extensionProcessor.resolve(binding, resolver);
+
+ }
+
+ // Resolve callback bindings
+ if (contract.getCallback() != null) {
+
+ for (int i = 0, n = contract.getCallback().getBindings().size(); i < n; i++) {
+ Binding binding = contract.getCallback().getBindings().get(i);
+ extensionProcessor.resolve(binding, resolver);
+ }
+ }
+ }
+ }
+
+ /**
+ * Resolve interface and callback interface on a list of abstract contracts.
+ * @param contracts the list of contracts
+ * @param resolver the resolver to use to resolve models
+ */
+ protected <C extends AbstractContract> void resolveAbstractContracts(List<C> contracts, ModelResolver resolver)
+ throws ContributionResolveException {
+ for (AbstractContract contract : contracts) {
+
+ // Resolve the interface contract
+ InterfaceContract interfaceContract = contract.getInterfaceContract();
+ if (interfaceContract != null) {
+ extensionProcessor.resolve(interfaceContract, resolver);
+ }
+ }
+ }
+
+ /**
+ * Returns a constrainingType attribute.
+ * @param componentType
+ * @return
+ */
+ protected XAttr writeConstrainingType(ComponentType componentType) {
+ ConstrainingType constrainingType = componentType.getConstrainingType();
+ if (constrainingType != null)
+ return new XAttr(Constants.CONSTRAINING_TYPE, constrainingType.getName());
+ else
+ return null;
+ }
+
+ /*
+ protected List<Extension> readPropertyValue(XMLStreamReader reader) throws XMLStreamException,
+ ContributionReadException {
+ List<Extension> values = new ArrayList<Extension>();
+ QName name = reader.getName(); // Should be sca:property
+
+ // SCA 1.1 supports the @value for simple types
+ String valueAttr = getString(reader, VALUE);
+ if (valueAttr != null) {
+ Extension ext = assemblyFactory.createExtension();
+ ext.setValue(valueAttr);
+ ext.setQName(VALUE_QNAME);
+ ext.setAttribute(true);
+ values.add(ext);
+ }
+
+ boolean isTextForProperty = true;
+ StringBuffer text = new StringBuffer();
+
+ int event = reader.getEventType();
+ while (true) {
+ switch (event) {
+ case START_ELEMENT:
+ name = reader.getName();
+ if (PROPERTY_QNAME.equals(name)) {
+ isTextForProperty = true;
+ break;
+ }
+ isTextForProperty = false;
+ // Read <value>
+ if (VALUE_QNAME.equals(name)) {
+ Object value = extensionProcessor.read(reader);
+ // Assume the value is the XMLStreamReader for the content
+ Extension ext = assemblyFactory.createExtension();
+ ext.setValue(value);
+ ext.setQName(name);
+ values.add(ext);
+ } else {
+ // Global elements
+ // FIXME: do we want to check if the element mataches property.element
+ Object value = extensionProcessor.read(reader);
+ Extension ext = assemblyFactory.createExtension();
+ ext.setValue(value);
+ ext.setQName(name);
+ values.add(ext);
+ }
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ case XMLStreamConstants.CDATA:
+ if (isTextForProperty) {
+ text.append(reader.getText());
+ }
+ break;
+ case END_ELEMENT:
+ name = reader.getName();
+ if (PROPERTY_QNAME.equals(name)) {
+ return values;
+ }
+ break;
+ }
+ if (reader.hasNext()) {
+ event = reader.next();
+ } else {
+ return values;
+ }
+ }
+ }
+ */
+
+ /**
+ * Read a property value into a DOM document.
+ * @param element
+ * @param type
+ * @param reader
+ * @return
+ * @throws XMLStreamException
+ * @throws ContributionReadException
+ * @throws ParserConfigurationException
+ */
+ protected Document readPropertyValue(QName element, QName type, XMLStreamReader reader) throws XMLStreamException,
+ ContributionReadException {
+ Document document;
+ try {
+ if (documentBuilderFactory == null) {
+ documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ }
+ document = documentBuilderFactory.newDocumentBuilder().newDocument();
+ } catch (ParserConfigurationException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", documentBuilderFactory, ce);
+ throw ce;
+ }
+
+ // Collect the property values as <value> elements under the <property>
+ Element root = document.createElementNS(SCA11_NS, "sca:" + PROPERTY);
+ String nameAttr = getString(reader, NAME);
+ if (nameAttr != null) {
+ root.setAttributeNS(SCA11_NS, "sca:" + NAME, nameAttr);
+ }
+ declareNamespace(root, "sca", SCA11_NS);
+ if (type != null) {
+ org.w3c.dom.Attr xsi = document.createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, "xmlns:xsi");
+ xsi.setValue(W3C_XML_SCHEMA_INSTANCE_NS_URI);
+ root.setAttributeNodeNS(xsi);
+
+ String prefix = type.getPrefix();
+ if (prefix == null || prefix.length() == 0) {
+ prefix = "ns";
+ }
+
+ declareNamespace(root, prefix, type.getNamespaceURI());
+
+ org.w3c.dom.Attr xsiType = document.createAttributeNS(W3C_XML_SCHEMA_INSTANCE_NS_URI, "xsi:type");
+ xsiType.setValue(prefix + ":" + type.getLocalPart());
+ root.setAttributeNodeNS(xsiType);
+ }
+ document.appendChild(root);
+
+ // Start to parse the property
+ QName name = reader.getName(); // Should be sca:property
+
+ // SCA 1.1 supports the @value for simple types
+ String valueAttr = getString(reader, VALUE);
+ if (valueAttr != null) {
+ Element valueElement = document.createElementNS(SCA11_NS, VALUE);
+ root.appendChild(valueElement);
+ valueElement.setTextContent(valueAttr);
+ }
+
+ boolean isTextForProperty = true;
+ StringBuffer text = new StringBuffer();
+
+ int event = reader.getEventType();
+ while (true) {
+ switch (event) {
+ case START_ELEMENT:
+ name = reader.getName();
+ if (PROPERTY_QNAME.equals(name)) {
+ isTextForProperty = true;
+ break;
+ }
+ isTextForProperty = false;
+ // Read <value>
+ if (VALUE_QNAME.equals(name)) {
+ loadElement(reader, root);
+ } else {
+ // Global elements
+ loadElement(reader, root);
+ }
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ case XMLStreamConstants.CDATA:
+ if (isTextForProperty) {
+ text.append(reader.getText());
+ }
+ break;
+ case END_ELEMENT:
+ name = reader.getName();
+ if (PROPERTY_QNAME.equals(name)) {
+ if (root.getChildNodes().getLength() == 0) {
+ // Add the text as an <value>
+ Element valueElement = document.createElementNS(SCA11_NS, VALUE);
+ root.appendChild(valueElement);
+ valueElement.setTextContent(text.toString());
+ }
+ return document;
+ }
+ break;
+ }
+ if (reader.hasNext()) {
+ event = reader.next();
+ } else {
+ break;
+ }
+ }
+ return document;
+ }
+
+ /**
+ * Create a DOM element
+ * @param document
+ * @param name
+ * @return
+ */
+ private Element createElement(Document document, QName name) {
+ String prefix = name.getPrefix();
+ String qname =
+ (prefix != null && prefix.length() > 0) ? prefix + ":" + name.getLocalPart() : name.getLocalPart();
+ return document.createElementNS(name.getNamespaceURI(), qname);
+ }
+
+ /**
+ * Declare a namespace.
+ * @param element
+ * @param prefix
+ * @param ns
+ */
+ private void declareNamespace(Element element, String prefix, String ns) {
+ if (ns == null) {
+ ns = "";
+ }
+ if (prefix == null) {
+ prefix = "";
+ }
+ String qname = null;
+ if ("".equals(prefix)) {
+ qname = "xmlns";
+ } else {
+ qname = "xmlns:" + prefix;
+ }
+ Node node = element;
+ boolean declared = false;
+ while (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
+ NamedNodeMap attrs = node.getAttributes();
+ if (attrs == null) {
+ break;
+ }
+ Node attr = attrs.getNamedItem(qname);
+ if (attr != null) {
+ declared = ns.equals(attr.getNodeValue());
+ break;
+ }
+ node = node.getParentNode();
+ }
+ if (!declared) {
+ org.w3c.dom.Attr attr = element.getOwnerDocument().createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, qname);
+ attr.setValue(ns);
+ element.setAttributeNodeNS(attr);
+ }
+ }
+
+ /**
+ * Load a property value specification from an StAX stream into a DOM
+ * Document. Only elements, text and attributes are processed; all comments
+ * and other whitespace are ignored.
+ *
+ * @param reader the stream to read from
+ * @param root the DOM node to load
+ * @throws javax.xml.stream.XMLStreamException
+ */
+ private void loadElement(XMLStreamReader reader, Element root) throws XMLStreamException {
+ Document document = root.getOwnerDocument();
+ Node current = root;
+ while (true) {
+ switch (reader.getEventType()) {
+ case START_ELEMENT:
+ QName name = reader.getName();
+ Element child = createElement(document, name);
+
+ // push the new element and make it the current one
+ current.appendChild(child);
+ current = child;
+
+ int count = reader.getNamespaceCount();
+ for (int i = 0; i < count; i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ String ns = reader.getNamespaceURI(i);
+ declareNamespace(child, prefix, ns);
+ }
+
+ if (!"".equals(name.getNamespaceURI())) {
+ declareNamespace(child, name.getPrefix(), name.getNamespaceURI());
+ }
+
+ // add the attributes for this element
+ count = reader.getAttributeCount();
+ for (int i = 0; i < count; i++) {
+ String ns = reader.getAttributeNamespace(i);
+ String prefix = reader.getAttributePrefix(i);
+ String qname = reader.getAttributeLocalName(i);
+ String value = reader.getAttributeValue(i);
+ if (prefix != null && prefix.length() != 0) {
+ qname = prefix + ":" + qname;
+ }
+ child.setAttributeNS(ns, qname, value);
+ if (ns != null) {
+ declareNamespace(child, prefix, ns);
+ }
+ }
+
+ break;
+ case CDATA:
+ current.appendChild(document.createCDATASection(reader.getText()));
+ break;
+ case CHARACTERS:
+ current.appendChild(document.createTextNode(reader.getText()));
+ break;
+ case COMMENT:
+ current.appendChild(document.createComment(reader.getText()));
+ break;
+ case END_ELEMENT:
+ // pop the element off the stack
+ current = current.getParentNode();
+ // if we are back at the root then we are done
+ if (current == root) {
+ return;
+ }
+
+ }
+ if (reader.hasNext()) {
+ reader.next();
+ } else {
+ return;
+ }
+ }
+ }
+
+ /**
+ * Write the value of a property
+ * @param document
+ * @param element
+ * @param type
+ * @param writer
+ * @throws XMLStreamException
+ */
+ protected void writePropertyValue(Object propertyValue, QName element, QName type, XMLStreamWriter writer)
+ throws XMLStreamException {
+
+ if (propertyValue instanceof Document) {
+ Document document = (Document)propertyValue;
+ NodeList nodeList = document.getDocumentElement().getChildNodes();
+
+ for (int item = 0; item < nodeList.getLength(); ++item) {
+ Node node = nodeList.item(item);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(new DOMSource(node));
+
+ while (reader.hasNext()) {
+ switch (reader.next()) {
+ case XMLStreamConstants.START_ELEMENT:
+ QName name = reader.getName();
+ writer.writeStartElement(name.getPrefix(), name.getLocalPart(), name.getNamespaceURI());
+
+ int namespaces = reader.getNamespaceCount();
+ for (int i = 0; i < namespaces; i++) {
+ String prefix = reader.getNamespacePrefix(i);
+ String ns = reader.getNamespaceURI(i);
+ writer.writeNamespace(prefix, ns);
+ }
+
+ if (!"".equals(name.getNamespaceURI())) {
+ writer.writeNamespace(name.getPrefix(), name.getNamespaceURI());
+ }
+
+ // add the attributes for this element
+ namespaces = reader.getAttributeCount();
+ for (int i = 0; i < namespaces; i++) {
+ String ns = reader.getAttributeNamespace(i);
+ String prefix = reader.getAttributePrefix(i);
+ String qname = reader.getAttributeLocalName(i);
+ String value = reader.getAttributeValue(i);
+
+ writer.writeAttribute(prefix, ns, qname, value);
+ }
+
+ break;
+ case XMLStreamConstants.CDATA:
+ writer.writeCData(reader.getText());
+ break;
+ case XMLStreamConstants.CHARACTERS:
+ writer.writeCharacters(reader.getText());
+ break;
+ case XMLStreamConstants.END_ELEMENT:
+ writer.writeEndElement();
+ break;
+ }
+ }
+ } else {
+ writer.writeCharacters(node.getTextContent());
+ }
+ }
+ }
+ }
+
+ protected void addInheritedIntents(List<Intent> sourceList, List<Intent> targetList) {
+ if (sourceList != null) {
+ targetList.addAll(sourceList);
+ }
+ }
+
+ protected void addInheritedPolicySets(List<PolicySet> sourceList, List<PolicySet> targetList) {
+ if (sourceList != null) {
+ targetList.addAll(sourceList);
+ }
+ }
+
+ /**
+ *
+ * @param reader
+ * @param elementName
+ * @param estensibleElement
+ * @param extensionAttributeProcessor
+ * @throws ContributionReadException
+ * @throws XMLStreamException
+ */
+ protected void readExtendedAttributes(XMLStreamReader reader,
+ QName elementName,
+ Extensible estensibleElement,
+ StAXAttributeProcessor extensionAttributeProcessor)
+ throws ContributionReadException, XMLStreamException {
+ 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);
+ Extension attributeExtension;
+ if (attributeValue instanceof Extension) {
+ attributeExtension = (Extension)attributeValue;
+ } else {
+ attributeExtension = assemblyFactory.createExtension();
+ attributeExtension.setQName(attributeName);
+ attributeExtension.setAttribute(true);
+ attributeExtension.setValue(attributeValue);
+ }
+ estensibleElement.getAttributeExtensions().add(attributeExtension);
+ }
+ }
+ }
+ }
+
+ /**
+ *
+ * @param attributeModel
+ * @param writer
+ * @param extensibleElement
+ * @param extensionAttributeProcessor
+ * @throws ContributionWriteException
+ * @throws XMLStreamException
+ */
+ protected void writeExtendedAttributes(XMLStreamWriter writer,
+ Extensible extensibleElement,
+ StAXAttributeProcessor extensionAttributeProcessor)
+ throws ContributionWriteException, XMLStreamException {
+ for (Extension extension : extensibleElement.getAttributeExtensions()) {
+ if (extension.isAttribute()) {
+ extensionAttributeProcessor.write(extension, writer);
+ }
+ }
+ }
+
+ /*protected void validatePolicySets(PolicySubject policySetAttachPoint)
+ throws ContributionResolveException {
+ validatePolicySets(policySetAttachPoint, policySetAttachPoint.getApplicablePolicySets());
+ }
+
+
+ protected void validatePolicySets(PolicySubject policySetAttachPoint,
+ List<PolicySet> applicablePolicySets) throws ContributionResolveException {
+ //Since the applicablePolicySets in a policySetAttachPoint will already have the
+ //list of policysets that might ever be applicable to this attachPoint, just check
+ //if the defined policysets feature in the list of applicable policysets
+ ExtensionType attachPointType = policySetAttachPoint.getType();
+ for ( PolicySet definedPolicySet : policySetAttachPoint.getPolicySets() ) {
+ if ( !definedPolicySet.isUnresolved() ) {
+ if ( !applicablePolicySets.contains(definedPolicySet)) {
+ throw new ContributionResolveException("Policy Set '" + definedPolicySet.getName()
+ + "' does not apply to binding type "
+ + attachPointType.getName());
+ }
+ } else {
+ throw new ContributionResolveException("Policy Set '" + definedPolicySet.getName()
+ + "' is not defined in this domain ");
+
+
+ }
+ }
+ }*/
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java
new file mode 100644
index 0000000000..969115cf4c
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeDocumentProcessor.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * A componentType processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentTypeDocumentProcessor extends BaseAssemblyProcessor implements URLArtifactProcessor<ComponentType> {
+ private XMLInputFactory inputFactory;
+
+ /**
+ * Constructs a new componentType processor.
+ * @param modelFactories
+ * @param staxProcessor
+ */
+ public ComponentTypeDocumentProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ super(modelFactories, staxProcessor, monitor);
+ this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class);
+ }
+
+ public ComponentType read(URL contributionURL, URI uri, URL url) throws ContributionReadException {
+ InputStream urlStream = null;
+ try {
+
+ // Create a stream reader
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ urlStream = connection.getInputStream();
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream);
+ reader.nextTag();
+
+ // Reader the componentType model
+ ComponentType componentType = (ComponentType)extensionProcessor.read(reader);
+ if (componentType != null) {
+ componentType.setURI(uri.toString());
+ }
+
+ // For debugging purposes, write it back to XML
+// if (componentType != null) {
+// try {
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+// outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+// extensionProcessor.write(componentType, outputFactory.createXMLStreamWriter(bos));
+// Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray()));
+// OutputFormat format = new OutputFormat();
+// format.setIndenting(true);
+// format.setIndent(2);
+// XMLSerializer serializer = new XMLSerializer(System.out, format);
+// serializer.serialize(document);
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+
+ return componentType;
+
+ } catch (XMLStreamException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", inputFactory, ce);
+ throw ce;
+ } catch (IOException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", inputFactory, ce);
+ throw ce;
+ } finally {
+ try {
+ if (urlStream != null) {
+ urlStream.close();
+ urlStream = null;
+ }
+ } catch (IOException ioe) {
+ //ignore
+ }
+ }
+ }
+
+ public void resolve(ComponentType componentType, ModelResolver resolver) throws ContributionResolveException {
+ extensionProcessor.resolve(componentType, resolver);
+ }
+
+ public String getArtifactType() {
+ return ".componentType";
+ }
+
+ public Class<ComponentType> getModelType() {
+ return ComponentType.class;
+ }
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java
new file mode 100644
index 0000000000..166bba8757
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeModelResolver.java
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.java.JavaImport;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * A Model Resolver for ComponentType models.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentTypeModelResolver implements ModelResolver {
+ private Contribution contribution;
+ private Map<String, ComponentType> map = new HashMap<String, ComponentType>();
+
+ public ComponentTypeModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ this.contribution = contribution;
+ }
+
+ public void addModel(Object resolved) {
+ ComponentType componentType = (ComponentType)resolved;
+ map.put(componentType.getURI(), componentType);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(((ComponentType)resolved).getURI());
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ //get componentType artifact URI
+ String uri = ((ComponentType)unresolved).getURI();
+ if (uri == null) {
+ return (T)unresolved;
+ }
+
+ //lookup the componentType
+ ComponentType resolved = (ComponentType) map.get(uri);
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+
+ //If not found, delegate the resolution to the imports (in this case based on the java imports)
+ //compute the package name from the componentType URI
+ if (unresolved instanceof ComponentType) {
+ //FIXME The core assembly model now depends on java imports to
+ // resolve componentTypes of all kinds, this is not right at all!!!
+ int s = uri.lastIndexOf('/');
+ if (s != -1) {
+ String packageName = uri.substring(0, uri.lastIndexOf("/"));
+ for (Import import_ : this.contribution.getImports()) {
+ if (import_ instanceof JavaImport) {
+ JavaImport javaImport = (JavaImport)import_;
+ //check the import location against the computed package name from the componentType URI
+ if (javaImport.getPackage().equals(packageName)) {
+ // Delegate the resolution to the import resolver
+ resolved = javaImport.getModelResolver().resolveModel(ComponentType.class, (ComponentType)unresolved);
+ if (!resolved.isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return (T)unresolved;
+ }
+
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java
new file mode 100644
index 0000000000..0ea78177ff
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ComponentTypeProcessor.java
@@ -0,0 +1,381 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_TYPE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_TYPE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MANY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.NAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.OPERATION_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE;
+
+import 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.Binding;
+import org.apache.tuscany.sca.assembly.Callback;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Extensible;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.policy.PolicySubject;
+import org.w3c.dom.Document;
+
+/**
+ * A componentType processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComponentTypeProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<ComponentType> {
+
+ /**
+ * Constructs a new componentType processor.
+ *
+ * @param modelFactories
+ * @param extensionProcessor
+ * @param extensionAttributeProcessor
+ * @param monitor
+ */
+ public ComponentTypeProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor extensionProcessor,
+ StAXAttributeProcessor extensionAttributeProcessor,
+ Monitor monitor) {
+ super(modelFactories, extensionProcessor, monitor);
+ }
+
+ public ComponentType read(XMLStreamReader reader) throws ContributionReadException {
+ ComponentType componentType = null;
+ Service service = null;
+ Reference reference = null;
+ Contract contract = null;
+ Property property = null;
+ Callback callback = null;
+ QName name = null;
+
+ try {
+ // Read the componentType document
+ while (reader.hasNext()) {
+ int event = reader.getEventType();
+ switch (event) {
+ case START_ELEMENT:
+ name = reader.getName();
+
+ if (Constants.COMPONENT_TYPE_QNAME.equals(name)) {
+
+ // Read a <componentType>
+ componentType = assemblyFactory.createComponentType();
+ componentType.setConstrainingType(readConstrainingType(reader));
+
+ } else if (Constants.SERVICE_QNAME.equals(name)) {
+
+ // Read a <service>
+ service = assemblyFactory.createService();
+ contract = service;
+ service.setName(getString(reader, Constants.NAME));
+ componentType.getServices().add(service);
+ policyProcessor.readPolicies(service, reader);
+
+ } else if (Constants.REFERENCE_QNAME.equals(name)) {
+
+ // Read a <reference>
+ reference = assemblyFactory.createReference();
+ contract = reference;
+ reference.setName(getString(reader, Constants.NAME));
+ reference.setWiredByImpl(getBoolean(reader, Constants.WIRED_BY_IMPL));
+ readMultiplicity(reference, reader);
+ readTargets(reference, reader);
+ componentType.getReferences().add(reference);
+ policyProcessor.readPolicies(reference, reader);
+
+ } else if (Constants.PROPERTY_QNAME.equals(name)) {
+
+ // Read a <property>
+ property = assemblyFactory.createProperty();
+ readAbstractProperty(property, reader);
+ policyProcessor.readPolicies(property, reader);
+
+ // Read the property value
+ Document value = readPropertyValue(property.getXSDElement(), property.getXSDType(), reader);
+ property.setValue(value);
+
+ componentType.getProperties().add(property);
+
+ } else if (Constants.IMPLEMENTATION_QNAME.equals(name)) {
+
+ // Read an <implementation> element
+ policyProcessor.readPolicies(componentType, reader);
+
+ } else if (Constants.CALLBACK_QNAME.equals(name)) {
+
+ // Read a <callback>
+ callback = assemblyFactory.createCallback();
+ contract.setCallback(callback);
+ policyProcessor.readPolicies(callback, reader);
+
+ } else if (OPERATION_QNAME.equals(name)) {
+
+ // Read an <operation>
+ Operation operation = new OperationImpl();
+ operation.setName(getString(reader, NAME));
+ operation.setUnresolved(true);
+ if (callback != null) {
+ policyProcessor.readPolicies(callback, operation, reader);
+ } else {
+ policyProcessor.readPolicies(contract, operation, reader);
+ }
+ } else {
+
+ // Read an extension element
+ Object extension = extensionProcessor.read(reader);
+ if (extension != null) {
+ if (extension instanceof InterfaceContract) {
+
+ // <service><interface> and <reference><interface>
+ contract.setInterfaceContract((InterfaceContract)extension);
+
+ } else if (extension instanceof Binding) {
+
+ // <service><binding> and <reference><binding>
+ if (callback != null) {
+ callback.getBindings().add((Binding)extension);
+ } else {
+ contract.getBindings().add((Binding)extension);
+ }
+ } else {
+
+ // Add the extension element to the current element
+ if (callback != null) {
+ callback.getExtensions().add(extension);
+ } else if (contract != null) {
+ contract.getExtensions().add(extension);
+ } else if (property != null) {
+ property.getExtensions().add(extension);
+ } else {
+ if (componentType instanceof Extensible) {
+ ((Extensible)componentType).getExtensions().add(extension);
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case END_ELEMENT:
+ name = reader.getName();
+
+ // Clear current state when reading reaching end element
+ if (SERVICE_QNAME.equals(name)) {
+ service = null;
+ contract = null;
+ } else if (REFERENCE_QNAME.equals(name)) {
+ reference = null;
+ contract = null;
+ } else if (PROPERTY_QNAME.equals(name)) {
+ property = null;
+ } else if (CALLBACK_QNAME.equals(name)) {
+ callback = null;
+ }
+ break;
+ }
+
+ // Read the next element
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+ }
+ catch (XMLStreamException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("XMLStreamException", reader, ex);
+ }
+
+ return componentType;
+ }
+
+ public void write(ComponentType componentType, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+
+ // Write <componentType> element
+ writeStartDocument(writer, COMPONENT_TYPE,
+ writeConstrainingType(componentType));
+
+ // Write <service> elements
+ for (Service service : componentType.getServices()) {
+ writeStart(writer, SERVICE, new XAttr(NAME, service.getName()),
+ policyProcessor.writePolicies(service));
+
+ if (service.getInterfaceContract() != null) {
+ extensionProcessor.write(service.getInterfaceContract(), writer);
+ }
+
+ for (Binding binding: service.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ if (service.getCallback() != null) {
+ Callback callback = service.getCallback();
+ writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback));
+
+ for (Binding binding: callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+ for (Object extension: callback.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ for (Object extension: service.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <reference> elements
+ for (Reference reference : componentType.getReferences()) {
+
+ writeStart(writer, REFERENCE,
+ new XAttr(NAME, reference.getName()),
+ writeMultiplicity(reference),
+ writeTargets(reference),
+ policyProcessor.writePolicies(reference));
+
+ extensionProcessor.write(reference.getInterfaceContract(), writer);
+
+ for (Binding binding: reference.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ if (reference.getCallback() != null) {
+ Callback callback = reference.getCallback();
+ writeStart(writer, CALLBACK,
+ policyProcessor.writePolicies(callback));
+
+ for (Binding binding: callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+ for (Object extension: callback.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ for (Object extension: reference.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <property> elements
+ for (Property property : componentType.getProperties()) {
+ writeStart(writer,
+ PROPERTY,
+ new XAttr(NAME, property.getName()),
+ new XAttr(MUST_SUPPLY, property.isMustSupply()),
+ new XAttr(MANY, property.isMany()),
+ new XAttr(TYPE, property.getXSDType()),
+ new XAttr(ELEMENT, property.getXSDElement()),
+ policyProcessor.writePolicies(property));
+
+ // Write property value
+ writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer);
+
+ // Write extensions
+ for (Object extension : property.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extension elements
+ if (componentType instanceof Extensible) {
+ for (Object extension: ((Extensible)componentType).getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+ }
+
+ // Write <implementation> elements if the componentType has
+ // any intents or policySets
+ boolean writeImplementation = false;
+ if (componentType instanceof PolicySubject) {
+ if (!((PolicySubject)componentType).getRequiredIntents().isEmpty()) {
+ writeImplementation = true;
+ }
+ }
+ if (componentType instanceof PolicySubject) {
+ if (!((PolicySubject)componentType).getPolicySets().isEmpty()) {
+ writeImplementation = true;
+ }
+ }
+ if (writeImplementation) {
+ writeStart(writer, IMPLEMENTATION,
+ policyProcessor.writePolicies(componentType));
+ }
+
+ writeEndDocument(writer);
+ }
+
+ public void resolve(ComponentType componentType, ModelResolver resolver) throws ContributionResolveException {
+
+ // Resolve component type services and references
+ resolveContracts(componentType.getServices(), resolver);
+ resolveContracts(componentType.getReferences(), resolver);
+ }
+
+ public QName getArtifactType() {
+ return COMPONENT_TYPE_QNAME;
+ }
+
+ public Class<ComponentType> getModelType() {
+ return ComponentType.class;
+ }
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java
new file mode 100644
index 0000000000..b6182e3950
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeDocumentProcessor.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Collection;
+import java.util.List;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.util.PolicyComputationUtils;
+
+/**
+ * A composite processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeDocumentProcessor extends BaseAssemblyProcessor implements URLArtifactProcessor<Composite> {
+ private XMLInputFactory inputFactory;
+ private DocumentBuilderFactory documentBuilderFactory;
+ private List scaDefnSink;
+ private Collection<PolicySet> domainPolicySets = null;
+ private int scaDefnsCount = 0;
+
+ /**
+ * Constructs a new composite processor.
+ * @param modelFactories
+ * @param staxProcessor
+ */
+ public CompositeDocumentProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ super(modelFactories, staxProcessor, monitor);
+ this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class);
+ this.documentBuilderFactory = modelFactories.getFactory(DocumentBuilderFactory.class);
+ }
+
+ public Composite read(URL contributionURL, URI uri, URL url) throws ContributionReadException {
+ InputStream scdlStream = null;
+ try {
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ scdlStream = connection.getInputStream();
+ } catch (IOException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", url, ce);
+ throw ce;
+ }
+ return read(uri, scdlStream);
+ }
+
+ public Composite read(URI uri, InputStream scdlStream) throws ContributionReadException {
+ try {
+/*
+ if (scaDefnSink != null ) {
+ fillDomainPolicySets(scaDefnSink);
+ }
+*/
+
+ Composite composite = null;
+
+ byte[] transformedArtifactContent;
+ try {
+ if ( domainPolicySets != null ) {
+ transformedArtifactContent =
+ PolicyComputationUtils.addApplicablePolicySets(scdlStream, domainPolicySets, documentBuilderFactory);
+ scdlStream = new ByteArrayInputStream(transformedArtifactContent);
+ }
+ } catch ( IOException e ) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", scdlStream, ce);
+ throw ce;
+ } catch ( Exception e ) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", scdlStream, ce);
+ //throw ce;
+ }
+
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(scdlStream);
+
+ reader.nextTag();
+
+ // Read the composite model
+ composite = (Composite)extensionProcessor.read(reader);
+ if (composite != null) {
+ composite.setURI(uri.toString());
+ }
+
+ // For debugging purposes, write it back to XML
+// if (composite != null) {
+// try {
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+// outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+// extensionProcessor.write(composite, outputFactory.createXMLStreamWriter(bos));
+// Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray()));
+// OutputFormat format = new OutputFormat();
+// format.setIndenting(true);
+// format.setIndent(2);
+// XMLSerializer serializer = new XMLSerializer(System.out, format);
+// serializer.serialize(document);
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+
+ return composite;
+
+ } catch (XMLStreamException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", inputFactory, ce);
+ throw ce;
+ } finally {
+ try {
+ if (scdlStream != null) {
+ scdlStream.close();
+ scdlStream = null;
+ }
+ } catch (IOException ioe) {
+ //ignore
+ }
+ }
+ }
+
+ public void resolve(Composite composite, ModelResolver resolver) throws ContributionResolveException {
+ if (composite != null)
+ extensionProcessor.resolve(composite, resolver);
+ }
+
+ public String getArtifactType() {
+ return ".composite";
+ }
+
+ public Class<Composite> getModelType() {
+ return Composite.class;
+ }
+
+ /*
+ * TODO - remove - definitions information is now aggregated in the
+ * systems definitions contribution and we need to add
+ * applicable policy sets once all composites have been read
+ private void fillDomainPolicySets(List scaDefnsSink) {
+ Map<QName, PolicySet> domainPolicySetMap = null;
+ if ( scaDefnsSink.size() > scaDefnsCount ) {
+ //if ( !scaDefnsSink.isEmpty() ) {
+ domainPolicySetMap = new Hashtable<QName, PolicySet>();
+
+ if ( domainPolicySets != null ) {
+ for ( PolicySet policySet : domainPolicySets ) {
+ domainPolicySetMap.put(policySet.getName(), policySet);
+ }
+ }
+
+ for ( Object object : scaDefnsSink ) {
+ if ( object instanceof Definitions ) {
+ for ( PolicySet policySet : ((Definitions)object).getPolicySets() ) {
+ domainPolicySetMap.put( policySet.getName(), policySet);
+ }
+ }
+ }
+ domainPolicySets = domainPolicySetMap.values();
+ //scaDefnsSink.clear();
+ scaDefnsCount = scaDefnsSink.size();
+ }
+ }
+ */
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java
new file mode 100644
index 0000000000..62ed95cb01
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeModelResolver.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceImport;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * A Model Resolver for Composite models.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeModelResolver implements ModelResolver {
+
+ private Contribution contribution;
+ private Map<QName, Composite> map = new HashMap<QName, Composite>();
+
+ public CompositeModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ this.contribution = contribution;
+ }
+
+ public void addModel(Object resolved) {
+ Composite composite = (Composite)resolved;
+ map.put(composite.getName(), composite);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(((Composite)resolved).getName());
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ // Lookup a definition for the given namespace
+ QName qname = ((Composite)unresolved).getName();
+ Composite resolved = (Composite) map.get(qname);
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+
+ // No definition found, delegate the resolution to the imports
+ for (Import import_ : this.contribution.getImports()) {
+ if (import_ instanceof NamespaceImport) {
+ NamespaceImport namespaceImport = (NamespaceImport)import_;
+ if (namespaceImport.getNamespace().equals(qname.getNamespaceURI())) {
+
+ // Delegate the resolution to the import resolver
+ resolved = namespaceImport.getModelResolver().resolveModel(Composite.class, (Composite)unresolved);
+ if (!resolved.isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ }
+ }
+ return (T)unresolved;
+ }
+
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java
new file mode 100644
index 0000000000..7a2eba494f
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java
@@ -0,0 +1,1047 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.AUTOWIRE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CALLBACK_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPONENT_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPOSITE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.COMPOSITE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.FILE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION_COMPOSITE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.IMPLEMENTATION_COMPOSITE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.INCLUDE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.INCLUDE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.LOCAL;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MANY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.NAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.NONOVERRIDABLE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROMOTE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REPLACE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SCA11_NS;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SOURCE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET_NAMESPACE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.URI;
+import static org.apache.tuscany.sca.assembly.xml.Constants.WIRE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.WIRED_BY_IMPL;
+import static org.apache.tuscany.sca.assembly.xml.Constants.WIRE_QNAME;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamConstants;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.tuscany.sca.assembly.Binding;
+import org.apache.tuscany.sca.assembly.Callback;
+import org.apache.tuscany.sca.assembly.Component;
+import org.apache.tuscany.sca.assembly.ComponentProperty;
+import org.apache.tuscany.sca.assembly.ComponentReference;
+import org.apache.tuscany.sca.assembly.ComponentService;
+import org.apache.tuscany.sca.assembly.Composite;
+import org.apache.tuscany.sca.assembly.CompositeReference;
+import org.apache.tuscany.sca.assembly.CompositeService;
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.assembly.Contract;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.assembly.Property;
+import org.apache.tuscany.sca.assembly.Reference;
+import org.apache.tuscany.sca.assembly.Service;
+import org.apache.tuscany.sca.assembly.Wire;
+import org.apache.tuscany.sca.contribution.Artifact;
+import org.apache.tuscany.sca.contribution.ContributionFactory;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.StAXAttributeProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.contribution.resolver.ResolverExtension;
+import org.apache.tuscany.sca.core.ExtensionPointRegistry;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.UtilityExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.monitor.MonitorFactory;
+import org.apache.tuscany.sca.policy.ExtensionType;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySubject;
+import org.w3c.dom.Document;
+
+/**
+ * A composite processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<Composite> {
+ private XPathFactory xPathFactory;
+ private PolicyFactory intentAttachPointTypeFactory;
+ private StAXAttributeProcessor<Object> extensionAttributeProcessor;
+ private ContributionFactory contributionFactory;
+
+
+ /**
+ * Construct a new composite processor
+ *
+ * @param extensionPoints
+ * @param extensionProcessor
+ */
+ public CompositeProcessor(ExtensionPointRegistry extensionPoints,
+ StAXArtifactProcessor extensionProcessor,
+ StAXAttributeProcessor extensionAttributeProcessor,
+ Monitor monitor) {
+
+ this(modelFactories(extensionPoints),
+ extensionProcessor,
+ extensionAttributeProcessor,
+ monitor(extensionPoints));
+
+ this.extensionAttributeProcessor = extensionAttributeProcessor;
+ }
+
+ /**
+ * Constructs a new composite processor
+ *
+ * @param modelFactories
+ * @param extensionProcessor
+ * @param monitor
+ */
+ private CompositeProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor extensionProcessor,
+ StAXAttributeProcessor extensionAttributeProcessor,
+ Monitor monitor) {
+
+ super(modelFactories, extensionProcessor, monitor);
+ this.intentAttachPointTypeFactory = modelFactories.getFactory(PolicyFactory.class);
+ this.xPathFactory = modelFactories.getFactory(XPathFactory.class);
+ this.contributionFactory = modelFactories.getFactory(ContributionFactory.class);
+ this.extensionAttributeProcessor = extensionAttributeProcessor;
+
+ }
+
+ public Composite read(XMLStreamReader reader) throws ContributionReadException {
+ Composite composite = null;
+ Composite include = null;
+ Component component = null;
+ Property property = null;
+ ComponentService componentService = null;
+ ComponentReference componentReference = null;
+ ComponentProperty componentProperty = null;
+ CompositeService compositeService = null;
+ CompositeReference compositeReference = null;
+ Contract contract = null;
+ Wire wire = null;
+ Callback callback = null;
+ QName name = null;
+
+ try {
+ // Read the composite document
+ while (reader.hasNext()) {
+ int event = reader.getEventType();
+ switch (event) {
+ case START_ELEMENT:
+ name = reader.getName();
+
+ if (COMPOSITE_QNAME.equals(name)) {
+
+ // Read a <composite>
+ composite = assemblyFactory.createComposite();
+ composite.setSpecVersion(Constants.SCA11_NS);
+
+ composite.setName(new QName(getString(reader, TARGET_NAMESPACE), getString(reader, NAME)));
+
+ if(!isSet(reader, TARGET_NAMESPACE)){
+ // spec says that a composite must have a namespace
+ warning("NoCompositeNamespace", composite, composite.getName().toString());
+ }
+
+ if(isSet(reader, AUTOWIRE)) {
+ composite.setAutowire(getBoolean(reader, AUTOWIRE));
+ }
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, composite, extensionAttributeProcessor);
+
+ composite.setLocal(getBoolean(reader, LOCAL));
+ composite.setConstrainingType(readConstrainingType(reader));
+ policyProcessor.readPolicies(composite, reader);
+
+ } else if (INCLUDE_QNAME.equals(name)) {
+
+ // Read an <include>
+ include = assemblyFactory.createComposite();
+ include.setName(getQName(reader, NAME));
+ include.setURI(getString(reader, URI));
+ include.setUnresolved(true);
+ composite.getIncludes().add(include);
+
+ } else if (SERVICE_QNAME.equals(name)) {
+ if (component != null) {
+
+ // Read a <component><service>
+ componentService = assemblyFactory.createComponentService();
+ contract = componentService;
+ componentService.setName(getString(reader, NAME));
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, componentService, extensionAttributeProcessor);
+
+ component.getServices().add(componentService);
+ policyProcessor.readPolicies(contract, reader);
+ } else {
+
+ // Read a <composite><service>
+ compositeService = assemblyFactory.createCompositeService();
+ contract = compositeService;
+ compositeService.setName(getString(reader, NAME));
+
+ String promoted = getString(reader, PROMOTE);
+ if (promoted != null) {
+ String promotedComponentName;
+ String promotedServiceName;
+ int s = promoted.indexOf('/');
+ if (s == -1) {
+ promotedComponentName = promoted;
+ promotedServiceName = null;
+ } else {
+ promotedComponentName = promoted.substring(0, s);
+ promotedServiceName = promoted.substring(s + 1);
+ }
+
+ Component promotedComponent = assemblyFactory.createComponent();
+ promotedComponent.setUnresolved(true);
+ promotedComponent.setName(promotedComponentName);
+ compositeService.setPromotedComponent(promotedComponent);
+
+ ComponentService promotedService = assemblyFactory.createComponentService();
+ promotedService.setUnresolved(true);
+ promotedService.setName(promotedServiceName);
+ compositeService.setPromotedService(promotedService);
+ }
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, compositeService, extensionAttributeProcessor);
+
+ composite.getServices().add(compositeService);
+ policyProcessor.readPolicies(contract, reader);
+ }
+
+ } else if (REFERENCE_QNAME.equals(name)) {
+ if (component != null) {
+ // Read a <component><reference>
+ componentReference = assemblyFactory.createComponentReference();
+ contract = componentReference;
+ componentReference.setName(getString(reader, NAME));
+ readMultiplicity(componentReference, reader);
+ if (isSet(reader, AUTOWIRE)) {
+ componentReference.setAutowire(getBoolean(reader, AUTOWIRE));
+ }
+ // Read @nonOverridable
+ String nonOverridable = reader.getAttributeValue(null, NONOVERRIDABLE);
+ if (nonOverridable != null) {
+ componentReference.setNonOverridable(Boolean.parseBoolean(nonOverridable));
+ }
+ readTargets(componentReference, reader);
+ componentReference.setWiredByImpl(getBoolean(reader, WIRED_BY_IMPL));
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, componentReference, extensionAttributeProcessor);
+
+ component.getReferences().add(componentReference);
+ policyProcessor.readPolicies(contract, reader);
+ } else {
+ // Read a <composite><reference>
+ compositeReference = assemblyFactory.createCompositeReference();
+ contract = compositeReference;
+ compositeReference.setName(getString(reader, NAME));
+ readMultiplicity(compositeReference, reader);
+ readTargets(compositeReference, reader);
+ String promote = reader.getAttributeValue(null, Constants.PROMOTE);
+ if (promote != null) {
+ for (StringTokenizer tokens = new StringTokenizer(promote); tokens.hasMoreTokens();) {
+ String refName = tokens.nextToken();
+ Component promotedComponent = assemblyFactory.createComponent();
+ int index = refName.indexOf('/');
+ if (index == -1) {
+ error("Invalid reference name", compositeReference, refName);
+ }
+ String promotedComponentName = refName.substring(0, index);
+ promotedComponent.setName(promotedComponentName);
+ promotedComponent.setUnresolved(true);
+ compositeReference.getPromotedComponents().add(promotedComponent);
+ ComponentReference promotedReference =
+ assemblyFactory.createComponentReference();
+ promotedReference.setUnresolved(true);
+ promotedReference.setName(refName);
+ compositeReference.getPromotedReferences().add(promotedReference);
+ }
+ }
+ compositeReference.setWiredByImpl(getBoolean(reader, WIRED_BY_IMPL));
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, compositeReference, extensionAttributeProcessor);
+
+ composite.getReferences().add(compositeReference);
+ policyProcessor.readPolicies(contract, reader);
+ }
+
+ } else if (PROPERTY_QNAME.equals(name)) {
+ if (component != null) {
+
+ // Read a <component><property>
+ componentProperty = assemblyFactory.createComponentProperty();
+ property = componentProperty;
+ String source = getString(reader, SOURCE);
+ if(source!=null) {
+ source = source.trim();
+ }
+ componentProperty.setSource(source);
+ if (source != null) {
+ // $<name>/...
+ if (source.charAt(0) == '$') {
+ int index = source.indexOf('/');
+ if (index == -1) {
+ // Tolerating $prop
+ source = source + "/";
+ index = source.length() - 1;
+ }
+ source = source.substring(index + 1);
+ if ("".equals(source)) {
+ source = ".";
+ }
+ }
+ XPath xpath = xPathFactory.newXPath();
+ xpath.setNamespaceContext(reader.getNamespaceContext());
+ try {
+ componentProperty.setSourceXPathExpression(xpath.compile(source));
+ } catch (XPathExpressionException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", xpath, ce);
+ //throw ce;
+ }
+ }
+ componentProperty.setFile(getString(reader, FILE));
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, componentProperty, extensionAttributeProcessor);
+
+ policyProcessor.readPolicies(property, reader);
+ readAbstractProperty(componentProperty, reader);
+
+ // Read the property value
+ Document value = readPropertyValue(property.getXSDElement(), property.getXSDType(), reader);
+ property.setValue(value);
+
+ component.getProperties().add(componentProperty);
+ } else {
+
+ // Read a <composite><property>
+ property = assemblyFactory.createProperty();
+ policyProcessor.readPolicies(property, reader);
+ readAbstractProperty(property, reader);
+
+ // Read the property value
+ Document value = readPropertyValue(property.getXSDElement(), property.getXSDType(), reader);
+ property.setValue(value);
+
+ composite.getProperties().add(property);
+ }
+
+ // TUSCANY-1949
+ // If the property doesn't have a value, the END_ELEMENT event is read by the readPropertyValue
+ if (reader.getEventType() == END_ELEMENT && PROPERTY_QNAME.equals(reader.getName())) {
+ property = null;
+ componentProperty = null;
+ }
+
+ } else if (COMPONENT_QNAME.equals(name)) {
+
+ // Read a <component>
+ component = assemblyFactory.createComponent();
+ component.setName(getString(reader, NAME));
+ if (isSet(reader, AUTOWIRE)) {
+ component.setAutowire(getBoolean(reader, AUTOWIRE));
+ }
+ if (isSet(reader, URI)) {
+ component.setURI(getString(reader, URI));
+ }
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, component, extensionAttributeProcessor);
+
+ component.setConstrainingType(readConstrainingType(reader));
+ composite.getComponents().add(component);
+ policyProcessor.readPolicies(component, reader);
+
+ } else if (WIRE_QNAME.equals(name)) {
+
+ // Read a <wire>
+ wire = assemblyFactory.createWire();
+ ComponentReference source = assemblyFactory.createComponentReference();
+ source.setUnresolved(true);
+ source.setName(getString(reader, SOURCE));
+ wire.setSource(source);
+
+ ComponentService target = assemblyFactory.createComponentService();
+ target.setUnresolved(true);
+ target.setName(getString(reader, TARGET));
+ wire.setTarget(target);
+
+ // Read @replace
+ String replace = reader.getAttributeValue(null, REPLACE);
+ if (replace != null) {
+ wire.setReplace(Boolean.parseBoolean(replace));
+ }
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, wire, extensionAttributeProcessor);
+
+ composite.getWires().add(wire);
+ policyProcessor.readPolicies(wire, reader);
+
+ } else if (CALLBACK_QNAME.equals(name)) {
+
+ // Read a <callback>
+ callback = assemblyFactory.createCallback();
+ contract.setCallback(callback);
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, callback, extensionAttributeProcessor);
+
+ policyProcessor.readPolicies(callback, reader);
+
+ } else if (IMPLEMENTATION_COMPOSITE_QNAME.equals(name)) {
+
+ // Read an implementation.composite
+ Composite implementation = assemblyFactory.createComposite();
+ implementation.setName(getQName(reader, NAME));
+ implementation.setUnresolved(true);
+
+ //handle extension attributes
+ this.readExtendedAttributes(reader, name, implementation, extensionAttributeProcessor);
+
+ component.setImplementation(implementation);
+ policyProcessor.readPolicies(implementation, reader);
+ } else {
+
+ // Read an extension element
+ Object extension = extensionProcessor.read(reader);
+ if (extension != null) {
+ if (extension instanceof InterfaceContract) {
+
+ // <service><interface> and
+ // <reference><interface>
+ if (contract != null) {
+ contract.setInterfaceContract((InterfaceContract)extension);
+ } else {
+ if (name.getNamespaceURI().equals(SCA11_NS)) {
+ error("UnexpectedInterfaceElement", extension);
+ //throw new ContributionReadException("Unexpected <interface> element found. It should appear inside a <service> or <reference> element");
+ } else {
+ composite.getExtensions().add(extension);
+ }
+ }
+ } else if (extension instanceof Binding) {
+ if ( extension instanceof PolicySubject ) {
+ ExtensionType bindingType = intentAttachPointTypeFactory.createBindingType();
+ bindingType.setType(name);
+ bindingType.setUnresolved(true);
+ ((PolicySubject)extension).setType(bindingType);
+ }
+ // <service><binding> and
+ // <reference><binding>
+ if (callback != null) {
+ callback.getBindings().add((Binding)extension);
+ } else {
+ if (contract != null) {
+ contract.getBindings().add((Binding)extension);
+ } else {
+ if (name.getNamespaceURI().equals(SCA11_NS)) {
+ error("UnexpectedBindingElement", extension);
+ //throw new ContributionReadException("Unexpected <binding> element found. It should appear inside a <service> or <reference> element");
+ } else {
+ composite.getExtensions().add(extension);
+ }
+ }
+ }
+
+ } else if (extension instanceof Implementation) {
+ if ( extension instanceof PolicySubject ) {
+ ExtensionType implType = intentAttachPointTypeFactory.createImplementationType();
+ implType.setType(name);
+ implType.setUnresolved(true);
+ ((PolicySubject)extension).setType(implType);
+ }
+ // <component><implementation>
+ if (component != null) {
+ component.setImplementation((Implementation)extension);
+ } else {
+ if (name.getNamespaceURI().equals(SCA11_NS)) {
+ error("UnexpectedImplementationElement", extension);
+ //throw new ContributionReadException("Unexpected <implementation> element found. It should appear inside a <component> element");
+ } else {
+ composite.getExtensions().add(extension);
+ }
+ }
+ } else {
+
+ // Add the extension element to the current
+ // element
+ if (callback != null) {
+ callback.getExtensions().add(extension);
+ } else if (contract != null) {
+ contract.getExtensions().add(extension);
+ } else if (property != null) {
+ property.getExtensions().add(extension);
+ } else if (component != null) {
+ component.getExtensions().add(extension);
+ } else {
+ composite.getExtensions().add(extension);
+ }
+ }
+ }
+ }
+ break;
+
+ case XMLStreamConstants.CHARACTERS:
+ break;
+
+ case END_ELEMENT:
+ name = reader.getName();
+
+ // Clear current state when reading reaching end element
+ if (SERVICE_QNAME.equals(name)) {
+ componentService = null;
+ compositeService = null;
+ contract = null;
+ } else if (INCLUDE_QNAME.equals(name)) {
+ include = null;
+ } else if (REFERENCE_QNAME.equals(name)) {
+ componentReference = null;
+ compositeReference = null;
+ contract = null;
+ } else if (PROPERTY_QNAME.equals(name)) {
+ componentProperty = null;
+ property = null;
+ } else if (COMPONENT_QNAME.equals(name)) {
+ component = null;
+ } else if (WIRE_QNAME.equals(name)) {
+ wire = null;
+ } else if (CALLBACK_QNAME.equals(name)) {
+ callback = null;
+ }
+ break;
+ }
+
+ // Read the next element
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+ }
+ catch (XMLStreamException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("XMLStreamException", reader, ex);
+ }
+
+ return composite;
+ }
+
+ public void write(Composite composite, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+
+ // Write <composite> element
+ writeStartDocument(writer,
+ COMPOSITE,
+ writeConstrainingType(composite),
+ new XAttr(TARGET_NAMESPACE, composite.getName().getNamespaceURI()),
+ new XAttr(NAME, composite.getName().getLocalPart()),
+ new XAttr(LOCAL, composite.isLocal() ? Boolean.TRUE : null),
+ new XAttr(AUTOWIRE, composite.getAutowire()),
+ policyProcessor.writePolicies(composite));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, composite, extensionAttributeProcessor);
+
+ // Write <include> elements
+ for (Composite include : composite.getIncludes()) {
+ String uri = include.isUnresolved()? include.getURI() : null;
+ writeStart(writer,
+ INCLUDE,
+ new XAttr(NAME, include.getName()),
+ new XAttr(URI, uri));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, include, extensionAttributeProcessor);
+
+ writeEnd(writer);
+ }
+
+ // Write <service> elements
+ for (Service service : composite.getServices()) {
+ CompositeService compositeService = (CompositeService)service;
+ Component promotedComponent = compositeService.getPromotedComponent();
+ ComponentService promotedService = compositeService.getPromotedService();
+ String promote;
+ if (promotedService != null) {
+ if (promotedService.getName() != null) {
+ promote = promotedComponent.getName() + '/' + promotedService.getName();
+ } else {
+ promote = promotedComponent.getName();
+ }
+ } else {
+ promote = null;
+ }
+ writeStart(writer, SERVICE, new XAttr(NAME, service.getName()), new XAttr(PROMOTE, promote),
+ policyProcessor.writePolicies(service));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, service, extensionAttributeProcessor);
+
+
+ // Write service interface
+ extensionProcessor.write(service.getInterfaceContract(), writer);
+
+ // Write bindings
+ for (Binding binding : service.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write <callback> element
+ if (service.getCallback() != null) {
+ Callback callback = service.getCallback();
+ writeStart(writer, CALLBACK,
+ policyProcessor.writePolicies(callback));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor);
+
+ // Write callback bindings
+ for (Binding binding : callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write extensions
+ for (Object extension : callback.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extensions
+ for (Object extension : service.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <component> elements
+ for (Component component : composite.getComponents()) {
+ writeStart(writer, COMPONENT, new XAttr(NAME, component.getName()),
+ new XAttr(URI, component.getURI()),
+ new XAttr(AUTOWIRE, component.getAutowire()),
+ policyProcessor.writePolicies(component));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, component, extensionAttributeProcessor);
+
+ // Write the component implementation
+ Implementation implementation = component.getImplementation();
+ if (implementation instanceof Composite) {
+ writeStart(writer, IMPLEMENTATION_COMPOSITE, new XAttr(NAME, ((Composite)implementation).getName()));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, (Composite)implementation, extensionAttributeProcessor);
+
+ writeEnd(writer);
+ } else {
+ extensionProcessor.write(component.getImplementation(), writer);
+ }
+
+ for (Object extension : component.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ // Write <service> elements
+ for (ComponentService service : component.getServices()) {
+ writeStart(writer, SERVICE, new XAttr(NAME, service.getName()),
+ policyProcessor.writePolicies(service));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, service, extensionAttributeProcessor);
+
+ // Write service interface
+ extensionProcessor.write(service.getInterfaceContract(), writer);
+
+ // Write bindings
+ for (Binding binding : service.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write <callback> element
+ if (service.getCallback() != null) {
+ Callback callback = service.getCallback();
+ writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor);
+
+ // Write bindings
+ for (Binding binding : callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write extensions
+ for (Object extension : callback.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extensions
+ for (Object extension : service.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <reference> elements
+ for (ComponentReference reference : component.getReferences()) {
+ writeStart(writer,
+ REFERENCE,
+ new XAttr(NAME, reference.getName()),
+ new XAttr(AUTOWIRE, reference.getAutowire()),
+ (reference.isNonOverridable() ? new XAttr(NONOVERRIDABLE, true) : null),
+ writeMultiplicity(reference),
+ writeTargets(reference),
+ policyProcessor.writePolicies(reference));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, reference, extensionAttributeProcessor);
+
+ // Write reference interface
+ extensionProcessor.write(reference.getInterfaceContract(), writer);
+
+ // Write bindings
+ for (Binding binding : reference.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write callback
+ if (reference.getCallback() != null) {
+ Callback callback = reference.getCallback();
+ writeStart(writer, CALLBACK, policyProcessor.writePolicies(callback));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor);
+
+ // Write callback bindings
+ for (Binding binding : callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write extensions
+ for (Object extensions : callback.getExtensions()) {
+ extensionProcessor.write(extensions, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extensions
+ for (Object extensions : reference.getExtensions()) {
+ extensionProcessor.write(extensions, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <property> elements
+ for (ComponentProperty property : component.getProperties()) {
+ writeStart(writer,
+ PROPERTY,
+ new XAttr(NAME, property.getName()),
+ new XAttr(MUST_SUPPLY, property.isMustSupply()),
+ new XAttr(MANY, property.isMany()),
+ new XAttr(TYPE, property.getXSDType()),
+ new XAttr(ELEMENT, property.getXSDElement()),
+ new XAttr(SOURCE, property.getSource()),
+ new XAttr(FILE, property.getFile()),
+ policyProcessor.writePolicies(property));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, property, extensionAttributeProcessor);
+
+ // Write property value
+ writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer);
+
+ // Write extensions
+ for (Object extension : property.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <reference> elements
+ for (Reference reference : composite.getReferences()) {
+ CompositeReference compositeReference = (CompositeReference)reference;
+
+ // Write list of promoted references
+ List<String> promote = new ArrayList<String>();
+ for (ComponentReference promoted: compositeReference.getPromotedReferences()) {
+ promote.add(promoted.getName());
+ }
+
+ // Write <reference> element
+ writeStart(writer, REFERENCE, new XAttr(NAME, reference.getName()),
+ new XAttr(PROMOTE, promote),
+ writeMultiplicity(reference),
+ policyProcessor.writePolicies(reference));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, reference, extensionAttributeProcessor);
+
+ // Write reference interface
+ extensionProcessor.write(reference.getInterfaceContract(), writer);
+
+ // Write bindings
+ for (Binding binding : reference.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write <callback> element
+ if (reference.getCallback() != null) {
+ Callback callback = reference.getCallback();
+ writeStart(writer, CALLBACK);
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, callback, extensionAttributeProcessor);
+
+ // Write callback bindings
+ for (Binding binding : callback.getBindings()) {
+ extensionProcessor.write(binding, writer);
+ }
+
+ // Write extensions
+ for (Object extension : callback.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extensions
+ for (Object extension : reference.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <property> elements
+ for (Property property : composite.getProperties()) {
+ writeStart(writer,
+ PROPERTY,
+ new XAttr(NAME, property.getName()),
+ new XAttr(MUST_SUPPLY, property.isMustSupply()),
+ new XAttr(MANY, property.isMany()),
+ new XAttr(TYPE, property.getXSDType()),
+ new XAttr(ELEMENT, property.getXSDElement()),
+ policyProcessor.writePolicies(property));
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, property, extensionAttributeProcessor);
+
+ // Write property value
+ writePropertyValue(property.getValue(), property.getXSDElement(), property.getXSDType(), writer);
+
+ // Write extensions
+ for (Object extension : property.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <wire> elements
+ for (Wire wire : composite.getWires()) {
+ writeStart(writer, WIRE, new XAttr(SOURCE, wire.getSource().getName()), new XAttr(TARGET, wire.getTarget()
+ .getName()), wire.isReplace() ? new XAttr(Constants.REPLACE, true) : null);
+
+ //write extended attributes
+ this.writeExtendedAttributes(writer, wire, extensionAttributeProcessor);
+
+ // Write extensions
+ for (Object extension : wire.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+ writeEnd(writer);
+ }
+
+ for (Object extension : composite.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEndDocument(writer);
+ }
+
+ public void resolve(Composite composite, ModelResolver resolver) throws ContributionResolveException {
+
+ // Resolve constraining type
+ ConstrainingType constrainingType = composite.getConstrainingType();
+ if (constrainingType != null) {
+ constrainingType = resolver.resolveModel(ConstrainingType.class, constrainingType);
+ composite.setConstrainingType(constrainingType);
+ }
+
+ // Resolve includes in the composite
+ for (int i = 0, n = composite.getIncludes().size(); i < n; i++) {
+ Composite include = composite.getIncludes().get(i);
+ if (include != null) {
+ include = resolver.resolveModel(Composite.class, include);
+ composite.getIncludes().set(i, include);
+ }
+ }
+
+ // Resolve extensions
+ for (Object extension : composite.getExtensions()) {
+ if (extension != null) {
+ extensionProcessor.resolve(extension, resolver);
+ }
+ }
+
+ //Resolve composite services and references
+ resolveContracts(composite, composite.getServices(), resolver);
+ resolveContracts(composite, composite.getReferences(), resolver);
+
+ // Resolve component implementations, services and references
+ for (Component component : composite.getComponents()) {
+ constrainingType = component.getConstrainingType();
+ if (constrainingType != null) {
+ constrainingType = resolver.resolveModel(ConstrainingType.class, constrainingType);
+ component.setConstrainingType(constrainingType);
+ }
+
+ //resolve component services and references
+ resolveContracts(component, component.getServices(), resolver);
+ resolveContracts(component, component.getReferences(), resolver);
+
+ for (ComponentProperty componentProperty : component.getProperties()) {
+ if (componentProperty.getFile() != null) {
+ Artifact artifact = contributionFactory.createArtifact();
+ artifact.setURI(componentProperty.getFile());
+ artifact = resolver.resolveModel(Artifact.class, artifact);
+ if (artifact.getLocation() != null) {
+ componentProperty.setFile(artifact.getLocation());
+ }
+ }
+ }
+
+ //resolve component implementation
+ Implementation implementation = component.getImplementation();
+ if (implementation != null) {
+ //now resolve the implementation so that even if there is a shared instance
+ //for this that is resolved, the specified intents and policysets are safe in the
+ //component and not lost
+ implementation = resolveImplementation(implementation, resolver);
+
+ component.setImplementation(implementation);
+ }
+
+ //add model resolver to component
+ if (component instanceof ResolverExtension) {
+ ((ResolverExtension)component).setModelResolver(resolver);
+ }
+ }
+
+ // Add model resolver to promoted components
+ for (Service service : composite.getServices()) {
+ CompositeService compositeService = (CompositeService)service;
+ Component promotedComponent = compositeService.getPromotedComponent();
+ if (promotedComponent instanceof ResolverExtension) {
+ ((ResolverExtension)promotedComponent).setModelResolver(resolver);
+ }
+ }
+ }
+
+ public QName getArtifactType() {
+ return COMPOSITE_QNAME;
+ }
+
+ public Class<Composite> getModelType() {
+ return Composite.class;
+ }
+
+ /**
+ * Returns the model factory extension point to use.
+ *
+ * @param extensionPoints
+ * @return
+ */
+ private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) {
+ return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class);
+ }
+
+ /**
+ * Returns the monitor to use.
+ *
+ * @param extensionPoints
+ * @return
+ */
+ private static Monitor monitor(ExtensionPointRegistry extensionPoints) {
+ UtilityExtensionPoint utilities = extensionPoints.getExtensionPoint(UtilityExtensionPoint.class);
+ if (utilities != null) {
+ MonitorFactory monitorFactory = utilities.getUtility(MonitorFactory.class);
+ if (monitorFactory != null) {
+ return monitorFactory.createMonitor();
+ }
+ }
+ return null;
+ }
+
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java
new file mode 100644
index 0000000000..ce8b461a27
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/Constants.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import javax.xml.namespace.QName;
+
+/**
+ * Constants used in SCA assembly XML files.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface Constants {
+ String SCA11_NS = "http://docs.oasis-open.org/ns/opencsa/sca/200903";
+ String SCA11_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1";
+
+ String COMPONENT_TYPE = "componentType";
+ QName COMPONENT_TYPE_QNAME = new QName(SCA11_NS, COMPONENT_TYPE);
+
+ String SERVICE = "service";
+ QName SERVICE_QNAME = new QName(SCA11_NS, SERVICE);
+
+ String REFERENCE = "reference";
+ QName REFERENCE_QNAME = new QName(SCA11_NS, REFERENCE);
+
+ String PROPERTY = "property";
+ QName PROPERTY_QNAME = new QName(SCA11_NS, PROPERTY);
+
+ String CONSTRAINING_TYPE = "constrainingType";
+ QName CONSTRAINING_TYPE_QNAME = new QName(SCA11_NS, CONSTRAINING_TYPE);
+
+ String COMPOSITE = "composite";
+ QName COMPOSITE_QNAME = new QName(SCA11_NS, COMPOSITE);
+
+ String INCLUDE = "include";
+ QName INCLUDE_QNAME = new QName(SCA11_NS, INCLUDE);
+
+ String COMPONENT = "component";
+ QName COMPONENT_QNAME = new QName(SCA11_NS, COMPONENT);
+
+ String WIRE = "wire";
+ QName WIRE_QNAME = new QName(SCA11_NS, WIRE);
+
+ String OPERATION = "operation";
+ QName OPERATION_QNAME = new QName(SCA11_NS, OPERATION);
+
+ String CALLBACK = "callback";
+ QName CALLBACK_QNAME = new QName(SCA11_NS, CALLBACK);
+
+ String IMPLEMENTATION_COMPOSITE = "implementation.composite";
+ QName IMPLEMENTATION_COMPOSITE_QNAME = new QName(SCA11_NS, IMPLEMENTATION_COMPOSITE);
+
+ String IMPLEMENTATION = "implementation";
+ QName IMPLEMENTATION_QNAME = new QName(SCA11_NS, IMPLEMENTATION);
+
+ String BINDING_SCA = "binding.sca";
+ QName BINDING_SCA_QNAME = new QName(Constants.SCA11_NS, BINDING_SCA);
+
+ String NAME = "name";
+ String VALUE = "value";
+ QName VALUE_QNAME = new QName(SCA11_NS, VALUE);
+ String TARGET_NAMESPACE = "targetNamespace";
+ String LOCAL = "local";
+ String AUTOWIRE = "autowire";
+ String NONOVERRIDABLE = "nonOverridable";
+ String REPLACE = "replace";
+ String REQUIRES = "requires";
+ String POLICY_SETS = "policySets";
+ String APPLICABLE_POLICY_SETS = "applicablePolicySets";
+ String PROMOTE = "promote";
+ String TARGET = "target";
+ String WIRED_BY_IMPL = "wiredByImpl";
+ String MULTIPLICITY = "multiplicity";
+ String TYPE = "type";
+ String ELEMENT = "element";
+ String MANY = "many";
+ String MUST_SUPPLY = "mustSupply";
+ String SOURCE = "source";
+ String FILE = "file";
+ String URI = "uri";
+ String ZERO_ONE = "0..1";
+ String ZERO_N = "0..n";
+ String ONE_ONE = "1..1";
+ String ONE_N = "1..n";
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeDocumentProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeDocumentProcessor.java
new file mode 100644
index 0000000000..401fa7123e
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeDocumentProcessor.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.assembly.xml;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.URLArtifactProcessor;
+import org.apache.tuscany.sca.contribution.processor.ValidatingXMLInputFactory;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+
+/**
+ * A contrainingType content handler.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConstrainingTypeDocumentProcessor extends BaseAssemblyProcessor implements URLArtifactProcessor<ConstrainingType> {
+ private XMLInputFactory inputFactory;
+
+ /**
+ * Constructs a new constrainingType processor.
+ * @param modelFactories
+ * @param staxProcessor
+ */
+ public ConstrainingTypeDocumentProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor staxProcessor,
+ Monitor monitor) {
+ super(modelFactories, staxProcessor, monitor);
+ this.inputFactory = modelFactories.getFactory(ValidatingXMLInputFactory.class);
+ }
+
+ public ConstrainingType read(URL contributionURL, URI uri, URL url) throws ContributionReadException {
+ InputStream urlStream = null;
+ try {
+
+ // Create a stream reader
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ urlStream = connection.getInputStream();
+ XMLStreamReader reader = inputFactory.createXMLStreamReader(url.toString(), urlStream);
+ reader.nextTag();
+
+ // Read the constrainingType model
+ ConstrainingType constrainingType = (ConstrainingType)extensionProcessor.read(reader);
+
+ // For debugging purposes, write it back to XML
+// if (constrainingType != null) {
+// try {
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
+// outputFactory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, Boolean.TRUE);
+// extensionProcessor.write(constrainingType, outputFactory.createXMLStreamWriter(bos));
+// Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteArrayInputStream(bos.toByteArray()));
+// OutputFormat format = new OutputFormat();
+// format.setIndenting(true);
+// format.setIndent(2);
+// XMLSerializer serializer = new XMLSerializer(System.out, format);
+// serializer.serialize(document);
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+// }
+
+ return constrainingType;
+
+ } catch (XMLStreamException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", inputFactory, ce);
+ throw ce;
+ } catch (IOException e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", inputFactory, ce);
+ throw ce;
+ } finally {
+ try {
+ if (urlStream != null) {
+ urlStream.close();
+ urlStream = null;
+ }
+ } catch (IOException ioe) {
+ //ignore
+ }
+ }
+ }
+
+ public void resolve(ConstrainingType constrainingType, ModelResolver resolver) throws ContributionResolveException {
+ extensionProcessor.resolve(constrainingType, resolver);
+ }
+
+ public String getArtifactType() {
+ return ".constrainingType";
+ }
+
+ public Class<ConstrainingType> getModelType() {
+ return ConstrainingType.class;
+ }
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeModelResolver.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeModelResolver.java
new file mode 100644
index 0000000000..d73ce5ab66
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeModelResolver.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.contribution.Contribution;
+import org.apache.tuscany.sca.contribution.Import;
+import org.apache.tuscany.sca.contribution.namespace.NamespaceImport;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+
+/**
+ * A Model Resolver for ConstrainingType models.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConstrainingTypeModelResolver implements ModelResolver {
+
+ private Contribution contribution;
+ private Map<QName, ConstrainingType> map = new HashMap<QName, ConstrainingType>();
+
+ public ConstrainingTypeModelResolver(Contribution contribution, FactoryExtensionPoint modelFactories) {
+ this.contribution = contribution;
+ }
+
+ public void addModel(Object resolved) {
+ ConstrainingType composite = (ConstrainingType)resolved;
+ map.put(composite.getName(), composite);
+ }
+
+ public Object removeModel(Object resolved) {
+ return map.remove(((ConstrainingType)resolved).getName());
+ }
+
+ public <T> T resolveModel(Class<T> modelClass, T unresolved) {
+
+ // Lookup a definition for the given namespace
+ QName qname = ((ConstrainingType)unresolved).getName();
+ ConstrainingType resolved = (ConstrainingType) map.get(qname);
+ if (resolved != null) {
+ return modelClass.cast(resolved);
+ }
+
+ // No definition found, delegate the resolution to the imports
+ for (Import import_ : this.contribution.getImports()) {
+ if (import_ instanceof NamespaceImport) {
+ NamespaceImport namespaceImport = (NamespaceImport)import_;
+ if (namespaceImport.getNamespace().equals(qname.getNamespaceURI())) {
+
+ // Delegate the resolution to the import resolver
+ resolved = namespaceImport.getModelResolver().resolveModel(ConstrainingType.class, (ConstrainingType)unresolved);
+ if (!resolved.isUnresolved()) {
+ return modelClass.cast(resolved);
+ }
+ }
+ }
+ }
+ return (T)unresolved;
+ }
+
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeProcessor.java
new file mode 100644
index 0000000000..34c4bc9909
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/ConstrainingTypeProcessor.java
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+import static javax.xml.stream.XMLStreamConstants.START_ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CONSTRAINING_TYPE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.CONSTRAINING_TYPE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.ELEMENT;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MANY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.MUST_SUPPLY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.NAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.OPERATION_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY;
+import static org.apache.tuscany.sca.assembly.xml.Constants.PROPERTY_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REFERENCE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.SERVICE_QNAME;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TARGET_NAMESPACE;
+import static org.apache.tuscany.sca.assembly.xml.Constants.TYPE;
+
+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.AbstractContract;
+import org.apache.tuscany.sca.assembly.AbstractProperty;
+import org.apache.tuscany.sca.assembly.AbstractReference;
+import org.apache.tuscany.sca.assembly.AbstractService;
+import org.apache.tuscany.sca.assembly.ConstrainingType;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.interfacedef.InterfaceContract;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.interfacedef.impl.OperationImpl;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.w3c.dom.Document;
+
+/**
+ * A constrainingType processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ConstrainingTypeProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor<ConstrainingType> {
+
+ /**
+ * Constructs a new constrainingType processor.
+ *
+ * @param modelFactories
+ * @param extensionProcessor
+ */
+ public ConstrainingTypeProcessor(FactoryExtensionPoint modelFactories,
+ StAXArtifactProcessor extensionProcessor,
+ Monitor monitor) {
+ super(modelFactories, extensionProcessor, monitor);
+ }
+
+ public ConstrainingType read(XMLStreamReader reader) throws ContributionReadException {
+ ConstrainingType constrainingType = null;
+ AbstractService abstractService = null;
+ AbstractReference abstractReference = null;
+ AbstractProperty abstractProperty = null;
+ AbstractContract abstractContract = null;
+ QName name = null;
+
+ try {
+ // Read the constrainingType document
+ while (reader.hasNext()) {
+ int event = reader.getEventType();
+ switch (event) {
+
+ case START_ELEMENT:
+ name = reader.getName();
+
+ // Read a <constrainingType>
+ if (Constants.CONSTRAINING_TYPE_QNAME.equals(name)) {
+ constrainingType = assemblyFactory.createConstrainingType();
+ constrainingType.setName(new QName(getString(reader, TARGET_NAMESPACE), getString(reader, NAME)));
+ policyProcessor.readPolicies(constrainingType, reader);
+
+ } else if (Constants.SERVICE_QNAME.equals(name)) {
+
+ // Read a <service>
+ abstractService = assemblyFactory.createAbstractService();
+ abstractContract = abstractService;
+ abstractService.setName(getString(reader, Constants.NAME));
+ constrainingType.getServices().add(abstractService);
+ policyProcessor.readPolicies(abstractService, reader);
+
+ } else if (Constants.REFERENCE_QNAME.equals(name)) {
+
+ // Read a <reference>
+ abstractReference = assemblyFactory.createAbstractReference();
+ abstractContract = abstractReference;
+ abstractReference.setName(getString(reader, Constants.NAME));
+ readMultiplicity(abstractReference, reader);
+ constrainingType.getReferences().add(abstractReference);
+ policyProcessor.readPolicies(abstractReference, reader);
+
+ } else if (Constants.PROPERTY_QNAME.equals(name)) {
+
+ // Read a <property>
+ abstractProperty = assemblyFactory.createAbstractProperty();
+ readAbstractProperty(abstractProperty, reader);
+
+ // Read the property value
+ Document value = readPropertyValue(abstractProperty.getXSDElement(), abstractProperty.getXSDType(), reader);
+ abstractProperty.setValue(value);
+
+ constrainingType.getProperties().add(abstractProperty);
+ policyProcessor.readPolicies(abstractProperty, reader);
+
+ } else if (OPERATION_QNAME.equals(name)) {
+
+ // Read an <operation>
+ Operation operation = new OperationImpl();
+ operation.setName(getString(reader, NAME));
+ operation.setUnresolved(true);
+ policyProcessor.readPolicies(abstractContract, operation, reader);
+
+ } else {
+
+ // Read an extension element
+ Object extension = extensionProcessor.read(reader);
+ if (extension instanceof InterfaceContract) {
+
+ // <service><interface> and <reference><interface>
+ abstractContract.setInterfaceContract((InterfaceContract)extension);
+ } else {
+
+ // Add the extension element to the current element
+ if (abstractContract != null) {
+ abstractContract.getExtensions().add(extension);
+ } else {
+ constrainingType.getExtensions().add(extension);
+ }
+
+ }
+ }
+ break;
+
+ case END_ELEMENT:
+ name = reader.getName();
+
+ // Clear current state when reading reaching end element
+ if (SERVICE_QNAME.equals(name)) {
+ abstractService = null;
+ abstractContract = null;
+ } else if (REFERENCE_QNAME.equals(name)) {
+ abstractReference = null;
+ abstractContract = null;
+ } else if (PROPERTY_QNAME.equals(name)) {
+ abstractProperty = null;
+ }
+ break;
+ }
+ if (reader.hasNext()) {
+ reader.next();
+ }
+ }
+ }
+ catch (XMLStreamException e) {
+ ContributionReadException ex = new ContributionReadException(e);
+ error("XMLStreamException", reader, ex);
+ }
+
+ return constrainingType;
+ }
+
+ public void write(ConstrainingType constrainingType, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+
+ // Write <constrainingType> element
+ writeStartDocument(writer, CONSTRAINING_TYPE,
+ new XAttr(TARGET_NAMESPACE, constrainingType.getName().getNamespaceURI()),
+ new XAttr(NAME, constrainingType.getName().getLocalPart()),
+ policyProcessor.writePolicies(constrainingType));
+
+ // Write <service> elements
+ for (AbstractService service : constrainingType.getServices()) {
+ writeStart(writer, SERVICE, new XAttr(NAME, service.getName()),
+ policyProcessor.writePolicies(service));
+
+ extensionProcessor.write(service.getInterfaceContract(), writer);
+
+ for (Object extension: service.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <reference> elements
+ for (AbstractReference reference : constrainingType.getReferences()) {
+ writeStart(writer, REFERENCE, new XAttr(NAME, reference.getName()),
+ writeMultiplicity(reference),
+ policyProcessor.writePolicies(reference));
+
+ extensionProcessor.write(reference.getInterfaceContract(), writer);
+
+ for (Object extension: reference.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write <property> elements
+ for (AbstractProperty abstractProperty : constrainingType.getProperties()) {
+ writeStart(writer,
+ PROPERTY,
+ new XAttr(NAME, abstractProperty.getName()),
+ new XAttr(MUST_SUPPLY, abstractProperty.isMustSupply()),
+ new XAttr(MANY, abstractProperty.isMany()),
+ new XAttr(TYPE, abstractProperty.getXSDType()),
+ new XAttr(ELEMENT, abstractProperty.getXSDElement()),
+ policyProcessor.writePolicies(abstractProperty));
+
+ // Write property value
+ writePropertyValue(abstractProperty.getValue(), abstractProperty.getXSDElement(), abstractProperty.getXSDType(), writer);
+
+ // Write extensions
+ for (Object extension : abstractProperty.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEnd(writer);
+ }
+
+ // Write extension elements
+ for (Object extension: constrainingType.getExtensions()) {
+ extensionProcessor.write(extension, writer);
+ }
+
+ writeEndDocument(writer);
+ }
+
+ public void resolve(ConstrainingType constrainingType, ModelResolver resolver) throws ContributionResolveException {
+ // Resolve component type services and references
+ resolveAbstractContracts(constrainingType.getServices(), resolver);
+ resolveAbstractContracts(constrainingType.getReferences(), resolver);
+ }
+
+ public QName getArtifactType() {
+ return CONSTRAINING_TYPE_QNAME;
+ }
+
+ public Class<ConstrainingType> getModelType() {
+ return ConstrainingType.class;
+ }
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java
new file mode 100644
index 0000000000..e525cc677a
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/DefaultBeanModelProcessor.java
@@ -0,0 +1,254 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static javax.xml.stream.XMLStreamConstants.END_ELEMENT;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.assembly.Base;
+import org.apache.tuscany.sca.assembly.ComponentType;
+import org.apache.tuscany.sca.assembly.Implementation;
+import org.apache.tuscany.sca.contribution.processor.ContributionReadException;
+import org.apache.tuscany.sca.contribution.processor.ContributionResolveException;
+import org.apache.tuscany.sca.contribution.processor.ContributionWriteException;
+import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.monitor.Monitor;
+import org.apache.tuscany.sca.policy.PolicySubject;
+
+/**
+ * Default Model Processor for beans.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultBeanModelProcessor extends BaseAssemblyProcessor implements StAXArtifactProcessor {
+
+ private QName artifactType;
+ private Class<Implementation> modelClass;
+ private Object modelFactory;
+ private Method factoryMethod;
+ private Map<String, Method> setterMethods = new HashMap<String, Method>();
+ private Map<String, Method> getterMethods = new HashMap<String, Method>();
+
+ public DefaultBeanModelProcessor(FactoryExtensionPoint modeFactories,
+ QName artifactType,
+ Class<Implementation> modelClass,
+ Object modelFactory,
+ Monitor monitor) {
+ super(modeFactories, null, monitor);
+ this.artifactType = artifactType;
+ this.modelClass = modelClass;
+ this.modelFactory = modelFactory;
+
+ // Introspect the factory class and bean model class
+ if (modelFactory != null) {
+
+ // Find the model create method
+ for (Method method: modelFactory.getClass().getMethods()) {
+ if (method.getName().startsWith("create") && method.getReturnType() == modelClass) {
+ factoryMethod = method;
+ break;
+ }
+ }
+ }
+
+ // Index the bean's setter methods
+ for (Method method: modelClass.getMethods()) {
+ Method getter;
+ String name = method.getName();
+ if (name.startsWith("set") && name.length() > 3) {
+
+ // Get the corresponding getter method
+ try {
+ getter = modelClass.getMethod("get" + name.substring(3));
+ } catch (Exception e) {
+ getter = null;
+ continue;
+ }
+
+ // Get the property name
+ name = name.substring(3);
+ if (name.length() > 1) {
+ if (!name.toUpperCase().equals(name)) {
+ name = name.substring(0, 1).toLowerCase() + name.substring(1);
+ }
+ }
+ } else {
+ continue;
+ }
+
+ // Map an uppercase property name to a lowercase attribute name
+ if (name.toUpperCase().equals(name)) {
+ name = name.toLowerCase();
+ }
+
+ // Trim trailing _ from property names
+ if (name.endsWith("_")) {
+ name = name.substring(0, name.length()-1);
+ }
+ setterMethods.put(name, method);
+ getterMethods.put(name, getter);
+ }
+ }
+
+ public Object read(XMLStreamReader reader) throws ContributionReadException, XMLStreamException {
+
+ // Read an element
+ try {
+
+ // Create a new instance of the model
+ Object model;
+ if (modelFactory != null) {
+ // Invoke the factory create method
+ model = factoryMethod.invoke(modelFactory);
+ } else {
+ // Invoke the model bean class default constructor
+ model = modelClass.newInstance();
+ }
+
+ // Initialize the bean properties with the attributes found in the
+ // XML element
+ for (int i = 0, n = reader.getAttributeCount(); i < n; i++) {
+ String attributeName = reader.getAttributeLocalName(i);
+ Method setter = setterMethods.get(attributeName);
+ if (setter != null) {
+ String value = reader.getAttributeValue(i);
+ setter.invoke(model, value);
+ }
+ }
+
+ // Read policies
+ policyProcessor.readPolicies(model, reader);
+
+ // FIXME read extension elements
+
+ // By default mark the model object unresolved
+ if (model instanceof Base) {
+ ((Base)model).setUnresolved(true);
+ }
+
+ // Skip to end element
+ while (reader.hasNext()) {
+ if (reader.next() == END_ELEMENT && artifactType.equals(reader.getName())) {
+ break;
+ }
+ }
+ return model;
+
+ } catch (Exception e) {
+ ContributionReadException ce = new ContributionReadException(e);
+ error("ContributionReadException", reader, ce);
+ throw ce;
+ }
+ }
+
+ public void write(Object bean, XMLStreamWriter writer) throws ContributionWriteException, XMLStreamException {
+ try {
+ // Write the bean properties as attributes
+ List<XAttr> attrs = new ArrayList<XAttr>();
+ for (Map.Entry<String, Method> entry: getterMethods.entrySet()) {
+ if (entry.getValue().getReturnType() == String.class) {
+ String value = (String)entry.getValue().invoke(bean);
+ attrs.add(new XAttr(entry.getKey(), value));
+ }
+ }
+
+ // Write element
+ writeStart(writer, artifactType.getNamespaceURI(), artifactType.getLocalPart(),
+ policyProcessor.writePolicies(bean), new XAttr(null, attrs));
+
+ writeEnd(writer);
+
+ } catch (Exception e) {
+ ContributionWriteException ce = new ContributionWriteException(e);
+ error("ContributionWriteException", writer, ce);
+ throw ce;
+ }
+ }
+
+ public void resolve(Object bean, ModelResolver resolver) throws ContributionResolveException {
+
+ // Resolve and merge the component type associated with an
+ // implementation model
+ if (bean instanceof Implementation) {
+ Implementation implementation = (Implementation)bean;
+ String uri = implementation.getURI();
+ if (uri != null) {
+ int d = uri.lastIndexOf('.');
+ if (d != -1) {
+ uri = uri.substring(0, d) + ".componentType";
+
+ // Resolve the component type
+ ComponentType componentType = assemblyFactory.createComponentType();
+ componentType.setURI(uri);
+ componentType.setUnresolved(true);
+
+ componentType = resolver.resolveModel(ComponentType.class, componentType);
+ if (componentType != null && !componentType.isUnresolved()) {
+
+ // We found a component type, merge it into the implementation model
+ implementation.getServices().addAll(componentType.getServices());
+ implementation.getReferences().addAll(componentType.getReferences());
+ implementation.getProperties().addAll(componentType.getProperties());
+ implementation.setConstrainingType(componentType.getConstrainingType());
+
+ if (implementation instanceof PolicySubject &&
+ componentType instanceof PolicySubject ) {
+ PolicySubject policiedImpl = (PolicySubject)implementation;
+ PolicySubject policiedCompType = (PolicySubject)componentType;
+
+ if ( policiedImpl.getPolicySets() != null) {
+ policiedImpl.getPolicySets().addAll(policiedCompType.getPolicySets());
+ }
+ if (policiedImpl.getRequiredIntents() != null) {
+ policiedImpl.getRequiredIntents().addAll(policiedCompType.getRequiredIntents());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Mark the model resolved
+ if (bean instanceof Base) {
+ ((Base)bean).setUnresolved(false);
+ }
+ }
+
+ public QName getArtifactType() {
+ return artifactType;
+ }
+
+ public Class<?> getModelType() {
+ return modelClass;
+ }
+
+}
diff --git a/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java
new file mode 100644
index 0000000000..d69f30aceb
--- /dev/null
+++ b/sca-java-2.x/branches/sca-java-2.0-M2/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/PolicySubjectProcessor.java
@@ -0,0 +1,252 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tuscany.sca.assembly.xml;
+
+import static org.apache.tuscany.sca.assembly.xml.Constants.POLICY_SETS;
+import static org.apache.tuscany.sca.assembly.xml.Constants.REQUIRES;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.apache.tuscany.sca.contribution.processor.BaseStAXArtifactProcessor;
+import org.apache.tuscany.sca.contribution.resolver.ModelResolver;
+import org.apache.tuscany.sca.interfacedef.Operation;
+import org.apache.tuscany.sca.policy.Intent;
+import org.apache.tuscany.sca.policy.PolicyFactory;
+import org.apache.tuscany.sca.policy.PolicySet;
+import org.apache.tuscany.sca.policy.PolicySubject;
+
+/**
+ * A Policy Attach Point processor.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PolicySubjectProcessor extends BaseStAXArtifactProcessor {
+
+ private PolicyFactory policyFactory;
+
+ public PolicySubjectProcessor(PolicyFactory policyFactory) {
+ this.policyFactory = policyFactory;
+ }
+
+ /**
+ * Read policy intents associated with an operation.
+ * @param attachPoint
+ * @param operation
+ * @param reader
+ */
+ private void readIntents(Object attachPoint, Operation operation, XMLStreamReader reader) {
+ if (!(attachPoint instanceof PolicySubject))
+ return;
+ PolicySubject intentAttachPoint = (PolicySubject)attachPoint;
+ String value = reader.getAttributeValue(null, REQUIRES);
+ if (value != null) {
+ List<Intent> requiredIntents = intentAttachPoint.getRequiredIntents();
+ for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) {
+ QName qname = getQNameValue(reader, tokens.nextToken());
+ Intent intent = policyFactory.createIntent();
+ intent.setName(qname);
+ if (operation != null) {
+ //FIXME Don't we need to handle intent specification
+ // on an operation basis?
+ //intent.getOperations().add(operation);
+ }
+ requiredIntents.add(intent);
+ }
+ }
+ }
+
+ /**
+ * Reads policy intents and policy sets associated with an operation.
+ * @param attachPoint
+ * @param operation
+ * @param reader
+ */
+ public void readPolicies(Object attachPoint, Operation operation, XMLStreamReader reader) {
+ readIntents(attachPoint, operation, reader);
+ readPolicySets(attachPoint, operation, reader);
+ }
+
+ /**
+ * Reads policy intents and policy sets.
+ * @param attachPoint
+ * @param reader
+ */
+ public void readPolicies(Object attachPoint, XMLStreamReader reader) {
+ readPolicies(attachPoint, null, reader);
+ }
+
+ /**
+ * Reads policy sets associated with an operation.
+ * @param attachPoint
+ * @param operation
+ * @param reader
+ */
+ private void readPolicySets(Object attachPoint, Operation operation, XMLStreamReader reader) {
+ if (!(attachPoint instanceof PolicySubject)) {
+ return;
+ }
+ PolicySubject policySubject = (PolicySubject)attachPoint;
+ String value = reader.getAttributeValue(null, POLICY_SETS);
+ if (value != null) {
+ List<PolicySet> policySets = policySubject.getPolicySets();
+ for (StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();) {
+ QName qname = getQNameValue(reader, tokens.nextToken());
+ PolicySet policySet = policyFactory.createPolicySet();
+ policySet.setName(qname);
+ if (operation != null) {
+ //FIXME Don't we need to handle policySet specification
+ // on an operation basis?
+ //policySet.getOperations().add(operation);
+ }
+ policySets.add(policySet);
+ }
+ }
+ }
+
+ /**
+ * Write policies
+ * @param attachPoint
+ * @return
+ */
+ XAttr writePolicies(Object attachPoint) throws XMLStreamException {
+ return writePolicies(attachPoint, (Operation)null);
+ }
+
+ /**
+ * Write policies
+ * @param attachPoint
+ * @return
+ */
+ public void writePolicyAttributes(Object attachPoint, XMLStreamWriter writer) throws XMLStreamException {
+ writePolicyAttributes(attachPoint, (Operation)null, writer);
+ }
+
+ /**
+ * Write policies
+ * @param attachPoint
+ * @return
+ */
+ public void writePolicyPrefixes(Object attachPoint, XMLStreamWriter writer) throws XMLStreamException {
+ writePolicyPrefixes(attachPoint, (Operation)null, writer);
+ }
+
+ /**
+ * Write policies associated with an operation
+ * @param attachPoint
+ * @param operation
+ * @return
+ */
+ XAttr writePolicies(Object attachPoint, Operation operation) {
+ List<XAttr> attrs =new ArrayList<XAttr>();
+ attrs.add(writeIntents(attachPoint, operation));
+ attrs.add(writePolicySets(attachPoint, operation));
+ return new XAttr(null, attrs);
+ }
+
+ /**
+ * Write policies
+ * @param attachPoint
+ * @return
+ */
+ public void writePolicyAttributes(Object attachPoint, Operation operation, XMLStreamWriter writer) throws XMLStreamException {
+ XAttr attr = writePolicies(attachPoint, operation);
+ attr.write(writer);
+ }
+
+ /**
+ * Write policies
+ * @param attachPoint
+ * @return
+ */
+ public void writePolicyPrefixes(Object attachPoint, Operation operation, XMLStreamWriter writer) throws XMLStreamException {
+ XAttr attr = writePolicies(attachPoint, operation);
+ attr.writePrefix(writer);
+ }
+
+ /**
+ * Write policy intents associated with an operation.
+ * @param attachPoint
+ * @param operation
+ */
+ private XAttr writeIntents(Object attachPoint, Operation operation) {
+ if (!(attachPoint instanceof PolicySubject)) {
+ return null;
+ }
+ PolicySubject intentAttachPoint = (PolicySubject)attachPoint;
+ List<QName> qnames = new ArrayList<QName>();
+ for (Intent intent: intentAttachPoint.getRequiredIntents()) {
+ qnames.add(intent.getName());
+ }
+ return new XAttr(Constants.REQUIRES, qnames);
+ }
+
+ /**
+ * Write policy sets associated with an operation.
+ * @param attachPoint
+ * @param operation
+ */
+ private XAttr writePolicySets(Object attachPoint, Operation operation) {
+ if (!(attachPoint instanceof PolicySubject)) {
+ return null;
+ }
+ PolicySubject policySetAttachPoint = (PolicySubject)attachPoint;
+ List<QName> qnames = new ArrayList<QName>();
+ for (PolicySet policySet: policySetAttachPoint.getPolicySets()) {
+ qnames.add(policySet.getName());
+ }
+ return new XAttr(Constants.POLICY_SETS, qnames);
+ }
+
+ public void resolvePolicies(Object attachPoint, ModelResolver resolver) {
+ if ( attachPoint instanceof PolicySubject ) {
+ PolicySubject policySetAttachPoint = (PolicySubject)attachPoint;
+
+ List<Intent> requiredIntents = new ArrayList<Intent>();
+ Intent resolvedIntent = null;
+
+ if ( policySetAttachPoint.getRequiredIntents() != null && policySetAttachPoint.getRequiredIntents().size() > 0 ) {
+ for ( Intent intent : policySetAttachPoint.getRequiredIntents() ) {
+ resolvedIntent = resolver.resolveModel(Intent.class, intent);
+ requiredIntents.add(resolvedIntent);
+ }
+ policySetAttachPoint.getRequiredIntents().clear();
+ policySetAttachPoint.getRequiredIntents().addAll(requiredIntents);
+ }
+
+ if ( policySetAttachPoint.getPolicySets() != null && policySetAttachPoint.getPolicySets().size() > 0 ) {
+ List<PolicySet> resolvedPolicySets = new ArrayList<PolicySet>();
+ PolicySet resolvedPolicySet = null;
+ for ( PolicySet policySet : policySetAttachPoint.getPolicySets() ) {
+ resolvedPolicySet = resolver.resolveModel(PolicySet.class, policySet);
+ resolvedPolicySets.add(resolvedPolicySet);
+ }
+ policySetAttachPoint.getPolicySets().clear();
+ policySetAttachPoint.getPolicySets().addAll(resolvedPolicySets);
+ }
+ }
+ }
+}