You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by rr...@apache.org on 2010/05/07 19:15:57 UTC

svn commit: r942153 - in /ode/branches/APACHE_ODE_1.X/bpel-compiler/src: main/java/org/apache/ode/bpel/elang/xpath20/compiler/ test/java/org/apache/ode/bpel/elang/xpath20/compiler/

Author: rr
Date: Fri May  7 17:15:56 2010
New Revision: 942153

URL: http://svn.apache.org/viewvc?rev=942153&view=rev
Log:
ODE-807: Infinite Loop when locating unresolved functions in XPath expression (fix), thanks to David Carver

Added:
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java   (with props)
Modified:
    ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java

Modified: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java?rev=942153&r1=942152&r2=942153&view=diff
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java (original)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/main/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImpl.java Fri May  7 17:15:56 2010
@@ -20,9 +20,12 @@
 package org.apache.ode.bpel.elang.xpath20.compiler;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.xml.namespace.QName;
 import javax.xml.transform.TransformerFactory;
@@ -251,60 +254,19 @@ public class XPath20ExpressionCompilerIm
      * @return list of function expressions that may not have been resolved properly
      */
     private List<String> extractFunctionExprs(String xpathStr) {    	
-		ArrayList<String> functionExprs = new ArrayList<String>();
+		ArrayList<String> functionExprs = new ArrayList<String>(); 
+		// Match the prefix : function name ( all contents except the ) and the closing )'s that may occur
+		final String FUNCTION_REGEX = "\\w+:\\w+\\([.[^\\)]]*\\)*";
 		int firstFunction = xpathStr.indexOf("("), 
 			lastFunction = xpathStr.lastIndexOf("("); 
-		StringBuffer functionExpr = new StringBuffer();
-		if ((firstFunction > 0 && // the xpath contains a function
-				firstFunction < lastFunction)) { // the xpath references multiple variables 
-			// most likely, the variable reference has not been resolved, so make that happen
-			boolean quoted = false, doubleQuoted = false, function = false, arguments = false;
-			Name11Checker nameChecker = Name11Checker.getInstance();
-			for (int index = firstFunction; index < xpathStr.length(); index++) {
-				if (!function) {
-					int colonIndex = xpathStr.indexOf(':', index);
-					if (colonIndex == -1) {
-						break;
-					}
-					while (colonIndex >= 0 && nameChecker.isNCNameChar(xpathStr.charAt(--colonIndex)));
-					if (xpathStr.charAt(colonIndex) == '$') {
-						index = xpathStr.indexOf(':', index) + 1;
-						continue;
-					}
-					function = true;
-					arguments = false;
-					functionExpr.setLength(0);
-					index = colonIndex;
-					continue;
-				}
-				char ch = xpathStr.charAt(index);
-				if (function) {
-					functionExpr.append(ch);
-					// in the name is qualified, don't check if its a qname when we're at the ":" character
-					if (ch == ':') {
-						continue;
-					} else if (ch == '(') {
-						if (nameChecker.isQName(functionExpr.substring(0, functionExpr.length() - 1))) {
-							arguments = true;
-						} else {
-							function = false;
-							continue;
-						}
-					} else if (ch == ')') {
-						if (arguments) {
-							function = false;
-							functionExprs.add(functionExpr.toString());
-							functionExpr.setLength(0);							
-						}
-					} else {
-						if (!arguments) {
-							if (!nameChecker.isQName(functionExpr.substring(0, functionExpr.length()))) {
-								function = false;
-							}
-						}
-					}
-				}
-			}
+		if ((firstFunction > 0 && firstFunction < lastFunction)) {
+	        Pattern regex = Pattern.compile(FUNCTION_REGEX);
+	        Matcher matcher = regex.matcher(xpathStr);
+	        
+	        while (matcher.find()) {
+	            String function = matcher.group();
+	            functionExprs.add(function);
+	        }
 		}
 		return functionExprs;
 	}

Added: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
URL: http://svn.apache.org/viewvc/ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java?rev=942153&view=auto
==============================================================================
--- ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java (added)
+++ ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java Fri May  7 17:15:56 2010
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ode.bpel.elang.xpath20.compiler;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.junit.*;
+
+
+public class XPath20ExpressionCompilerImplTest {
+    
+    private static final String TEST_NAMESPACE = "http://www.example.com/";
+    private static final String EXTRACT_FUNCTION_EXPRS = "extractFunctionExprs";
+
+    @Test
+    public void testresolvedFunctionsExpr() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "count(count(1))" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(0, values.size());
+            }
+        }
+    }
+    
+    @Test
+    public void testTimeStampInFunction() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "concat(xs:concat(\"P\", \"08:30:00.000+08:00\"))" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(1, values.size());
+            }
+        }
+
+    }
+    
+    @Test
+    public void testresolvedFunctionsTimeStamp() throws Exception {
+        XPath20ExpressionCompilerImpl xp20Exp = new XPath20ExpressionCompilerImpl(TEST_NAMESPACE);
+        final Method[] methods =
+            xp20Exp.getClass().getDeclaredMethods();
+        for (int i = 0; i < methods.length; ++i) {
+            if (methods[i].getName().equals(EXTRACT_FUNCTION_EXPRS)) {
+                final Object params[] = { "concat(current-date() + xs:dayTimeDuration(concat(\"P\", $DAYS_TO_NEXT_REMINDER, \"D\")), \"T\", \"08:30:00.000+08:00\")" };
+                methods[i].setAccessible(true);
+                Object ret = methods[i].invoke(xp20Exp, params);
+                List<?> values = (List<?>) ret;
+                Assert.assertEquals(1, values.size());
+                Assert.assertEquals("Unexpected Function value", "xs:dayTimeDuration(concat(\"P\", $DAYS_TO_NEXT_REMINDER, \"D\"))", (String)values.get(0));
+            }
+        }
+    }
+    
+    
+    
+
+}

Propchange: ode/branches/APACHE_ODE_1.X/bpel-compiler/src/test/java/org/apache/ode/bpel/elang/xpath20/compiler/XPath20ExpressionCompilerImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native