summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68>2010-06-22 15:25:22 +0000
committerbdaniel <bdaniel@13f79535-47bb-0310-9956-ffa450edef68>2010-06-22 15:25:22 +0000
commit5eb8043a5abd44f4df8bdd7de099b45a12a251fe (patch)
tree2f63501c0cc05a90229564a1cbcdd632f3ff52bd
parent49e45e8c838b1b822c2e34aa50491ed9bd523d08 (diff)
Support policy XPath functions without ns prefixes and without a single node context
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@956919 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java2
-rw-r--r--sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java87
-rw-r--r--sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java35
3 files changed, 110 insertions, 14 deletions
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
index 454f382575..ee3fa5a7fc 100644
--- a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
+++ b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
@@ -164,7 +164,7 @@ public class PolicySetProcessor extends BaseStAXArtifactProcessor implements StA
NamespaceContext nsContext = xpathHelper.getNamespaceContext(attachTo, reader.getNamespaceContext());
path.setXPathFunctionResolver(new PolicyXPathFunctionResolver(nsContext));
- attachTo = PolicyXPathFunction.normalize(attachTo);
+ attachTo = PolicyXPathFunction.normalize(attachTo,nsContext.getPrefix(SCA11_NS));
XPathExpression expression = xpathHelper.compile(path, nsContext, attachTo);
policySet.setAttachTo(attachTo);
policySet.setAttachToXPathExpression(expression);
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
index aa27c41e5c..b6ed79c3c2 100644
--- a/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
+++ b/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
@@ -19,6 +19,7 @@
package org.apache.tuscany.sca.policy.xml;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -78,6 +79,22 @@ public class PolicyXPathFunction implements XPathFunction {
String arg = (String)args.get(0);
Node node = getContextNode(args);
+ /**
+ * If the xpath expression that contains the function does not select any nodes
+ * (eg IntentRefs('someIntent')), the context node passed in will be a Document.
+ * In this case we need to iterate over every Node in the Document and evaluate it.
+ *
+ * If the xpath expression does select nodes (eg //sca:component[IntentRefs('someIntent')])
+ * then xpath will call evaluate for each node and we only need to return the result for that
+ * node.
+ */
+ if ( node instanceof Document )
+ return evaluateDocument(arg, (Document)node);
+ else
+ return evaluateNode(arg, node);
+ }
+
+ public Object evaluateNode(String arg, Node node) {
if (InterfaceRef.equals(functionName)) {
return evaluateInterface(arg, node);
} else if (OperationRef.equals(functionName)) {
@@ -107,7 +124,38 @@ public class PolicyXPathFunction implements XPathFunction {
}
}
- private Boolean evaluateInterface(String interfaceName, Node node) {
+ private class NodeListImpl implements NodeList {
+
+ private ArrayList<Node> list;
+
+ public NodeListImpl() {
+ this.list = new ArrayList<Node>();
+ }
+ public int getLength() {
+ return this.list.size();
+ }
+
+ public Node item(int index) {
+ return this.list.get(index);
+ }
+ public boolean add(Node node) {
+ return this.list.add(node);
+
+ }
+
+ }
+ private Object evaluateDocument(String arg, Document doc) {
+ NodeListImpl retList = new NodeListImpl();
+ NodeList elements = doc.getElementsByTagName("*");
+ for ( int i=0; i < elements.getLength(); i++) {
+ Object node = evaluateNode(arg, elements.item(i));
+ if ( node != null )
+ retList.add((Node)node);
+ }
+ return retList;
+ }
+
+ private Boolean evaluateInterface(String interfaceName, Node node) {
return Boolean.FALSE;
}
@@ -123,9 +171,16 @@ public class PolicyXPathFunction implements XPathFunction {
return Boolean.FALSE;
}
- private Boolean evaluateIntents(String[] intents, Node node) {
+ /**
+ * Evaluates a single node for the given intents.
+ * @param intents
+ * @param node
+ * @return
+ */
+ private Object evaluateIntents(String[] intents, Node node) {
if ( node == null )
return false;
+
if ( node.getAttributes() != null ) {
for ( int i=0; i < node.getAttributes().getLength(); i++) {
Node attr = node.getAttributes().item(i);
@@ -136,21 +191,30 @@ public class PolicyXPathFunction implements XPathFunction {
// Check negative intents
if ( intents[j].startsWith("!")) {
if ( matchIntent(intents[j].substring(1), attr, node.getNamespaceURI()))
- return Boolean.FALSE;
+ return null;
} else if ( !matchIntent(intents[j], attr, node.getNamespaceURI())){
- return Boolean.FALSE;
+ return null;
}
}
- return Boolean.TRUE;
+ return node;
}
}
}
- return Boolean.FALSE;
+ return null;
}
- private boolean matchIntent(String intent, Node node, String namespaceURI) {
+
+
+ /**
+ * Determine whether the given intent is present in the "requires" attribute
+ * @param intent
+ * @param node
+ * @param namespaceURI
+ * @return
+ */
+ private boolean matchIntent(String intent, Node node, String namespaceURI) {
String[] requires = node.getNodeValue().split("(\\s)+");
QName intentName = getStringAsQName(intent);
@@ -197,7 +261,10 @@ public class PolicyXPathFunction implements XPathFunction {
/** Adds the node as an argument to the XPath function.
* Required in order to have access to the NodeList within the function
*/
- public static String normalize(String attachTo) {
+ public static String normalize(String attachTo, String scaPrefix) {
+ // Get rid of any whitespace
+ attachTo = attachTo.trim();
+
Matcher matcher = FUNCTION.matcher(attachTo);
boolean result = matcher.find();
if (result) {
@@ -205,6 +272,9 @@ public class PolicyXPathFunction implements XPathFunction {
do {
String function = matcher.group(1);
String args = matcher.group(2);
+ if ( (matcher.start() == 0) || (attachTo.charAt( matcher.start() -1) != ':' )) {
+ function = scaPrefix + ":" + function;
+ }
String replacement = null;
if (args.trim().length() > 0) {
replacement = function + "(" + args + "," + "self::node())";
@@ -214,6 +284,7 @@ public class PolicyXPathFunction implements XPathFunction {
matcher.appendReplacement(sb, replacement);
result = matcher.find();
} while (result);
+
matcher.appendTail(sb);
return sb.toString();
}
diff --git a/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java b/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
index fdbdcec1c9..d2b0775361 100644
--- a/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
+++ b/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
@@ -57,8 +57,8 @@ public class PolicyXPathFunctionResolverTestCase {
@Test
public void testIntentsRef() throws Exception {
InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
- String str = "//sca:composite/sca:component[sca:IntentRefs('sca:confidentiality')]";
- str = normalize(str);
+ String str = "//sca:composite/sca:component[IntentRefs('sca:confidentiality')]";
+ str = normalize(str, "sca");
// Test the rewrite of xpath so that the self:node() is passed into the SCA function
XPathExpression exp = xpath.compile(str);
Object result = exp.evaluate(xml, XPathConstants.NODESET);
@@ -68,9 +68,34 @@ public class PolicyXPathFunctionResolverTestCase {
}
@Test
+ public void testIntentsRef2() throws Exception {
+ InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
+ String str = " //sca:composite/sca:component[sca:IntentRefs('sca:confidentiality')]";
+ str = normalize(str, "sca");
+ // Test the rewrite of xpath so that the self:node() is passed into the SCA function
+ XPathExpression exp = xpath.compile(str);
+ Object result = exp.evaluate(xml, XPathConstants.NODESET);
+ Assert.assertTrue(result instanceof NodeList);
+ NodeList nodes = (NodeList)result;
+ Assert.assertEquals(1, nodes.getLength());
+ }
+
+ @Test
+ public void testIntentsRef3() throws Exception {
+ InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
+ String str = " IntentRefs('sca:confidentiality') ";
+ str = normalize(str, "sca");
+ // Test the rewrite of xpath so that the self:node() is passed into the SCA function
+ XPathExpression exp = xpath.compile(str);
+ Object result = exp.evaluate(xml, XPathConstants.NODESET);
+ Assert.assertTrue(result instanceof NodeList);
+ NodeList nodes = (NodeList)result;
+ Assert.assertEquals(1, nodes.getLength());
+ }
+ @Test
public void testURIRef() throws Exception {
InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
- XPathExpression exp = xpath.compile(normalize("sca:composite/sca:component[sca:URIRef('AddServiceComponent')]"));
+ XPathExpression exp = xpath.compile(normalize("sca:composite/sca:component[sca:URIRef('AddServiceComponent')]","sca"));
Object result = exp.evaluate(xml, XPathConstants.NODESET);
Assert.assertTrue(result instanceof NodeList);
NodeList nodes = (NodeList)result;
@@ -80,7 +105,7 @@ public class PolicyXPathFunctionResolverTestCase {
@Test
public void testInterfaceRef() throws Exception {
InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
- XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:service[sca:InterfaceRef('AddService')]"));
+ XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:service[sca:InterfaceRef('AddService')]","sca"));
Object result = exp.evaluate(xml, XPathConstants.NODESET);
Assert.assertTrue(result instanceof NodeList);
NodeList nodes = (NodeList)result;
@@ -90,7 +115,7 @@ public class PolicyXPathFunctionResolverTestCase {
@Test
public void testOperationRef() throws Exception {
InputSource xml = new InputSource(getClass().getResourceAsStream("Calculator.composite"));
- XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:reference[sca:OperationRef('AddService/add')]"));
+ XPathExpression exp = xpath.compile(normalize("//sca:composite/sca:component/sca:reference[sca:OperationRef('AddService/add')]","sca"));
Object result = exp.evaluate(xml, XPathConstants.NODESET);
Assert.assertTrue(result instanceof NodeList);
NodeList nodes = (NodeList)result;