You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by ro...@apache.org on 2008/05/13 21:49:36 UTC

svn commit: r655988 - /webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java

Author: rott
Date: Tue May 13 12:49:36 2008
New Revision: 655988

URL: http://svn.apache.org/viewvc?rev=655988&view=rev
Log:
AXIS2-3772:  make use of regular expressions instead of rolling our own matching algorithm for handler chain configuration file

Modified:
    webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java

Modified: webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java
URL: http://svn.apache.org/viewvc/webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java?rev=655988&r1=655987&r2=655988&view=diff
==============================================================================
--- webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java (original)
+++ webservices/axis2/trunk/java/modules/jaxws/src/org/apache/axis2/jaxws/spi/handler/BaseHandlerResolver.java Tue May 13 12:49:36 2008
@@ -37,6 +37,8 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * This class can be subclassed to produce different implementations of {@link HandlerResolver}
@@ -117,179 +119,51 @@
     private static boolean doesPatternMatch(QName portInfoQName, QName pattern) {
         if (pattern == null)
             return true;
-        String portInfoString = portInfoQName.toString();
-        String patternString = pattern.toString();
-        if (patternString.equals("*"))
-            return true;
-        if (patternString.contains("*")) {
-            return match(patternString, portInfoString, false);
-        }
-        return portInfoString.equals(patternString);
+        // build up the strings according to the regular expression defined at http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd
+        String portInfoNamespaceURI = portInfoQName.getNamespaceURI();
+        String portInfoLocalPart = portInfoQName.getLocalPart();
+        String portInfoString = ((portInfoNamespaceURI == null) || (portInfoNamespaceURI.equals(""))) ? "" : portInfoNamespaceURI + ":";
+        portInfoString += portInfoLocalPart;
         
-    }
-    
-    /**
-     * Matches a string against a pattern. The pattern contains two special
-     * characters:
-     * '*' which means zero or more characters,
-     *
-     * @param pattern the (non-null) pattern to match against
-     * @param str     the (non-null) string that must be matched against the
-     *                pattern
-     * @param isCaseSensitive
-     *
-     * @return <code>true</code> when the string matches against the pattern,
-     *         <code>false</code> otherwise.
-     */
-    private static boolean match(String pattern, String str,
-                                   boolean isCaseSensitive) {
-
-        char[] patArr = pattern.toCharArray();
-        char[] strArr = str.toCharArray();
-        int patIdxStart = 0;
-        int patIdxEnd = patArr.length - 1;
-        int strIdxStart = 0;
-        int strIdxEnd = strArr.length - 1;
-        char ch;
-        boolean containsStar = false;
-
-        for (int i = 0; i < patArr.length; i++) {
-            if (patArr[i] == '*') {
-                containsStar = true;
-                break;
-            }
-        }
-        if (!containsStar) {
-
-            // No '*'s, so we make a shortcut
-            if (patIdxEnd != strIdxEnd) {
-                return false;        // Pattern and string do not have the same size
-            }
-            for (int i = 0; i <= patIdxEnd; i++) {
-                ch = patArr[i];
-                if (isCaseSensitive && (ch != strArr[i])) {
-                    return false;    // Character mismatch
-                }
-                if (!isCaseSensitive
-                        && (Character.toUpperCase(ch)
-                        != Character.toUpperCase(strArr[i]))) {
-                    return false;    // Character mismatch
-                }
-            }
-            return true;             // String matches against pattern
-        }
-        if (patIdxEnd == 0) {
-            return true;    // Pattern contains only '*', which matches anything
-        }
-
-        // Process characters before first star
-        while ((ch = patArr[patIdxStart]) != '*'
-                && (strIdxStart <= strIdxEnd)) {
-            if (isCaseSensitive && (ch != strArr[strIdxStart])) {
-                return false;    // Character mismatch
-            }
-            if (!isCaseSensitive
-                    && (Character.toUpperCase(ch)
-                    != Character.toUpperCase(strArr[strIdxStart]))) {
-                return false;    // Character mismatch
-            }
-            patIdxStart++;
-            strIdxStart++;
-        }
-        if (strIdxStart > strIdxEnd) {
+        String patternStringNamespaceURI = pattern.getNamespaceURI();
+        String patternInfoLocalPart = pattern.getLocalPart();
+        String patternString = ((patternStringNamespaceURI == null) || (patternStringNamespaceURI.equals(""))) ? "" : patternStringNamespaceURI + ":";
+        patternString += patternInfoLocalPart;
 
-            // All characters in the string are used. Check if only '*'s are
-            // left in the pattern. If so, we succeeded. Otherwise failure.
-            for (int i = patIdxStart; i <= patIdxEnd; i++) {
-                if (patArr[i] != '*') {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        // Process characters after last star
-        while ((ch = patArr[patIdxEnd]) != '*' && (strIdxStart <= strIdxEnd)) {
-            if (isCaseSensitive && (ch != strArr[strIdxEnd])) {
-                return false;    // Character mismatch
-            }
-            if (!isCaseSensitive
-                    && (Character.toUpperCase(ch)
-                    != Character.toUpperCase(strArr[strIdxEnd]))) {
-                return false;    // Character mismatch
-            }
-            patIdxEnd--;
-            strIdxEnd--;
-        }
-        if (strIdxStart > strIdxEnd) {
-
-            // All characters in the string are used. Check if only '*'s are
-            // left in the pattern. If so, we succeeded. Otherwise failure.
-            for (int i = patIdxStart; i <= patIdxEnd; i++) {
-                if (patArr[i] != '*') {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        // process pattern between stars. padIdxStart and patIdxEnd point
-        // always to a '*'.
-        while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
-            int patIdxTmp = -1;
-
-            for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
-                if (patArr[i] == '*') {
-                    patIdxTmp = i;
-                    break;
-                }
-            }
-            if (patIdxTmp == patIdxStart + 1) {
-
-                // Two stars next to each other, skip the first one.
-                patIdxStart++;
-                continue;
-            }
-
-            // Find the pattern between padIdxStart & padIdxTmp in str between
-            // strIdxStart & strIdxEnd
-            int patLength = (patIdxTmp - patIdxStart - 1);
-            int strLength = (strIdxEnd - strIdxStart + 1);
-            int foundIdx = -1;
-
-            strLoop:
-            for (int i = 0; i <= strLength - patLength; i++) {
-                for (int j = 0; j < patLength; j++) {
-                    ch = patArr[patIdxStart + j + 1];
-                    if (isCaseSensitive
-                            && (ch != strArr[strIdxStart + i + j])) {
-                        continue strLoop;
-                    }
-                    if (!isCaseSensitive && (Character
-                            .toUpperCase(ch) != Character
-                            .toUpperCase(strArr[strIdxStart + i + j]))) {
-                        continue strLoop;
-                    }
-                }
-                foundIdx = strIdxStart + i;
-                break;
-            }
-            if (foundIdx == -1) {
-                return false;
-            }
-            patIdxStart = patIdxTmp;
-            strIdxStart = foundIdx + patLength;
-        }
+        /*
+         * Below pattern is ported from:  http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd
+         * Schema regular expressions are defined differently from Java regular expressions which are different from Perl regular
+         * expressions.  I've converted the pattern defined in the above linked schema to its Java equivalent, as best as I can.
+         * 
+         * Schema reg ex:  "\*|([\i-[:]][\c-[:]]*:)?[\i-[:]][\c-[:]]*\*?"
+         * Java reg ex:  "\\*|((\\w|_)(\\w|\\.|-|_)*:)?(\\w|_)(\\w|\\.|-|_)*\\*?"
+         */
 
-        // All characters in the string are used. Check if only '*'s are left
-        // in the pattern. If so, we succeeded. Otherwise failure.
-        for (int i = patIdxStart; i <= patIdxEnd; i++) {
-            if (patArr[i] != '*') {
-                return false;
+        // first, confirm the defined pattern is legal
+        Pattern p = Pattern.compile("\\*|((\\w|_)(\\w|\\.|-|_)*:)?(\\w|_)(\\w|\\.|-|_)*\\*?");
+        Matcher m = p.matcher(patternString);
+        if (!m.matches()) {
+            // pattern defined by user in handler chain xml file is illegal -- report it but continue
+            log.warn("Pattern defined by user is illegal:  \"" + patternString + "\" does not match regular expression in schema http://java.sun.com/xml/ns/javaee/javaee_web_services_1_2.xsd.  Pattern matching should now be considered \"best-effort.\"");
+        }
+        // now match the portInfoQName to the user pattern
+        // But first, convert the user pattern to a regular expression.  Remember, the only non-QName character allowed is "*", which
+        // is a wildcard, with obvious restrictions on what characters can match (for example, a .java filename cannot contain perentheses).
+        // We'll just use part of the above reg ex to form the appropriate restrictions on the user-specified "*" character:
+        Pattern userp = Pattern.compile(patternString.replace("*", "(\\w|\\.|-|_)*"));
+        Matcher userm = userp.matcher(portInfoString);
+        boolean match = userm.matches();
+        if (log.isDebugEnabled()) {
+            if (!match) {
+                log.debug("Pattern match failed: \"" + portInfoString + "\" does not match \"" + patternString + "\"");
+            } else {
+                log.debug("Pattern match succeeded: \"" + portInfoString + "\" matches \"" + patternString + "\"");
             }
         }
-        return true;
+        return match;
+        
     }
+    
 
     /**
      * Return the class for this name



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-cvs-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-cvs-help@ws.apache.org