From 1f25076267cc5a6630421f78bfb5cc9299bb72c0 Mon Sep 17 00:00:00 2001 From: antelder Date: Sat, 24 Jul 2010 06:43:15 +0000 Subject: Merge r966650,966653,966658,966714 from trunk to beta1 branch for property source and writing fixes git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@978812 13f79535-47bb-0310-9956-ffa450edef68 --- .../sca/assembly/xml/BaseAssemblyProcessor.java | 2 +- .../sca/assembly/xml/CompositeProcessor.java | 144 ++++++++++++++++++--- 2 files changed, 130 insertions(+), 16 deletions(-) (limited to 'sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java') diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java index 641e523d2c..21a7efc9c8 100644 --- a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java +++ b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java @@ -409,7 +409,7 @@ abstract class BaseAssemblyProcessor extends BaseStAXArtifactProcessor { * @param element * @param type * @param reader - * @param context TODO + * @param context * @return * @throws XMLStreamException * @throws ContributionReadException diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java index 22879c2beb..8922c232b0 100644 --- a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java +++ b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java @@ -66,10 +66,12 @@ import java.util.List; import java.util.StringTokenizer; import javax.xml.namespace.QName; +import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamConstants; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.dom.DOMSource; import javax.xml.xpath.XPathExpressionException; import org.apache.tuscany.sca.assembly.Binding; @@ -87,6 +89,7 @@ import org.apache.tuscany.sca.assembly.Property; import org.apache.tuscany.sca.assembly.Reference; import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.Wire; +import org.apache.tuscany.sca.common.xml.stax.StAXHelper; import org.apache.tuscany.sca.common.xml.xpath.XPathHelper; import org.apache.tuscany.sca.contribution.Artifact; import org.apache.tuscany.sca.contribution.Contribution; @@ -111,6 +114,8 @@ import org.apache.tuscany.sca.policy.PolicySubject; import org.apache.tuscany.sca.xsd.XSDFactory; import org.apache.tuscany.sca.xsd.XSDefinition; import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; /** * A composite processor. @@ -123,6 +128,8 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt private StAXAttributeProcessor extensionAttributeProcessor; private ContributionFactory contributionFactory; private XSDFactory xsdFactory; + + private StAXHelper staxHelper; /** * Construct a new composite processor @@ -140,6 +147,9 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt this.extensionAttributeProcessor = extensionAttributeProcessor; this.xsdFactory = extensionPoints.getExtensionPoint(XSDFactory.class); + + // + staxHelper = StAXHelper.getInstance(extensionPoints); } /** @@ -354,23 +364,11 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt } componentProperty.setSource(source); if (source != null) { - // $/... - if (source.charAt(0) == '$') { - int index = source.indexOf('/'); - if (index == -1) { - // Tolerating $prop - source = ""; - } else { - source = source.substring(index + 1); - } - if ("".equals(source)) { - source = "."; - } - } - + String xPath = prepareSourceXPathString( source ); + try { componentProperty.setSourceXPathExpression(xpathHelper.compile(reader - .getNamespaceContext(), source)); + .getNamespaceContext(), xPath)); } catch (XPathExpressionException e) { ContributionReadException ce = new ContributionReadException(e); error(monitor, "ContributionReadException", source, ce); @@ -648,6 +646,51 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt return composite; } + + /** + * Prepares the property @source XPath expression + * + * The form of the @source attribute in the composite file must take one of the forms + * $propertyName + * $propertyName/expression + * $propertyName[n] + * $propertyName[n]/expression + * Property values are stored as elements with one or more subelements or one or more + * global element subelements. The XPath constructed is designed to work against this XML structure and aims to + * retrieve one or more of the subelements or subportions of those subelements (eg some text content). + * Thus the XPath: + * - starts with "*", which means "all the child elements of the root" where root = the element + * - may then be followed by [xxx] (typically [n] to select one of the child elements) if the source string has [xxx] + * following the propertyName + * - may then be followed by /expression, if the source contains an expression, which will typically select some subportion + * of the child element(s) + * + * @param source - the @source attribute string from a element + * @return the XPath string to use for the source property + */ + private String prepareSourceXPathString( String source ) { + String output = null; + // Expression must begin with '$' + if( source.charAt(0) != '$' ) return output; + + int slash = source.indexOf('/'); + int bracket = source.indexOf('['); + if (slash == -1) { + // Form is $propertyName or $propertyName[n] + output = "*"; + if( bracket != -1 ) { + output = "*" + source.substring(bracket); + } + } else { + // Form is $propertyName/exp or $propertyName[n]/exp + output = "*/" + source.substring(slash + 1); + if( bracket != -1 && bracket < slash ) { + output = "*" + source.substring(bracket); + } + } // end if + + return output; + } // end method prepareSourceXPathString( source ) public void write(Composite composite, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException, XMLStreamException { @@ -1088,6 +1131,77 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt public Class getModelType() { return Composite.class; } + + /** + * Write the value of a property - override to use correct method of creating an XMLStreamReader + * @param document + * @param element + * @param type + * @param writer + * @throws XMLStreamException + */ + @Override + protected void writePropertyValue(Object propertyValue, QName element, QName type, XMLStreamWriter writer) + throws XMLStreamException { + + if (propertyValue instanceof Document) { + Document document = (Document)propertyValue; + NodeList nodeList = document.getDocumentElement().getChildNodes(); + + for (int item = 0; item < nodeList.getLength(); ++item) { + Node node = nodeList.item(item); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + // Correct way to create a reader for a node object... + XMLStreamReader reader = staxHelper.createXMLStreamReader(node); + + while (reader.hasNext()) { + switch (reader.next()) { + case XMLStreamConstants.START_ELEMENT: + QName name = reader.getName(); + writer.writeStartElement(name.getPrefix(), name.getLocalPart(), name.getNamespaceURI()); + + int namespaces = reader.getNamespaceCount(); + for (int i = 0; i < namespaces; i++) { + String prefix = reader.getNamespacePrefix(i); + String ns = reader.getNamespaceURI(i); + writer.writeNamespace(prefix, ns); + } + + if (!"".equals(name.getNamespaceURI())) { + writer.writeNamespace(name.getPrefix(), name.getNamespaceURI()); + } + + // add the attributes for this element + namespaces = reader.getAttributeCount(); + for (int i = 0; i < namespaces; i++) { + String ns = reader.getAttributeNamespace(i); + String prefix = reader.getAttributePrefix(i); + String qname = reader.getAttributeLocalName(i); + String value = reader.getAttributeValue(i); + + writer.writeAttribute(prefix, ns, qname, value); + } + + break; + case XMLStreamConstants.CDATA: + writer.writeCData(reader.getText()); + break; + case XMLStreamConstants.CHARACTERS: + writer.writeCharacters(reader.getText()); + break; + case XMLStreamConstants.END_ELEMENT: + writer.writeEndElement(); + break; + } + } + } else { + writer.writeCharacters(node.getTextContent()); + } + } + } + } // end method writePropertyValue + /** * Returns the model factory extension point to use. -- cgit v1.2.3