diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Expand.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Expand.java
index ffe124383..66a657e1a 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Expand.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/Expand.java
@@ -22,6 +22,7 @@ import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Unzip a file.
@@ -205,7 +206,7 @@ public class Expand extends MatchingTask
{
for( int w = 0; w < incls.length; w++ )
{
- boolean isIncl = DirectoryScanner.match( incls[ w ], name );
+ boolean isIncl = ScannerUtil.match( incls[ w ], name );
if( isIncl )
{
included = true;
@@ -218,7 +219,7 @@ public class Expand extends MatchingTask
{
for( int w = 0; w < excls.length; w++ )
{
- boolean isExcl = DirectoryScanner.match( excls[ w ], name );
+ boolean isExcl = ScannerUtil.match( excls[ w ], name );
if( isExcl )
{
included = false;
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
index d87c61245..d429e467e 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
@@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.apache.tools.ant.types.DirectoryScanner;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Class for scanning a Visual Age for Java workspace for packages matching a
@@ -69,7 +70,7 @@ class VAJWorkspaceScanner extends DirectoryScanner
*/
protected static boolean match( String pattern, String str )
{
- return DirectoryScanner.match( pattern, str );
+ return ScannerUtil.match( pattern, str );
}
/**
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
index 463bfb851..b16308621 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
@@ -18,6 +18,7 @@ import com.starbase.util.Platform;
import java.util.StringTokenizer;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.types.DirectoryScanner;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Checks out files from a specific StarTeam server, project, view, and folder.
@@ -765,7 +766,7 @@ public class AntStarTeamCheckOut extends org.apache.tools.ant.Task
StringTokenizer exStr = new StringTokenizer( patterns, " " );
while( exStr.hasMoreTokens() )
{
- if( DirectoryScanner.match( exStr.nextToken(), pName ) )
+ if( ScannerUtil.match( exStr.nextToken(), pName ) )
{
return true;
}
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/types/DirectoryScanner.java b/proposal/myrmidon/src/main/org/apache/tools/ant/types/DirectoryScanner.java
index a8854b840..ac6496e5d 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/types/DirectoryScanner.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/types/DirectoryScanner.java
@@ -91,24 +91,6 @@ import org.apache.myrmidon.api.TaskException;
public class DirectoryScanner
implements FileScanner
{
- /**
- * Patterns that should be excluded by default.
- *
- * @see #addDefaultExcludes()
- */
- private final static String[] DEFAULTEXCLUDES =
- {
- "**/*~",
- "**/#*#",
- "**/.#*",
- "**/%*%",
- "**/CVS",
- "**/CVS/**",
- "**/.cvsignore",
- "**/SCCS",
- "**/SCCS/**",
- "**/vssver.scc"
- };
/**
* Have the ArrayLists holding our results been built by a slow scan?
@@ -174,493 +156,6 @@ public class DirectoryScanner
*/
private String[] m_includes;
- /**
- * Matches a string against a pattern. The pattern contains two special
- * characters: '*' which means zero or more characters, '?' which means one
- * and only one character.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string that must be matched against the pattern
- * @return true
when the string matches against the pattern,
- * false
otherwise.
- */
- public static boolean match( final String pattern, final String str )
- {
- return match( pattern, str, true );
- }
-
- /**
- * Matches a string against a pattern. The pattern contains two special
- * characters: '*' which means zero or more characters, '?' which means one
- * and only one character.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string that must be matched against the pattern
- * @param isCaseSensitive Description of Parameter
- * @return true
when the string matches against the pattern,
- * false
otherwise.
- */
- protected static boolean match( final String pattern,
- final String str,
- final 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( ch != '?' )
- {
- 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( ch != '?' )
- {
- 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 )
- {
- // 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( ch != '?' )
- {
- 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( ch != '?' )
- {
- 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;
- }
-
- // 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;
- }
-
- /**
- * Matches a path against a pattern.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @return true
when the pattern matches against the string.
- * false
otherwise.
- */
- protected static boolean matchPath( final String pattern, final String str )
- {
- return matchPath( pattern, str, true );
- }
-
- /**
- * Matches a path against a pattern.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @param isCaseSensitive must a case sensitive match be done?
- * @return true
when the pattern matches against the string.
- * false
otherwise.
- */
- protected static boolean matchPath( final String pattern,
- final String str,
- final boolean isCaseSensitive )
- {
- // When str starts with a File.separator, pattern has to start with a
- // File.separator.
- // When pattern starts with a File.separator, str has to start with a
- // File.separator.
- if( str.startsWith( File.separator ) !=
- pattern.startsWith( File.separator ) )
- {
- return false;
- }
-
- ArrayList patDirs = new ArrayList();
- StringTokenizer st = new StringTokenizer( pattern, File.separator );
- while( st.hasMoreTokens() )
- {
- patDirs.add( st.nextToken() );
- }
-
- ArrayList strDirs = new ArrayList();
- st = new StringTokenizer( str, File.separator );
- while( st.hasMoreTokens() )
- {
- strDirs.add( st.nextToken() );
- }
-
- int patIdxStart = 0;
- int patIdxEnd = patDirs.size() - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.size() - 1;
-
- // up to first '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxStart );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
- return true;
- }
- else
- {
- if( patIdxStart > patIdxEnd )
- {
- // String not exhausted, but pattern is. Failure.
- return false;
- }
- }
-
- // up to last '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxEnd );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxEnd ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxEnd--;
- strIdxEnd--;
- }
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
- return true;
- }
-
- while( patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd )
- {
- int patIdxTmp = -1;
- for( int i = patIdxStart + 1; i <= patIdxEnd; i++ )
- {
- if( patDirs.get( i ).equals( "**" ) )
- {
- patIdxTmp = i;
- break;
- }
- }
- if( patIdxTmp == patIdxStart + 1 )
- {
- // '**/**' situation, so skip 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++ )
- {
- String subPat = (String)patDirs.get( patIdxStart + j + 1 );
- String subStr = (String)strDirs.get( strIdxStart + i + j );
- if( !match( subPat, subStr, isCaseSensitive ) )
- {
- continue strLoop;
- }
- }
-
- foundIdx = strIdxStart + i;
- break;
- }
-
- if( foundIdx == -1 )
- {
- return false;
- }
-
- patIdxStart = patIdxTmp;
- strIdxStart = foundIdx + patLength;
- }
-
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Does the path match the start of this pattern up to the first "**".
- * - * This is not a general purpose test and should only be used if you can - * live with false positives.
- *
- * pattern=**\\a
and str=b
will yield true.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @return Description of the Returned Value
- */
- protected static boolean matchPatternStart( final String pattern, final String str )
- {
- return matchPatternStart( pattern, str, true );
- }
-
- /**
- * Does the path match the start of this pattern up to the first "**".
- * - * This is not a general purpose test and should only be used if you can - * live with false positives.
- *
- * pattern=**\\a
and str=b
will yield true.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @param isCaseSensitive must matches be case sensitive?
- * @return Description of the Returned Value
- */
- protected static boolean matchPatternStart( final String pattern,
- final String str,
- final boolean isCaseSensitive )
- {
- // When str starts with a File.separator, pattern has to start with a
- // File.separator.
- // When pattern starts with a File.separator, str has to start with a
- // File.separator.
- if( str.startsWith( File.separator ) !=
- pattern.startsWith( File.separator ) )
- {
- return false;
- }
-
- ArrayList patDirs = new ArrayList();
- StringTokenizer st = new StringTokenizer( pattern, File.separator );
- while( st.hasMoreTokens() )
- {
- patDirs.add( st.nextToken() );
- }
-
- ArrayList strDirs = new ArrayList();
- st = new StringTokenizer( str, File.separator );
- while( st.hasMoreTokens() )
- {
- strDirs.add( st.nextToken() );
- }
-
- int patIdxStart = 0;
- int patIdxEnd = patDirs.size() - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.size() - 1;
-
- // up to first '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxStart );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
-
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- return true;
- }
- else if( patIdxStart > patIdxEnd )
- {
- // String not exhausted, but pattern is. Failure.
- return false;
- }
- else
- {
- // pattern now holds ** while string is not exhausted
- // this will generate false positives but we can live with that.
- return true;
- }
- }
-
/**
* Sets the basedir for scanning. This is the directory that is scanned
* recursively. All '/' and '\' characters are replaced by File.separatorChar
@@ -900,14 +395,14 @@ public class DirectoryScanner
{
int excludesLength = m_excludes == null ? 0 : m_excludes.length;
String[] newExcludes;
- newExcludes = new String[ excludesLength + DEFAULTEXCLUDES.length ];
+ newExcludes = new String[ excludesLength + ScannerUtil.DEFAULTEXCLUDES.length ];
if( excludesLength > 0 )
{
System.arraycopy( m_excludes, 0, newExcludes, 0, excludesLength );
}
- for( int i = 0; i < DEFAULTEXCLUDES.length; i++ )
+ for( int i = 0; i < ScannerUtil.DEFAULTEXCLUDES.length; i++ )
{
- newExcludes[ i + excludesLength ] = DEFAULTEXCLUDES[ i ].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
+ newExcludes[ i + excludesLength ] = ScannerUtil.DEFAULTEXCLUDES[ i ].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
}
m_excludes = newExcludes;
}
@@ -982,7 +477,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_excludes.length; i++ )
{
- if( matchPath( m_excludes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPath( m_excludes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1001,7 +496,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_includes.length; i++ )
{
- if( matchPath( m_includes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPath( m_includes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1020,7 +515,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_includes.length; i++ )
{
- if( matchPatternStart( m_includes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPatternStart( m_includes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1166,11 +661,6 @@ public class DirectoryScanner
m_haveSlowResults = true;
}
- public static String[] getDEFAULTEXCLUDES()
- {
- return DEFAULTEXCLUDES;
- }
-
public ArrayList getDirsExcluded()
{
return m_dirsExcluded;
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/types/PatternSet.java b/proposal/myrmidon/src/main/org/apache/tools/ant/types/PatternSet.java
index fa3e69850..ce86a5e7f 100644
--- a/proposal/myrmidon/src/main/org/apache/tools/ant/types/PatternSet.java
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/types/PatternSet.java
@@ -13,23 +13,18 @@ import java.util.StringTokenizer;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.Pattern;
-import org.apache.tools.ant.ProjectComponent;
/**
* Named collection of include/exclude tags.
*
- * Moved out of MatchingTask to make it a standalone object that could be
- * referenced (by scripts for example).
- *
- * @author Arnout J. Kuiper ajkuiper@wxs.nl
- * @author Stefano Mazzocchi
- * stefano@apache.org
- * @author Sam Ruby rubys@us.ibm.com
- * @author Jon S. Stevens jon@clearink.com
+ * @author Arnout J. Kuiper
+ * @author Stefano Mazzocchi
+ * @author Sam Ruby
+ * @author Jon S. Stevens
* @author Stefan Bodewig
+ * @author Peter Donald
*/
public class PatternSet
- extends ProjectComponent
{
private ArrayList m_includeList = new ArrayList();
private ArrayList m_excludeList = new ArrayList();
@@ -106,8 +101,8 @@ public class PatternSet
public String toString()
{
- return "patternSet{ includes: " + m_includeList +
- " excludes: " + m_excludeList + " }";
+ return "PatternSet [ includes: " + m_includeList +
+ " excludes: " + m_excludeList + " ]";
}
private Pattern[] parsePatterns( final String patternString )
diff --git a/proposal/myrmidon/src/main/org/apache/tools/ant/types/ScannerUtil.java b/proposal/myrmidon/src/main/org/apache/tools/ant/types/ScannerUtil.java
new file mode 100644
index 000000000..7ade7091f
--- /dev/null
+++ b/proposal/myrmidon/src/main/org/apache/tools/ant/types/ScannerUtil.java
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+/**
+ *
+ *
+ * @author Peter Donald
+ * @version $Revision$ $Date$
+ */
+public class ScannerUtil
+{
+ /**
+ * Patterns that should be excluded by default.
+ */
+ public final static String[] DEFAULTEXCLUDES = new String[]
+ {
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/CVS",
+ "**/CVS/**",
+ "**/.cvsignore",
+ "**/SCCS",
+ "**/SCCS/**",
+ "**/vssver.scc"
+ };
+
+ /**
+ * Matches a string against a pattern. The pattern contains two special
+ * characters: '*' which means zero or more characters, '?' which means one
+ * and only one character.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string that must be matched against the pattern
+ * @return true
when the string matches against the pattern,
+ * false
otherwise.
+ */
+ public static boolean match( final String pattern, final String str )
+ {
+ return match( pattern, str, true );
+ }
+
+ /**
+ * Matches a string against a pattern. The pattern contains two special
+ * characters: '*' which means zero or more characters, '?' which means one
+ * and only one character.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string that must be matched against the pattern
+ * @param isCaseSensitive Description of Parameter
+ * @return true
when the string matches against the pattern,
+ * false
otherwise.
+ */
+ protected static boolean match( final String pattern,
+ final String str,
+ final 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( ch != '?' )
+ {
+ 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( ch != '?' )
+ {
+ 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 )
+ {
+ // 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( ch != '?' )
+ {
+ 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( ch != '?' )
+ {
+ 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;
+ }
+
+ // 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;
+ }
+
+ /**
+ * Matches a path against a pattern.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @return true
when the pattern matches against the string.
+ * false
otherwise.
+ */
+ protected static boolean matchPath( final String pattern, final String str )
+ {
+ return matchPath( pattern, str, true );
+ }
+
+ /**
+ * Matches a path against a pattern.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @param isCaseSensitive must a case sensitive match be done?
+ * @return true
when the pattern matches against the string.
+ * false
otherwise.
+ */
+ protected static boolean matchPath( final String pattern,
+ final String str,
+ final boolean isCaseSensitive )
+ {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if( str.startsWith( File.separator ) !=
+ pattern.startsWith( File.separator ) )
+ {
+ return false;
+ }
+
+ ArrayList patDirs = new ArrayList();
+ StringTokenizer st = new StringTokenizer( pattern, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ patDirs.add( st.nextToken() );
+ }
+
+ ArrayList strDirs = new ArrayList();
+ st = new StringTokenizer( str, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ strDirs.add( st.nextToken() );
+ }
+
+ int patIdxStart = 0;
+ int patIdxEnd = patDirs.size() - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.size() - 1;
+
+ // up to first '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxStart );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ if( patIdxStart > patIdxEnd )
+ {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ }
+
+ // up to last '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxEnd );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxEnd ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ while( patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ int patIdxTmp = -1;
+ for( int i = patIdxStart + 1; i <= patIdxEnd; i++ )
+ {
+ if( patDirs.get( i ).equals( "**" ) )
+ {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if( patIdxTmp == patIdxStart + 1 )
+ {
+ // '**/**' situation, so skip 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++ )
+ {
+ String subPat = (String)patDirs.get( patIdxStart + j + 1 );
+ String subStr = (String)strDirs.get( strIdxStart + i + j );
+ if( !match( subPat, subStr, isCaseSensitive ) )
+ {
+ continue strLoop;
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if( foundIdx == -1 )
+ {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Does the path match the start of this pattern up to the first "**".
+ * + * This is not a general purpose test and should only be used if you can + * live with false positives.
+ *
+ * pattern=**\\a
and str=b
will yield true.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @return Description of the Returned Value
+ */
+ protected static boolean matchPatternStart( final String pattern, final String str )
+ {
+ return matchPatternStart( pattern, str, true );
+ }
+
+ /**
+ * Does the path match the start of this pattern up to the first "**".
+ * + * This is not a general purpose test and should only be used if you can + * live with false positives.
+ *
+ * pattern=**\\a
and str=b
will yield true.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @param isCaseSensitive must matches be case sensitive?
+ * @return Description of the Returned Value
+ */
+ protected static boolean matchPatternStart( final String pattern,
+ final String str,
+ final boolean isCaseSensitive )
+ {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if( str.startsWith( File.separator ) !=
+ pattern.startsWith( File.separator ) )
+ {
+ return false;
+ }
+
+ ArrayList patDirs = new ArrayList();
+ StringTokenizer st = new StringTokenizer( pattern, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ patDirs.add( st.nextToken() );
+ }
+
+ ArrayList strDirs = new ArrayList();
+ st = new StringTokenizer( str, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ strDirs.add( st.nextToken() );
+ }
+
+ int patIdxStart = 0;
+ int patIdxEnd = patDirs.size() - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.size() - 1;
+
+ // up to first '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxStart );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ return true;
+ }
+ else if( patIdxStart > patIdxEnd )
+ {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ else
+ {
+ // pattern now holds ** while string is not exhausted
+ // this will generate false positives but we can live with that.
+ return true;
+ }
+ }
+}
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/Expand.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/Expand.java
index ffe124383..66a657e1a 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/Expand.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/Expand.java
@@ -22,6 +22,7 @@ import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.types.DirectoryScanner;
import org.apache.tools.ant.types.FileSet;
import org.apache.tools.ant.types.PatternSet;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Unzip a file.
@@ -205,7 +206,7 @@ public class Expand extends MatchingTask
{
for( int w = 0; w < incls.length; w++ )
{
- boolean isIncl = DirectoryScanner.match( incls[ w ], name );
+ boolean isIncl = ScannerUtil.match( incls[ w ], name );
if( isIncl )
{
included = true;
@@ -218,7 +219,7 @@ public class Expand extends MatchingTask
{
for( int w = 0; w < excls.length; w++ )
{
- boolean isExcl = DirectoryScanner.match( excls[ w ], name );
+ boolean isExcl = ScannerUtil.match( excls[ w ], name );
if( isExcl )
{
included = false;
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
index d87c61245..d429e467e 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/ide/VAJWorkspaceScanner.java
@@ -15,6 +15,7 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.StringTokenizer;
import org.apache.tools.ant.types.DirectoryScanner;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Class for scanning a Visual Age for Java workspace for packages matching a
@@ -69,7 +70,7 @@ class VAJWorkspaceScanner extends DirectoryScanner
*/
protected static boolean match( String pattern, String str )
{
- return DirectoryScanner.match( pattern, str );
+ return ScannerUtil.match( pattern, str );
}
/**
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
index 463bfb851..b16308621 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/taskdefs/optional/scm/AntStarTeamCheckOut.java
@@ -18,6 +18,7 @@ import com.starbase.util.Platform;
import java.util.StringTokenizer;
import org.apache.myrmidon.api.TaskException;
import org.apache.tools.ant.types.DirectoryScanner;
+import org.apache.tools.ant.types.ScannerUtil;
/**
* Checks out files from a specific StarTeam server, project, view, and folder.
@@ -765,7 +766,7 @@ public class AntStarTeamCheckOut extends org.apache.tools.ant.Task
StringTokenizer exStr = new StringTokenizer( patterns, " " );
while( exStr.hasMoreTokens() )
{
- if( DirectoryScanner.match( exStr.nextToken(), pName ) )
+ if( ScannerUtil.match( exStr.nextToken(), pName ) )
{
return true;
}
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/types/DirectoryScanner.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/DirectoryScanner.java
index a8854b840..ac6496e5d 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/types/DirectoryScanner.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/DirectoryScanner.java
@@ -91,24 +91,6 @@ import org.apache.myrmidon.api.TaskException;
public class DirectoryScanner
implements FileScanner
{
- /**
- * Patterns that should be excluded by default.
- *
- * @see #addDefaultExcludes()
- */
- private final static String[] DEFAULTEXCLUDES =
- {
- "**/*~",
- "**/#*#",
- "**/.#*",
- "**/%*%",
- "**/CVS",
- "**/CVS/**",
- "**/.cvsignore",
- "**/SCCS",
- "**/SCCS/**",
- "**/vssver.scc"
- };
/**
* Have the ArrayLists holding our results been built by a slow scan?
@@ -174,493 +156,6 @@ public class DirectoryScanner
*/
private String[] m_includes;
- /**
- * Matches a string against a pattern. The pattern contains two special
- * characters: '*' which means zero or more characters, '?' which means one
- * and only one character.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string that must be matched against the pattern
- * @return true
when the string matches against the pattern,
- * false
otherwise.
- */
- public static boolean match( final String pattern, final String str )
- {
- return match( pattern, str, true );
- }
-
- /**
- * Matches a string against a pattern. The pattern contains two special
- * characters: '*' which means zero or more characters, '?' which means one
- * and only one character.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string that must be matched against the pattern
- * @param isCaseSensitive Description of Parameter
- * @return true
when the string matches against the pattern,
- * false
otherwise.
- */
- protected static boolean match( final String pattern,
- final String str,
- final 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( ch != '?' )
- {
- 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( ch != '?' )
- {
- 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 )
- {
- // 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( ch != '?' )
- {
- 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( ch != '?' )
- {
- 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;
- }
-
- // 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;
- }
-
- /**
- * Matches a path against a pattern.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @return true
when the pattern matches against the string.
- * false
otherwise.
- */
- protected static boolean matchPath( final String pattern, final String str )
- {
- return matchPath( pattern, str, true );
- }
-
- /**
- * Matches a path against a pattern.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @param isCaseSensitive must a case sensitive match be done?
- * @return true
when the pattern matches against the string.
- * false
otherwise.
- */
- protected static boolean matchPath( final String pattern,
- final String str,
- final boolean isCaseSensitive )
- {
- // When str starts with a File.separator, pattern has to start with a
- // File.separator.
- // When pattern starts with a File.separator, str has to start with a
- // File.separator.
- if( str.startsWith( File.separator ) !=
- pattern.startsWith( File.separator ) )
- {
- return false;
- }
-
- ArrayList patDirs = new ArrayList();
- StringTokenizer st = new StringTokenizer( pattern, File.separator );
- while( st.hasMoreTokens() )
- {
- patDirs.add( st.nextToken() );
- }
-
- ArrayList strDirs = new ArrayList();
- st = new StringTokenizer( str, File.separator );
- while( st.hasMoreTokens() )
- {
- strDirs.add( st.nextToken() );
- }
-
- int patIdxStart = 0;
- int patIdxEnd = patDirs.size() - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.size() - 1;
-
- // up to first '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxStart );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
- return true;
- }
- else
- {
- if( patIdxStart > patIdxEnd )
- {
- // String not exhausted, but pattern is. Failure.
- return false;
- }
- }
-
- // up to last '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxEnd );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxEnd ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxEnd--;
- strIdxEnd--;
- }
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
- return true;
- }
-
- while( patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd )
- {
- int patIdxTmp = -1;
- for( int i = patIdxStart + 1; i <= patIdxEnd; i++ )
- {
- if( patDirs.get( i ).equals( "**" ) )
- {
- patIdxTmp = i;
- break;
- }
- }
- if( patIdxTmp == patIdxStart + 1 )
- {
- // '**/**' situation, so skip 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++ )
- {
- String subPat = (String)patDirs.get( patIdxStart + j + 1 );
- String subStr = (String)strDirs.get( strIdxStart + i + j );
- if( !match( subPat, subStr, isCaseSensitive ) )
- {
- continue strLoop;
- }
- }
-
- foundIdx = strIdxStart + i;
- break;
- }
-
- if( foundIdx == -1 )
- {
- return false;
- }
-
- patIdxStart = patIdxTmp;
- strIdxStart = foundIdx + patLength;
- }
-
- for( int i = patIdxStart; i <= patIdxEnd; i++ )
- {
- if( !patDirs.get( i ).equals( "**" ) )
- {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Does the path match the start of this pattern up to the first "**".
- * - * This is not a general purpose test and should only be used if you can - * live with false positives.
- *
- * pattern=**\\a
and str=b
will yield true.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @return Description of the Returned Value
- */
- protected static boolean matchPatternStart( final String pattern, final String str )
- {
- return matchPatternStart( pattern, str, true );
- }
-
- /**
- * Does the path match the start of this pattern up to the first "**".
- * - * This is not a general purpose test and should only be used if you can - * live with false positives.
- *
- * pattern=**\\a
and str=b
will yield true.
- *
- * @param pattern the (non-null) pattern to match against
- * @param str the (non-null) string (path) to match
- * @param isCaseSensitive must matches be case sensitive?
- * @return Description of the Returned Value
- */
- protected static boolean matchPatternStart( final String pattern,
- final String str,
- final boolean isCaseSensitive )
- {
- // When str starts with a File.separator, pattern has to start with a
- // File.separator.
- // When pattern starts with a File.separator, str has to start with a
- // File.separator.
- if( str.startsWith( File.separator ) !=
- pattern.startsWith( File.separator ) )
- {
- return false;
- }
-
- ArrayList patDirs = new ArrayList();
- StringTokenizer st = new StringTokenizer( pattern, File.separator );
- while( st.hasMoreTokens() )
- {
- patDirs.add( st.nextToken() );
- }
-
- ArrayList strDirs = new ArrayList();
- st = new StringTokenizer( str, File.separator );
- while( st.hasMoreTokens() )
- {
- strDirs.add( st.nextToken() );
- }
-
- int patIdxStart = 0;
- int patIdxEnd = patDirs.size() - 1;
- int strIdxStart = 0;
- int strIdxEnd = strDirs.size() - 1;
-
- // up to first '**'
- while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
- {
- String patDir = (String)patDirs.get( patIdxStart );
- if( patDir.equals( "**" ) )
- {
- break;
- }
- if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
- {
- return false;
- }
- patIdxStart++;
- strIdxStart++;
- }
-
- if( strIdxStart > strIdxEnd )
- {
- // String is exhausted
- return true;
- }
- else if( patIdxStart > patIdxEnd )
- {
- // String not exhausted, but pattern is. Failure.
- return false;
- }
- else
- {
- // pattern now holds ** while string is not exhausted
- // this will generate false positives but we can live with that.
- return true;
- }
- }
-
/**
* Sets the basedir for scanning. This is the directory that is scanned
* recursively. All '/' and '\' characters are replaced by File.separatorChar
@@ -900,14 +395,14 @@ public class DirectoryScanner
{
int excludesLength = m_excludes == null ? 0 : m_excludes.length;
String[] newExcludes;
- newExcludes = new String[ excludesLength + DEFAULTEXCLUDES.length ];
+ newExcludes = new String[ excludesLength + ScannerUtil.DEFAULTEXCLUDES.length ];
if( excludesLength > 0 )
{
System.arraycopy( m_excludes, 0, newExcludes, 0, excludesLength );
}
- for( int i = 0; i < DEFAULTEXCLUDES.length; i++ )
+ for( int i = 0; i < ScannerUtil.DEFAULTEXCLUDES.length; i++ )
{
- newExcludes[ i + excludesLength ] = DEFAULTEXCLUDES[ i ].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
+ newExcludes[ i + excludesLength ] = ScannerUtil.DEFAULTEXCLUDES[ i ].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
}
m_excludes = newExcludes;
}
@@ -982,7 +477,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_excludes.length; i++ )
{
- if( matchPath( m_excludes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPath( m_excludes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1001,7 +496,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_includes.length; i++ )
{
- if( matchPath( m_includes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPath( m_includes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1020,7 +515,7 @@ public class DirectoryScanner
{
for( int i = 0; i < m_includes.length; i++ )
{
- if( matchPatternStart( m_includes[ i ], name, m_isCaseSensitive ) )
+ if( ScannerUtil.matchPatternStart( m_includes[ i ], name, m_isCaseSensitive ) )
{
return true;
}
@@ -1166,11 +661,6 @@ public class DirectoryScanner
m_haveSlowResults = true;
}
- public static String[] getDEFAULTEXCLUDES()
- {
- return DEFAULTEXCLUDES;
- }
-
public ArrayList getDirsExcluded()
{
return m_dirsExcluded;
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/types/PatternSet.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/PatternSet.java
index fa3e69850..ce86a5e7f 100644
--- a/proposal/myrmidon/src/todo/org/apache/tools/ant/types/PatternSet.java
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/PatternSet.java
@@ -13,23 +13,18 @@ import java.util.StringTokenizer;
import org.apache.myrmidon.api.TaskContext;
import org.apache.myrmidon.api.TaskException;
import org.apache.myrmidon.framework.Pattern;
-import org.apache.tools.ant.ProjectComponent;
/**
* Named collection of include/exclude tags.
*
- * Moved out of MatchingTask to make it a standalone object that could be
- * referenced (by scripts for example).
- *
- * @author Arnout J. Kuiper ajkuiper@wxs.nl
- * @author Stefano Mazzocchi
- * stefano@apache.org
- * @author Sam Ruby rubys@us.ibm.com
- * @author Jon S. Stevens jon@clearink.com
+ * @author Arnout J. Kuiper
+ * @author Stefano Mazzocchi
+ * @author Sam Ruby
+ * @author Jon S. Stevens
* @author Stefan Bodewig
+ * @author Peter Donald
*/
public class PatternSet
- extends ProjectComponent
{
private ArrayList m_includeList = new ArrayList();
private ArrayList m_excludeList = new ArrayList();
@@ -106,8 +101,8 @@ public class PatternSet
public String toString()
{
- return "patternSet{ includes: " + m_includeList +
- " excludes: " + m_excludeList + " }";
+ return "PatternSet [ includes: " + m_includeList +
+ " excludes: " + m_excludeList + " ]";
}
private Pattern[] parsePatterns( final String patternString )
diff --git a/proposal/myrmidon/src/todo/org/apache/tools/ant/types/ScannerUtil.java b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/ScannerUtil.java
new file mode 100644
index 000000000..7ade7091f
--- /dev/null
+++ b/proposal/myrmidon/src/todo/org/apache/tools/ant/types/ScannerUtil.java
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) The Apache Software Foundation. All rights reserved.
+ *
+ * This software is published under the terms of the Apache Software License
+ * version 1.1, a copy of which has been included with this distribution in
+ * the LICENSE.txt file.
+ */
+package org.apache.tools.ant.types;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+/**
+ *
+ *
+ * @author Peter Donald
+ * @version $Revision$ $Date$
+ */
+public class ScannerUtil
+{
+ /**
+ * Patterns that should be excluded by default.
+ */
+ public final static String[] DEFAULTEXCLUDES = new String[]
+ {
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/CVS",
+ "**/CVS/**",
+ "**/.cvsignore",
+ "**/SCCS",
+ "**/SCCS/**",
+ "**/vssver.scc"
+ };
+
+ /**
+ * Matches a string against a pattern. The pattern contains two special
+ * characters: '*' which means zero or more characters, '?' which means one
+ * and only one character.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string that must be matched against the pattern
+ * @return true
when the string matches against the pattern,
+ * false
otherwise.
+ */
+ public static boolean match( final String pattern, final String str )
+ {
+ return match( pattern, str, true );
+ }
+
+ /**
+ * Matches a string against a pattern. The pattern contains two special
+ * characters: '*' which means zero or more characters, '?' which means one
+ * and only one character.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string that must be matched against the pattern
+ * @param isCaseSensitive Description of Parameter
+ * @return true
when the string matches against the pattern,
+ * false
otherwise.
+ */
+ protected static boolean match( final String pattern,
+ final String str,
+ final 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( ch != '?' )
+ {
+ 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( ch != '?' )
+ {
+ 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 )
+ {
+ // 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( ch != '?' )
+ {
+ 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( ch != '?' )
+ {
+ 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;
+ }
+
+ // 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;
+ }
+
+ /**
+ * Matches a path against a pattern.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @return true
when the pattern matches against the string.
+ * false
otherwise.
+ */
+ protected static boolean matchPath( final String pattern, final String str )
+ {
+ return matchPath( pattern, str, true );
+ }
+
+ /**
+ * Matches a path against a pattern.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @param isCaseSensitive must a case sensitive match be done?
+ * @return true
when the pattern matches against the string.
+ * false
otherwise.
+ */
+ protected static boolean matchPath( final String pattern,
+ final String str,
+ final boolean isCaseSensitive )
+ {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if( str.startsWith( File.separator ) !=
+ pattern.startsWith( File.separator ) )
+ {
+ return false;
+ }
+
+ ArrayList patDirs = new ArrayList();
+ StringTokenizer st = new StringTokenizer( pattern, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ patDirs.add( st.nextToken() );
+ }
+
+ ArrayList strDirs = new ArrayList();
+ st = new StringTokenizer( str, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ strDirs.add( st.nextToken() );
+ }
+
+ int patIdxStart = 0;
+ int patIdxEnd = patDirs.size() - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.size() - 1;
+
+ // up to first '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxStart );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+ else
+ {
+ if( patIdxStart > patIdxEnd )
+ {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ }
+
+ // up to last '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxEnd );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxEnd ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxEnd--;
+ strIdxEnd--;
+ }
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ while( patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ int patIdxTmp = -1;
+ for( int i = patIdxStart + 1; i <= patIdxEnd; i++ )
+ {
+ if( patDirs.get( i ).equals( "**" ) )
+ {
+ patIdxTmp = i;
+ break;
+ }
+ }
+ if( patIdxTmp == patIdxStart + 1 )
+ {
+ // '**/**' situation, so skip 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++ )
+ {
+ String subPat = (String)patDirs.get( patIdxStart + j + 1 );
+ String subStr = (String)strDirs.get( strIdxStart + i + j );
+ if( !match( subPat, subStr, isCaseSensitive ) )
+ {
+ continue strLoop;
+ }
+ }
+
+ foundIdx = strIdxStart + i;
+ break;
+ }
+
+ if( foundIdx == -1 )
+ {
+ return false;
+ }
+
+ patIdxStart = patIdxTmp;
+ strIdxStart = foundIdx + patLength;
+ }
+
+ for( int i = patIdxStart; i <= patIdxEnd; i++ )
+ {
+ if( !patDirs.get( i ).equals( "**" ) )
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Does the path match the start of this pattern up to the first "**".
+ * + * This is not a general purpose test and should only be used if you can + * live with false positives.
+ *
+ * pattern=**\\a
and str=b
will yield true.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @return Description of the Returned Value
+ */
+ protected static boolean matchPatternStart( final String pattern, final String str )
+ {
+ return matchPatternStart( pattern, str, true );
+ }
+
+ /**
+ * Does the path match the start of this pattern up to the first "**".
+ * + * This is not a general purpose test and should only be used if you can + * live with false positives.
+ *
+ * pattern=**\\a
and str=b
will yield true.
+ *
+ * @param pattern the (non-null) pattern to match against
+ * @param str the (non-null) string (path) to match
+ * @param isCaseSensitive must matches be case sensitive?
+ * @return Description of the Returned Value
+ */
+ protected static boolean matchPatternStart( final String pattern,
+ final String str,
+ final boolean isCaseSensitive )
+ {
+ // When str starts with a File.separator, pattern has to start with a
+ // File.separator.
+ // When pattern starts with a File.separator, str has to start with a
+ // File.separator.
+ if( str.startsWith( File.separator ) !=
+ pattern.startsWith( File.separator ) )
+ {
+ return false;
+ }
+
+ ArrayList patDirs = new ArrayList();
+ StringTokenizer st = new StringTokenizer( pattern, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ patDirs.add( st.nextToken() );
+ }
+
+ ArrayList strDirs = new ArrayList();
+ st = new StringTokenizer( str, File.separator );
+ while( st.hasMoreTokens() )
+ {
+ strDirs.add( st.nextToken() );
+ }
+
+ int patIdxStart = 0;
+ int patIdxEnd = patDirs.size() - 1;
+ int strIdxStart = 0;
+ int strIdxEnd = strDirs.size() - 1;
+
+ // up to first '**'
+ while( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
+ {
+ String patDir = (String)patDirs.get( patIdxStart );
+ if( patDir.equals( "**" ) )
+ {
+ break;
+ }
+ if( !match( patDir, (String)strDirs.get( strIdxStart ), isCaseSensitive ) )
+ {
+ return false;
+ }
+ patIdxStart++;
+ strIdxStart++;
+ }
+
+ if( strIdxStart > strIdxEnd )
+ {
+ // String is exhausted
+ return true;
+ }
+ else if( patIdxStart > patIdxEnd )
+ {
+ // String not exhausted, but pattern is. Failure.
+ return false;
+ }
+ else
+ {
+ // pattern now holds ** while string is not exhausted
+ // this will generate false positives but we can live with that.
+ return true;
+ }
+ }
+}