summaryrefslogtreecommitdiffstats
path: root/sca-java-2.x
diff options
context:
space:
mode:
authorantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2010-07-24 06:43:15 +0000
committerantelder <antelder@13f79535-47bb-0310-9956-ffa450edef68>2010-07-24 06:43:15 +0000
commit1f25076267cc5a6630421f78bfb5cc9299bb72c0 (patch)
treedbbbac8d82c84892fae02475cddf025ab5f48a99 /sca-java-2.x
parentcae0be77f0e5fab1fdac08104b569483fa93f026 (diff)
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
Diffstat (limited to '')
-rw-r--r--sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/META-INF/MANIFEST.MF3
-rw-r--r--sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/pom.xml6
-rw-r--r--sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/BaseAssemblyProcessor.java2
-rw-r--r--sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java144
-rw-r--r--sca-java-2.x/branches/2.0-Beta1/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java391
5 files changed, 417 insertions, 129 deletions
diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/META-INF/MANIFEST.MF b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/META-INF/MANIFEST.MF
index 57e693005b..d1ff0fb160 100644
--- a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/META-INF/MANIFEST.MF
+++ b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/META-INF/MANIFEST.MF
@@ -38,7 +38,7 @@ Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
Bundle-Description: Apache Tuscany SCA XML Assembly Model
Import-Package: javax.xml.namespace,
javax.xml.parsers,
- javax.xml.stream,
+ javax.xml.stream;version="1.0.0",
javax.xml.transform,
javax.xml.transform.dom,
javax.xml.transform.stream,
@@ -47,6 +47,7 @@ Import-Package: javax.xml.namespace,
org.apache.tuscany.sca.assembly;version="2.0.0",
org.apache.tuscany.sca.assembly.xml;version="2.0.0",
org.apache.tuscany.sca.common.java.io;version="2.0.0",
+ org.apache.tuscany.sca.common.xml.stax;version="2.0.0",
org.apache.tuscany.sca.common.xml.xpath;version="2.0.0",
org.apache.tuscany.sca.contribution;version="2.0.0",
org.apache.tuscany.sca.contribution.java;version="2.0.0",
diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/pom.xml b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/pom.xml
index 20d943ced4..df43930bc2 100644
--- a/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/pom.xml
+++ b/sca-java-2.x/branches/2.0-Beta1/modules/assembly-xml/pom.xml
@@ -45,6 +45,12 @@
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-xsd</artifactId>
<version>2.0-Beta1-SNAPSHOT</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.apache.tuscany.sca</groupId>
+ <artifactId>tuscany-common-xml</artifactId>
+ <version>2.0-SNAPSHOT</version>
</dependency>
<!--
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<Object> 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) {
- // $<name>/...
- 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 <sca:property> elements with one or more <sca:value> subelements or one or more
+ * global element subelements. The XPath constructed is designed to work against this XML structure and aims to
+ * retrieve one or more of the subelements or subportions of those subelements (eg some text content).
+ * Thus the XPath:
+ * - starts with "*", which means "all the child elements of the root" where root = the <property/> element
+ * - may then be followed by [xxx] (typically [n] to select one of the child elements) if the source string has [xxx]
+ * following the propertyName
+ * - may then be followed by /expression, if the source contains an expression, which will typically select some subportion
+ * of the child element(s)
+ *
+ * @param source - the @source attribute string from a <sca:property> element
+ * @return the XPath string to use for the source property
+ */
+ private String prepareSourceXPathString( String source ) {
+ String output = null;
+ // Expression must begin with '$'
+ if( source.charAt(0) != '$' ) return output;
+
+ int slash = source.indexOf('/');
+ int bracket = source.indexOf('[');
+ if (slash == -1) {
+ // Form is $propertyName or $propertyName[n]
+ output = "*";
+ if( bracket != -1 ) {
+ output = "*" + source.substring(bracket);
+ }
+ } else {
+ // Form is $propertyName/exp or $propertyName[n]/exp
+ output = "*/" + source.substring(slash + 1);
+ if( bracket != -1 && bracket < slash ) {
+ output = "*" + source.substring(bracket);
+ }
+ } // end if
+
+ return output;
+ } // end method prepareSourceXPathString( source )
public void write(Composite composite, XMLStreamWriter writer, ProcessorContext context) throws ContributionWriteException,
XMLStreamException {
@@ -1088,6 +1131,77 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt
public Class<Composite> getModelType() {
return Composite.class;
}
+
+ /**
+ * Write the value of a property - override to use correct method of creating an XMLStreamReader
+ * @param document
+ * @param element
+ * @param type
+ * @param writer
+ * @throws XMLStreamException
+ */
+ @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.
diff --git a/sca-java-2.x/branches/2.0-Beta1/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java b/sca-java-2.x/branches/2.0-Beta1/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java
index 694ece2d6c..13e30f7f78 100644
--- a/sca-java-2.x/branches/2.0-Beta1/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java
+++ b/sca-java-2.x/branches/2.0-Beta1/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java
@@ -18,6 +18,7 @@
*/
package org.apache.tuscany.sca.builder.impl;
+import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URI;
@@ -266,7 +267,7 @@ public class ComponentBuilderImpl {
calculateServiceInterfaceContract(component, componentService, componentTypeService, monitor);
// bindings
- calculateBindings(component, componentService, componentTypeService, monitor);
+ calculateBindings(component, componentService, componentTypeService, context);
// add callback reference model objects
createCallbackReference(component, componentService);
@@ -807,138 +808,257 @@ public class ComponentBuilderImpl {
Monitor monitor) {
String source = componentProperty.getSource();
- if (source != null) {
- // $<name>/...
- int index = source.indexOf('/');
- if (index == -1) {
- // Tolerating $prop
- source = source + "/";
- index = source.length() - 1;
- }
- if (source.charAt(0) == '$') {
- String name = source.substring(1, index);
- Property sourceProp = null;
- if (outerComponent != null) {
- sourceProp = outerComponent.getProperty(name);
- } else {
- sourceProp = parentComposite.getProperty(name);
- }
- if (sourceProp == null) {
- Monitor.error(monitor,
- this,
- Messages.ASSEMBLY_VALIDATION,
- "PropertySourceNotFound",
- source,
- componentProperty.getName(),
- component.getName());
- }
-
- Document sourcePropValue = (Document)sourceProp.getValue();
+ if (source == null) return;
+
+ try {
+ String sourceName = extractSourcePropertyName( source );
- try {
- // FIXME: How to deal with namespaces?
- Document node =
- evaluateXPath(sourcePropValue,
- componentProperty.getSourceXPathExpression(),
- documentBuilderFactory);
-
- if (node != null) {
- componentProperty.setValue(node);
- } else {
- Monitor.warning(monitor,
- this,
- Messages.ASSEMBLY_VALIDATION,
- "PropertyXpathExpressionReturnedNull",
- component.getName(),
- componentProperty.getName(),
- componentProperty.getSource());
- }
- } catch (Exception ex) {
- Monitor.error(monitor,
- this,
- Messages.ASSEMBLY_VALIDATION,
- "PropertySourceXpathInvalid",
- source,
- componentProperty.getName(),
- component.getName(),
- ex);
- }
+ Property sourceProp = null;
+ if (outerComponent != null) {
+ sourceProp = outerComponent.getProperty(sourceName);
} else {
+ sourceProp = parentComposite.getProperty(sourceName);
+ }
+ if (sourceProp == null) {
Monitor.error(monitor,
this,
Messages.ASSEMBLY_VALIDATION,
- "PropertySourceValueInvalid",
+ "PropertySourceNotFound",
source,
componentProperty.getName(),
component.getName());
- }
- }
- }
+ } else {
+ Document sourcePropValue = (Document)sourceProp.getValue();
+
+ try {
+ // FIXME: How to deal with namespaces?
+ Document node =
+ evaluateXPath2(sourcePropValue,
+ componentProperty.getSourceXPathExpression(),
+ documentBuilderFactory);
+
+ if (node != null) {
+ componentProperty.setValue(node);
+ } else {
+ Monitor.warning(monitor,
+ this,
+ Messages.ASSEMBLY_VALIDATION,
+ "PropertyXpathExpressionReturnedNull",
+ component.getName(),
+ componentProperty.getName(),
+ componentProperty.getSource());
+ } // end if
+
+ } catch (Exception ex) {
+ Monitor.error(monitor,
+ this,
+ Messages.ASSEMBLY_VALIDATION,
+ "PropertySourceXpathInvalid",
+ source,
+ componentProperty.getName(),
+ component.getName(),
+ ex);
+ } // end try
+ } // end if
+ } catch (IllegalArgumentException e ) {
+ Monitor.error(monitor,
+ this,
+ Messages.ASSEMBLY_VALIDATION,
+ "PropertySourceValueInvalid",
+ source,
+ componentProperty.getName(),
+ component.getName());
+ } // end try
+ } // end method
+
/**
- * If the property has a file attribute use this to retrieve the value from a
- * local file
+ * Extracts the name of the source property from the value of an @source attribute string
+ * @param source - the value of the @source attribute
+ * @return - the source property name as a String
+ */
+ private String extractSourcePropertyName( String source ) throws IllegalArgumentException {
+ String propertyName = null;
+
+ // Possible values for the source string:
+ // a) $name
+ // b) $name/expression
+ // c) $name[xx]
+ // d) $name[xx]/expression
+ // ...and note that the expression MAY contain '/' and '[' characters
+ if( source.charAt(0) != '$' ) throw new IllegalArgumentException("Source value does not start with '$'");
+
+ int index = source.indexOf('/');
+ int bracket = source.indexOf('[');
+
+ if( index == -1 && bracket == -1 ) {
+ // Format a) - simply remove the '$'
+ propertyName = source.substring(1);
+ } else if ( bracket == -1 ) {
+ // Format b) - remove the '$' and the '/' and everything following it
+ propertyName = source.substring(1, index);
+ } else if ( index == -1 ) {
+ // Format c) - remove the '$' and the '[' and everything following it
+ propertyName = source.substring(1, bracket);
+ } else {
+ // Format d) - but need to ensure that the '[' is BEFORE the '/'
+ if( bracket < index ) {
+ // Format d) - remove the '$' and the '[' and everything following it
+ propertyName = source.substring(1, bracket);
+ } else {
+ // Format b) variant where there is a '[' in the expression...
+ propertyName = source.substring(1, index);
+ } // end if
+ } // end if
+
+ return propertyName;
+ } // end method extractSourcePropertyName( source, monitor )
+ /**
+ * If the property has a file attribute use this to retrieve the property value from a local file
+ * Format of the property value file is defined in the SCA Assembly specification in ASM50046
*
- * @param parentCompoent the composite that contains the component
- * @param component
+ * @param component the component holding the property
+ * @param componentProperty - the property
+ * @param monitor - a Monitor object for reporting problems
+ */
+ /**
+ * Property file format:
+ * MUST contain a <sca:values/> element
+ * - either contains one or more <sca:value/> subelements (mandatory for property with a simple XML type)
+ * - or contains one or more global elements of the type of the property
+ *
+ * eg.
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <values>
+ * <value>MyValue</value>
+ * </values>
+ *
+ * <?xml version="1.0" encoding="UTF-8"?>
+ * <values>
+ * <foo:fooElement>
+ * <foo:a>AValue</foo:a>
+ * <foo:b>InterestingURI</foo:b>
+ * </foo:fooElement>
+ * </values/>
*/
private void processPropertyFileAttribute(Component component, ComponentProperty componentProperty, Monitor monitor) {
String file = componentProperty.getFile();
- if (file != null) {
+ if (file == null) return;
+ try {
+/*
+ URI uri = URI.create(file);
+ // URI resolution for relative URIs is done when the composite is resolved.
+ URL url = uri.toURL();
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ InputStream is = null;
try {
- URI uri = URI.create(file);
- // URI resolution for relative URIs is done when the composite is resolved.
- URL url = uri.toURL();
- URLConnection connection = url.openConnection();
- connection.setUseCaches(false);
- InputStream is = null;
- try {
- is = connection.getInputStream();
- Source streamSource = new SAXSource(new InputSource(is));
- DOMResult result = new DOMResult();
- javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
- transformer.transform(streamSource, result);
+ is = connection.getInputStream();
- Document document = (Document)result.getNode();
+ Source streamSource = new SAXSource(new InputSource(is));
+ DOMResult result = new DOMResult();
+ javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
+ transformer.transform(streamSource, result);
- // TUSCANY-2377, Add a fake value element so it's consistent with
- // the DOM tree loaded from inside SCDL
- if (!document.getDocumentElement().getLocalName().equals("value")){
- Element root = document.createElementNS(null, "value");
- root.appendChild(document.getDocumentElement());
-
- // remove all the child nodes as they will be replaced by
- // the "value" node
- NodeList children = document.getChildNodes();
- for (int i=0; i < children.getLength(); i++){
- document.removeChild(children.item(i));
- }
-
- // add the value node back in
- document.appendChild(root);
- }
+ Document document = (Document)result.getNode();
+*/
+ Document document = readPropertyFileData( file );
+
+ Element docElement = document.getDocumentElement();
+ if( docElement == null ) throw new Exception("Property File has no XML document element");
+
+ if( !"values".equals( docElement.getLocalName() ) ) {
+ throw new Exception("Property File does not start with <values/> element");
+ } // end if
+
+ // The property value is the subelement(s) of the <values/> element
+ NodeList values = docElement.getChildNodes();
+
+ Document newdoc = documentBuilderFactory.newDocumentBuilder().newDocument();
+ Element newProperty = newdoc.createElementNS(SCA11_NS, "property");
+ newdoc.appendChild( newProperty );
+
+ int count = 0;
+
+ // Copy the property values under the new <property/> element
+ for( int i = 0 ; i < values.getLength() ; i++ ) {
+ Node valueNode = values.item(i);
+ // Only <value/> elements or global elements are valid values...
+ if( valueNode.getNodeType() == Node.ELEMENT_NODE ) {
+ newProperty.appendChild(newdoc.importNode(values.item(i), true));
+ count++;
+ } // end if
+ } // end for
+
+ if( count == 0 ) {
+ throw new Exception("Property File has no property values");
+ } // end if
+
+ componentProperty.setValue(newdoc);
+
+/*
+ // TUSCANY-2377, Add a fake value element so it's consistent with
+ // the DOM tree loaded from inside SCDL
+ if (!document.getDocumentElement().getLocalName().equals("value")){
+ Element root = document.createElementNS(null, "value");
+ root.appendChild(document.getDocumentElement());
- componentProperty.setValue(document);
- } finally {
- if (is != null) {
- is.close();
+ // remove all the child nodes as they will be replaced by the "value" node
+ NodeList children = document.getChildNodes();
+ for (int i=0; i < children.getLength(); i++){
+ document.removeChild(children.item(i));
}
- }
- } catch (Exception ex) {
- Monitor.error(monitor,
- this,
- Messages.ASSEMBLY_VALIDATION,
- "PropertyFileValueInvalid",
- file,
- componentProperty.getName(),
- component.getName(),
- ex);
+
+ // add the value node back in
+ document.appendChild(root);
+ }
+ componentProperty.setValue(document);
+ } finally {
+ if (is != null) {
+ is.close();
+ }
+ } // end try
+*/
+ } catch (Exception ex) {
+ Monitor.error(monitor,
+ this,
+ Messages.ASSEMBLY_VALIDATION,
+ "PropertyFileValueInvalid",
+ file,
+ componentProperty.getName(),
+ component.getName(),
+ ex);
+ } // end try
+ } // end method processPropertyFileAttribute
+
+ private Document readPropertyFileData( String file ) throws Exception {
+ Document doc = null;
+
+ URI uri = URI.create(file);
+ // URI resolution for relative URIs is done when the composite is resolved.
+ URL url = uri.toURL();
+ URLConnection connection = url.openConnection();
+ connection.setUseCaches(false);
+ InputStream is = null;
+ try {
+ is = connection.getInputStream();
+
+ Source streamSource = new SAXSource(new InputSource(is));
+ DOMResult result = new DOMResult();
+ javax.xml.transform.Transformer transformer = transformerFactory.newTransformer();
+ transformer.transform(streamSource, result);
+
+ doc = (Document)result.getNode();
+ } finally {
+ if (is != null) {
+ is.close();
}
- }
+ } // end try
- }
+ return doc;
+ } // end method readPropertyFileData
/**
* Evaluate an XPath expression against a Property value, returning the result as a Property value
@@ -984,6 +1104,51 @@ public class ComponentBuilderImpl {
return document;
}
}
+
+ /**
+ * Evaluate an XPath expression against a Property value, returning the result as a Property value
+ * - deals with multi-valued input property values and with multi-valued output property values
+ * @param node - the document root element of a Property value
+ * @param expression - the XPath expression
+ * @param documentBuilderFactory - a DOM document builder factory
+ * @return - a DOM Document representing the result of the evaluation as a Property value
+ * @throws XPathExpressionException
+ * @throws ParserConfigurationException
+ */
+ private Document evaluateXPath2(Document node,
+ XPathExpression expression,
+ DocumentBuilderFactory documentBuilderFactory) throws XPathExpressionException,
+ ParserConfigurationException {
+
+ // The document element is a <sca:property/> element
+ Element property = node.getDocumentElement();
+
+ NodeList result = (NodeList)expression.evaluate(property, XPathConstants.NODESET);
+ if (result == null || result.getLength() == 0) return null;
+
+ if (result instanceof Document) {
+ return (Document)result;
+ } else {
+ Document document = documentBuilderFactory.newDocumentBuilder().newDocument();
+ Element newProperty = document.createElementNS(SCA11_NS, "property");
+
+ for( int i = 0 ; i < result.getLength() ; i++ ) {
+ if (result.item(i).getNodeType() == Node.ELEMENT_NODE) {
+ // If the result is an element, use it directly in the result
+ newProperty.appendChild(document.importNode(result.item(i), true));
+ } else {
+ // If the result is not an element, create a <value/> element to contain the result
+ Element newValue = document.createElementNS(SCA11_NS, "value");
+ newValue.appendChild(document.importNode(result.item(i), true));
+ newProperty.appendChild(newValue);
+ } // end if
+ } // end for
+
+ document.appendChild(newProperty);
+
+ return document;
+ } // end if
+ } // end method
/**
* Create a callback reference for a component service
@@ -1404,14 +1569,16 @@ public class ComponentBuilderImpl {
* @param componentService the top service
* @param componentTypeService the bottom service
*/
- private void calculateBindings(Component component, Service componentService, Service componentTypeService, Monitor monitor) {
+ private void calculateBindings(Component component, Service componentService, Service componentTypeService, BuilderContext context) {
+ Monitor monitor = context.getMonitor();
+
// forward bindings
if (componentService.getBindings().isEmpty()) {
componentService.getBindings().addAll(componentTypeService.getBindings());
}
if (componentService.getBindings().isEmpty()) {
- createSCABinding(componentService, null);
+ createSCABinding(componentService, context.getDefinitions());
}
// callback bindings