You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by jv...@apache.org on 2006/04/18 15:59:34 UTC
svn commit: r394946 [1/4] - in
/maven/components/trunk/maven-core-it-verifier/src/main/java/org:
apache/maven/it/ codehaus/plexus/util/
Author: jvanzyl
Date: Tue Apr 18 06:59:22 2006
New Revision: 394946
URL: http://svn.apache.org/viewcvs?rev=394946&view=rev
Log:
[MNG-2233] applying improvements to the verifier, thanks to jesse.
Added:
maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java (with props)
maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/IOUtil.java (with props)
maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/SelectorUtils.java (with props)
maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/StringUtils.java (with props)
Modified:
maven/components/trunk/maven-core-it-verifier/src/main/java/org/apache/maven/it/Verifier.java
maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/FileUtils.java
Modified: maven/components/trunk/maven-core-it-verifier/src/main/java/org/apache/maven/it/Verifier.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core-it-verifier/src/main/java/org/apache/maven/it/Verifier.java?rev=394946&r1=394945&r2=394946&view=diff
==============================================================================
--- maven/components/trunk/maven-core-it-verifier/src/main/java/org/apache/maven/it/Verifier.java (original)
+++ maven/components/trunk/maven-core-it-verifier/src/main/java/org/apache/maven/it/Verifier.java Tue Apr 18 06:59:22 2006
@@ -6,6 +6,7 @@
import org.codehaus.plexus.util.cli.StreamConsumer;
import org.codehaus.plexus.util.cli.WriterStreamConsumer;
import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@@ -741,6 +742,28 @@
return result;
}
+ private static List discoverIntegrationTests( String directory ) throws VerificationException
+ {
+ try
+ {
+ ArrayList tests = new ArrayList();
+
+ List subTests = FileUtils.getFiles( new File( directory ), "**/goals.txt", null );
+
+ for ( Iterator i = subTests.iterator(); i.hasNext(); )
+ {
+ File testCase = (File) i.next();
+ tests.add( testCase.getParent() );
+ }
+
+ return tests;
+ }
+ catch (IOException e )
+ {
+ throw new VerificationException( directory + " is not a valid test case container", e);
+ }
+ }
+
private void displayLogFile()
{
System.out.println( "Log file contents:" );
@@ -841,17 +864,24 @@
if ( argsList.size() == 0 )
{
- try
- {
- tests = loadFile( basedir, "integration-tests.txt", false );
- }
- catch ( VerificationException e )
+ if ( FileUtils.fileExists( basedir + File.separator + "integration-tests.txt" ) )
{
- System.err.println( "Unable to load integration tests file" );
+ try
+ {
+ tests = loadFile( basedir, "integration-tests.txt", false );
+ }
+ catch ( VerificationException e )
+ {
+ System.err.println( "Unable to load integration tests file" );
- System.err.println( e.getMessage() );
+ System.err.println( e.getMessage() );
- System.exit( 2 );
+ System.exit( 2 );
+ }
+ }
+ else
+ {
+ tests = discoverIntegrationTests( "." );
}
}
else
@@ -865,14 +895,29 @@
{
test = test.substring( 0, test.length() - 1 );
}
- if ( !test.startsWith( "it" ) )
+
+ if ( StringUtils.isNumeric( test ) )
+ {
+
+ test = "it" + fmt.format( Integer.valueOf( test ) );
+ test.trim();
+ tests.add( test );
+ }
+ else if ( "it".startsWith( test ))
+ {
+ test = test.trim();
+ if ( test.length() > 0 )
+ {
+ tests.add( test );
+ }
+ }
+ else if ( FileUtils.fileExists( test ) && new File(test).isDirectory() )
{
- test = "it" + fmt.format( Integer.valueOf( test ) );
+ tests.addAll( discoverIntegrationTests( test ) );
}
- test = test.trim();
- if ( test.length() > 0 )
+ else
{
- tests.add( test );
+ System.err.println( "[WARNING] rejecting " + test + " as an invalid test or test source directory" );
}
}
}
Added: maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java?rev=394946&view=auto
==============================================================================
--- maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java (added)
+++ maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java Tue Apr 18 06:59:22 2006
@@ -0,0 +1,1059 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowlegement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.codehaus.org/)."
+ * Alternately, this acknowlegement may appear in the software itself,
+ * if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "Ant" and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact codehaus@codehaus.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.codehaus.org/>.
+ */
+
+package org.codehaus.plexus.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * Class for scanning a directory for files/directories which match certain
+ * criteria.
+ * <p>
+ * These criteria consist of selectors and patterns which have been specified.
+ * With the selectors you can select which files you want to have included.
+ * Files which are not selected are excluded. With patterns you can include
+ * or exclude files based on their filename.
+ * <p>
+ * The idea is simple. A given directory is recursively scanned for all files
+ * and directories. Each file/directory is matched against a set of selectors,
+ * including special support for matching against filenames with include and
+ * and exclude patterns. Only files/directories which match at least one
+ * pattern of the include pattern list or other file selector, and don't match
+ * any pattern of the exclude pattern list or fail to match against a required
+ * selector will be placed in the list of files/directories found.
+ * <p>
+ * When no list of include patterns is supplied, "**" will be used, which
+ * means that everything will be matched. When no list of exclude patterns is
+ * supplied, an empty list is used, such that nothing will be excluded. When
+ * no selectors are supplied, none are applied.
+ * <p>
+ * The filename pattern matching is done as follows:
+ * The name to be matched is split up in path segments. A path segment is the
+ * name of a directory or file, which is bounded by
+ * <code>File.separator</code> ('/' under UNIX, '\' under Windows).
+ * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
+ * "def","ghi" and "xyz.java".
+ * The same is done for the pattern against which should be matched.
+ * <p>
+ * The segments of the name and the pattern are then matched against each
+ * other. When '**' is used for a path segment in the pattern, it matches
+ * zero or more path segments of the name.
+ * <p>
+ * There is a special case regarding the use of <code>File.separator</code>s
+ * at the beginning of the pattern and the string to match:<br>
+ * When a pattern starts with a <code>File.separator</code>, the string
+ * to match must also start with a <code>File.separator</code>.
+ * When a pattern does not start with a <code>File.separator</code>, the
+ * string to match may not start with a <code>File.separator</code>.
+ * When one of these rules is not obeyed, the string will not
+ * match.
+ * <p>
+ * When a name path segment is matched against a pattern path segment, the
+ * following special characters can be used:<br>
+ * '*' matches zero or more characters<br>
+ * '?' matches one character.
+ * <p>
+ * Examples:
+ * <p>
+ * "**\*.class" matches all .class files/dirs in a directory tree.
+ * <p>
+ * "test\a??.java" matches all files/dirs which start with an 'a', then two
+ * more characters and then ".java", in a directory called test.
+ * <p>
+ * "**" matches everything in a directory tree.
+ * <p>
+ * "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where
+ * there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
+ * <p>
+ * Case sensitivity may be turned off if necessary. By default, it is
+ * turned on.
+ * <p>
+ * Example of usage:
+ * <pre>
+ * String[] includes = {"**\\*.class"};
+ * String[] excludes = {"modules\\*\\**"};
+ * ds.setIncludes(includes);
+ * ds.setExcludes(excludes);
+ * ds.setBasedir(new File("test"));
+ * ds.setCaseSensitive(true);
+ * ds.scan();
+ *
+ * System.out.println("FILES:");
+ * String[] files = ds.getIncludedFiles();
+ * for (int i = 0; i < files.length; i++) {
+ * System.out.println(files[i]);
+ * }
+ * </pre>
+ * This will scan a directory called test for .class files, but excludes all
+ * files in all proper subdirectories of a directory called "modules"
+ *
+ * @author Arnout J. Kuiper
+ * <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
+ * @author Magesh Umasankar
+ * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
+ * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
+ */
+public class DirectoryScanner
+{
+ /**
+ * Patterns which should be excluded by default.
+ *
+ * @see #addDefaultExcludes()
+ */
+ public static final String[] DEFAULTEXCLUDES = {
+ // Miscellaneous typical temporary files
+ "**/*~",
+ "**/#*#",
+ "**/.#*",
+ "**/%*%",
+ "**/._*",
+
+ // CVS
+ "**/CVS",
+ "**/CVS/**",
+ "**/.cvsignore",
+
+ // SCCS
+ "**/SCCS",
+ "**/SCCS/**",
+
+ // Visual SourceSafe
+ "**/vssver.scc",
+
+ // Subversion
+ "**/.svn",
+ "**/.svn/**",
+
+ // Arch
+ "**/.arch-ids",
+ "**/.arch-ids/**",
+
+ //Bazaar
+ "**/.bzr",
+ "**/.bzr/**",
+
+ //SurroundSCM
+ "**/.MySCMServerInfo",
+
+ // Mac
+ "**/.DS_Store"
+ };
+
+ /** The base directory to be scanned. */
+ protected File basedir;
+
+ /** The patterns for the files to be included. */
+ protected String[] includes;
+
+ /** The patterns for the files to be excluded. */
+ protected String[] excludes;
+
+ /** The files which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected Vector filesIncluded;
+
+ /** The files which did not match any includes or selectors. */
+ protected Vector filesNotIncluded;
+
+ /**
+ * The files which matched at least one include and at least
+ * one exclude.
+ */
+ protected Vector filesExcluded;
+
+ /** The directories which matched at least one include and no excludes
+ * and were selected.
+ */
+ protected Vector dirsIncluded;
+
+ /** The directories which were found and did not match any includes. */
+ protected Vector dirsNotIncluded;
+
+ /**
+ * The directories which matched at least one include and at least one
+ * exclude.
+ */
+ protected Vector dirsExcluded;
+
+ /** The files which matched at least one include and no excludes and
+ * which a selector discarded.
+ */
+ protected Vector filesDeselected;
+
+ /** The directories which matched at least one include and no excludes
+ * but which a selector discarded.
+ */
+ protected Vector dirsDeselected;
+
+ /** Whether or not our results were built by a slow scan. */
+ protected boolean haveSlowResults = false;
+
+ /**
+ * Whether or not the file system should be treated as a case sensitive
+ * one.
+ */
+ protected boolean isCaseSensitive = true;
+
+ /**
+ * Whether or not symbolic links should be followed.
+ *
+ * @since Ant 1.5
+ */
+ private boolean followSymlinks = true;
+
+ /** Whether or not everything tested so far has been included. */
+ protected boolean everythingIncluded = true;
+
+ /**
+ * Sole constructor.
+ */
+ public DirectoryScanner()
+ {
+ }
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ protected static boolean matchPatternStart( String pattern, String str )
+ {
+ return SelectorUtils.matchPatternStart( pattern, str );
+ }
+
+ /**
+ * Tests whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ * <p>
+ * This is not a general purpose test and should only be used if you
+ * can live with false positives. For example, <code>pattern=**\a</code>
+ * and <code>str=b</code> will yield <code>true</code>.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return whether or not a given path matches the start of a given
+ * pattern up to the first "**".
+ */
+ protected static boolean matchPatternStart( String pattern, String str,
+ boolean isCaseSensitive )
+ {
+ return SelectorUtils.matchPatternStart( pattern, str, isCaseSensitive );
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean matchPath( String pattern, String str )
+ {
+ return SelectorUtils.matchPath( pattern, str );
+ }
+
+ /**
+ * Tests whether or not a given path matches a given pattern.
+ *
+ * @param pattern The pattern to match against. Must not be
+ * <code>null</code>.
+ * @param str The path to match, as a String. Must not be
+ * <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ * @return <code>true</code> if the pattern matches against the string,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean matchPath( String pattern, String str,
+ boolean isCaseSensitive )
+ {
+ return SelectorUtils.matchPath( pattern, str, isCaseSensitive );
+ }
+
+ /**
+ * Tests whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ public static boolean match( String pattern, String str )
+ {
+ return SelectorUtils.match( pattern, str );
+ }
+
+ /**
+ * Tests whether or not a string matches against a pattern.
+ * The pattern may contain two special characters:<br>
+ * '*' means zero or more characters<br>
+ * '?' means one and only one character
+ *
+ * @param pattern The pattern to match against.
+ * Must not be <code>null</code>.
+ * @param str The string which must be matched against the pattern.
+ * Must not be <code>null</code>.
+ * @param isCaseSensitive Whether or not matching should be performed
+ * case sensitively.
+ *
+ *
+ * @return <code>true</code> if the string matches against the pattern,
+ * or <code>false</code> otherwise.
+ */
+ protected static boolean match( String pattern, String str,
+ boolean isCaseSensitive )
+ {
+ return SelectorUtils.match( pattern, str, isCaseSensitive );
+ }
+
+ /**
+ * Sets the base directory to be scanned. This is the directory which is
+ * scanned recursively. All '/' and '\' characters are replaced by
+ * <code>File.separatorChar</code>, so the separator used need not match
+ * <code>File.separatorChar</code>.
+ *
+ * @param basedir The base directory to scan.
+ * Must not be <code>null</code>.
+ */
+ public void setBasedir( String basedir )
+ {
+ setBasedir( new File( basedir.replace( '/', File.separatorChar ).replace(
+ '\\', File.separatorChar ) ) );
+ }
+
+ /**
+ * Sets the base directory to be scanned. This is the directory which is
+ * scanned recursively.
+ *
+ * @param basedir The base directory for scanning.
+ * Should not be <code>null</code>.
+ */
+ public void setBasedir( File basedir )
+ {
+ this.basedir = basedir;
+ }
+
+ /**
+ * Returns the base directory to be scanned.
+ * This is the directory which is scanned recursively.
+ *
+ * @return the base directory to be scanned
+ */
+ public File getBasedir()
+ {
+ return basedir;
+ }
+
+ /**
+ * Sets whether or not the file system should be regarded as case sensitive.
+ *
+ * @param isCaseSensitive whether or not the file system should be
+ * regarded as a case sensitive one
+ */
+ public void setCaseSensitive( boolean isCaseSensitive )
+ {
+ this.isCaseSensitive = isCaseSensitive;
+ }
+
+ /**
+ * Sets whether or not symbolic links should be followed.
+ *
+ * @param followSymlinks whether or not symbolic links should be followed
+ */
+ public void setFollowSymlinks( boolean followSymlinks )
+ {
+ this.followSymlinks = followSymlinks;
+ }
+
+ /**
+ * Sets the list of include patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separatorChar</code>, so the separator used
+ * need not match <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param includes A list of include patterns.
+ * May be <code>null</code>, indicating that all files
+ * should be included. If a non-<code>null</code>
+ * list is given, all elements must be
+ * non-<code>null</code>.
+ */
+ public void setIncludes( String[] includes )
+ {
+ if ( includes == null )
+ {
+ this.includes = null;
+ }
+ else
+ {
+ this.includes = new String[includes.length];
+ for ( int i = 0; i < includes.length; i++ )
+ {
+ String pattern;
+ pattern = includes[i].trim().replace( '/', File.separatorChar ).replace(
+ '\\', File.separatorChar );
+ if ( pattern.endsWith( File.separator ) )
+ {
+ pattern += "**";
+ }
+ this.includes[i] = pattern;
+ }
+ }
+ }
+
+
+ /**
+ * Sets the list of exclude patterns to use. All '/' and '\' characters
+ * are replaced by <code>File.separatorChar</code>, so the separator used
+ * need not match <code>File.separatorChar</code>.
+ * <p>
+ * When a pattern ends with a '/' or '\', "**" is appended.
+ *
+ * @param excludes A list of exclude patterns.
+ * May be <code>null</code>, indicating that no files
+ * should be excluded. If a non-<code>null</code> list is
+ * given, all elements must be non-<code>null</code>.
+ */
+ public void setExcludes( String[] excludes )
+ {
+ if ( excludes == null )
+ {
+ this.excludes = null;
+ }
+ else
+ {
+ this.excludes = new String[excludes.length];
+ for ( int i = 0; i < excludes.length; i++ )
+ {
+ String pattern;
+ pattern = excludes[i].trim().replace( '/', File.separatorChar ).replace(
+ '\\', File.separatorChar );
+ if ( pattern.endsWith( File.separator ) )
+ {
+ pattern += "**";
+ }
+ this.excludes[i] = pattern;
+ }
+ }
+ }
+
+ /**
+ * Returns whether or not the scanner has included all the files or
+ * directories it has come across so far.
+ *
+ * @return <code>true</code> if all files and directories which have
+ * been found so far have been included.
+ */
+ public boolean isEverythingIncluded()
+ {
+ return everythingIncluded;
+ }
+
+ /**
+ * Scans the base directory for files which match at least one include
+ * pattern and don't match any exclude patterns. If there are selectors
+ * then the files must pass muster there, as well.
+ *
+ * @exception IllegalStateException if the base directory was set
+ * incorrectly (i.e. if it is <code>null</code>, doesn't exist,
+ * or isn't a directory).
+ */
+ public void scan() throws IllegalStateException
+ {
+ if ( basedir == null )
+ {
+ throw new IllegalStateException( "No basedir set" );
+ }
+ if ( !basedir.exists() )
+ {
+ throw new IllegalStateException( "basedir " + basedir
+ + " does not exist" );
+ }
+ if ( !basedir.isDirectory() )
+ {
+ throw new IllegalStateException( "basedir " + basedir
+ + " is not a directory" );
+ }
+
+ if ( includes == null )
+ {
+ // No includes supplied, so set it to 'matches all'
+ includes = new String[1];
+ includes[0] = "**";
+ }
+ if ( excludes == null )
+ {
+ excludes = new String[0];
+ }
+
+ filesIncluded = new Vector();
+ filesNotIncluded = new Vector();
+ filesExcluded = new Vector();
+ filesDeselected = new Vector();
+ dirsIncluded = new Vector();
+ dirsNotIncluded = new Vector();
+ dirsExcluded = new Vector();
+ dirsDeselected = new Vector();
+
+ if ( isIncluded( "" ) )
+ {
+ if ( !isExcluded( "" ) )
+ {
+ if ( isSelected( "", basedir ) )
+ {
+ dirsIncluded.addElement( "" );
+ }
+ else
+ {
+ dirsDeselected.addElement( "" );
+ }
+ }
+ else
+ {
+ dirsExcluded.addElement( "" );
+ }
+ }
+ else
+ {
+ dirsNotIncluded.addElement( "" );
+ }
+ scandir( basedir, "", true );
+ }
+
+ /**
+ * Top level invocation for a slow scan. A slow scan builds up a full
+ * list of excluded/included files/directories, whereas a fast scan
+ * will only have full results for included files, as it ignores
+ * directories which can't possibly hold any included files/directories.
+ * <p>
+ * Returns immediately if a slow scan has already been completed.
+ */
+ protected void slowScan()
+ {
+ if ( haveSlowResults )
+ {
+ return;
+ }
+
+ String[] excl = new String[dirsExcluded.size()];
+ dirsExcluded.copyInto( excl );
+
+ String[] notIncl = new String[dirsNotIncluded.size()];
+ dirsNotIncluded.copyInto( notIncl );
+
+ for ( int i = 0; i < excl.length; i++ )
+ {
+ if ( !couldHoldIncluded( excl[i] ) )
+ {
+ scandir( new File( basedir, excl[i] ),
+ excl[i] + File.separator, false );
+ }
+ }
+
+ for ( int i = 0; i < notIncl.length; i++ )
+ {
+ if ( !couldHoldIncluded( notIncl[i] ) )
+ {
+ scandir( new File( basedir, notIncl[i] ),
+ notIncl[i] + File.separator, false );
+ }
+ }
+
+ haveSlowResults = true;
+ }
+
+ /**
+ * Scans the given directory for files and directories. Found files and
+ * directories are placed in their respective collections, based on the
+ * matching of includes, excludes, and the selectors. When a directory
+ * is found, it is scanned recursively.
+ *
+ * @param dir The directory to scan. Must not be <code>null</code>.
+ * @param vpath The path relative to the base directory (needed to
+ * prevent problems with an absolute path when using
+ * dir). Must not be <code>null</code>.
+ * @param fast Whether or not this call is part of a fast scan.
+ *
+ * @see #filesIncluded
+ * @see #filesNotIncluded
+ * @see #filesExcluded
+ * @see #dirsIncluded
+ * @see #dirsNotIncluded
+ * @see #dirsExcluded
+ * @see #slowScan
+ */
+ protected void scandir( File dir, String vpath, boolean fast )
+ {
+ String[] newfiles = dir.list();
+
+ if ( newfiles == null )
+ {
+ /*
+ * two reasons are mentioned in the API docs for File.list
+ * (1) dir is not a directory. This is impossible as
+ * we wouldn't get here in this case.
+ * (2) an IO error occurred (why doesn't it throw an exception
+ * then???)
+ */
+ //throw new Exception( "IO error scanning directory " + dir.getAbsolutePath() );
+ }
+
+ if ( !followSymlinks )
+ {
+ Vector noLinks = new Vector();
+ for ( int i = 0; i < newfiles.length; i++ )
+ {
+ try
+ {
+ if ( isSymbolicLink( dir, newfiles[i] ) )
+ {
+ String name = vpath + newfiles[i];
+ File file = new File( dir, newfiles[i] );
+ if ( file.isDirectory() )
+ {
+ dirsExcluded.addElement( name );
+ }
+ else
+ {
+ filesExcluded.addElement( name );
+ }
+ }
+ else
+ {
+ noLinks.addElement( newfiles[i] );
+ }
+ }
+ catch ( IOException ioe )
+ {
+ String msg = "IOException caught while checking "
+ + "for links, couldn't get cannonical path!";
+ // will be caught and redirected to Ant's logging system
+ System.err.println( msg );
+ noLinks.addElement( newfiles[i] );
+ }
+ }
+ newfiles = new String[noLinks.size()];
+ noLinks.copyInto( newfiles );
+ }
+
+ for ( int i = 0; i < newfiles.length; i++ )
+ {
+ String name = vpath + newfiles[i];
+ File file = new File( dir, newfiles[i] );
+ if ( file.isDirectory() )
+ {
+ if ( isIncluded( name ) )
+ {
+ if ( !isExcluded( name ) )
+ {
+ if ( isSelected( name, file ) )
+ {
+ dirsIncluded.addElement( name );
+ if ( fast )
+ {
+ scandir( file, name + File.separator, fast );
+ }
+ }
+ else
+ {
+ everythingIncluded = false;
+ dirsDeselected.addElement( name );
+ if ( fast && couldHoldIncluded( name ) )
+ {
+ scandir( file, name + File.separator, fast );
+ }
+ }
+
+ }
+ else
+ {
+ everythingIncluded = false;
+ dirsExcluded.addElement( name );
+ if ( fast && couldHoldIncluded( name ) )
+ {
+ scandir( file, name + File.separator, fast );
+ }
+ }
+ }
+ else
+ {
+ everythingIncluded = false;
+ dirsNotIncluded.addElement( name );
+ if ( fast && couldHoldIncluded( name ) )
+ {
+ scandir( file, name + File.separator, fast );
+ }
+ }
+ if ( !fast )
+ {
+ scandir( file, name + File.separator, fast );
+ }
+ }
+ else if ( file.isFile() )
+ {
+ if ( isIncluded( name ) )
+ {
+ if ( !isExcluded( name ) )
+ {
+ if ( isSelected( name, file ) )
+ {
+ filesIncluded.addElement( name );
+ }
+ else
+ {
+ everythingIncluded = false;
+ filesDeselected.addElement( name );
+ }
+ }
+ else
+ {
+ everythingIncluded = false;
+ filesExcluded.addElement( name );
+ }
+ }
+ else
+ {
+ everythingIncluded = false;
+ filesNotIncluded.addElement( name );
+ }
+ }
+ }
+ }
+
+ /**
+ * Tests whether or not a name matches against at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * include pattern, or <code>false</code> otherwise.
+ */
+ protected boolean isIncluded( String name )
+ {
+ for ( int i = 0; i < includes.length; i++ )
+ {
+ if ( matchPath( includes[i], name, isCaseSensitive ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tests whether or not a name matches the start of at least one include
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against the start of at
+ * least one include pattern, or <code>false</code> otherwise.
+ */
+ protected boolean couldHoldIncluded( String name )
+ {
+ for ( int i = 0; i < includes.length; i++ )
+ {
+ if ( matchPatternStart( includes[i], name, isCaseSensitive ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tests whether or not a name matches against at least one exclude
+ * pattern.
+ *
+ * @param name The name to match. Must not be <code>null</code>.
+ * @return <code>true</code> when the name matches against at least one
+ * exclude pattern, or <code>false</code> otherwise.
+ */
+ protected boolean isExcluded( String name )
+ {
+ for ( int i = 0; i < excludes.length; i++ )
+ {
+ if ( matchPath( excludes[i], name, isCaseSensitive ) )
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Tests whether a name should be selected.
+ *
+ * @param name the filename to check for selecting
+ * @param file the java.io.File object for this filename
+ * @return <code>false</code> when the selectors says that the file
+ * should not be selected, <code>true</code> otherwise.
+ */
+ protected boolean isSelected( String name, File file )
+ {
+ return true;
+ }
+
+ /**
+ * Returns the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedFiles()
+ {
+ String[] files = new String[filesIncluded.size()];
+ filesIncluded.copyInto( files );
+ return files;
+ }
+
+ /**
+ * Returns the names of the files which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public String[] getNotIncludedFiles()
+ {
+ slowScan();
+ String[] files = new String[filesNotIncluded.size()];
+ filesNotIncluded.copyInto( files );
+ return files;
+ }
+
+ /**
+ * Returns the names of the files which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the files which matched at least one of the
+ * include patterns and at at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public String[] getExcludedFiles()
+ {
+ slowScan();
+ String[] files = new String[filesExcluded.size()];
+ filesExcluded.copyInto( files );
+ return files;
+ }
+
+ /**
+ * <p>Returns the names of the files which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the files which were deselected.
+ *
+ * @see #slowScan
+ */
+ public String[] getDeselectedFiles()
+ {
+ slowScan();
+ String[] files = new String[filesDeselected.size()];
+ filesDeselected.copyInto( files );
+ return files;
+ }
+
+ /**
+ * Returns the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ * The names are relative to the base directory.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and none of the exclude patterns.
+ */
+ public String[] getIncludedDirectories()
+ {
+ String[] directories = new String[dirsIncluded.size()];
+ dirsIncluded.copyInto( directories );
+ return directories;
+ }
+
+ /**
+ * Returns the names of the directories which matched none of the include
+ * patterns. The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched none of the include
+ * patterns.
+ *
+ * @see #slowScan
+ */
+ public String[] getNotIncludedDirectories()
+ {
+ slowScan();
+ String[] directories = new String[dirsNotIncluded.size()];
+ dirsNotIncluded.copyInto( directories );
+ return directories;
+ }
+
+ /**
+ * Returns the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ * The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.
+ *
+ * @return the names of the directories which matched at least one of the
+ * include patterns and at least one of the exclude patterns.
+ *
+ * @see #slowScan
+ */
+ public String[] getExcludedDirectories()
+ {
+ slowScan();
+ String[] directories = new String[dirsExcluded.size()];
+ dirsExcluded.copyInto( directories );
+ return directories;
+ }
+
+ /**
+ * <p>Returns the names of the directories which were selected out and
+ * therefore not ultimately included.</p>
+ *
+ * <p>The names are relative to the base directory. This involves
+ * performing a slow scan if one has not already been completed.</p>
+ *
+ * @return the names of the directories which were deselected.
+ *
+ * @see #slowScan
+ */
+ public String[] getDeselectedDirectories()
+ {
+ slowScan();
+ String[] directories = new String[dirsDeselected.size()];
+ dirsDeselected.copyInto( directories );
+ return directories;
+ }
+
+ /**
+ * Adds default exclusions to the current exclusions set.
+ */
+ public void addDefaultExcludes()
+ {
+ int excludesLength = excludes == null ? 0 : excludes.length;
+ String[] newExcludes;
+ newExcludes = new String[excludesLength + DEFAULTEXCLUDES.length];
+ if ( excludesLength > 0 )
+ {
+ System.arraycopy( excludes, 0, newExcludes, 0, excludesLength );
+ }
+ for ( int i = 0; i < DEFAULTEXCLUDES.length; i++ )
+ {
+ newExcludes[i + excludesLength] = DEFAULTEXCLUDES[i].replace( '/',
+ File.separatorChar ).replace( '\\', File.separatorChar );
+ }
+ excludes = newExcludes;
+ }
+
+ /**
+ * Checks whether a given file is a symbolic link.
+ *
+ * <p>It doesn't really test for symbolic links but whether the
+ * canonical and absolute paths of the file are identical - this
+ * may lead to false positives on some platforms.</p>
+ *
+ * @param parent the parent directory of the file to test
+ * @param name the name of the file to test.
+ *
+ * @since Ant 1.5
+ */
+ public boolean isSymbolicLink( File parent, String name )
+ throws IOException
+ {
+ File resolvedParent = new File( parent.getCanonicalPath() );
+ File toTest = new File( resolvedParent, name );
+ return !toTest.getAbsolutePath().equals( toTest.getCanonicalPath() );
+ }
+
+}
Propchange: maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: maven/components/trunk/maven-core-it-verifier/src/main/java/org/codehaus/plexus/util/DirectoryScanner.java
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Revision"