You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by cz...@apache.org on 2006/05/19 12:18:31 UTC

svn commit: r407763 - in /cocoon/trunk: blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/ blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/ core/c...

Author: cziegeler
Date: Fri May 19 03:18:29 2006
New Revision: 407763

URL: http://svn.apache.org/viewvc?rev=407763&view=rev
Log:
Move WildcardMatcher to util package

Added:
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java   (with props)
Modified:
    cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/UserRightsService.java
    cocoon/trunk/blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/JavaScriptAspectWeaver.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/bean/CocoonBean.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
    cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java

Modified: cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/UserRightsService.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/UserRightsService.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/UserRightsService.java (original)
+++ cocoon/trunk/blocks/cocoon-portal/cocoon-portal-impl/src/main/java/org/apache/cocoon/portal/tools/service/UserRightsService.java Fri May 19 03:18:29 2006
@@ -22,11 +22,11 @@
 import java.util.Properties;
 import java.util.StringTokenizer;
 
-import org.apache.cocoon.matching.helpers.WildcardHelper;
 import org.apache.cocoon.portal.profile.PortalUser;
 import org.apache.cocoon.portal.tools.helper.MultipleRoleMatcher;
 import org.apache.cocoon.portal.tools.helper.RoleMatcher;
 import org.apache.cocoon.portal.tools.helper.SingleRoleMatcher;
+import org.apache.cocoon.util.WildcardHelper;
 import org.apache.excalibur.source.Source;
 
 /**

Modified: cocoon/trunk/blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/JavaScriptAspectWeaver.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/JavaScriptAspectWeaver.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/JavaScriptAspectWeaver.java (original)
+++ cocoon/trunk/blocks/cocoon-scratchpad/cocoon-scratchpad-impl/src/main/java/org/apache/cocoon/components/flow/javascript/fom/JavaScriptAspectWeaver.java Fri May 19 03:18:29 2006
@@ -37,9 +37,9 @@
 import org.apache.avalon.framework.service.ServiceException;
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
+import org.apache.cocoon.util.WildcardHelper;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
 
 
 /**

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/bean/CocoonBean.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/bean/CocoonBean.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/bean/CocoonBean.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/bean/CocoonBean.java Fri May 19 03:18:29 2006
@@ -23,7 +23,7 @@
 import org.apache.cocoon.components.notification.Notifier;
 import org.apache.cocoon.components.notification.DefaultNotifyingBuilder;
 import org.apache.cocoon.components.notification.Notifying;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.WildcardHelper;
 import org.apache.commons.lang.SystemUtils;
 
 import org.apache.excalibur.source.ModifiableSource;

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/AbstractClassLoaderFactory.java Fri May 19 03:18:29 2006
@@ -29,7 +29,7 @@
 import org.apache.avalon.framework.service.ServiceManager;
 import org.apache.avalon.framework.service.Serviceable;
 import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.WildcardHelper;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.excalibur.source.TraversableSource;

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/components/classloader/DefaultClassLoader.java Fri May 19 03:18:29 2006
@@ -20,7 +20,7 @@
 import java.net.URLClassLoader;
 import java.net.URLStreamHandlerFactory;
 
-import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.WildcardHelper;
 
 /**
  * @version $Id$

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/core/container/spring/ConfigReader.java Fri May 19 03:18:29 2006
@@ -30,7 +30,7 @@
 import org.apache.cocoon.components.source.SourceUtil;
 import org.apache.cocoon.core.container.util.ConfigurationBuilder;
 import org.apache.cocoon.core.container.util.SimpleSourceResolver;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
+import org.apache.cocoon.util.WildcardHelper;
 import org.apache.excalibur.source.Source;
 import org.apache.excalibur.source.SourceResolver;
 import org.apache.excalibur.source.TraversableSource;

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/AbstractWildcardMatcher.java Fri May 19 03:18:29 2006
@@ -17,9 +17,9 @@
 
 import org.apache.avalon.framework.parameters.Parameters;
 import org.apache.avalon.framework.thread.ThreadSafe;
-import org.apache.cocoon.matching.helpers.WildcardHelper;
 import org.apache.cocoon.sitemap.PatternException;
 import org.apache.cocoon.sitemap.SitemapParameters;
+import org.apache.cocoon.util.WildcardHelper;
 
 import java.util.HashMap;
 import java.util.Map;

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/matching/helpers/WildcardHelper.java Fri May 19 03:18:29 2006
@@ -20,361 +20,24 @@
 /**
  * This class is an utility class that perform wilcard-patterns matching and
  * isolation.
- *
+ * @deprecated This class has moved to the o.a.c.util package.
  * @version $Id$
  */
 public class WildcardHelper {
 
-    /** The int representing '*' in the pattern <code>int []</code>. */
-    protected static final int MATCH_FILE = -1;
-    /** The int representing '**' in the pattern <code>int []</code>. */
-    protected static final int MATCH_PATH = -2;
-    /** The int representing begin in the pattern <code>int []</code>. */
-    protected static final int MATCH_BEGIN = -4;
-    /** The int representing end in pattern <code>int []</code>. */
-    protected static final int MATCH_THEEND = -5;
-    /** The int value that terminates the pattern <code>int []</code>. */
-    protected static final int MATCH_END = -3;
-
-
     /**
-     * Translate the given <code>String</code> into a <code>int []</code>
-     * representing the pattern matchable by this class.
-     * <br>
-     * This function translates a <code>String</code> into an int array
-     * converting the special '*' and '\' characters.
-     * <br>
-     * Here is how the conversion algorithm works:
-     * <ul>
-     *   <li>The '*' character is converted to MATCH_FILE, meaning that zero
-     *        or more characters (excluding the path separator '/') are to
-     *        be matched.</li>
-     *   <li>The '**' sequence is converted to MATCH_PATH, meaning that zero
-     *       or more characters (including the path separator '/') are to
-     *        be matched.</li>
-     *   <li>The '\' character is used as an escape sequence ('\*' is
-     *       translated in '*', not in MATCH_FILE). If an exact '\' character
-     *       is to be matched the source string must contain a '\\'.
-     *       sequence.</li>
-     * </ul>
-     * When more than two '*' characters, not separated by another character,
-     * are found their value is considered as '**' (MATCH_PATH).
-     * <br>
-     * The array is always terminated by a special value (MATCH_END).
-     * <br>
-     * All MATCH* values are less than zero, while normal characters are equal
-     * or greater.
-     *
-     * @param data The string to translate.
-     * @return The encoded string as an int array, terminated by the MATCH_END
-     *         value (don't consider the array length).
-     * @exception NullPointerException If data is null.
+     * @see org.apache.cocoon.util.WildcardHelper#compilePattern(String)
      */
     public static int[] compilePattern(String data)
     throws NullPointerException {
-
-        // Prepare the arrays
-        int expr[] = new int[data.length() + 2];
-        char buff[] = data.toCharArray();
-
-        // Prepare variables for the translation loop
-        int y = 0;
-        boolean slash = false;
-
-        // Must start from beginning
-        expr[y++] = MATCH_BEGIN;
-
-        if (buff.length > 0) {
-            if (buff[0]=='\\') {
-                slash = true;
-            } else if (buff[0] == '*') {
-                expr[y++] = MATCH_FILE;
-            }  else {
-                expr[y++] = buff[0];
-            }
-
-            // Main translation loop
-            for (int x = 1; x < buff.length; x++) {
-                // If the previous char was '\' simply copy this char.
-                if (slash) {
-                    expr[y++] = buff[x];
-                    slash = false;
-                // If the previous char was not '\' we have to do a bunch of checks
-                } else {
-                    // If this char is '\' declare that and continue
-                    if (buff[x] == '\\') {
-                        slash = true;
-                    // If this char is '*' check the previous one
-                    } else if (buff[x] == '*') {
-                        // If the previous character als was '*' match a path
-                        if (expr[y-1] <= MATCH_FILE) {
-                            expr[y-1] = MATCH_PATH;
-                        } else {
-                            expr[y++] = MATCH_FILE;
-                        }
-                    } else {
-                        expr[y++]=buff[x];
-                    }
-                }
-            }
-        }
-
-        // Must match end at the end
-        expr[y] = MATCH_THEEND;
-        return expr;
+        return org.apache.cocoon.util.WildcardHelper.compilePattern(data);
     }
 
     /**
-     * match a pattern agains a string and isolates wildcard replacement into a
-     * <code>Stack</code>.
+     * @see org.apache.cocoon.util.WildcardHelper#match(HashMap, String, int[])
      */
-    public static boolean match (HashMap map, String data, int[] expr) 
+    public static boolean match(HashMap map, String data, int[] expr) 
     throws NullPointerException {
-        if (data == null) {
-            throw new NullPointerException ("No data provided");
-        }
-        if (expr == null) {
-            throw new NullPointerException ("No pattern expression provided");
-        }
-
-
-        char buff[] = data.toCharArray();
-        // Allocate the result buffer
-        char rslt[] = new char[expr.length + buff.length];
-
-
-        // The previous and current position of the expression character
-        // (MATCH_*)
-        int charpos = 0;
-
-        // The position in the expression, input, translation and result arrays
-        int exprpos = 0;
-        int buffpos = 0;
-        int rsltpos = 0;
-        int offset = -1;
-
-        // The matching count
-        int mcount = 0;
-
-        if ( map != null ) {
-            // We want the complete data be in {0}
-            map.put(Integer.toString(mcount),data);
-        }
-
-        // First check for MATCH_BEGIN
-        boolean matchBegin = false;
-        if (expr[charpos] == MATCH_BEGIN) {
-            matchBegin = true;
-            exprpos = ++charpos;
-        }
-
-        // Search the fist expression character (except MATCH_BEGIN - already skipped)
-        while (expr[charpos] >= 0)
-            charpos++;
-
-        // The expression charater (MATCH_*)
-        int exprchr = expr[charpos];
-
-        while (true) {
-            // Check if the data in the expression array before the current
-            // expression character matches the data in the input buffer
-            if (matchBegin) {
-                if (!matchArray(expr, exprpos, charpos, buff, buffpos))
-                    return (false);
-                matchBegin = false;
-            } else {
-                offset = indexOfArray (expr, exprpos, charpos, buff,
-                        buffpos);
-                if (offset < 0)
-                    return (false);
-            }
-
-            // Check for MATCH_BEGIN
-            if (matchBegin) {
-                if (offset != 0)
-                    return (false);
-                matchBegin = false;
-            }
-
-            // Advance buffpos
-            buffpos += (charpos - exprpos);
-
-            // Check for END's
-            if (exprchr == MATCH_END) {
-                if (rsltpos > 0 && map != null) {
-                    map.put(Integer.toString(++mcount),new String(rslt, 0, rsltpos));
-                }
-                // Don't care about rest of input buffer
-                return (true);
-            } else if (exprchr == MATCH_THEEND) {
-                if (rsltpos > 0 && map != null ) {
-                    map.put (Integer.toString(++mcount),new String(rslt, 0, rsltpos));
-                }
-                // Check that we reach buffer's end
-                return (buffpos == buff.length);
-            }
-
-            // Search the next expression character
-            exprpos = ++charpos;
-            while (expr[charpos] >= 0)
-                charpos++;
-            int prevchr = exprchr;
-            exprchr = expr[charpos];
-
-            // We have here prevchr == * or **.
-            offset = (prevchr == MATCH_FILE) ?
-                    indexOfArray (expr, exprpos, charpos, buff, buffpos) :
-                    lastIndexOfArray (expr, exprpos, charpos, buff,
-                    buffpos);
-
-            if (offset < 0)
-                return (false);
-
-            // Copy the data from the source buffer into the result buffer
-            // to substitute the expression character
-            if (prevchr == MATCH_PATH) {
-                while (buffpos < offset)
-                    rslt[rsltpos++] = buff[buffpos++];
-            } else {
-                // Matching file, don't copy '/'
-                while (buffpos < offset) {
-                    if (buff[buffpos] == '/')
-                        return (false);
-                    rslt[rsltpos++] = buff[buffpos++];
-                }
-            }
-
-            if ( map != null ) {
-                map.put(Integer.toString(++mcount),new String (rslt, 0, rsltpos));
-            }
-            rsltpos = 0;
-        }
-    }
-
-    /**
-      * Get the offset of a part of an int array within a char array.
-      * <br>
-      * This method return the index in d of the first occurrence after dpos of
-      * that part of array specified by r, starting at rpos and terminating at
-      * rend.
-      *
-      * @param r The array containing the data that need to be matched in d.
-      * @param rpos The index of the first character in r to look for.
-      * @param rend The index of the last character in r to look for plus 1.
-      * @param d The array of char that should contain a part of r.
-      * @param dpos The starting offset in d for the matching.
-      * @return The offset in d of the part of r matched in d or -1 if that was
-      *         not found.
-      */
-    protected static int indexOfArray (int r[], int rpos, int rend,
-            char d[], int dpos) {
-        // Check if pos and len are legal
-        if (rend < rpos)
-            throw new IllegalArgumentException ("rend < rpos");
-        // If we need to match a zero length string return current dpos
-        if (rend == rpos)
-            return (d.length); //?? dpos?
-        // If we need to match a 1 char length string do it simply
-        if ((rend - rpos) == 1) {
-            // Search for the specified character
-            for (int x = dpos; x < d.length; x++)
-                if (r[rpos] == d[x])
-                    return (x);
-        }
-        // Main string matching loop. It gets executed if the characters to
-        // match are less then the characters left in the d buffer
-        while ((dpos + rend - rpos) <= d.length) {
-            // Set current startpoint in d
-            int y = dpos;
-            // Check every character in d for equity. If the string is matched
-            // return dpos
-            for (int x = rpos; x <= rend; x++) {
-                if (x == rend)
-                    return (dpos);
-                if (r[x] != d[y++])
-                    break;
-            }
-            // Increase dpos to search for the same string at next offset
-            dpos++;
-        }
-        // The remaining chars in d buffer were not enough or the string
-        // wasn't matched
-        return (-1);
-    }
-
-    /**
-      * Get the offset of a last occurance of an int array within a char array.
-      * <br>
-      * This method return the index in d of the last occurrence after dpos of
-      * that part of array specified by r, starting at rpos and terminating at
-      * rend.
-      *
-      * @param r The array containing the data that need to be matched in d.
-      * @param rpos The index of the first character in r to look for.
-      * @param rend The index of the last character in r to look for plus 1.
-      * @param d The array of char that should contain a part of r.
-      * @param dpos The starting offset in d for the matching.
-      * @return The offset in d of the last part of r matched in d or -1 if that was
-      *         not found.
-      */
-    protected static int lastIndexOfArray (int r[], int rpos, int rend,
-            char d[], int dpos) {
-        // Check if pos and len are legal
-        if (rend < rpos)
-            throw new IllegalArgumentException ("rend < rpos");
-        // If we need to match a zero length string return current dpos
-        if (rend == rpos)
-            return (d.length); //?? dpos?
-
-        // If we need to match a 1 char length string do it simply
-        if ((rend - rpos) == 1) {
-            // Search for the specified character
-            for (int x = d.length - 1; x > dpos; x--)
-                if (r[rpos] == d[x])
-                    return (x);
-        }
-
-        // Main string matching loop. It gets executed if the characters to
-        // match are less then the characters left in the d buffer
-        int l = d.length - (rend - rpos);
-        while (l >= dpos) {
-            // Set current startpoint in d
-            int y = l;
-            // Check every character in d for equity. If the string is matched
-            // return dpos
-            for (int x = rpos; x <= rend; x++) {
-                if (x == rend)
-                    return (l);
-                if (r[x] != d[y++])
-                    break;
-            }
-            // Decrease l to search for the same string at next offset
-            l--;
-        }
-        // The remaining chars in d buffer were not enough or the string
-        // wasn't matched
-        return (-1);
-    }
-
-    /**
-      * Matches elements of array r from rpos to rend with array d, starting from dpos.
-      * <br>
-      * This method return true if elements of array r from rpos to rend
-      * equals elements of array d starting from dpos to dpos+(rend-rpos).
-      *
-      * @param r The array containing the data that need to be matched in d.
-      * @param rpos The index of the first character in r to look for.
-      * @param d The array of char that should start from a part of r.
-      * @param dpos The starting offset in d for the matching.
-      * @return true if array d starts from portion of array r.
-      */
-    protected static boolean matchArray (int r[], int rpos, int rend,
-            char d[], int dpos) {
-        if (d.length - dpos < rend - rpos)
-            return (false);
-        for (int i = rpos; i < rend; i++)
-            if (r[i] != d[dpos++])
-                return (false);
-        return (true);
+        return org.apache.cocoon.util.WildcardHelper.match(map, data, expr);
     }
 }

Modified: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java?rev=407763&r1=407762&r2=407763&view=diff
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java (original)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/transformation/helpers/PreemptiveLoader.java Fri May 19 03:18:29 2006
@@ -87,7 +87,6 @@
     
     /**
      * Start the preemptive loading
-     * @param manager   A component manager
      * @param resolver  A source resolver
      * @param logger    A logger
      */

Added: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java
URL: http://svn.apache.org/viewvc/cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java?rev=407763&view=auto
==============================================================================
--- cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java (added)
+++ cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java Fri May 19 03:18:29 2006
@@ -0,0 +1,379 @@
+/*
+ * Copyright 1999-2005 The Apache Software Foundation.
+ *
+ * Licensed 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.cocoon.util;
+
+import java.util.HashMap;
+
+/**
+ * This class is an utility class that perform wilcard-patterns matching and
+ * isolation.
+ *
+ * @version $Id$
+ */
+public class WildcardHelper {
+
+    /** The int representing '*' in the pattern <code>int []</code>. */
+    protected static final int MATCH_FILE = -1;
+    /** The int representing '**' in the pattern <code>int []</code>. */
+    protected static final int MATCH_PATH = -2;
+    /** The int representing begin in the pattern <code>int []</code>. */
+    protected static final int MATCH_BEGIN = -4;
+    /** The int representing end in pattern <code>int []</code>. */
+    protected static final int MATCH_THEEND = -5;
+    /** The int value that terminates the pattern <code>int []</code>. */
+    protected static final int MATCH_END = -3;
+
+    /**
+     * Translate the given <code>String</code> into a <code>int []</code>
+     * representing the pattern matchable by this class.
+     * <br>
+     * This function translates a <code>String</code> into an int array
+     * converting the special '*' and '\' characters.
+     * <br>
+     * Here is how the conversion algorithm works:
+     * <ul>
+     *   <li>The '*' character is converted to MATCH_FILE, meaning that zero
+     *        or more characters (excluding the path separator '/') are to
+     *        be matched.</li>
+     *   <li>The '**' sequence is converted to MATCH_PATH, meaning that zero
+     *       or more characters (including the path separator '/') are to
+     *        be matched.</li>
+     *   <li>The '\' character is used as an escape sequence ('\*' is
+     *       translated in '*', not in MATCH_FILE). If an exact '\' character
+     *       is to be matched the source string must contain a '\\'.
+     *       sequence.</li>
+     * </ul>
+     * When more than two '*' characters, not separated by another character,
+     * are found their value is considered as '**' (MATCH_PATH).
+     * <br>
+     * The array is always terminated by a special value (MATCH_END).
+     * <br>
+     * All MATCH* values are less than zero, while normal characters are equal
+     * or greater.
+     *
+     * @param data The string to translate.
+     * @return The encoded string as an int array, terminated by the MATCH_END
+     *         value (don't consider the array length).
+     * @exception NullPointerException If data is null.
+     */
+    public static int[] compilePattern(String data)
+    throws NullPointerException {
+
+        // Prepare the arrays
+        int expr[] = new int[data.length() + 2];
+        char buff[] = data.toCharArray();
+
+        // Prepare variables for the translation loop
+        int y = 0;
+        boolean slash = false;
+
+        // Must start from beginning
+        expr[y++] = MATCH_BEGIN;
+
+        if (buff.length > 0) {
+            if (buff[0]=='\\') {
+                slash = true;
+            } else if (buff[0] == '*') {
+                expr[y++] = MATCH_FILE;
+            }  else {
+                expr[y++] = buff[0];
+            }
+
+            // Main translation loop
+            for (int x = 1; x < buff.length; x++) {
+                // If the previous char was '\' simply copy this char.
+                if (slash) {
+                    expr[y++] = buff[x];
+                    slash = false;
+                // If the previous char was not '\' we have to do a bunch of checks
+                } else {
+                    // If this char is '\' declare that and continue
+                    if (buff[x] == '\\') {
+                        slash = true;
+                    // If this char is '*' check the previous one
+                    } else if (buff[x] == '*') {
+                        // If the previous character als was '*' match a path
+                        if (expr[y-1] <= MATCH_FILE) {
+                            expr[y-1] = MATCH_PATH;
+                        } else {
+                            expr[y++] = MATCH_FILE;
+                        }
+                    } else {
+                        expr[y++]=buff[x];
+                    }
+                }
+            }
+        }
+
+        // Must match end at the end
+        expr[y] = MATCH_THEEND;
+        return expr;
+    }
+
+    /**
+     * match a pattern agains a string and isolates wildcard replacement into a
+     * <code>Stack</code>.
+     */
+    public static boolean match (HashMap map, String data, int[] expr) 
+    throws NullPointerException {
+        if (data == null) {
+            throw new NullPointerException ("No data provided");
+        }
+        if (expr == null) {
+            throw new NullPointerException ("No pattern expression provided");
+        }
+
+
+        char buff[] = data.toCharArray();
+        // Allocate the result buffer
+        char rslt[] = new char[expr.length + buff.length];
+
+
+        // The previous and current position of the expression character
+        // (MATCH_*)
+        int charpos = 0;
+
+        // The position in the expression, input, translation and result arrays
+        int exprpos = 0;
+        int buffpos = 0;
+        int rsltpos = 0;
+        int offset = -1;
+
+        // The matching count
+        int mcount = 0;
+
+        if ( map != null ) {
+            // We want the complete data be in {0}
+            map.put(Integer.toString(mcount),data);
+        }
+
+        // First check for MATCH_BEGIN
+        boolean matchBegin = false;
+        if (expr[charpos] == MATCH_BEGIN) {
+            matchBegin = true;
+            exprpos = ++charpos;
+        }
+
+        // Search the fist expression character (except MATCH_BEGIN - already skipped)
+        while (expr[charpos] >= 0)
+            charpos++;
+
+        // The expression charater (MATCH_*)
+        int exprchr = expr[charpos];
+
+        while (true) {
+            // Check if the data in the expression array before the current
+            // expression character matches the data in the input buffer
+            if (matchBegin) {
+                if (!matchArray(expr, exprpos, charpos, buff, buffpos))
+                    return (false);
+                matchBegin = false;
+            } else {
+                offset = indexOfArray (expr, exprpos, charpos, buff,
+                        buffpos);
+                if (offset < 0)
+                    return (false);
+            }
+
+            // Check for MATCH_BEGIN
+            if (matchBegin) {
+                if (offset != 0)
+                    return (false);
+                matchBegin = false;
+            }
+
+            // Advance buffpos
+            buffpos += (charpos - exprpos);
+
+            // Check for END's
+            if (exprchr == MATCH_END) {
+                if (rsltpos > 0 && map != null) {
+                    map.put(Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+                }
+                // Don't care about rest of input buffer
+                return (true);
+            } else if (exprchr == MATCH_THEEND) {
+                if (rsltpos > 0 && map != null ) {
+                    map.put (Integer.toString(++mcount),new String(rslt, 0, rsltpos));
+                }
+                // Check that we reach buffer's end
+                return (buffpos == buff.length);
+            }
+
+            // Search the next expression character
+            exprpos = ++charpos;
+            while (expr[charpos] >= 0)
+                charpos++;
+            int prevchr = exprchr;
+            exprchr = expr[charpos];
+
+            // We have here prevchr == * or **.
+            offset = (prevchr == MATCH_FILE) ?
+                    indexOfArray (expr, exprpos, charpos, buff, buffpos) :
+                    lastIndexOfArray (expr, exprpos, charpos, buff,
+                    buffpos);
+
+            if (offset < 0)
+                return (false);
+
+            // Copy the data from the source buffer into the result buffer
+            // to substitute the expression character
+            if (prevchr == MATCH_PATH) {
+                while (buffpos < offset)
+                    rslt[rsltpos++] = buff[buffpos++];
+            } else {
+                // Matching file, don't copy '/'
+                while (buffpos < offset) {
+                    if (buff[buffpos] == '/')
+                        return (false);
+                    rslt[rsltpos++] = buff[buffpos++];
+                }
+            }
+
+            if ( map != null ) {
+                map.put(Integer.toString(++mcount),new String (rslt, 0, rsltpos));
+            }
+            rsltpos = 0;
+        }
+    }
+
+    /**
+      * Get the offset of a part of an int array within a char array.
+      * <br>
+      * This method return the index in d of the first occurrence after dpos of
+      * that part of array specified by r, starting at rpos and terminating at
+      * rend.
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param rend The index of the last character in r to look for plus 1.
+      * @param d The array of char that should contain a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return The offset in d of the part of r matched in d or -1 if that was
+      *         not found.
+      */
+    protected static int indexOfArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos)
+            throw new IllegalArgumentException ("rend < rpos");
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos)
+            return (d.length); //?? dpos?
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = dpos; x < d.length; x++)
+                if (r[rpos] == d[x])
+                    return (x);
+        }
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        while ((dpos + rend - rpos) <= d.length) {
+            // Set current startpoint in d
+            int y = dpos;
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend)
+                    return (dpos);
+                if (r[x] != d[y++])
+                    break;
+            }
+            // Increase dpos to search for the same string at next offset
+            dpos++;
+        }
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+      * Get the offset of a last occurance of an int array within a char array.
+      * <br>
+      * This method return the index in d of the last occurrence after dpos of
+      * that part of array specified by r, starting at rpos and terminating at
+      * rend.
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param rend The index of the last character in r to look for plus 1.
+      * @param d The array of char that should contain a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return The offset in d of the last part of r matched in d or -1 if that was
+      *         not found.
+      */
+    protected static int lastIndexOfArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos)
+            throw new IllegalArgumentException ("rend < rpos");
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos)
+            return (d.length); //?? dpos?
+
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = d.length - 1; x > dpos; x--)
+                if (r[rpos] == d[x])
+                    return (x);
+        }
+
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        int l = d.length - (rend - rpos);
+        while (l >= dpos) {
+            // Set current startpoint in d
+            int y = l;
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend)
+                    return (l);
+                if (r[x] != d[y++])
+                    break;
+            }
+            // Decrease l to search for the same string at next offset
+            l--;
+        }
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+      * Matches elements of array r from rpos to rend with array d, starting from dpos.
+      * <br>
+      * This method return true if elements of array r from rpos to rend
+      * equals elements of array d starting from dpos to dpos+(rend-rpos).
+      *
+      * @param r The array containing the data that need to be matched in d.
+      * @param rpos The index of the first character in r to look for.
+      * @param d The array of char that should start from a part of r.
+      * @param dpos The starting offset in d for the matching.
+      * @return true if array d starts from portion of array r.
+      */
+    protected static boolean matchArray (int r[], int rpos, int rend,
+            char d[], int dpos) {
+        if (d.length - dpos < rend - rpos)
+            return (false);
+        for (int i = rpos; i < rend; i++)
+            if (r[i] != d[dpos++])
+                return (false);
+        return (true);
+    }
+}

Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cocoon/trunk/core/cocoon-core/src/main/java/org/apache/cocoon/util/WildcardHelper.java
------------------------------------------------------------------------------
    svn:keywords = Id