diff options
author | slaws <slaws@13f79535-47bb-0310-9956-ffa450edef68> | 2010-05-06 12:31:45 +0000 |
---|---|---|
committer | slaws <slaws@13f79535-47bb-0310-9956-ffa450edef68> | 2010-05-06 12:31:45 +0000 |
commit | 79ee3ef4b1e7014231af2627572b03c497063e3a (patch) | |
tree | 39a2948aeb4ad8be0c41891dc80f271d79ff57f7 /sca-java-2.x/trunk | |
parent | 5d02eac6f0ecb65cf887b5870009aaa7e6bafd3f (diff) |
TUSCANY-3530 - first raft of changes to turn on property type checking at deployment time. Required by ASM_5038 and ASM_5039. Still some TODOs including handling elements, composite properties, multiplicity and complex types derived from the component type.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@941695 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-java-2.x/trunk')
12 files changed, 257 insertions, 11 deletions
diff --git a/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ValidateDependenciesTestCase.java b/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ValidateDependenciesTestCase.java index 6be72d79b8..475586f016 100644 --- a/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ValidateDependenciesTestCase.java +++ b/sca-java-2.x/trunk/itest/scdl/src/test/java/org/apache/tuscany/sca/itest/scdl/ValidateDependenciesTestCase.java @@ -63,6 +63,6 @@ public class ValidateDependenciesTestCase { Assert.assertTrue(dependenciesDir.exists());
File[] dependencyFiles = dependenciesDir.listFiles();
- Assert.assertEquals(20, dependencyFiles.length);
+ Assert.assertEquals(28, dependencyFiles.length);
}
}
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/assembly-xml/META-INF/MANIFEST.MF index 8722cb3b06..010d6f168c 100644 --- a/sca-java-2.x/trunk/modules/assembly-xml/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/assembly-xml/META-INF/MANIFEST.MF @@ -61,6 +61,7 @@ Import-Package: javax.xml.namespace, org.apache.tuscany.sca.interfacedef.impl;version="2.0.0",
org.apache.tuscany.sca.monitor;version="2.0.0",
org.apache.tuscany.sca.policy;version="2.0.0",
+ org.apache.tuscany.sca.xsd;version="2.0.0",
org.w3c.dom,
org.xml.sax;resolution:=optional
Bundle-SymbolicName: org.apache.tuscany.sca.assembly.xml
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/pom.xml b/sca-java-2.x/trunk/modules/assembly-xml/pom.xml index 25bb479962..8eb306f07c 100644 --- a/sca-java-2.x/trunk/modules/assembly-xml/pom.xml +++ b/sca-java-2.x/trunk/modules/assembly-xml/pom.xml @@ -40,6 +40,12 @@ <artifactId>tuscany-contribution</artifactId> <version>2.0-SNAPSHOT</version> </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-xsd</artifactId> + <version>2.0-SNAPSHOT</version> + </dependency> <!-- <dependency> @@ -75,6 +81,8 @@ <version>2.0-SNAPSHOT</version> <scope>runtime</scope> </dependency> + + </dependencies> </project> diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java index 885fde0612..2069696ff1 100644 --- a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java +++ b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/assembly/xml/CompositeProcessor.java @@ -62,6 +62,7 @@ import static org.apache.tuscany.sca.assembly.xml.Constants.WIRE_QNAME; import static org.apache.tuscany.sca.assembly.xml.Constants.EXTENSION; import static org.apache.tuscany.sca.assembly.xml.Constants.EXTENSION_QNAME; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -90,6 +91,7 @@ import org.apache.tuscany.sca.assembly.Service; import org.apache.tuscany.sca.assembly.Wire; import org.apache.tuscany.sca.common.xml.xpath.XPathHelper; import org.apache.tuscany.sca.contribution.Artifact; +import org.apache.tuscany.sca.contribution.Contribution; import org.apache.tuscany.sca.contribution.ContributionFactory; import org.apache.tuscany.sca.contribution.processor.ContributionReadException; import org.apache.tuscany.sca.contribution.processor.ContributionResolveException; @@ -108,6 +110,8 @@ 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; +import org.apache.tuscany.sca.xsd.XSDFactory; +import org.apache.tuscany.sca.xsd.XSDefinition; import org.w3c.dom.Document; /** @@ -120,6 +124,7 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt private PolicyFactory intentAttachPointTypeFactory; private StAXAttributeProcessor<Object> extensionAttributeProcessor; private ContributionFactory contributionFactory; + private XSDFactory xsdFactory; /** * Construct a new composite processor @@ -135,6 +140,8 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt this.xpathHelper = XPathHelper.getInstance(extensionPoints); this.extensionAttributeProcessor = extensionAttributeProcessor; + + this.xsdFactory = extensionPoints.getExtensionPoint(XSDFactory.class); } /** @@ -153,6 +160,7 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt this.contributionFactory = modelFactories.getFactory(ContributionFactory.class); this.extensionAttributeProcessor = extensionAttributeProcessor; + this.xsdFactory = modelFactories.getFactory(XSDFactory.class); } public Composite read(XMLStreamReader reader, ProcessorContext context) throws ContributionReadException { @@ -997,6 +1005,12 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt //Resolve composite services and references resolveContracts(composite, composite.getServices(), resolver, context); resolveContracts(composite, composite.getReferences(), resolver, context); + + for (Property property : composite.getProperties()){ + resolvePropertyType("composite " + composite.getName().toString(), + property, + context.getContribution(), context); + } // Resolve component implementations, services and references for (Component component : composite.getComponents()) { @@ -1006,6 +1020,7 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt resolveContracts(component, component.getReferences(), resolver, context); for (ComponentProperty componentProperty : component.getProperties()) { + // resolve a reference to a property file if (componentProperty.getFile() != null) { Artifact artifact = contributionFactory.createArtifact(); artifact.setURI(componentProperty.getFile()); @@ -1014,6 +1029,11 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt componentProperty.setFile(artifact.getLocation()); } } + + // resolve the reference to a complex property + resolvePropertyType("component " + component.getName(), + componentProperty, + context.getContribution(), context); } //resolve component implementation @@ -1065,5 +1085,36 @@ public class CompositeProcessor extends BaseAssemblyProcessor implements StAXArt private static FactoryExtensionPoint modelFactories(ExtensionPointRegistry extensionPoints) { return extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); } + + /** + * Property elements can have XSD types attributes so, in the case of a complex type, we need to find + * the XSD definition that defines that type in the contribution while we still have access to the + * contribution. Later, in the builder, we use this XSD definition to ensure that the property value + * is of the correct type + * + * @param property + * @param contribution + */ + private void resolvePropertyType(String parentName, Property property, Contribution contribution, ProcessorContext context){ + // resolve the reference to a complex property + // we ignore any types in the schema namespace + if (property.getXSDType() != null && + property.getXSDType().getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema") != true){ + XSDefinition xsdDefinition = xsdFactory.createXSDefinition(); + xsdDefinition.setUnresolved(true); + xsdDefinition.setNamespace(property.getXSDType().getNamespaceURI()); + // some unit tests don't set up contribution and model resolvers properly + if (contribution != null && contribution.getModelResolver() != null) { + XSDefinition resolved = contribution.getModelResolver().resolveModel(XSDefinition.class, xsdDefinition, context); + if (resolved == null || resolved.isUnresolved()){ + // raise an error + error(context.getMonitor(), "PropertyTypeNotFound", property, property.getXSDType().toString(), property.getName(), parentName); + } else { + // store the schema in the property + property.setXSDDefinition(resolved); + } + } + } + } } diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties b/sca-java-2.x/trunk/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties index f12e94d968..8ad5f88892 100644 --- a/sca-java-2.x/trunk/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties +++ b/sca-java-2.x/trunk/modules/assembly-xml/src/main/resources/org/apache/tuscany/sca/assembly/xml/assembly-xml-validation-messages.properties @@ -29,3 +29,4 @@ ContributionResolveException = ContributionResolveException occured due to : {0} ContributionWriteException = ContributionWriteException occured due to : {0} XMLStreamException = XMLStreamException occured due to : {0} DuplicateCompositeName = [ASM_6001] More than one composite with the same name {0} found in contribution {1} +PropertyTypeNotFound = The type {0} specified on property {1} of {2} can't be found in any loaded contribution (makes sure the .xsd file is in a contribution, that the contribution is being loaded and that contribution imports and exports are correct) diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/AbstractProperty.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/AbstractProperty.java index 6d2f665c0a..45fa05d66c 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/AbstractProperty.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/AbstractProperty.java @@ -132,4 +132,20 @@ public interface AbstractProperty extends Base, Extensible { * @param dataType The data type */ void setDataType(DataType dataType); + + /** + * Get the XML schema that represents the type if this property. + * Used during property value validation + * + * @return + */ + Object getXSDDefinition(); + + /** + * Set the XML schema that represents the type if this property. + * Used during property value validation + * + * @param xsdDefintion + */ + void setXSDDefinition(Object xsdDefintion); } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/AbstractPropertyImpl.java b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/AbstractPropertyImpl.java index a7c033d479..24dc20f815 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/AbstractPropertyImpl.java +++ b/sca-java-2.x/trunk/modules/assembly/src/main/java/org/apache/tuscany/sca/assembly/impl/AbstractPropertyImpl.java @@ -37,6 +37,7 @@ public class AbstractPropertyImpl extends ExtensibleImpl implements AbstractProp protected boolean many; protected boolean mustSupply; protected DataType dataType; + protected Object xsdDefinition; /** * Constructs a new abstract property. @@ -99,5 +100,13 @@ public class AbstractPropertyImpl extends ExtensibleImpl implements AbstractProp public void setDataType(DataType dataType) { this.dataType = dataType; } + + public Object getXSDDefinition() { + return xsdDefinition; + } + + public void setXSDDefinition(Object xsdDefinition) { + this.xsdDefinition = xsdDefinition; + } } diff --git a/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties b/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties index 8e6b351ea4..c529a518d6 100644 --- a/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties +++ b/sca-java-2.x/trunk/modules/assembly/src/main/resources/org/apache/tuscany/sca/assembly/builder/assembly-validation-messages.properties @@ -76,3 +76,6 @@ PropertXSDElementsDontMatch = [ASM_5036] The property component {0} property {1} IntentNotSatisfied = The intent {0} associated with policy subject {1} has no matching policy set URIFoundOnServiceSCABinding = [ASM90005] The SCA binding {0} on component {1} service {2} should not have a URI and the URI is currently set to {3} CompositeReferencePromotesNonOverridableReference = [ASM50042] Composite reference promotes component reference with 1..1 multiplicity and nonOverridable flag set true: Composite = {0} Composite reference = {1} Component reference = {2} +PropertyValueDoesNotMatchSimpleType = [ASM50027] The property {0} on component {1} has a value which does not match the simple type {2} with which it is associated +PropertyValueDoesNotMatchComplexType = [ASM50038] The property {0} on component {1} has a value which does not match the complex type {2} with which it is associated. Validation reported {3} +PropertyValueDoesNotMatchElement = [ASM50029] The property {0} on component {1} has a value which does not match the element {2} with which it is associated. Validation reported {3} diff --git a/sca-java-2.x/trunk/modules/builder/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/builder/META-INF/MANIFEST.MF index 4533852cf2..0f7918bea8 100644 --- a/sca-java-2.x/trunk/modules/builder/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/builder/META-INF/MANIFEST.MF @@ -19,11 +19,18 @@ Import-Package: javax.xml.namespace, org.apache.tuscany.sca.contribution.processor;version="2.0.0",
org.apache.tuscany.sca.contribution.resolver;version="2.0.0";resolution:=optional,
org.apache.tuscany.sca.core;version="2.0.0",
+ org.apache.tuscany.sca.databinding;version="2.0.0",
+ org.apache.tuscany.sca.databinding.impl;version="2.0.0",
+ org.apache.tuscany.sca.databinding.jaxb;version="2.0.0",
+ org.apache.tuscany.sca.databinding.xml;version="2.0.0",
org.apache.tuscany.sca.definitions;version="2.0.0",
org.apache.tuscany.sca.interfacedef;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.impl;version="2.0.0",
+ org.apache.tuscany.sca.interfacedef.util;version="2.0.0",
org.apache.tuscany.sca.monitor;version="2.0.0",
org.apache.tuscany.sca.policy;version="2.0.0",
org.apache.tuscany.sca.runtime;version="2.0.0",
+ org.apache.tuscany.sca.xsd;version="2.0.0",
org.oasisopen.sca;version="2.0.0",
org.w3c.dom
Bundle-SymbolicName: org.apache.tuscany.sca.builder
diff --git a/sca-java-2.x/trunk/modules/builder/pom.xml b/sca-java-2.x/trunk/modules/builder/pom.xml index ae65e542c2..615a001dd8 100644 --- a/sca-java-2.x/trunk/modules/builder/pom.xml +++ b/sca-java-2.x/trunk/modules/builder/pom.xml @@ -38,9 +38,8 @@ <dependency> <groupId>org.apache.tuscany.sca</groupId> - <artifactId>tuscany-assembly-xml</artifactId> + <artifactId>tuscany-xsd</artifactId> <version>2.0-SNAPSHOT</version> - <scope>test</scope> </dependency> <dependency> @@ -48,6 +47,19 @@ <artifactId>tuscany-contribution</artifactId> <version>2.0-SNAPSHOT</version> </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-databinding-jaxb</artifactId> + <version>2.0-SNAPSHOT</version> + </dependency> + + <dependency> + <groupId>org.apache.tuscany.sca</groupId> + <artifactId>tuscany-assembly-xml</artifactId> + <version>2.0-SNAPSHOT</version> + <scope>test</scope> + </dependency> </dependencies> diff --git a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java index 322db27f05..372a802036 100644 --- a/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java +++ b/sca-java-2.x/trunk/modules/builder/src/main/java/org/apache/tuscany/sca/builder/impl/ComponentBuilderImpl.java @@ -19,17 +19,25 @@ package org.apache.tuscany.sca.builder.impl; import java.io.InputStream; +import java.io.StringReader; import java.net.URI; import java.net.URL; import java.net.URLConnection; +import javax.xml.XMLConstants; import javax.xml.namespace.QName; +import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.Source; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXSource; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; @@ -58,18 +66,28 @@ import org.apache.tuscany.sca.assembly.builder.Messages; 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.databinding.Mediator; +import org.apache.tuscany.sca.databinding.impl.MediatorImpl; +import org.apache.tuscany.sca.databinding.jaxb.JAXBDataBinding; +import org.apache.tuscany.sca.databinding.xml.DOMDataBinding; import org.apache.tuscany.sca.definitions.Definitions; import org.apache.tuscany.sca.interfacedef.Compatibility; +import org.apache.tuscany.sca.interfacedef.DataType; import org.apache.tuscany.sca.interfacedef.IncompatibleInterfaceContractException; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.InterfaceContractMapper; +import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl; +import org.apache.tuscany.sca.interfacedef.util.XMLType; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.policy.ExtensionType; import org.apache.tuscany.sca.policy.PolicySubject; +import org.apache.tuscany.sca.xsd.XSDefinition; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import org.xml.sax.InputSource; +import org.xml.sax.SAXException; /** * @version $Rev$ $Date$ @@ -87,6 +105,7 @@ public class ComponentBuilderImpl { protected TransformerFactory transformerFactory; private InterfaceContractMapper interfaceContractMapper; private BuilderExtensionPoint builders; + private Mediator mediator; public ComponentBuilderImpl(ExtensionPointRegistry registry) { UtilityExtensionPoint utilities = registry.getExtensionPoint(UtilityExtensionPoint.class); @@ -100,6 +119,7 @@ public class ComponentBuilderImpl { interfaceContractMapper = utilities.getUtility(InterfaceContractMapper.class); policyBuilder = new ComponentPolicyBuilderImpl(registry); builders = registry.getExtensionPoint(BuilderExtensionPoint.class); + mediator = new MediatorImpl(registry); } public void setComponentTypeBuilder(CompositeComponentTypeBuilderImpl componentTypeBuilder) { @@ -342,6 +362,9 @@ public class ComponentBuilderImpl { componentProperty.getName()); } + // check the property type + checkComponentPropertyType(component, componentProperty, monitor); + } } @@ -648,11 +671,104 @@ public class ComponentBuilderImpl { } } } + + /** + * checks that the component property value is correctly typed when compared with + * the type specified in the composite file property + * + * TODO - Don't yet handle multiplicity + * Need to check composite properties also + * + * @param component + * @param componentProperty + * @param monitor + */ + private void checkComponentPropertyType(Component component, ComponentProperty componentProperty, Monitor monitor) { + + QName propertyXSDType = componentProperty.getXSDType(); + QName propertyElementType = componentProperty.getXSDElement(); + + if (propertyXSDType != null){ + if (propertyXSDType.getNamespaceURI().equals("http://www.w3.org/2001/XMLSchema")) { + // The property has a simple schema type so we can uses the + // data binding framework to see if the XML value can be transformed + // into a simple Java value + Document source = (Document)componentProperty.getValue(); + DataType<XMLType> sourceDataType = new DataTypeImpl<XMLType>(DOMDataBinding.NAME, + Node.class, + new XMLType(null, componentProperty.getXSDType())); + DataType<XMLType> targetDataType = new DataTypeImpl<XMLType>(JAXBDataBinding.NAME, + Object.class, + new XMLType(null, componentProperty.getXSDType())); + try { + mediator.mediate(source, sourceDataType, targetDataType, null); + } catch (Exception ex){ + Monitor.error(monitor, + this, + Messages.ASSEMBLY_VALIDATION, + "PropertyValueDoesNotMatchSimpleType", + componentProperty.getName(), + component.getName(), + componentProperty.getXSDType().toString()); + } + } else { + // The property has a complex schema type so we fluff up a schema + // and use that to validate the property value + XSDefinition xsdDefinition = (XSDefinition)componentProperty.getXSDDefinition(); + + if (xsdDefinition != null) { + try { + // create schema factory for XML schema + SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + + Document schemaDom = xsdDefinition.getSchema().getSchemaDocument(); + + String valueSchema = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> " + + "<schema xmlns=\"http://www.w3.org/2001/XMLSchema\" "+ + "xmlns:sca=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" "+ + "xmlns:__tmp=\"" + componentProperty.getXSDType().getNamespaceURI() + "\" "+ + "targetNamespace=\"http://docs.oasis-open.org/ns/opencsa/sca/200912\" " + + "elementFormDefault=\"qualified\">" + + "<import namespace=\"" + componentProperty.getXSDType().getNamespaceURI() + "\"/>" + + "<element name=\"value\" type=\"" + "__tmp:" + componentProperty.getXSDType().getLocalPart() + "\"/>" + + "</schema>"; + + Source sources[] = {new DOMSource(schemaDom), new StreamSource(new StringReader(valueSchema))}; + + // create a schema for the property based on all the DOMs from the schema collection + // of the namspace of the property type + // TODO - only getting the top level document here + Schema schema = factory.newSchema(sources); + + // get the value child of the property element + Document property = (Document)componentProperty.getValue(); + Element value = (Element)property.getDocumentElement().getFirstChild(); + + // validate the element property/value from the DOM + Validator validator = schema.newValidator(); + validator.validate(new DOMSource(value)); + + } catch (Exception e) { + Monitor.error(monitor, + this, + Messages.ASSEMBLY_VALIDATION, + "PropertyValueDoesNotMatchComplexType", + componentProperty.getName(), + component.getName(), + componentProperty.getXSDType().toString(), + e.getMessage()); + } + } + } + } else if (propertyElementType != null) { + // TODO - TUSCANY-3530 - still need to add validation for element type + + } + } /** * If the property has a source attribute use this to retrieve the value from a * property in the parent composite - * * @param parentCompoent the composite that contains the component * @param component @@ -708,7 +824,8 @@ public class ComponentBuilderImpl { Messages.ASSEMBLY_VALIDATION, "PropertyXpathExpressionReturnedNull", component.getName(), - componentProperty.getName()); + componentProperty.getName(), + componentProperty.getSource()); } } catch (Exception ex) { Monitor.error(monitor, @@ -762,9 +879,21 @@ public class ComponentBuilderImpl { // TUSCANY-2377, Add a fake value element so it's consistent with // the DOM tree loaded from inside SCDL - Element root = document.createElementNS(null, "value"); - root.appendChild(document.getDocumentElement()); - document.appendChild(root); + 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); + } + componentProperty.setValue(document); } finally { if (is != null) { @@ -1050,11 +1179,11 @@ public class ComponentBuilderImpl { return false; } - if (value.getFirstChild() == null) { + if (value.getDocumentElement() == null) { return false; } - if (value.getFirstChild().getChildNodes().getLength() == 0) { + if (value.getDocumentElement().getChildNodes().getLength() == 0) { return false; } @@ -1071,7 +1200,7 @@ public class ComponentBuilderImpl { if (isPropertyValueSet(property)){ Document value = (Document)property.getValue(); - if (value.getFirstChild().getChildNodes().getLength() > 1){ + if (value.getDocumentElement().getChildNodes().getLength() > 1){ return true; } } diff --git a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java index 635375a4ed..cf01ede748 100644 --- a/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java +++ b/sca-java-2.x/trunk/modules/implementation-java/src/main/java/org/apache/tuscany/sca/implementation/java/introspect/impl/AbstractPropertyProcessor.java @@ -23,6 +23,8 @@ import java.lang.annotation.ElementType; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.Collection; import java.util.List; import java.util.Map; @@ -35,6 +37,7 @@ import org.apache.tuscany.sca.implementation.java.JavaImplementation; import org.apache.tuscany.sca.implementation.java.JavaParameterImpl; import org.apache.tuscany.sca.implementation.java.introspect.BaseJavaClassVisitor; import org.apache.tuscany.sca.implementation.java.introspect.JavaIntrospectionHelper; +import org.apache.tuscany.sca.interfacedef.util.JavaXMLMapper; /** * Base class for ImplementationProcessors that handle annotations that add @@ -206,6 +209,12 @@ public abstract class AbstractPropertyProcessor<A extends Annotation> extends Ba Class<?> javaType = element.getType(); if (javaType.isArray() || Collection.class.isAssignableFrom(javaType)) { property.setMany(true); + Type type = element.getGenericType(); + if (type instanceof ParameterizedType){ + property.setXSDType(JavaXMLMapper.getXMLType((Class)((ParameterizedType)type).getActualTypeArguments()[0])); + } + } else { + property.setXSDType(JavaXMLMapper.getXMLType(javaType)); } return property; |