diff options
Diffstat (limited to 'java/sca')
2 files changed, 107 insertions, 18 deletions
diff --git a/java/sca/modules/policy-builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentBuilderImpl.java b/java/sca/modules/policy-builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentBuilderImpl.java index e2550c1e88..e579d4b897 100644 --- a/java/sca/modules/policy-builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentBuilderImpl.java +++ b/java/sca/modules/policy-builder/src/main/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentBuilderImpl.java @@ -19,9 +19,16 @@ package org.apache.tuscany.sca.policy.builder.impl; +import static javax.xml.XMLConstants.DEFAULT_NS_PREFIX; +import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE; +import static javax.xml.XMLConstants.XMLNS_ATTRIBUTE_NS_URI; + import java.io.StringWriter; +import java.util.StringTokenizer; +import javax.xml.namespace.QName; import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamReader; import javax.xml.stream.XMLStreamWriter; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; @@ -39,8 +46,9 @@ import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.definitions.Definitions; import org.apache.tuscany.sca.monitor.Monitor; import org.apache.tuscany.sca.policy.PolicySet; -import org.apache.tuscany.sca.policy.PolicySubject; +import org.w3c.dom.Attr; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -74,13 +82,22 @@ public class PolicyAttachmentBuilderImpl implements CompositeBuilder { public void build(Composite composite, Definitions definitions, Monitor monitor) throws CompositeBuilderException { try { - applyXPath(composite, definitions, monitor); + Composite patched = applyXPath(composite, definitions, monitor); + System.out.println(patched); } catch (Exception e) { throw new CompositeBuilderException(e); } } - private void applyXPath(Composite composite, Definitions definitions, Monitor monitor) throws Exception { + /** + * Apply the attachTo XPath against the composite model + * @param composite The orginal composite + * @param definitions SCA definitions that contain the policy sets + * @param monitor The monitor + * @return A reloaded composite + * @throws Exception + */ + private Composite applyXPath(Composite composite, Definitions definitions, Monitor monitor) throws Exception { // First write the composite into a DOM document so that we can apply the xpath StringWriter sw = new StringWriter(); XMLStreamWriter writer = staxHelper.createXMLStreamWriter(sw); @@ -90,6 +107,7 @@ public class PolicyAttachmentBuilderImpl implements CompositeBuilder { Document document = domHelper.load(sw.toString()); + boolean changed = false; for (PolicySet ps : definitions.getPolicySets()) { XPathExpression exp = ps.getAttachToXPathExpression(); if (exp != null) { @@ -97,21 +115,98 @@ public class PolicyAttachmentBuilderImpl implements CompositeBuilder { for (int i = 0; i < nodes.getLength(); i++) { Node node = nodes.item(i); // The node can be a component, service, reference or binding - node.getNamespaceURI(); - // Use the node to find the corresponding element in the java model + if (attach(node, ps) && !changed) { + changed = true; + } } } } + + if (changed) { + XMLStreamReader reader = staxHelper.createXMLStreamReader(document); + reader.nextTag(); + Composite patchedComposite = (Composite)processor.read(reader); + return patchedComposite; + } else { + return composite; + } } /** - * Look up the corresponding Java model within the composite based on the DOM node - * @param composite - * @param node - * @return + * Attach the policySet to the given DOM node + * @param node The DOM node (should be an element) + * @param policySet The policy set to be attached + * @return true if the element is changed, false if the element already contains the same policy set + * and no change is made */ - private PolicySubject lookup(Composite composite, Node node) { - return null; + private boolean attach(Node node, PolicySet policySet) { + Element element = (Element)node; + Document document = element.getOwnerDocument(); + + QName qname = policySet.getName(); + String prefix = DOMHelper.getPrefix(element, qname.getNamespaceURI()); + if (prefix == null) { + // Find the a non-conflicting prefix + int i = 0; + while (true) { + prefix = "ns" + i; + String ns = DOMHelper.getNamespaceURI(element, prefix); + if (ns == null) { + break; + } + } + // Declare the namespace + Attr nsAttr = document.createAttributeNS(XMLNS_ATTRIBUTE_NS_URI, XMLNS_ATTRIBUTE + ":" + prefix); + nsAttr.setValue(qname.getNamespaceURI()); + element.setAttributeNodeNS(nsAttr); + } + // Form the value as a qualified name + String qvalue = null; + if (DEFAULT_NS_PREFIX.equals(prefix)) { + qvalue = qname.getLocalPart(); + } else { + qvalue = prefix + ":" + qname.getLocalPart(); + } + + // Check if the attribute exists + Attr attr = element.getAttributeNode("policySets"); + if (attr == null) { + // Create the policySets attr + attr = document.createAttributeNS(null, "policySets"); + attr.setValue(qvalue); + element.setAttributeNodeNS(attr); + return true; + } else { + // Append to the existing value + boolean duplicate = false; + String value = attr.getValue(); + StringTokenizer tokenizer = new StringTokenizer(value); + while (tokenizer.hasMoreTokens()) { + String ps = tokenizer.nextToken(); + int index = ps.indexOf(':'); + String ns = null; + String localName = null; + if (index == -1) { + ns = DOMHelper.getNamespaceURI(element, DEFAULT_NS_PREFIX); + localName = ps; + } else { + ns = DOMHelper.getNamespaceURI(element, ps.substring(0, index)); + localName = ps.substring(index + 1); + } + QName psName = new QName(ns, localName); + if (qname.equals(psName)) { + duplicate = true; + break; + } + } + if (!duplicate) { + // REVIEW: [rfeng] How to comply to POL40012? + value = value + " " + qvalue; + attr.setValue(value.trim()); + return true; + } + return false; + } } } diff --git a/java/sca/modules/policy-builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentTestCase.java b/java/sca/modules/policy-builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentTestCase.java index d2c3f4eeec..d8c39ae65e 100644 --- a/java/sca/modules/policy-builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentTestCase.java +++ b/java/sca/modules/policy-builder/src/test/java/org/apache/tuscany/sca/policy/builder/impl/PolicyAttachmentTestCase.java @@ -19,18 +19,13 @@ package org.apache.tuscany.sca.policy.builder.impl; -import java.io.IOException; import java.io.InputStream; import java.net.URL; -import javax.xml.stream.FactoryConfigurationError; 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.assembly.builder.CompositeBuilderException; -import org.apache.tuscany.sca.contribution.processor.ContributionReadException; import org.apache.tuscany.sca.contribution.processor.ExtensibleStAXArtifactProcessor; import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessor; import org.apache.tuscany.sca.contribution.processor.StAXArtifactProcessorExtensionPoint; @@ -53,8 +48,7 @@ public class PolicyAttachmentTestCase { private Monitor monitor; @Test - public void testBuild() throws FactoryConfigurationError, IOException, XMLStreamException, - ContributionReadException, CompositeBuilderException { + public void testBuild() throws Exception { DefaultExtensionPointRegistry extensionPoints = new DefaultExtensionPointRegistry(); XMLInputFactory inputFactory = XMLInputFactory.newInstance(); // Create a monitor |