Author: bdaniel
Date: Tue Jun 22 15:25:22 2010
New Revision: 956919

URL: http://svn.apache.org/viewvc?rev=956919&view=rev
Log:
Support policy XPath functions without ns prefixes and without a single node 
context

Modified:
    
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
    
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
    
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java

Modified: 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java?rev=956919&r1=956918&r2=956919&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicySetProcessor.java
 Tue Jun 22 15:25:22 2010
@@ -164,7 +164,7 @@ public class PolicySetProcessor extends 
                 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);

Modified: 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java?rev=956919&r1=956918&r2=956919&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/main/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunction.java
 Tue Jun 22 15:25:22 2010
@@ -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 impleme
 
         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 impleme
         }
     }
 
-    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 impleme
         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 impleme
                                        // 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 impleme
     /** 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 impleme
             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 impleme
                 matcher.appendReplacement(sb, replacement);
                 result = matcher.find();
             } while (result);
+            
             matcher.appendTail(sb);
             return sb.toString();
         }

Modified: 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
URL: 
http://svn.apache.org/viewvc/tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java?rev=956919&r1=956918&r2=956919&view=diff
==============================================================================
--- 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
 (original)
+++ 
tuscany/sca-java-2.x/trunk/modules/assembly-xml/src/test/java/org/apache/tuscany/sca/policy/xml/PolicyXPathFunctionResolverTestCase.java
 Tue Jun 22 15:25:22 2010
@@ -57,8 +57,8 @@ public class PolicyXPathFunctionResolver
     @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 PolicyXPathFunctionResolver
     }
     
     @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 PolicyXPathFunctionResolver
     @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 PolicyXPathFunctionResolver
     @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;


Reply via email to