maven-verifier-1.2/ 0000755 0001750 0001750 00000000000 11625266351 014240 5 ustar twerner twerner maven-verifier-1.2/pom.xml 0000644 0001750 0001750 00000003607 11253546300 015553 0 ustar twerner twerner
* Possible values:
*
Methods exist to retrieve the components of a typical file path. For example
* /www/hosted/mysite/index.html
, can be broken into:
*
/www/hosted/mysite/
-- retrievable through {@link #getPath}index.html
-- retrievable through {@link #removePath}/www/hosted/mysite/index
-- retrievable through {@link #removeExtension}html
-- retrievable through {@link #getExtension}File
manager.
*/
public static File getFile( String fileName )
{
return new File( fileName );
}
/**
* Given a directory and an array of extensions return an array of compliant files.
*
* TODO Should an ignore list be passed in?
* TODO Should a recurse flag be passed in?
*
* The given extensions should be like "java" and not like ".java"
*/
public static String[] getFilesFromExtension( String directory, String[] extensions )
{
Vector files = new Vector();
java.io.File currentDir = new java.io.File( directory );
String[] unknownFiles = currentDir.list();
if ( unknownFiles == null )
{
return new String[0];
}
for ( int i = 0; i < unknownFiles.length; ++i )
{
String currentFileName = directory + System.getProperty( "file.separator" ) + unknownFiles[i];
java.io.File currentFile = new java.io.File( currentFileName );
if ( currentFile.isDirectory() )
{
//ignore all CVS directories...
if ( currentFile.getName().equals( "CVS" ) )
{
continue;
}
//ok... transverse into this directory and get all the files... then combine
//them with the current list.
String[] fetchFiles = getFilesFromExtension( currentFileName, extensions );
files = blendFilesToVector( files, fetchFiles );
}
else
{
//ok... add the file
String add = currentFile.getAbsolutePath();
if ( isValidFile( add, extensions ) )
{
files.addElement( add );
}
}
}
//ok... move the Vector into the files list...
String[] foundFiles = new String[files.size()];
files.copyInto( foundFiles );
return foundFiles;
}
/**
* Private hepler method for getFilesFromExtension()
*/
private static Vector blendFilesToVector( Vector v, String[] files )
{
for ( int i = 0; i < files.length; ++i )
{
v.addElement( files[i] );
}
return v;
}
/**
* Checks to see if a file is of a particular type(s).
* Note that if the file does not have an extension, an empty string
* ("") is matched for.
*/
private static boolean isValidFile( String file, String[] extensions )
{
String extension = extension( file );
if ( extension == null )
{
extension = "";
}
//ok.. now that we have the "extension" go through the current know
//excepted extensions and determine if this one is OK.
for ( int i = 0; i < extensions.length; ++i )
{
if ( extensions[i].equals( extension ) )
{
return true;
}
}
return false;
}
/**
* Simple way to make a directory
*/
public static void mkdir( String dir )
{
File file = new File( dir );
if ( !file.exists() )
{
file.mkdirs();
}
}
/**
* Compare the contents of two files to determine if they are equal or not.
*
* @param file1 the first file
* @param file2 the second file
* @return true if the content of the files are equal or they both don't exist, false otherwise
*/
public static boolean contentEquals( final File file1, final File file2 )
throws IOException
{
final boolean file1Exists = file1.exists();
if ( file1Exists != file2.exists() )
{
return false;
}
if ( !file1Exists )
{
// two not existing files are equal
return true;
}
if ( file1.isDirectory() || file2.isDirectory() )
{
// don't want to compare directory contents
return false;
}
InputStream input1 = null;
InputStream input2 = null;
try
{
input1 = new FileInputStream( file1 );
input2 = new FileInputStream( file2 );
return IOUtil.contentEquals( input1, input2 );
}
finally
{
IOUtil.close( input1 );
IOUtil.close( input2 );
}
}
/**
* Convert from a URL
to a File
.
*
* @param url File URL.
* @return The equivalent File
object, or null
if the URL's protocol
* is not file
*/
public static File toFile( final URL url )
{
if ( url.getProtocol().equals( "file" ) == false )
{
return null;
}
else
{
final String filename = url.getFile().replace( '/', File.separatorChar );
return new File( filename );
}
}
/**
* Convert the array of Files into a list of URLs.
*
* @param files the array of files
* @return the array of URLs
* @throws IOException if an error occurs
*/
public static URL[] toURLs( final File[] files )
throws IOException
{
final URL[] urls = new URL[files.length];
for ( int i = 0; i < urls.length; i++ )
{
urls[i] = files[i].toURL();
}
return urls;
}
/**
* Remove extension from filename.
* ie
* * foo.txt --> foo * a\b\c.jpg --> a\b\c * a\b\c --> a\b\c ** * @param filename the filename * @return the filename minus extension */ public static String removeExtension( final String filename ) { final int index = filename.lastIndexOf( '.' ); if ( -1 == index ) { return filename; } else { return filename.substring( 0, index ); } } /** * Get extension from filename. * ie *
* foo.txt --> "txt" * a\b\c.jpg --> "jpg" * a\b\c --> "" ** * @param filename the filename * @return the extension of filename or "" if none */ public static String getExtension( final String filename ) { final int index = filename.lastIndexOf( '.' ); if ( -1 == index ) { return ""; } else { return filename.substring( index + 1 ); } } /** * Remove path from filename. Equivalent to the unix command
basename
* ie.
* * a/b/c.txt --> c.txt * a.txt --> a.txt ** * @param filepath the filepath * @return the filename minus path */ public static String removePath( final String filepath ) { return removePath( filepath, File.separatorChar ); } /** * Remove path from filename. * ie. *
* a/b/c.txt --> c.txt * a.txt --> a.txt ** * @param filepath the filepath * @return the filename minus path */ public static String removePath( final String filepath, final char fileSeparatorChar ) { final int index = filepath.lastIndexOf( fileSeparatorChar ); if ( -1 == index ) { return filepath; } else { return filepath.substring( index + 1 ); } } /** * Get path from filename. Roughly equivalent to the unix command
dirname
.
* ie.
* * a/b/c.txt --> a/b * a.txt --> "" ** * @param filepath the filepath * @return the filename minus path */ public static String getPath( final String filepath ) { return getPath( filepath, File.separatorChar ); } /** * Get path from filename. * ie. *
* a/b/c.txt --> a/b * a.txt --> "" ** * @param filepath the filepath * @return the filename minus path */ public static String getPath( final String filepath, final char fileSeparatorChar ) { final int index = filepath.lastIndexOf( fileSeparatorChar ); if ( -1 == index ) { return ""; } else { return filepath.substring( 0, index ); } } /** * Copy file from source to destination. If
destinationDirectory
does not exist, it
* (and any parent directories) will be created. If a file source
in
* destinationDirectory
exists, it will be overwritten.
*
* @param source An existing File
to copy.
* @param destinationDirectory A directory to copy source
into.
* @throws java.io.FileNotFoundException if source
isn't a normal file.
* @throws IllegalArgumentException if destinationDirectory
isn't a directory.
* @throws IOException if source
does not exist, the file in
* destinationDirectory
cannot be written to, or an IO error occurs during copying.
*/
public static void copyFileToDirectory( final String source, final String destinationDirectory )
throws IOException
{
copyFileToDirectory( new File( source ), new File( destinationDirectory ) );
}
/**
* Copy file from source to destination only if source is newer than the target file.
* If destinationDirectory
does not exist, it
* (and any parent directories) will be created. If a file source
in
* destinationDirectory
exists, it will be overwritten.
*
* @param source An existing File
to copy.
* @param destinationDirectory A directory to copy source
into.
* @throws java.io.FileNotFoundException if source
isn't a normal file.
* @throws IllegalArgumentException if destinationDirectory
isn't a directory.
* @throws IOException if source
does not exist, the file in
* destinationDirectory
cannot be written to, or an IO error occurs during copying.
*/
public static void copyFileToDirectoryIfModified( final String source, final String destinationDirectory )
throws IOException
{
copyFileToDirectoryIfModified( new File( source ), new File( destinationDirectory ) );
}
/**
* Copy file from source to destination. If destinationDirectory
does not exist, it
* (and any parent directories) will be created. If a file source
in
* destinationDirectory
exists, it will be overwritten.
*
* @param source An existing File
to copy.
* @param destinationDirectory A directory to copy source
into.
* @throws java.io.FileNotFoundException if source
isn't a normal file.
* @throws IllegalArgumentException if destinationDirectory
isn't a directory.
* @throws IOException if source
does not exist, the file in
* destinationDirectory
cannot be written to, or an IO error occurs during copying.
*/
public static void copyFileToDirectory( final File source, final File destinationDirectory )
throws IOException
{
if ( destinationDirectory.exists() && !destinationDirectory.isDirectory() )
{
throw new IllegalArgumentException( "Destination is not a directory" );
}
copyFile( source, new File( destinationDirectory, source.getName() ) );
}
/**
* Copy file from source to destination only if source is newer than the target file.
* If destinationDirectory
does not exist, it
* (and any parent directories) will be created. If a file source
in
* destinationDirectory
exists, it will be overwritten.
*
* @param source An existing File
to copy.
* @param destinationDirectory A directory to copy source
into.
* @throws java.io.FileNotFoundException if source
isn't a normal file.
* @throws IllegalArgumentException if destinationDirectory
isn't a directory.
* @throws IOException if source
does not exist, the file in
* destinationDirectory
cannot be written to, or an IO error occurs during copying.
*/
public static void copyFileToDirectoryIfModified( final File source, final File destinationDirectory )
throws IOException
{
if ( destinationDirectory.exists() && !destinationDirectory.isDirectory() )
{
throw new IllegalArgumentException( "Destination is not a directory" );
}
copyFileIfModified( source, new File( destinationDirectory, source.getName() ) );
}
/**
* Copy file from source to destination. The directories up to destination
will be
* created if they don't already exist. destination
will be overwritten if it
* already exists.
*
* @param source An existing non-directory File
to copy bytes from.
* @param destination A non-directory File
to write bytes to (possibly
* overwriting).
* @throws IOException if source
does not exist, destination
cannot be
* written to, or an IO error occurs during copying.
* @throws java.io.FileNotFoundException if destination
is a directory
* (use {@link #copyFileToDirectory}).
*/
public static void copyFile( final File source, final File destination )
throws IOException
{
//check source exists
if ( !source.exists() )
{
final String message = "File " + source + " does not exist";
throw new IOException( message );
}
//does destinations directory exist ?
if ( destination.getParentFile() != null && !destination.getParentFile().exists() )
{
destination.getParentFile().mkdirs();
}
//make sure we can write to destination
if ( destination.exists() && !destination.canWrite() )
{
final String message = "Unable to open file " + destination + " for writing.";
throw new IOException( message );
}
FileInputStream input = null;
FileOutputStream output = null;
try
{
input = new FileInputStream( source );
output = new FileOutputStream( destination );
IOUtil.copy( input, output );
}
finally
{
IOUtil.close( input );
IOUtil.close( output );
}
if ( source.length() != destination.length() )
{
final String message = "Failed to copy full contents from " + source + " to " + destination;
throw new IOException( message );
}
}
/**
* Copy file from source to destination only if source timestamp is later than the destination timestamp.
* The directories up to destination
will be created if they don't already exist.
* destination
will be overwritten if it already exists.
*
* @param source An existing non-directory File
to copy bytes from.
* @param destination A non-directory File
to write bytes to (possibly
* overwriting).
* @throws IOException if source
does not exist, destination
cannot be
* written to, or an IO error occurs during copying.
* @throws java.io.FileNotFoundException if destination
is a directory
* (use {@link #copyFileToDirectory}).
*/
public static boolean copyFileIfModified( final File source, final File destination )
throws IOException
{
if ( destination.lastModified() < source.lastModified() )
{
copyFile( source, destination );
return true;
}
return false;
}
/**
* Copies bytes from the URL source
to a file destination
.
* The directories up to destination
will be created if they don't already exist.
* destination
will be overwritten if it already exists.
*
* @param source A URL
to copy bytes from.
* @param destination A non-directory File
to write bytes to (possibly
* overwriting).
* @throws IOException if
* source
URL cannot be openeddestination
cannot be written tonull
if the ..'s went past the
* root.
* Eg:
* * /foo// --> /foo/ * /foo/./ --> /foo/ * /foo/../bar --> /bar * /foo/../bar/ --> /bar/ * /foo/../bar/../baz --> /baz * //foo//./bar --> /foo/bar * /../ --> null ** * @param path the path to normalize * @return the normalized String, or
null
if too many ..'s.
*/
public static String normalize( final String path )
{
String normalized = path;
// Resolve occurrences of "//" in the normalized path
while ( true )
{
int index = normalized.indexOf( "//" );
if ( index < 0 )
{
break;
}
normalized = normalized.substring( 0, index ) + normalized.substring( index + 1 );
}
// Resolve occurrences of "/./" in the normalized path
while ( true )
{
int index = normalized.indexOf( "/./" );
if ( index < 0 )
{
break;
}
normalized = normalized.substring( 0, index ) + normalized.substring( index + 2 );
}
// Resolve occurrences of "/../" in the normalized path
while ( true )
{
int index = normalized.indexOf( "/../" );
if ( index < 0 )
{
break;
}
if ( index == 0 )
{
return null; // Trying to go outside our context
}
int index2 = normalized.lastIndexOf( '/', index - 1 );
normalized = normalized.substring( 0, index2 ) + normalized.substring( index + 3 );
}
// Return the normalized path that we have completed
return normalized;
}
/**
* Will concatenate 2 paths. Paths with ..
will be
* properly handled.
* Eg.,
* /a/b/c
+ d
= /a/b/d
* /a/b/c
+ ../d
= /a/d
*
filename
to it's canonical form. If filename
is
* relative (doesn't start with /
), it will be resolved relative to
* baseFile
, otherwise it is treated as a normal root-relative path.
*
* @param baseFile Where to resolve filename
from, if filename
is
* relative.
* @param filename Absolute or relative file path to resolve.
* @return The canonical File
of filename
.
*/
public static File resolveFile( final File baseFile, String filename )
{
String filenm = filename;
if ( '/' != File.separatorChar )
{
filenm = filename.replace( '/', File.separatorChar );
}
if ( '\\' != File.separatorChar )
{
filenm = filename.replace( '\\', File.separatorChar );
}
// deal with absolute files
if ( filenm.startsWith( File.separator ) || ( Os.isFamily( "windows" ) && filenm.indexOf( ":" ) > 0 ) )
{
File file = new File( filenm );
try
{
file = file.getCanonicalFile();
}
catch ( final IOException ioe )
{
}
return file;
}
// FIXME: I'm almost certain this // removal is unnecessary, as getAbsoluteFile() strips
// them. However, I'm not sure about this UNC stuff. (JT)
final char[] chars = filename.toCharArray();
final StringBuffer sb = new StringBuffer();
//remove duplicate file separators in succession - except
//on win32 at start of filename as UNC filenames can
//be \\AComputer\AShare\myfile.txt
int start = 0;
if ( '\\' == File.separatorChar )
{
sb.append( filenm.charAt( 0 ) );
start++;
}
for ( int i = start; i < chars.length; i++ )
{
final boolean doubleSeparator = File.separatorChar == chars[i] && File.separatorChar == chars[i - 1];
if ( !doubleSeparator )
{
sb.append( chars[i] );
}
}
filenm = sb.toString();
//must be relative
File file = ( new File( baseFile, filenm ) ).getAbsoluteFile();
try
{
file = file.getCanonicalFile();
}
catch ( final IOException ioe )
{
}
return file;
}
/**
* Delete a file. If file is directory delete it and all sub-directories.
*/
public static void forceDelete( final String file )
throws IOException
{
forceDelete( new File( file ) );
}
/**
* Delete a file. If file is directory delete it and all sub-directories.
*/
public static void forceDelete( final File file )
throws IOException
{
if ( file.isDirectory() )
{
deleteDirectory( file );
}
else
{
/*
* NOTE: Always try to delete the file even if it appears to be non-existent. This will ensure that a
* symlink whose target does not exist is deleted, too.
*/
boolean filePresent = file.getCanonicalFile().exists();
if ( !deleteFile( file ) && filePresent )
{
final String message = "File " + file + " unable to be deleted.";
throw new IOException( message );
}
}
}
/**
* Accommodate Windows bug encountered in both Sun and IBM JDKs.
* Others possible. If the delete does not work, call System.gc(),
* wait a little and try again.
*/
private static boolean deleteFile( File file )
throws IOException
{
if ( file.isDirectory() )
{
throw new IOException( "File " + file + " isn't a file." );
}
if ( !file.delete() )
{
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
{
System.gc();
}
try
{
Thread.sleep( 10 );
return file.delete();
}
catch ( InterruptedException ex )
{
return file.delete();
}
}
return true;
}
/**
* Schedule a file to be deleted when JVM exits.
* If file is directory delete it and all sub-directories.
*/
public static void forceDeleteOnExit( final File file )
throws IOException
{
if ( !file.exists() )
{
return;
}
if ( file.isDirectory() )
{
deleteDirectoryOnExit( file );
}
else
{
file.deleteOnExit();
}
}
/**
* Recursively schedule directory for deletion on JVM exit.
*/
private static void deleteDirectoryOnExit( final File directory )
throws IOException
{
if ( !directory.exists() )
{
return;
}
cleanDirectoryOnExit( directory );
directory.deleteOnExit();
}
/**
* Clean a directory without deleting it.
*/
private static void cleanDirectoryOnExit( final File directory )
throws IOException
{
if ( !directory.exists() )
{
final String message = directory + " does not exist";
throw new IllegalArgumentException( message );
}
if ( !directory.isDirectory() )
{
final String message = directory + " is not a directory";
throw new IllegalArgumentException( message );
}
IOException exception = null;
final File[] files = directory.listFiles();
for ( int i = 0; i < files.length; i++ )
{
final File file = files[i];
try
{
forceDeleteOnExit( file );
}
catch ( final IOException ioe )
{
exception = ioe;
}
}
if ( null != exception )
{
throw exception;
}
}
/**
* Make a directory. If there already exists a file with specified name or
* the directory is unable to be created then an exception is thrown.
*/
public static void forceMkdir( final File file )
throws IOException
{
if ( file.exists() )
{
if ( file.isFile() )
{
final String message =
"File " + file + " exists and is " + "not a directory. Unable to create directory.";
throw new IOException( message );
}
}
else
{
if ( false == file.mkdirs() )
{
final String message = "Unable to create directory " + file;
throw new IOException( message );
}
}
}
/**
* Recursively delete a directory.
*/
public static void deleteDirectory( final String directory )
throws IOException
{
deleteDirectory( new File( directory ) );
}
/**
* Recursively delete a directory.
*/
public static void deleteDirectory( final File directory )
throws IOException
{
if ( !directory.exists() )
{
return;
}
cleanDirectory( directory );
if ( !directory.delete() )
{
final String message = "Directory " + directory + " unable to be deleted.";
throw new IOException( message );
}
}
/**
* Clean a directory without deleting it.
*/
public static void cleanDirectory( final String directory )
throws IOException
{
cleanDirectory( new File( directory ) );
}
/**
* Clean a directory without deleting it.
*/
public static void cleanDirectory( final File directory )
throws IOException
{
if ( !directory.exists() )
{
final String message = directory + " does not exist";
throw new IllegalArgumentException( message );
}
if ( !directory.isDirectory() )
{
final String message = directory + " is not a directory";
throw new IllegalArgumentException( message );
}
IOException exception = null;
final File[] files = directory.listFiles();
if ( files == null )
{
return;
}
for ( int i = 0; i < files.length; i++ )
{
final File file = files[i];
try
{
forceDelete( file );
}
catch ( final IOException ioe )
{
exception = ioe;
}
}
if ( null != exception )
{
throw exception;
}
}
/**
* Recursively count size of a directory.
*
* @return size of directory in bytes.
*/
public static long sizeOfDirectory( final String directory )
{
return sizeOfDirectory( new File( directory ) );
}
/**
* Recursively count size of a directory.
*
* @return size of directory in bytes.
*/
public static long sizeOfDirectory( final File directory )
{
if ( !directory.exists() )
{
final String message = directory + " does not exist";
throw new IllegalArgumentException( message );
}
if ( !directory.isDirectory() )
{
final String message = directory + " is not a directory";
throw new IllegalArgumentException( message );
}
long size = 0;
final File[] files = directory.listFiles();
for ( int i = 0; i < files.length; i++ )
{
final File file = files[i];
if ( file.isDirectory() )
{
size += sizeOfDirectory( file );
}
else
{
size += file.length();
}
}
return size;
}
/**
* Return the files contained in the directory, using inclusion and exclusion Ant patterns,
* including the directory name in each of the files
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @return a list of File objects
* @throws IOException
*/
public static List getFiles( File directory, String includes, String excludes )
throws IOException
{
return getFiles( directory, includes, excludes, true );
}
/**
* Return the files contained in the directory, using inclusion and exclusion Ant patterns
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each file
* @return a list of File objects
* @throws IOException
*/
public static List getFiles( File directory, String includes, String excludes, boolean includeBasedir )
throws IOException
{
List fileNames = getFileNames( directory, includes, excludes, includeBasedir );
List files = new ArrayList();
for ( Iterator i = fileNames.iterator(); i.hasNext(); )
{
files.add( new File( (String) i.next() ) );
}
return files;
}
/**
* Return a list of files as String depending options.
* This method use case sensitive file name.
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each String of file
* @return a list of files as String
* @throws IOException
*/
public static List getFileNames( File directory, String includes, String excludes, boolean includeBasedir )
throws IOException
{
return getFileNames( directory, includes, excludes, includeBasedir, true );
}
/**
* Return a list of files as String depending options.
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each String of file
* @param isCaseSensitive true if case sensitive
* @return a list of files as String
* @throws IOException
*/
public static List getFileNames( File directory, String includes, String excludes, boolean includeBasedir,
boolean isCaseSensitive )
throws IOException
{
return getFileAndDirectoryNames( directory, includes, excludes, includeBasedir, isCaseSensitive, true, false );
}
/**
* Return a list of directories as String depending options.
* This method use case sensitive file name.
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each String of file
* @return a list of directories as String
* @throws IOException
*/
public static List getDirectoryNames( File directory, String includes, String excludes, boolean includeBasedir )
throws IOException
{
return getDirectoryNames( directory, includes, excludes, includeBasedir, true );
}
/**
* Return a list of directories as String depending options.
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each String of file
* @param isCaseSensitive true if case sensitive
* @return a list of directories as String
* @throws IOException
*/
public static List getDirectoryNames( File directory, String includes, String excludes, boolean includeBasedir,
boolean isCaseSensitive )
throws IOException
{
return getFileAndDirectoryNames( directory, includes, excludes, includeBasedir, isCaseSensitive, false, true );
}
/**
* Return a list of files as String depending options.
*
* @param directory the directory to scan
* @param includes the includes pattern, comma separated
* @param excludes the excludes pattern, comma separated
* @param includeBasedir true to include the base dir in each String of file
* @param isCaseSensitive true if case sensitive
* @param getFiles true if get files
* @param getDirectories true if get directories
* @return a list of files as String
* @throws IOException
*/
public static List getFileAndDirectoryNames( File directory, String includes, String excludes,
boolean includeBasedir, boolean isCaseSensitive, boolean getFiles,
boolean getDirectories )
throws IOException
{
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( directory );
if ( includes != null )
{
scanner.setIncludes( StringUtils.split( includes, "," ) );
}
if ( excludes != null )
{
scanner.setExcludes( StringUtils.split( excludes, "," ) );
}
scanner.setCaseSensitive( isCaseSensitive );
scanner.scan();
List list = new ArrayList();
if ( getFiles )
{
String[] files = scanner.getIncludedFiles();
for ( int i = 0; i < files.length; i++ )
{
if ( includeBasedir )
{
list.add( directory + FileUtils.FS + files[i] );
}
else
{
list.add( files[i] );
}
}
}
if ( getDirectories )
{
String[] directories = scanner.getIncludedDirectories();
for ( int i = 0; i < directories.length; i++ )
{
if ( includeBasedir )
{
list.add( directory + FileUtils.FS + directories[i] );
}
else
{
list.add( directories[i] );
}
}
}
return list;
}
public static void copyDirectory( File sourceDirectory, File destinationDirectory )
throws IOException
{
copyDirectory( sourceDirectory, destinationDirectory, "**", null );
}
public static void copyDirectory( File sourceDirectory, File destinationDirectory, String includes,
String excludes )
throws IOException
{
if ( !sourceDirectory.exists() )
{
return;
}
List files = getFiles( sourceDirectory, includes, excludes );
for ( Iterator i = files.iterator(); i.hasNext(); )
{
File file = (File) i.next();
copyFileToDirectory( file, destinationDirectory );
}
}
/**
* Copies a entire directory structure.
*
* Note:
* sourceDirectory
must exists.
* sourceDirectory
must exists.
* This will remove to
(if it exists), ensure that
* to
's parent directory exists and move
* from
, which involves deleting from
as
* well.
to
may have been deleted
* already when this happens.
*/
public static void rename( File from, File to )
throws IOException
{
if ( to.exists() && !to.delete() )
{
throw new IOException( "Failed to delete " + to + " while trying to rename " + from );
}
File parent = to.getParentFile();
if ( parent != null && !parent.exists() && !parent.mkdirs() )
{
throw new IOException( "Failed to create directory " + parent + " while trying to rename " + from );
}
if ( !from.renameTo( to ) )
{
copyFile( from, to );
if ( !from.delete() )
{
throw new IOException( "Failed to delete " + from + " while trying to rename it." );
}
}
}
/**
* Create a temporary file in a given directory.
*
* The file denoted by the returned abstract pathname did not * exist before this method was invoked, any subsequent invocation * of this method will yield a different file name.
* * The filename is prefixNNNNNsuffix where NNNN is a random number * *This method is different to File.createTempFile of JDK 1.2 * as it doesn't create the file itself. * It uses the location pointed to by java.io.tmpdir * when the parentDir attribute is * null.
* * @param prefix prefix before the random number * @param suffix file extension; include the '.' * @param parentDir Directory to create the temporary file in - * java.io.tmpdir used if not specificed * @return a File reference to the new temporary file. */ public static File createTempFile( String prefix, String suffix, File parentDir ) { File result = null; String parent = System.getProperty( "java.io.tmpdir" ); if ( parentDir != null ) { parent = parentDir.getPath(); } DecimalFormat fmt = new DecimalFormat( "#####" ); Random rand = new Random( System.currentTimeMillis() + Runtime.getRuntime().freeMemory() ); synchronized ( rand ) { do { result = new File( parent, prefix + fmt.format( Math.abs( rand.nextInt() ) ) + suffix ); } while ( result.exists() ); } return result; } public static void copyFile( File from, File to, String encoding, FilterWrapper[] wrappers ) throws IOException { if ( wrappers != null && wrappers.length > 0 ) { // buffer so it isn't reading a byte at a time! Reader fileReader = null; Writer fileWriter = null; try { if ( encoding == null || encoding.length() < 1 ) { fileReader = new BufferedReader( new FileReader( from ) ); fileWriter = new FileWriter( to ); } else { FileInputStream instream = new FileInputStream( from ); FileOutputStream outstream = new FileOutputStream( to ); fileReader = new BufferedReader( new InputStreamReader( instream, encoding ) ); fileWriter = new OutputStreamWriter( outstream, encoding ); } Reader reader = fileReader; for ( int i = 0; i < wrappers.length; i++ ) { FilterWrapper wrapper = wrappers[i]; reader = wrapper.getReader( reader ); } IOUtil.copy( reader, fileWriter ); } finally { IOUtil.close( fileReader ); IOUtil.close( fileWriter ); } } else { if ( to.lastModified() < from.lastModified() ) { copyFile( from, to ); } } } public static abstract class FilterWrapper { public abstract Reader getReader( Reader fileReader ); } public static List loadFile( File file ) throws IOException { List lines = new ArrayList(); if ( file.exists() ) { BufferedReader reader = new BufferedReader( new FileReader( file ) ); String line = reader.readLine(); while ( line != null ) { line = line.trim(); if ( !line.startsWith( "#" ) && line.length() != 0 ) { lines.add ( line ); } line = reader.readLine(); } reader.close(); } return lines; } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/IOUtil.java 0000644 0001750 0001750 00000070474 11020006575 025414 0 ustar twerner twerner package org.apache.maven.it.util; /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2001 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 acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" and * "Apache Turbine" must not be used to endorse or promote products * derived from this software without prior written permission. For * written permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * "Apache Turbine", nor may "Apache" appear in their name, without * prior written permission of the Apache Software Foundation. * * 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 *
* This class provides static utility methods for input/output operations, particularly buffered
* copying between sources (InputStream
, Reader
, String
and
* byte[]
) and destinations (OutputStream
, Writer
,
* String
and byte[]
).
*
Unless otherwise noted, these copy
methods do not flush or close the
* streams. Often, doing so would require making non-portable assumptions about the streams' origin
* and further use. This means that both streams' close()
methods must be called after
* copying. if one omits this step, then the stream resources (sockets, file descriptors) are
* released when the associated Stream is garbage-collected. It is not a good idea to rely on this
* mechanism. For a good overview of the distinction between "memory management" and "resource
* management", see this
* UnixReview article
For each copy
method, a variant is provided that allows the caller to specify the
* buffer size (the default is 4k). As the buffer size can have a fairly large impact on speed, this
* may be worth tweaking. Often "large buffer -> faster" does not hold, even for large data
* transfers.
For byte-to-char methods, a copy
variant allows the encoding to be selected
* (otherwise the platform default is used).
The copy
methods use an internal buffer when copying. It is therefore advisable
* not to deliberately wrap the stream arguments to the copy
methods in
* Buffered*
streams. For example, don't do the
* following:
copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );
*
* The rationale is as follows:
* *Imagine that an InputStream's read() is a very expensive operation, which would usually suggest
* wrapping in a BufferedInputStream. The BufferedInputStream works by issuing infrequent
* {@link java.io.InputStream#read(byte[] b, int off, int len)} requests on the underlying InputStream, to
* fill an internal buffer, from which further read
requests can inexpensively get
* their data (until the buffer runs out).
However, the copy
methods do the same thing, keeping an internal buffer,
* populated by {@link InputStream#read(byte[] b, int off, int len)} requests. Having two buffers
* (or three if the destination stream is also buffered) is pointless, and the unnecessary buffer
* management hurts performance slightly (about 3%, according to some simple experiments).
InputStream
to an OutputStream
.
*/
public static void copy( final InputStream input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy bytes from an InputStream
to an OutputStream
.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final InputStream input,
final OutputStream output,
final int bufferSize )
throws IOException
{
final byte[] buffer = new byte[bufferSize];
int n = 0;
while ( -1 != ( n = input.read( buffer ) ) )
{
output.write( buffer, 0, n );
}
}
/**
* Copy chars from a Reader
to a Writer
.
*/
public static void copy( final Reader input, final Writer output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy chars from a Reader
to a Writer
.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final Reader input, final Writer output, final int bufferSize )
throws IOException
{
final char[] buffer = new char[bufferSize];
int n = 0;
while ( -1 != ( n = input.read( buffer ) ) )
{
output.write( buffer, 0, n );
}
output.flush();
}
///////////////////////////////////////////////////////////////
// Derived copy methods
// InputStream -> *
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// InputStream -> Writer
/**
* Copy and convert bytes from an InputStream
to chars on a
* Writer
.
* The platform's default encoding is used for the byte-to-char conversion.
*/
public static void copy( final InputStream input, final Writer output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy and convert bytes from an InputStream
to chars on a
* Writer
.
* The platform's default encoding is used for the byte-to-char conversion.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final InputStream input, final Writer output, final int bufferSize )
throws IOException
{
final InputStreamReader in = new InputStreamReader( input );
copy( in, output, bufferSize );
}
/**
* Copy and convert bytes from an InputStream
to chars on a
* Writer
, using the specified encoding.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
*/
public static void copy( final InputStream input, final Writer output, final String encoding )
throws IOException
{
final InputStreamReader in = new InputStreamReader( input, encoding );
copy( in, output );
}
/**
* Copy and convert bytes from an InputStream
to chars on a
* Writer
, using the specified encoding.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final InputStream input,
final Writer output,
final String encoding,
final int bufferSize )
throws IOException
{
final InputStreamReader in = new InputStreamReader( input, encoding );
copy( in, output, bufferSize );
}
///////////////////////////////////////////////////////////////
// InputStream -> String
/**
* Get the contents of an InputStream
as a String.
* The platform's default encoding is used for the byte-to-char conversion.
*/
public static String toString( final InputStream input )
throws IOException
{
return toString( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of an InputStream
as a String.
* The platform's default encoding is used for the byte-to-char conversion.
* @param bufferSize Size of internal buffer to use.
*/
public static String toString( final InputStream input, final int bufferSize )
throws IOException
{
final StringWriter sw = new StringWriter();
copy( input, sw, bufferSize );
return sw.toString();
}
/**
* Get the contents of an InputStream
as a String.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
*/
public static String toString( final InputStream input, final String encoding )
throws IOException
{
return toString( input, encoding, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of an InputStream
as a String.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
* @param bufferSize Size of internal buffer to use.
*/
public static String toString( final InputStream input,
final String encoding,
final int bufferSize )
throws IOException
{
final StringWriter sw = new StringWriter();
copy( input, sw, encoding, bufferSize );
return sw.toString();
}
///////////////////////////////////////////////////////////////
// InputStream -> byte[]
/**
* Get the contents of an InputStream
as a byte[]
.
*/
public static byte[] toByteArray( final InputStream input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of an InputStream
as a byte[]
.
* @param bufferSize Size of internal buffer to use.
*/
public static byte[] toByteArray( final InputStream input, final int bufferSize )
throws IOException
{
final ByteArrayOutputStream output = new ByteArrayOutputStream();
copy( input, output, bufferSize );
return output.toByteArray();
}
///////////////////////////////////////////////////////////////
// Derived copy methods
// Reader -> *
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// Reader -> OutputStream
/**
* Serialize chars from a Reader
to bytes on an OutputStream
, and
* flush the OutputStream
.
*/
public static void copy( final Reader input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Serialize chars from a Reader
to bytes on an OutputStream
, and
* flush the OutputStream
.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final Reader input, final OutputStream output, final int bufferSize )
throws IOException
{
final OutputStreamWriter out = new OutputStreamWriter( output );
copy( input, out, bufferSize );
// NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
// here.
out.flush();
}
///////////////////////////////////////////////////////////////
// Reader -> String
/**
* Get the contents of a Reader
as a String.
*/
public static String toString( final Reader input )
throws IOException
{
return toString( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a Reader
as a String.
* @param bufferSize Size of internal buffer to use.
*/
public static String toString( final Reader input, final int bufferSize )
throws IOException
{
final StringWriter sw = new StringWriter();
copy( input, sw, bufferSize );
return sw.toString();
}
///////////////////////////////////////////////////////////////
// Reader -> byte[]
/**
* Get the contents of a Reader
as a byte[]
.
*/
public static byte[] toByteArray( final Reader input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a Reader
as a byte[]
.
* @param bufferSize Size of internal buffer to use.
*/
public static byte[] toByteArray( final Reader input, final int bufferSize )
throws IOException
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
copy( input, output, bufferSize );
return output.toByteArray();
}
///////////////////////////////////////////////////////////////
// Derived copy methods
// String -> *
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// String -> OutputStream
/**
* Serialize chars from a String
to bytes on an OutputStream
, and
* flush the OutputStream
.
*/
public static void copy( final String input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Serialize chars from a String
to bytes on an OutputStream
, and
* flush the OutputStream
.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final String input, final OutputStream output, final int bufferSize )
throws IOException
{
final StringReader in = new StringReader( input );
final OutputStreamWriter out = new OutputStreamWriter( output );
copy( in, out, bufferSize );
// NOTE: Unless anyone is planning on rewriting OutputStreamWriter, we have to flush
// here.
out.flush();
}
///////////////////////////////////////////////////////////////
// String -> Writer
/**
* Copy chars from a String
to a Writer
.
*/
public static void copy( final String input, final Writer output )
throws IOException
{
output.write( input );
}
/**
* Copy bytes from an InputStream
to an
* OutputStream
, with buffering.
* This is equivalent to passing a
* {@link java.io.BufferedInputStream} and
* {@link java.io.BufferedOutputStream} to {@link #copy(InputStream, OutputStream)},
* and flushing the output stream afterwards. The streams are not closed
* after the copy.
* @deprecated Buffering streams is actively harmful! See the class description as to why. Use
* {@link #copy(InputStream, OutputStream)} instead.
*/
public static void bufferedCopy( final InputStream input, final OutputStream output )
throws IOException
{
final BufferedInputStream in = new BufferedInputStream( input );
final BufferedOutputStream out = new BufferedOutputStream( output );
copy( in, out );
out.flush();
}
///////////////////////////////////////////////////////////////
// String -> byte[]
/**
* Get the contents of a String
as a byte[]
.
*/
public static byte[] toByteArray( final String input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a String
as a byte[]
.
* @param bufferSize Size of internal buffer to use.
*/
public static byte[] toByteArray( final String input, final int bufferSize )
throws IOException
{
ByteArrayOutputStream output = new ByteArrayOutputStream();
copy( input, output, bufferSize );
return output.toByteArray();
}
///////////////////////////////////////////////////////////////
// Derived copy methods
// byte[] -> *
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
// byte[] -> Writer
/**
* Copy and convert bytes from a byte[]
to chars on a
* Writer
.
* The platform's default encoding is used for the byte-to-char conversion.
*/
public static void copy( final byte[] input, final Writer output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy and convert bytes from a byte[]
to chars on a
* Writer
.
* The platform's default encoding is used for the byte-to-char conversion.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final byte[] input, final Writer output, final int bufferSize )
throws IOException
{
final ByteArrayInputStream in = new ByteArrayInputStream( input );
copy( in, output, bufferSize );
}
/**
* Copy and convert bytes from a byte[]
to chars on a
* Writer
, using the specified encoding.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
*/
public static void copy( final byte[] input, final Writer output, final String encoding )
throws IOException
{
final ByteArrayInputStream in = new ByteArrayInputStream( input );
copy( in, output, encoding );
}
/**
* Copy and convert bytes from a byte[]
to chars on a
* Writer
, using the specified encoding.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final byte[] input,
final Writer output,
final String encoding,
final int bufferSize )
throws IOException
{
final ByteArrayInputStream in = new ByteArrayInputStream( input );
copy( in, output, encoding, bufferSize );
}
///////////////////////////////////////////////////////////////
// byte[] -> String
/**
* Get the contents of a byte[]
as a String.
* The platform's default encoding is used for the byte-to-char conversion.
*/
public static String toString( final byte[] input )
throws IOException
{
return toString( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a byte[]
as a String.
* The platform's default encoding is used for the byte-to-char conversion.
* @param bufferSize Size of internal buffer to use.
*/
public static String toString( final byte[] input, final int bufferSize )
throws IOException
{
final StringWriter sw = new StringWriter();
copy( input, sw, bufferSize );
return sw.toString();
}
/**
* Get the contents of a byte[]
as a String.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
*/
public static String toString( final byte[] input, final String encoding )
throws IOException
{
return toString( input, encoding, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a byte[]
as a String.
* @param encoding The name of a supported character encoding. See the
* IANA
* Charset Registry for a list of valid encoding types.
* @param bufferSize Size of internal buffer to use.
*/
public static String toString( final byte[] input,
final String encoding,
final int bufferSize )
throws IOException
{
final StringWriter sw = new StringWriter();
copy( input, sw, encoding, bufferSize );
return sw.toString();
}
///////////////////////////////////////////////////////////////
// byte[] -> OutputStream
/**
* Copy bytes from a byte[]
to an OutputStream
.
*/
public static void copy( final byte[] input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy bytes from a byte[]
to an OutputStream
.
* @param bufferSize Size of internal buffer to use.
*/
public static void copy( final byte[] input,
final OutputStream output,
final int bufferSize )
throws IOException
{
output.write( input );
}
/**
* Compare the contents of two Streams to determine if they are equal or not.
*
* @param input1 the first stream
* @param input2 the second stream
* @return true if the content of the streams are equal or they both don't exist, false otherwise
*/
public static boolean contentEquals( final InputStream input1,
final InputStream input2 )
throws IOException
{
final InputStream bufferedInput1 = new BufferedInputStream( input1 );
final InputStream bufferedInput2 = new BufferedInputStream( input2 );
int ch = bufferedInput1.read();
while ( -1 != ch )
{
final int ch2 = bufferedInput2.read();
if ( ch != ch2 )
{
return false;
}
ch = bufferedInput1.read();
}
final int ch2 = bufferedInput2.read();
if ( -1 != ch2 )
{
return false;
}
else
{
return true;
}
}
// ----------------------------------------------------------------------
// closeXXX()
// ----------------------------------------------------------------------
/**
* Closes the input stream. The input stream can be null and any IOException's will be swallowed.
*
* @param inputStream The stream to close.
*/
public static void close( InputStream inputStream )
{
if ( inputStream == null )
{
return;
}
try
{
inputStream.close();
}
catch( IOException ex )
{
// ignore
}
}
/**
* Closes the output stream. The output stream can be null and any IOException's will be swallowed.
*
* @param outputStream The stream to close.
*/
public static void close( OutputStream outputStream )
{
if ( outputStream == null )
{
return;
}
try
{
outputStream.close();
}
catch( IOException ex )
{
// ignore
}
}
/**
* Closes the reader. The reader can be null and any IOException's will be swallowed.
*
* @param reader The reader to close.
*/
public static void close( Reader reader )
{
if ( reader == null )
{
return;
}
try
{
reader.close();
}
catch( IOException ex )
{
// ignore
}
}
/**
* Closes the writer. The writer can be null and any IOException's will be swallowed.
*
* @param wrtier The writer to close.
*/
public static void close( Writer writer )
{
if ( writer == null )
{
return;
}
try
{
writer.close();
}
catch( IOException ex )
{
// ignore
}
}
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/util/ResourceExtractor.java 0000644 0001750 0001750 00000011141 11020006575 027714 0 ustar twerner twerner /*
* Created on Oct 17, 2006
*
*/
package org.apache.maven.it.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/* @todo this can be replaced with plexus-archiver */
public class ResourceExtractor {
public static File simpleExtractResources(Class cl, String resourcePath) throws IOException {
String tempDirPath = System.getProperty( "maven.test.tmpdir", System.getProperty( "java.io.tmpdir" ) );
File tempDir = new File(tempDirPath);
File testDir = new File( tempDir, resourcePath );
FileUtils.deleteDirectory( testDir );
testDir = ResourceExtractor.extractResourcePath(cl, resourcePath, tempDir, false);
return testDir;
}
public static File extractResourcePath(String resourcePath, File dest) throws IOException {
return extractResourcePath(ResourceExtractor.class, resourcePath, dest);
}
public static File extractResourcePath(Class cl, String resourcePath, File dest) throws IOException {
return extractResourcePath(cl, resourcePath, dest, false);
}
public static File extractResourcePath(Class cl, String resourcePath, File tempDir, boolean alwaysExtract)
throws IOException {
File dest = new File(tempDir, resourcePath);
URL url = cl.getResource(resourcePath);
if (url == null) throw new IllegalArgumentException("Resource not found: " + resourcePath);
if ("jar".equalsIgnoreCase(url.getProtocol())) {
File jarFile = getJarFileFromUrl(url);
extractResourcePathFromJar(cl, jarFile, resourcePath, dest);
} else {
try {
File resourceFile = new File(new URI(url.toExternalForm()));
if (!alwaysExtract) return resourceFile;
if (resourceFile.isDirectory()) {
FileUtils.copyDirectoryStructure(resourceFile, dest);
} else {
FileUtils.copyFile(resourceFile, dest);
}
} catch (URISyntaxException e) {
throw new RuntimeException("Couldn't convert URL to File:" + url, e);
}
}
return dest;
}
private static void extractResourcePathFromJar(Class cl, File jarFile, String resourcePath, File dest) throws IOException {
ZipFile z = new ZipFile(jarFile, ZipFile.OPEN_READ);
String zipStyleResourcePath = resourcePath.substring(1) + "/";
ZipEntry ze = z.getEntry(zipStyleResourcePath);
if (ze != null) {
// DGF If it's a directory, then we need to look at all the entries
for (Enumeration entries = z.entries(); entries.hasMoreElements();) {
ze = (ZipEntry) entries.nextElement();
if (ze.getName().startsWith(zipStyleResourcePath)) {
String relativePath = ze.getName().substring(zipStyleResourcePath.length());
File destFile = new File(dest, relativePath);
if (ze.isDirectory()) {
destFile.mkdirs();
} else {
FileOutputStream fos = new FileOutputStream(destFile);
try {
IOUtil.copy(z.getInputStream(ze), fos);
} finally {
IOUtil.close(fos);
}
}
}
}
} else {
FileOutputStream fos = new FileOutputStream(dest);
try {
IOUtil.copy(cl.getResourceAsStream(resourcePath), fos);
} finally {
IOUtil.close(fos);
}
}
}
private static File getJarFileFromUrl(URL url) {
if (!"jar".equalsIgnoreCase(url.getProtocol()))
throw new IllegalArgumentException("This is not a Jar URL:"
+ url.toString());
String resourceFilePath = url.getFile();
int index = resourceFilePath.indexOf("!");
if (index == -1) {
throw new RuntimeException("Bug! " + url.toExternalForm()
+ " does not have a '!'");
}
String jarFileURI = resourceFilePath.substring(0, index);
try {
File jarFile = new File(new URI(jarFileURI));
return jarFile;
} catch (URISyntaxException e) {
throw new RuntimeException("Bug! URI failed to parse: " + jarFileURI, e);
}
}
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/util/DirectoryScanner.java 0000644 0001750 0001750 00000110431 11020006575 027511 0 ustar twerner twerner /*
* 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.apache.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 apache@apache.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
* * 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. *
* 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. *
* 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. *
* 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
* File.separator
('/' 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.
*
* 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. *
* There is a special case regarding the use of File.separator
s
* at the beginning of the pattern and the string to match:
* When a pattern starts with a File.separator
, the string
* to match must also start with a File.separator
.
* When a pattern does not start with a File.separator
, the
* string to match may not start with a File.separator
.
* When one of these rules is not obeyed, the string will not
* match.
*
* When a name path segment is matched against a pattern path segment, the
* following special characters can be used:
* '*' matches zero or more characters
* '?' matches one character.
*
* Examples: *
* "**\*.class" matches all .class files/dirs in a directory tree. *
* "test\a??.java" matches all files/dirs which start with an 'a', then two * more characters and then ".java", in a directory called test. *
* "**" matches everything in a directory tree. *
* "**\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"). *
* Case sensitivity may be turned off if necessary. By default, it is * turned on. *
* Example of usage: *
* 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]); * } ** 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 * ajkuiper@wxs.nl * @author Magesh Umasankar * @author Bruce Atherton * @author Antoine Levy-Lambert */ 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 "**". *
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, pattern=**\a
* and str=b
will yield true
.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
*
* @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 "**".
*
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, pattern=**\a
* and str=b
will yield true
.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
* @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
* null
.
* @param str The path to match, as a String. Must not be
* null
.
*
* @return true
if the pattern matches against the string,
* or false
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
* null
.
* @param str The path to match, as a String. Must not be
* null
.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
* @return true
if the pattern matches against the string,
* or false
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:
* '*' means zero or more characters
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be null
.
* @param str The string which must be matched against the pattern.
* Must not be null
.
*
* @return true
if the string matches against the pattern,
* or false
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:
* '*' means zero or more characters
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be null
.
* @param str The string which must be matched against the pattern.
* Must not be null
.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
*
* @return true
if the string matches against the pattern,
* or false
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
* File.separatorChar
, so the separator used need not match
* File.separatorChar
.
*
* @param basedir The base directory to scan.
* Must not be null
.
*/
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 null
.
*/
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 File.separatorChar
, so the separator used
* need not match File.separatorChar
.
*
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param includes A list of include patterns.
* May be null
, indicating that all files
* should be included. If a non-null
* list is given, all elements must be
* non-null
.
*/
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 File.separatorChar
, so the separator used
* need not match File.separatorChar
.
*
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param excludes A list of exclude patterns.
* May be null
, indicating that no files
* should be excluded. If a non-null
list is
* given, all elements must be non-null
.
*/
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 true
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 null
, 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.
*
* 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 null
.
* @param vpath The path relative to the base directory (needed to
* prevent problems with an absolute path when using
* dir). Must not be null
.
* @param fast Whether or not this call is part of a fast scan.
* @throws IOException
*
* @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???)
*/
/*
* [jdcasey] (2) is apparently happening to me, as this is killing one of my tests...
* this is affecting the assembly plugin, fwiw. I will initialize the newfiles array as
* zero-length for now.
*
* NOTE: I can't find the problematic code, as it appears to come from a native method
* in UnixFileSystem...
*/
newfiles = new String[0];
// throw new IOException( "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 null
.
* @return true
when the name matches against at least one
* include pattern, or false
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 null
.
* @return true
when the name matches against the start of at
* least one include pattern, or false
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 null
.
* @return true
when the name matches against at least one
* exclude pattern, or false
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 false
when the selectors says that the file
* should not be selected, true
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;
}
/**
*
Returns the names of the files which were selected out and * therefore not ultimately included.
* *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 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; } /** *Returns the names of the directories which were selected out and * therefore not ultimately included.
* *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 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. * *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.
* * @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() ); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/StringUtils.java 0000644 0001750 0001750 00000176572 11020006575 026544 0 ustar twerner twerner /* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2002 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.apache.org/)." * Alternately, this acknowlegement may appear in the software itself, * if and wherever such third-party acknowlegements normally appear. * * 4. The names "The Jakarta Project", "Commons", 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 apache@apache.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 Software Foundation. * * 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 *Common String
manipulation routines.
Originally from * Turbine and the * GenerationJavaCore library.
* * @author Jon S. Stevens * @author Daniel Rall * @author Greg Coladonato * @author Henri Yandell * @author Ed Korthof * @author Rand McNeely * @author Stephen Colebourne * @author Fredrik Westermarck * @author Holger Krauth * @author Alexander Day Chaffee * @since 1.0 * @version $Id: StringUtils.java 661727 2008-05-30 14:21:49Z bentmann $ */ public class StringUtils { /** *StringUtils
instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* StringUtils.trim(" foo ");
.
This constructor is public to permit tools that require a JavaBean * manager to operate.
*/ public StringUtils() { } // Empty //-------------------------------------------------------------------------- /** *Removes control characters, including whitespace, from both
* ends of this String, handling null
by returning
* an empty String.
null
)
*/
public static String clean( String str )
{
return ( str == null ? "" : str.trim() );
}
/**
* Removes control characters, including whitespace, from both
* ends of this String, handling null
by returning
* null
.
null
)
*/
public static String trim( String str )
{
return ( str == null ? null : str.trim() );
}
/**
* Deletes all whitespaces from a String.
* *Whitespace is defined by * {@link Character#isWhitespace(char)}.
* * @param str String target to delete whitespace from * @return the String without whitespaces * @throws NullPointerException */ public static String deleteWhitespace( String str ) { StringBuffer buffer = new StringBuffer(); int sz = str.length(); for ( int i = 0; i < sz; i++ ) { if ( !Character.isWhitespace( str.charAt( i ) ) ) { buffer.append( str.charAt( i ) ); } } return buffer.toString(); } /** *Checks if a String is non null
and is
* not empty (length > 0
).
Checks if a (trimmed) String is null
or empty.
true
if the String is null
, or
* length zero once trimmed
*/
public static boolean isEmpty( String str )
{
return ( str == null || str.trim().length() == 0 );
}
// Equals and IndexOf
//--------------------------------------------------------------------------
/**
* Compares two Strings, returning true
if they are equal.
null
s are handled without exceptions. Two null
* references are considered to be equal. The comparison is case sensitive.
true
if the Strings are equal, case sensitive, or
* both null
*/
public static boolean equals( String str1, String str2 )
{
return ( str1 == null ? str2 == null : str1.equals( str2 ) );
}
/**
* Compares two Strings, returning true
if they are equal ignoring
* the case.
Nulls
are handled without exceptions. Two null
* references are considered equal. Comparison is case insensitive.
true
if the Strings are equal, case insensitive, or
* both null
*/
public static boolean equalsIgnoreCase( String str1, String str2 )
{
return ( str1 == null ? str2 == null : str1.equalsIgnoreCase( str2 ) );
}
/**
* Find the first index of any of a set of potential substrings.
* *null
String will return -1
.
null
*/
public static int indexOfAny( String str, String[] searchStrs )
{
if ( ( str == null ) || ( searchStrs == null ) )
{
return -1;
}
int sz = searchStrs.length;
// String's can't have a MAX_VALUEth index.
int ret = Integer.MAX_VALUE;
int tmp = 0;
for ( int i = 0; i < sz; i++ )
{
tmp = str.indexOf( searchStrs[i] );
if ( tmp == -1 )
{
continue;
}
if ( tmp < ret )
{
ret = tmp;
}
}
return ( ret == Integer.MAX_VALUE ) ? -1 : ret;
}
/**
* Find the latest index of any of a set of potential substrings.
* *null
string will return -1
.
null
*/
public static int lastIndexOfAny( String str, String[] searchStrs )
{
if ( ( str == null ) || ( searchStrs == null ) )
{
return -1;
}
int sz = searchStrs.length;
int ret = -1;
int tmp = 0;
for ( int i = 0; i < sz; i++ )
{
tmp = str.lastIndexOf( searchStrs[i] );
if ( tmp > ret )
{
ret = tmp;
}
}
return ret;
}
// Substring
//--------------------------------------------------------------------------
/**
* Gets a substring from the specified string avoiding exceptions.
* *A negative start position can be used to start n
* characters from the end of the String.
Gets a substring from the specified String avoiding exceptions.
* *A negative start position can be used to start/end n
* characters from the end of the String.
Gets the leftmost n
characters of a String.
If n
characters are not available, or the
* String is null
, the String will be returned without
* an exception.
Gets the rightmost n
characters of a String.
If n
characters are not available, or the String
* is null
, the String will be returned without an
* exception.
Gets n
characters from the middle of a String.
If n
characters are not available, the remainder
* of the String will be returned without an exception. If the
* String is null
, null
will be returned.
Splits the provided text into a array, using whitespace as the * separator.
* *The separator is not included in the returned String array.
* * @param str the String to parse * @return an array of parsed Strings */ public static String[] split( String str ) { return split( str, null, -1 ); } /** * @see #split(String, String, int) */ public static String[] split( String text, String separator ) { return split( text, separator, -1 ); } /** *Splits the provided text into a array, based on a given separator.
* *The separator is not included in the returned String array. The
* maximum number of splits to perfom can be controlled. A null
* separator will cause parsing to be on whitespace.
This is useful for quickly splitting a String directly into
* an array of tokens, instead of an enumeration of tokens (as
* StringTokenizer
does).
null
, splits on whitespace.
* @param max The maximum number of elements to include in the
* array. A zero or negative value implies no limit.
* @return an array of parsed Strings
*/
public static String[] split( String str, String separator, int max )
{
StringTokenizer tok = null;
if ( separator == null )
{
// Null separator means we're using StringTokenizer's default
// delimiter, which comprises all whitespace characters.
tok = new StringTokenizer( str );
}
else
{
tok = new StringTokenizer( str, separator );
}
int listSize = tok.countTokens();
if ( max > 0 && listSize > max )
{
listSize = max;
}
String[] list = new String[listSize];
int i = 0;
int lastTokenBegin = 0;
int lastTokenEnd = 0;
while ( tok.hasMoreTokens() )
{
if ( max > 0 && i == listSize - 1 )
{
// In the situation where we hit the max yet have
// tokens left over in our input, the last list
// element gets all remaining text.
String endToken = tok.nextToken();
lastTokenBegin = str.indexOf( endToken, lastTokenEnd );
list[i] = str.substring( lastTokenBegin );
break;
}
else
{
list[i] = tok.nextToken();
lastTokenBegin = str.indexOf( list[i], lastTokenEnd );
lastTokenEnd = lastTokenBegin + list[i].length();
}
i++;
}
return list;
}
// Joining
//--------------------------------------------------------------------------
/**
* Concatenates elements of an array into a single String.
* *The difference from join is that concatenate has no delimiter.
* * @param array the array of values to concatenate. * @return the concatenated string. */ public static String concatenate( Object[] array ) { return join( array, "" ); } /** *Joins the elements of the provided array into a single String * containing the provided list of elements.
* *No delimiter is added before or after the list. A
* null
separator is the same as a blank String.
Joins the elements of the provided Iterator
into
* a single String containing the provided elements.
No delimiter is added before or after the list. A
* null
separator is the same as a blank String.
Iterator
of values to join together
* @param separator the separator character to use
* @return the joined String
*/
public static String join( Iterator iterator, String separator )
{
if ( separator == null )
{
separator = "";
}
StringBuffer buf = new StringBuffer( 256 ); // Java default is 16, probably too small
while ( iterator.hasNext() )
{
buf.append( iterator.next() );
if ( iterator.hasNext() )
{
buf.append( separator );
}
}
return buf.toString();
}
// Replacing
//--------------------------------------------------------------------------
/**
* Replace a char with another char inside a larger String, once.
* *A null
reference passed to this method is a no-op.
Replace all occurances of a char within another char.
* *A null
reference passed to this method is a no-op.
Replace a char with another char inside a larger String,
* for the first max
values of the search char.
A null
reference passed to this method is a no-op.
-1
if no maximum
* @return the text with any replacements processed
*/
public static String replace( String text, char repl, char with, int max )
{
return replace( text, String.valueOf( repl ), String.valueOf( with ), max );
}
/**
* Replace a String with another String inside a larger String, once.
* *A null
reference passed to this method is a no-op.
Replace all occurances of a String within another String.
* *A null
reference passed to this method is a no-op.
Replace a String with another String inside a larger String,
* for the first max
values of the search String.
A null
reference passed to this method is a no-op.
-1
if no maximum
* @return the text with any replacements processed
*/
public static String replace( String text, String repl, String with, int max )
{
if ( text == null || repl == null || with == null || repl.length() == 0 )
{
return text;
}
StringBuffer buf = new StringBuffer( text.length() );
int start = 0, end = 0;
while ( ( end = text.indexOf( repl, start ) ) != -1 )
{
buf.append( text.substring( start, end ) ).append( with );
start = end + repl.length();
if ( --max == 0 )
{
break;
}
}
buf.append( text.substring( start ) );
return buf.toString();
}
/**
* Overlay a part of a String with another String.
* * @param text String to do overlaying in * @param overlay String to overlay * @param start int to start overlaying at * @param end int to stop overlaying before * @return String with overlayed text * @throws NullPointerException if text or overlay isnull
*/
public static String overlayString( String text, String overlay, int start, int end )
{
return new StringBuffer( start + overlay.length() + text.length() - end + 1 )
.append( text.substring( 0, start ) )
.append( overlay )
.append( text.substring( end ) )
.toString();
}
// Centering
//--------------------------------------------------------------------------
/**
* Center a String in a larger String of size n
.
* *
Uses spaces as the value to buffer the String with.
* Equivalent to center(str, size, " ")
.
null
*/
public static String center( String str, int size )
{
return center( str, size, " " );
}
/**
* Center a String in a larger String of size n
.
Uses a supplied String as the value to buffer the String with.
* * @param str String to center * @param size int size of new String * @param delim String to buffer the new String with * @return String containing centered String * @throws NullPointerException if str or delim isnull
* @throws ArithmeticException if delim is the empty String
*/
public static String center( String str, int size, String delim )
{
int sz = str.length();
int p = size - sz;
if ( p < 1 )
{
return str;
}
str = leftPad( str, sz + p / 2, delim );
str = rightPad( str, size, delim );
return str;
}
// Chomping
//--------------------------------------------------------------------------
/**
* Remove the last newline, and everything after it from a String.
* * @param str String to chomp the newline from * @return String without chomped newline * @throws NullPointerException if str isnull
*/
public static String chomp( String str )
{
return chomp( str, "\n" );
}
/**
* Remove the last value of a supplied String, and everything after * it from a String.
* * @param str String to chomp from * @param sep String to chomp * @return String without chomped ending * @throws NullPointerException if str or sep isnull
*/
public static String chomp( String str, String sep )
{
int idx = str.lastIndexOf( sep );
if ( idx != -1 )
{
return str.substring( 0, idx );
}
else
{
return str;
}
}
/**
* Remove a newline if and only if it is at the end * of the supplied String.
* * @param str String to chomp from * @return String without chomped ending * @throws NullPointerException if str isnull
*/
public static String chompLast( String str )
{
return chompLast( str, "\n" );
}
/**
* Remove a value if and only if the String ends with that value.
* * @param str String to chomp from * @param sep String to chomp * @return String without chomped ending * @throws NullPointerException if str or sep isnull
*/
public static String chompLast( String str, String sep )
{
if ( str.length() == 0 )
{
return str;
}
String sub = str.substring( str.length() - sep.length() );
if ( sep.equals( sub ) )
{
return str.substring( 0, str.length() - sep.length() );
}
else
{
return str;
}
}
/**
* Remove everything and return the last value of a supplied String, and * everything after it from a String.
* * @param str String to chomp from * @param sep String to chomp * @return String chomped * @throws NullPointerException if str or sep isnull
*/
public static String getChomp( String str, String sep )
{
int idx = str.lastIndexOf( sep );
if ( idx == str.length() - sep.length() )
{
return sep;
}
else if ( idx != -1 )
{
return str.substring( idx );
}
else
{
return "";
}
}
/**
* Remove the first value of a supplied String, and everything before it * from a String.
* * @param str String to chomp from * @param sep String to chomp * @return String without chomped beginning * @throws NullPointerException if str or sep isnull
*/
public static String prechomp( String str, String sep )
{
int idx = str.indexOf( sep );
if ( idx != -1 )
{
return str.substring( idx + sep.length() );
}
else
{
return str;
}
}
/**
* Remove and return everything before the first value of a * supplied String from another String.
* * @param str String to chomp from * @param sep String to chomp * @return String prechomped * @throws NullPointerException if str or sep isnull
*/
public static String getPrechomp( String str, String sep )
{
int idx = str.indexOf( sep );
if ( idx != -1 )
{
return str.substring( 0, idx + sep.length() );
}
else
{
return "";
}
}
// Chopping
//--------------------------------------------------------------------------
/**
* Remove the last character from a String.
* *If the String ends in \r\n
, then remove both
* of them.
null
*/
public static String chop( String str )
{
if ( "".equals( str ) )
{
return "";
}
if ( str.length() == 1 )
{
return "";
}
int lastIdx = str.length() - 1;
String ret = str.substring( 0, lastIdx );
char last = str.charAt( lastIdx );
if ( last == '\n' )
{
if ( ret.charAt( lastIdx - 1 ) == '\r' )
{
return ret.substring( 0, lastIdx - 1 );
}
}
return ret;
}
/**
* Remove \n
from end of a String if it's there.
* If a \r
precedes it, then remove that too.
null
*/
public static String chopNewline( String str )
{
int lastIdx = str.length() - 1;
char last = str.charAt( lastIdx );
if ( last == '\n' )
{
if ( str.charAt( lastIdx - 1 ) == '\r' )
{
lastIdx--;
}
}
else
{
lastIdx++;
}
return str.substring( 0, lastIdx );
}
// Conversion
//--------------------------------------------------------------------------
// spec 3.10.6
/**
* Escapes any values it finds into their String form.
* *So a tab becomes the characters '\\'
and
* 't'
.
null
*/
public static String escape( String str )
{
// improved with code from cybertiger@cyberiantiger.org
// unicode from him, and defaul for < 32's.
int sz = str.length();
StringBuffer buffer = new StringBuffer( 2 * sz );
for ( int i = 0; i < sz; i++ )
{
char ch = str.charAt( i );
// handle unicode
if ( ch > 0xfff )
{
buffer.append( "\\u" + Integer.toHexString( ch ) );
}
else if ( ch > 0xff )
{
buffer.append( "\\u0" + Integer.toHexString( ch ) );
}
else if ( ch > 0x7f )
{
buffer.append( "\\u00" + Integer.toHexString( ch ) );
}
else if ( ch < 32 )
{
switch ( ch )
{
case '\b':
buffer.append( '\\' );
buffer.append( 'b' );
break;
case '\n':
buffer.append( '\\' );
buffer.append( 'n' );
break;
case '\t':
buffer.append( '\\' );
buffer.append( 't' );
break;
case '\f':
buffer.append( '\\' );
buffer.append( 'f' );
break;
case '\r':
buffer.append( '\\' );
buffer.append( 'r' );
break;
default :
if ( ch > 0xf )
{
buffer.append( "\\u00" + Integer.toHexString( ch ) );
}
else
{
buffer.append( "\\u000" + Integer.toHexString( ch ) );
}
break;
}
}
else
{
switch ( ch )
{
case '\'':
buffer.append( '\\' );
buffer.append( '\'' );
break;
case '"':
buffer.append( '\\' );
buffer.append( '"' );
break;
case '\\':
buffer.append( '\\' );
buffer.append( '\\' );
break;
default :
buffer.append( ch );
break;
}
}
}
return buffer.toString();
}
// Padding
//--------------------------------------------------------------------------
/**
* Repeat a String n
times to form a
* new string.
repeat < 0
* @throws NullPointerException if str is null
*/
public static String repeat( String str, int repeat )
{
StringBuffer buffer = new StringBuffer( repeat * str.length() );
for ( int i = 0; i < repeat; i++ )
{
buffer.append( str );
}
return buffer.toString();
}
/**
* Right pad a String with spaces.
* *The String is padded to the size of n
.
null
*/
public static String rightPad( String str, int size )
{
return rightPad( str, size, " " );
}
/**
* Right pad a String with a specified string.
* *The String is padded to the size of n
.
null
* @throws ArithmeticException if delim is the empty String
*/
public static String rightPad( String str, int size, String delim )
{
size = ( size - str.length() ) / delim.length();
if ( size > 0 )
{
str += repeat( delim, size );
}
return str;
}
/**
* Left pad a String with spaces.
* *The String is padded to the size of n
.
null
*/
public static String leftPad( String str, int size )
{
return leftPad( str, size, " " );
}
/**
* Left pad a String with a specified string. Pad to a size of n.
*
* @param str String to pad out
* @param size size to pad to
* @param delim String to pad with
* @return left padded String
* @throws NullPointerException if str or delim is null
* @throws ArithmeticException if delim is the empty string
*/
public static String leftPad( String str, int size, String delim )
{
size = ( size - str.length() ) / delim.length();
if ( size > 0 )
{
str = repeat( delim, size ) + str;
}
return str;
}
// Stripping
//--------------------------------------------------------------------------
/**
* Remove whitespace from the front and back of a String.
* * @param str the String to remove whitespace from * @return the stripped String */ public static String strip( String str ) { return strip( str, null ); } /** *Remove a specified String from the front and back of a * String.
* *If whitespace is wanted to be removed, used the * {@link #strip(java.lang.String)} method.
* * @param str the String to remove a string from * @param delim the String to remove at start and end * @return the stripped String */ public static String strip( String str, String delim ) { str = stripStart( str, delim ); return stripEnd( str, delim ); } /** *Strip whitespace from the front and back of every String * in the array.
* * @param strs the Strings to remove whitespace from * @return the stripped Strings */ public static String[] stripAll( String[] strs ) { return stripAll( strs, null ); } /** *Strip the specified delimiter from the front and back of * every String in the array.
* * @param strs the Strings to remove a String from * @param delimiter the String to remove at start and end * @return the stripped Strings */ public static String[] stripAll( String[] strs, String delimiter ) { if ( ( strs == null ) || ( strs.length == 0 ) ) { return strs; } int sz = strs.length; String[] newArr = new String[sz]; for ( int i = 0; i < sz; i++ ) { newArr[i] = strip( strs[i], delimiter ); } return newArr; } /** *Strip any of a supplied String from the end of a String.
* *If the strip String is null
, whitespace is
* stripped.
Strip any of a supplied String from the start of a String.
* *If the strip String is null
, whitespace is
* stripped.
Convert a String to upper case, null
String
* returns null
.
Convert a String to lower case, null
String
* returns null
.
Uncapitalise a String.
* *That is, convert the first character into lower-case.
* null
is returned as null
.
Capitalise a String.
* *That is, convert the first character into title-case.
* null
is returned as null
.
Swaps the case of String.
* *Properly looks after making sure the start of words * are Titlecase and not Uppercase.
* *null
is returned as null
.
Capitalise all the words in a String.
* *Uses {@link Character#isWhitespace(char)} as a * separator between words.
* *null
will return null
.
Uncapitalise all the words in a string.
* *Uses {@link Character#isWhitespace(char)} as a * separator between words.
* *null
will return null
.
Get the String that is nested in between two instances of the * same String.
* *If str
is null
, will
* return null
.
null
* @throws NullPointerException if tag is null
*/
public static String getNestedString( String str, String tag )
{
return getNestedString( str, tag, tag );
}
/**
* Get the String that is nested in between two Strings.
* * @param str the String containing nested-string * @param open the String before nested-string * @param close the String after nested-string * @return the String that was nested, ornull
* @throws NullPointerException if open or close is null
*/
public static String getNestedString( String str, String open, String close )
{
if ( str == null )
{
return null;
}
int start = str.indexOf( open );
if ( start != -1 )
{
int end = str.indexOf( close, start + open.length() );
if ( end != -1 )
{
return str.substring( start + open.length(), end );
}
}
return null;
}
/**
* How many times is the substring in the larger String.
* *null
returns 0
.
null
* @throws NullPointerException if sub is null
*/
public static int countMatches( String str, String sub )
{
if ( sub.equals( "" ) )
{
return 0;
}
if ( str == null )
{
return 0;
}
int count = 0;
int idx = 0;
while ( ( idx = str.indexOf( sub, idx ) ) != -1 )
{
count++;
idx += sub.length();
}
return count;
}
// Character Tests
//--------------------------------------------------------------------------
/**
* Checks if the String contains only unicode letters.
* *null
will return false
.
* An empty String will return true
.
true
if only contains letters, and is non-null
*/
public static boolean isAlpha( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( Character.isLetter( str.charAt( i ) ) == false )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only whitespace.
* *null
will return false
. An
* empty String will return true
.
true
if only contains whitespace, and is non-null
*/
public static boolean isWhitespace( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( ( Character.isWhitespace( str.charAt( i ) ) == false ) )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only unicode letters and
* space (' '
).
null
will return false
. An
* empty String will return true
.
true
if only contains letters and space,
* and is non-null
*/
public static boolean isAlphaSpace( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( ( Character.isLetter( str.charAt( i ) ) == false ) &&
( str.charAt( i ) != ' ' ) )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only unicode letters or digits.
* *null
will return false
. An empty
* String will return true
.
true
if only contains letters or digits,
* and is non-null
*/
public static boolean isAlphanumeric( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( Character.isLetterOrDigit( str.charAt( i ) ) == false )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only unicode letters, digits
* or space (' '
).
null
will return false
. An empty
* String will return true
.
true
if only contains letters, digits or space,
* and is non-null
*/
public static boolean isAlphanumericSpace( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( ( Character.isLetterOrDigit( str.charAt( i ) ) == false ) &&
( str.charAt( i ) != ' ' ) )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only unicode digits.
* *null
will return false
.
* An empty String will return true
.
true
if only contains digits, and is non-null
*/
public static boolean isNumeric( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( Character.isDigit( str.charAt( i ) ) == false )
{
return false;
}
}
return true;
}
/**
* Checks if the String contains only unicode digits or space
* (' '
).
null
will return false
. An empty
* String will return true
.
true
if only contains digits or space,
* and is non-null
*/
public static boolean isNumericSpace( String str )
{
if ( str == null )
{
return false;
}
int sz = str.length();
for ( int i = 0; i < sz; i++ )
{
if ( ( Character.isDigit( str.charAt( i ) ) == false ) &&
( str.charAt( i ) != ' ' ) )
{
return false;
}
}
return true;
}
// Defaults
//--------------------------------------------------------------------------
/**
* Returns either the passed in Object
as a String,
* or, if the Object
is null
, an empty
* String.
null
*/
public static String defaultString( Object obj )
{
return defaultString( obj, "" );
}
/**
* Returns either the passed in Object
as a String,
* or, if the Object
is null
, a passed
* in default String.
null
* @return the passed in string, or the default if it was
* null
*/
public static String defaultString( Object obj, String defaultString )
{
return ( obj == null ) ? defaultString : obj.toString();
}
// Reversing
//--------------------------------------------------------------------------
/**
* Reverse a String.
* *null
String returns null
.
Reverses a String that is delimited by a specific character.
* *The Strings between the delimiters are not reversed.
* Thus java.lang.String becomes String.lang.java (if the delimiter
* is '.'
).
Reverses an array.
* *TAKEN FROM CollectionsUtils.
* * @param array the array to reverse */ private static void reverseArray( Object[] array ) { int i = 0; int j = array.length - 1; Object tmp; while ( j > i ) { tmp = array[j]; array[j] = array[i]; array[i] = tmp; j--; i++; } } // Abbreviating //-------------------------------------------------------------------------- /** * Turn "Now is the time for all good men" into "Now is the time for..." ** Specifically: *
* If str is less than max characters long, return it. * Else abbreviate it to (substring(str, 0, max-3) + "..."). * If maxWidth is less than 3, throw an IllegalArgumentException. * In no case will it return a string of length greater than maxWidth. * * @param maxWidth maximum length of result string **/ public static String abbreviate( String s, int maxWidth ) { return abbreviate( s, 0, maxWidth ); } /** * Turn "Now is the time for all good men" into "...is the time for..." *
* Works like abbreviate(String, int), but allows you to specify a "left edge" * offset. Note that this left edge is not necessarily going to be the leftmost * character in the result, or the first * character following the ellipses, but it will appear somewhere in the result. * In no case will it return a string of length greater than maxWidth. * * @param offset left edge of source string * @param maxWidth maximum length of result string **/ public static String abbreviate( String s, int offset, int maxWidth ) { if ( maxWidth < 4 ) throw new IllegalArgumentException( "Minimum abbreviation width is 4" ); if ( s.length() <= maxWidth ) return s; if ( offset > s.length() ) offset = s.length(); if ( ( s.length() - offset ) < ( maxWidth - 3 ) ) offset = s.length() - ( maxWidth - 3 ); if ( offset <= 4 ) return s.substring( 0, maxWidth - 3 ) + "..."; if ( maxWidth < 7 ) throw new IllegalArgumentException( "Minimum abbreviation width with offset is 7" ); if ( ( offset + ( maxWidth - 3 ) ) < s.length() ) return "..." + abbreviate( s.substring( offset ), maxWidth - 3 ); return "..." + s.substring( s.length() - ( maxWidth - 3 ) ); } // Difference //-------------------------------------------------------------------------- /** * Compare two strings, and return the portion where they differ. * (More precisely, return the remainder of the second string, * starting from where it's different from the first.) *
* E.g. strdiff("i am a machine", "i am a robot") -> "robot" * * @return the portion of s2 where it differs from s1; returns the empty string ("") if they are equal **/ public static String difference( String s1, String s2 ) { int at = differenceAt( s1, s2 ); if ( at == -1 ) return ""; return s2.substring( at ); } /** * Compare two strings, and return the index at which the strings begin to differ. *
* E.g. strdiff("i am a machine", "i am a robot") -> 7 *
* * @return the index where s2 and s1 begin to differ; -1 if they are equal **/ public static int differenceAt( String s1, String s2 ) { int i; for ( i = 0; i < s1.length() && i < s2.length(); ++i ) { if ( s1.charAt( i ) != s2.charAt( i ) ) { break; } } if ( i < s2.length() || i < s1.length() ) { return i; } return -1; } public static String interpolate( String text, Map namespace ) { Iterator keys = namespace.keySet().iterator(); while ( keys.hasNext() ) { String key = keys.next().toString(); Object obj = namespace.get( key ); if ( obj == null ) { throw new NullPointerException( "The value of the key '" + key + "' is null." ); } String value = obj.toString(); text = StringUtils.replace( text, "${" + key + "}", value ); if ( key.indexOf( " " ) == -1 ) { text = StringUtils.replace( text, "$" + key, value ); } } return text; } public static String removeAndHump( String data, String replaceThis ) { String temp; StringBuffer out = new StringBuffer(); temp = data; StringTokenizer st = new StringTokenizer( temp, replaceThis ); while ( st.hasMoreTokens() ) { String element = (String) st.nextElement(); out.append( capitalizeFirstLetter( element ) ); } return out.toString(); } public static String capitalizeFirstLetter( String data ) { char firstLetter = Character.toTitleCase( data.substring( 0, 1 ).charAt( 0 ) ); String restLetters = data.substring( 1 ); return firstLetter + restLetters; } public static String lowercaseFirstLetter( String data ) { char firstLetter = Character.toLowerCase( data.substring( 0, 1 ).charAt( 0 ) ); String restLetters = data.substring( 1 ); return firstLetter + restLetters; } public static String addAndDeHump( String view ) { StringBuffer sb = new StringBuffer(); for ( int i = 0; i < view.length(); i++ ) { if ( i != 0 && Character.isUpperCase( view.charAt( i ) ) ) { sb.append( '-' ); } sb.append( view.charAt( i ) ); } return sb.toString().trim().toLowerCase(); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/ 0000755 0001750 0001750 00000000000 11625266351 024152 5 ustar twerner twerner maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/StreamFeeder.java 0000644 0001750 0001750 00000007504 10517750507 027371 0 ustar twerner twerner package org.apache.maven.it.util.cli; /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * Read from an InputStream and write the output to an OutputStream. * * @author Trygve Laugstøl * @version $Id: StreamFeeder.java 467764 2006-10-25 21:04:07Z jvanzyl $ */ public class StreamFeeder extends Thread { private InputStream input; private OutputStream output; private boolean done; /** * Create a new StreamFeeder * * @param input Stream to read from * @param output Stream to write to */ public StreamFeeder( InputStream input, OutputStream output ) { this.input = input; this.output = output; } // ---------------------------------------------------------------------- // Runnable implementation // ---------------------------------------------------------------------- public void run() { try { feed(); } catch ( Throwable ex ) { // Catched everything so the streams will be closed and flagged as done. } finally { close(); done = true; synchronized ( this ) { this.notifyAll(); } } } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- public void close() { if ( input != null ) { synchronized ( input ) { try { input.close(); } catch ( IOException ex ) { // ignore } input = null; } } if ( output != null ) { synchronized ( output ) { try { output.close(); } catch ( IOException ex ) { // ignore } output = null; } } } public boolean isDone() { return done; } // ---------------------------------------------------------------------- // // ---------------------------------------------------------------------- private void feed() throws IOException { int data = input.read(); while ( !done && data != -1 ) { synchronized ( output ) { output.write( data ); data = input.read(); } } } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/EnhancedStringTokenizer.java 0000644 0001750 0001750 00000010625 10517750507 031610 0 ustar twerner twerner package org.apache.maven.it.util.cli; /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /* ==================================================================== * Copyright 2003-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ==================================================================== */ import java.util.StringTokenizer; /** * The java.util.StringTokenizer is horribly broken. * Given the string 1,,,3,,4 (, delim) * It will return 1,3,4 * Which is clearly wrong - 1,EMPTY,EMPTY,3,EMPTY,4 is what it should return */ public final class EnhancedStringTokenizer { private StringTokenizer cst = null; String cdelim; final boolean cdelimSingleChar; final char cdelimChar; boolean creturnDelims; String lastToken = null; boolean delimLast = true; public EnhancedStringTokenizer( String str ) { this( str, " \t\n\r\f", false ); } public EnhancedStringTokenizer( String str, String delim ) { this( str, delim, false ); } public EnhancedStringTokenizer( String str, String delim, boolean returnDelims ) { cst = new StringTokenizer( str, delim, true ); cdelim = delim; creturnDelims = returnDelims; cdelimSingleChar = ( delim.length() == 1 ); cdelimChar = delim.charAt( 0 ); } public boolean hasMoreTokens() { return cst.hasMoreTokens(); } private String internalNextToken() { if ( lastToken != null ) { String last = lastToken; lastToken = null; return last; } String token = cst.nextToken(); if ( isDelim( token ) ) { if ( delimLast ) { lastToken = token; return ""; } else { delimLast = true; return token; } } else { delimLast = false; return token; } } public String nextToken() { String token = internalNextToken(); if ( creturnDelims ) { return token; } if ( isDelim( token ) ) { return hasMoreTokens() ? internalNextToken() : ""; } else { return token; } } private boolean isDelim( String str ) { if ( str.length() == 1 ) { char ch = str.charAt( 0 ); if ( cdelimSingleChar ) { if ( cdelimChar == ch ) { return true; } } else { if ( cdelim.indexOf( ch ) >= 0 ) { return true; } } } return false; } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/CommandLineException.java 0000644 0001750 0001750 00000003102 10517750507 031056 0 ustar twerner twerner package org.apache.maven.it.util.cli; /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /** * @author Trygve Laugstøl * @version $Id: CommandLineException.java 467764 2006-10-25 21:04:07Z jvanzyl $ */ public class CommandLineException extends Exception { public CommandLineException( String message ) { super( message ); } public CommandLineException( String message, Throwable cause ) { super( message, cause ); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/StreamPumper.java 0000644 0001750 0001750 00000014026 10517750507 027444 0 ustar twerner twerner package org.apache.maven.it.util.cli; /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /******************************************************************************** * CruiseControl, a Continuous Integration Toolkit * Copyright (c) 2001-2003, ThoughtWorks, Inc. * 651 W Washington Ave. Suite 500 * Chicago, IL 60661 USA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * + Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * + 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. * * + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the * names of its contributors may be used to endorse or promote * products derived from this software without specific prior * written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS 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 REGENTS OR * 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. ********************************************************************************/ /* ==================================================================== * Copyright 2003-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ==================================================================== */ import org.apache.maven.it.util.IOUtil; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; /** * Class to pump the error stream during Process's runtime. Copied from the Ant * built-in task. * * @author Florin Vancea * @author Paul Julius * @since June 11, 2001 */ public class StreamPumper extends Thread { private BufferedReader in; private StreamConsumer consumer = null; private PrintWriter out = null; private static final int SIZE = 1024; boolean done; public StreamPumper( InputStream in ) { this.in = new BufferedReader( new InputStreamReader( in ), SIZE ); } public StreamPumper( InputStream in, StreamConsumer consumer ) { this( in ); this.consumer = consumer; } public StreamPumper( InputStream in, PrintWriter writer ) { this( in ); out = writer; } public StreamPumper( InputStream in, PrintWriter writer, StreamConsumer consumer ) { this( in ); this.out = writer; this.consumer = consumer; } public void run() { try { String s = in.readLine(); while ( s != null ) { consumeLine( s ); if ( out != null ) { out.println( s ); out.flush(); } s = in.readLine(); } } catch ( Throwable e ) { // Catched everything so the streams will be closed and flagged as done. } finally { IOUtil.close( in ); done = true; synchronized ( this ) { this.notifyAll(); } } } public void flush() { if ( out != null ) { out.flush(); } } public void close() { IOUtil.close( out ); } public boolean isDone() { return done; } private void consumeLine( String line ) { if ( consumer != null ) { consumer.consumeLine( line ); } } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/shell/ 0000755 0001750 0001750 00000000000 11625266351 025261 5 ustar twerner twerner maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/shell/CommandShell.java 0000644 0001750 0001750 00000002002 11020006575 030451 0 ustar twerner twerner package org.apache.maven.it.util.cli.shell; /* * Copyright 2001-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** ** Implementation to call the Command.com Shell present on Windows 95, 98 and Me *
* * @author Carlos Sanchez * @since 1.2 */ public class CommandShell extends Shell { public CommandShell() { setShellCommand( "command.com" ); setShellArgs( new String[]{"/C"} ); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/shell/CmdShell.java 0000644 0001750 0001750 00000002677 11020006575 027620 0 ustar twerner twerner package org.apache.maven.it.util.cli.shell; import java.util.Arrays; import java.util.List; /* * Copyright 2001-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** ** Implementation to call the CMD Shell present on Windows NT, 2000 and XP *
* * @author Carlos Sanchez * @since 1.2 */ public class CmdShell extends Shell { public CmdShell() { setShellCommand( "cmd.exe" ); setShellArgs( new String[]{"/X", "/C"} ); } /** * Specific implementation that quotes the all the command line */ public List getCommandLine( String executable, String[] arguments ) { StringBuffer sb = new StringBuffer(); sb.append( "\"" ); sb.append( super.getCommandLine( executable, arguments ).get( 0 ) ); sb.append( "\"" ); return Arrays.asList( new String[]{sb.toString()} ); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/shell/BourneShell.java 0000644 0001750 0001750 00000000364 10520013760 030334 0 ustar twerner twerner package org.apache.maven.it.util.cli.shell; /** * @author Jason van Zyl */ public class BourneShell extends Shell { public BourneShell() { setShellCommand( "/bin/sh" ); setShellArgs( new String[]{"-c"} ); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/shell/Shell.java 0000644 0001750 0001750 00000007642 11020006575 027171 0 ustar twerner twerner package org.apache.maven.it.util.cli.shell; /* * Copyright 2001-2006 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import org.apache.maven.it.util.cli.CommandLineException; import org.apache.maven.it.util.cli.Commandline; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** ** Class that abstracts the Shell functionality, * with subclases for shells that behave particularly, like *
command.com
cmd.exe
* <someelement>
* <acommandline executable="/executable/to/run">
* <argument value="argument 1" />
* <argument line="argument_1 argument_2 argument_3" />
* <argument value="argument 4" />
* </acommandline>
* </someelement>
*
*
*
* The element someelement
must provide a method
* createAcommandline
which returns an instance of this class.
*
*
* @author thomas.haas@softwired-inc.com
* @author Stefan Bodewig
*/
public class Commandline
implements Cloneable
{
protected static final String OS_NAME = "os.name";
protected static final String WINDOWS = "Windows";
protected String executable = null;
protected Vector arguments = new Vector();
protected Hashtable envVars = new Hashtable();
private File workingDir = null;
private long pid = -1;
private Shell shell;
/**
* Create a new command line object.
* Shell is autodetected from operating system
*
* @param toProcess
*/
public Commandline( String toProcess )
{
super();
setDefaultShell();
String[] tmp = new String[0];
try
{
tmp = translateCommandline( toProcess );
}
catch ( Exception e )
{
System.err.println( "Error translating Commandline." );
}
if ( tmp != null && tmp.length > 0 )
{
setExecutable( tmp[0] );
for ( int i = 1; i < tmp.length; i++ )
{
createArgument().setValue( tmp[i] );
}
}
}
/**
* Create a new command line object.
* Shell is autodetected from operating system
*/
public Commandline()
{
super();
setDefaultShell();
}
public long getPid()
{
if ( pid == -1 )
{
pid = Long.parseLong( String.valueOf( System.currentTimeMillis() ) );
}
return pid;
}
public void setPid( long pid )
{
this.pid = pid;
}
/**
* Used for nested xml command line definitions.
*/
public static class Argument
{
private String[] parts;
/**
* Sets a single commandline argument.
*
* @param value a single commandline argument.
*/
public void setValue( String value )
{
if ( value != null )
{
parts = new String[]{value};
}
}
/**
* Line to split into several commandline arguments.
*
* @param line line to split into several commandline arguments
*/
public void setLine( String line )
{
if ( line == null )
{
return;
}
try
{
parts = translateCommandline( line );
}
catch ( Exception e )
{
System.err.println( "Error translating Commandline." );
}
}
/**
* Sets a single commandline argument to the absolute filename
* of the given file.
*
* @param value a single commandline argument.
*/
public void setFile( File value )
{
parts = new String[]{value.getAbsolutePath()};
}
/**
* Returns the parts this Argument consists of.
*/
public String[] getParts()
{
return parts;
}
}
/**
* Class to keep track of the position of an Argument.
*/
// This class is there to support the srcfile and targetfile // elements of <execon> and <transform> - don't know // whether there might be additional use cases.
--SB public class Marker { private int position; private int realPos = -1; Marker( int position ) { this.position = position; } /** * Return the number of arguments that preceeded this marker. * *The name of the executable - if set - is counted as the * very first argument.
*/ public int getPosition() { if ( realPos == -1 ) { realPos = ( executable == null ? 0 : 1 ); for ( int i = 0; i < position; i++ ) { Argument arg = (Argument) arguments.elementAt( i ); realPos += arg.getParts().length; } } return realPos; } } /** *Sets the shell or command-line interpretor for the detected operating system, * and the shell arguments.
*/ private void setDefaultShell() { String os = System.getProperty( OS_NAME ); //If this is windows set the shell to command.com or cmd.exe with correct arguments. if ( os.indexOf( WINDOWS ) > -1 ) { if ( os.indexOf( "95" ) > -1 || os.indexOf( "98" ) > -1 || os.indexOf( "Me" ) > -1 ) { setShell( new CommandShell() ); } else { setShell( new CmdShell() ); } } } /** * Creates an argument object. * *Each commandline object has at most one instance of the
* argument class. This method calls
* this.createArgument(false)
.
Each commandline object has at most one instance of the * argument class.
* * @param insertAtStart if true, the argument is inserted at the * beginning of the list of args, otherwise it is appended. */ public Argument createArgument( boolean insertAtStart ) { Argument argument = new Argument(); if ( insertAtStart ) { arguments.insertElementAt( argument, 0 ); } else { arguments.addElement( argument ); } return argument; } /** * Sets the executable to run. */ public void setExecutable( String executable ) { if ( executable == null || executable.length() == 0 ) { return; } this.executable = executable.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar ); } public String getExecutable() { return executable; } public void addArguments( String[] line ) { for ( int i = 0; i < line.length; i++ ) { createArgument().setValue( line[i] ); } } /** * Add an environment variable */ public void addEnvironment( String name, String value ) { envVars.put( name, name + "=" + value ); } /** * Add system environment variables */ public void addSystemEnvironment() throws Exception { Properties envVars = CommandLineUtils.getSystemEnvVars(); for ( Iterator i = envVars.keySet().iterator(); i.hasNext(); ) { String key = (String) i.next(); if ( !this.envVars.containsKey( key ) ) { this.envVars.put( key, key + "=" + envVars.getProperty( key ) ); } } } /** * Return the list of environment variables */ public String[] getEnvironmentVariables() throws CommandLineException { try { addSystemEnvironment(); } catch ( Exception e ) { throw new CommandLineException( "Error setting up environmental variables", e ); } return (String[]) envVars.values().toArray( new String[envVars.size()] ); } /** * Returns the executable and all defined arguments. */ public String[] getCommandline() { final String[] args = getArguments(); if ( executable == null ) { return args; } final String[] result = new String[args.length + 1]; result[0] = executable; System.arraycopy( args, 0, result, 1, args.length ); return result; } /** * Returns the shell, executable and all defined arguments. */ public String[] getShellCommandline() { if ( getShell() == null ) { if ( executable != null ) { List commandLine = new ArrayList(); commandLine.add( executable ); commandLine.addAll( Arrays.asList( getArguments() ) ); return (String[]) commandLine.toArray( new String[0] ); } else { return getArguments(); } } else { return (String[]) getShell().getShellCommandLine( executable, getArguments() ).toArray( new String[0] ); } } /** * Returns all arguments defined byaddLine
,
* addValue
or the argument object.
*/
public String[] getArguments()
{
Vector result = new Vector( arguments.size() * 2 );
for ( int i = 0; i < arguments.size(); i++ )
{
Argument arg = (Argument) arguments.elementAt( i );
String[] s = arg.getParts();
if ( s != null )
{
for ( int j = 0; j < s.length; j++ )
{
result.addElement( s[j] );
}
}
}
String[] res = new String[result.size()];
result.copyInto( res );
return res;
}
public String toString()
{
return toString( getCommandline() );
}
/**
* Put quotes around the given String if necessary.
*If the argument doesn't include spaces or quotes, return it * as is. If it contains double quotes, use single quotes - else * surround the argument by double quotes.
* * @throws CommandLineException if the argument contains both, single * and double quotes. */ public static String quoteArgument( String argument ) throws CommandLineException { if ( argument.indexOf( "\"" ) > -1 ) { if ( argument.indexOf( "\'" ) > -1 ) { throw new CommandLineException( "Can't handle single and double quotes in same argument" ); } else { return '\'' + argument + '\''; } } else if ( argument.indexOf( "\'" ) > -1 || argument.indexOf( " " ) > -1 ) { return '\"' + argument + '\"'; } else { return argument; } } public static String toString( String[] line ) { // empty path return empty string if ( line == null || line.length == 0 ) { return ""; } // path containing one or more elements final StringBuffer result = new StringBuffer(); for ( int i = 0; i < line.length; i++ ) { if ( i > 0 ) { result.append( ' ' ); } try { result.append( quoteArgument( line[i] ) ); } catch ( Exception e ) { System.err.println( "Error quoting argument." ); } } return result.toString(); } public static String[] translateCommandline( String toProcess ) throws Exception { if ( toProcess == null || toProcess.length() == 0 ) { return new String[0]; } // parse with a simple finite state machine final int normal = 0; final int inQuote = 1; final int inDoubleQuote = 2; int state = normal; StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true ); Vector v = new Vector(); StringBuffer current = new StringBuffer(); while ( tok.hasMoreTokens() ) { String nextTok = tok.nextToken(); switch ( state ) { case inQuote: if ( "\'".equals( nextTok ) ) { state = normal; } else { current.append( nextTok ); } break; case inDoubleQuote: if ( "\"".equals( nextTok ) ) { state = normal; } else { current.append( nextTok ); } break; default: if ( "\'".equals( nextTok ) ) { state = inQuote; } else if ( "\"".equals( nextTok ) ) { state = inDoubleQuote; } else if ( " ".equals( nextTok ) ) { if ( current.length() != 0 ) { v.addElement( current.toString() ); current.setLength( 0 ); } } else { current.append( nextTok ); } break; } } if ( current.length() != 0 ) { v.addElement( current.toString() ); } if ( state == inQuote || state == inDoubleQuote ) { throw new CommandLineException( "unbalanced quotes in " + toProcess ); } String[] args = new String[v.size()]; v.copyInto( args ); return args; } public int size() { return getCommandline().length; } public Object clone() { Commandline c = new Commandline(); c.setExecutable( executable ); c.addArguments( getArguments() ); return c; } /** * Clear out the whole command line. */ public void clear() { executable = null; arguments.removeAllElements(); } /** * Clear out the arguments but leave the executable in place for another operation. */ public void clearArgs() { arguments.removeAllElements(); } /** * Return a marker. * *This marker can be used to locate a position on the * commandline - to insert something for example - when all * parameters have been set.
*/ public Marker createMarker() { return new Marker( arguments.size() ); } /** * Sets execution directory. */ public void setWorkingDirectory( String path ) { if ( path != null ) { workingDir = new File( path ); } } public File getWorkingDirectory() { return workingDir; } /** * Executes the command. */ public Process execute() throws CommandLineException { Process process; //addEnvironment( "MAVEN_TEST_ENVAR", "MAVEN_TEST_ENVAR_VALUE" ); String[] environment = getEnvironmentVariables(); try { if ( workingDir == null ) { process = Runtime.getRuntime().exec( getShellCommandline(), environment ); } else { if ( !workingDir.exists() ) { throw new CommandLineException( "Working directory \"" + workingDir.getPath() + "\" does not exist!" ); } else if ( !workingDir.isDirectory() ) { throw new CommandLineException( "Path \"" + workingDir.getPath() + "\" does not specify a directory." ); } process = Runtime.getRuntime().exec( getShellCommandline(), environment, workingDir ); } } catch ( IOException ex ) { throw new CommandLineException( "Error while executing process.", ex ); } return process; } public Properties getSystemEnvVars() throws Exception { return CommandLineUtils.getSystemEnvVars(); } /** * Allows to set the shell to be used in this command line. * * @param shell * @since 1.2 */ public void setShell( Shell shell ) { this.shell = shell; } /** * Get the shell to be used in this command line. * * @since 1.2 */ public Shell getShell() { return shell; } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/WriterStreamConsumer.java 0000644 0001750 0001750 00000003254 10611512337 031155 0 ustar twerner twerner /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package org.apache.maven.it.util.cli; import java.io.PrintWriter; import java.io.Writer; /** * @author Jason van Zyl * @version $Id: WriterStreamConsumer.java 530177 2007-04-18 21:59:59Z jdcasey $ */ public class WriterStreamConsumer implements StreamConsumer { private PrintWriter writer; public WriterStreamConsumer( Writer writer ) { this.writer = new PrintWriter( writer ); } public void consumeLine( String line ) { writer.println( line ); writer.flush(); } } maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/CommandLineUtils.java 0000644 0001750 0001750 00000020523 11151744053 030220 0 ustar twerner twerner package org.apache.maven.it.util.cli; /* * The MIT License * * Copyright (c) 2004, The Codehaus * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is furnished to do * so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.Properties; /** * @author Trygve Laugstøl * @version $Id: CommandLineUtils.java 748485 2009-02-27 11:02:03Z bentmann $ */ public abstract class CommandLineUtils { private static Map processes = Collections.synchronizedMap( new HashMap() ); private static Properties envVars; static { Runtime.getRuntime().addShutdownHook( new Thread( "CommandlineUtil shutdown" ) { public void run() { if ( ( processes != null ) && ( processes.size() > 0 ) ) { System.err.println( "Destroying " + processes.size() + " processes" ); for ( Iterator it = processes.values().iterator(); it.hasNext(); ) { System.err.println( "Destroying process.." ); ( (Process) it.next() ).destroy(); } System.err.println( "Destroyed " + processes.size() + " processes" ); } } } ); } public static class StringStreamConsumer implements StreamConsumer { private StringBuffer string = new StringBuffer(); private String ls = System.getProperty( "line.separator" ); public void consumeLine( String line ) { string.append( line ).append( ls ); } public String getOutput() { return string.toString(); } } public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr ) throws CommandLineException { return executeCommandLine( cl, null, systemOut, systemErr ); } public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr ) throws CommandLineException { if ( cl == null ) { throw new IllegalArgumentException( "cl cannot be null." ); } Process p; p = cl.execute(); processes.put( new Long( cl.getPid() ), p ); StreamFeeder inputFeeder = null; if ( systemIn != null ) { inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() ); } StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut ); StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr ); if ( inputFeeder != null ) { inputFeeder.start(); } outputPumper.start(); errorPumper.start(); try { int returnValue = p.waitFor(); if ( inputFeeder != null ) { synchronized ( inputFeeder ) { if ( !inputFeeder.isDone() ) { inputFeeder.wait(); } } } synchronized ( outputPumper ) { if ( !outputPumper.isDone() ) { outputPumper.wait(); } } synchronized ( errorPumper ) { if ( !errorPumper.isDone() ) { errorPumper.wait(); } } processes.remove( new Long( cl.getPid() ) ); return returnValue; } catch ( InterruptedException ex ) { killProcess( cl.getPid() ); throw new CommandLineException( "Error while executing external command, process killed.", ex ); } finally { if ( inputFeeder != null ) { inputFeeder.close(); } outputPumper.close(); errorPumper.close(); } } public static Properties getSystemEnvVars() throws IOException { if ( envVars == null ) { envVars = getSystemEnvVars( true ); } Properties props = new Properties(); props.putAll( envVars ); return props; } /** * Return the shell environment variables. IfcaseSensitive == true
, then envar
* keys will all be upper-case.
*
* @param caseSensitive Whether environment variable keys should be treated case-sensitively.
* @return Properties object of (possibly modified) envar keys mapped to their values.
* @throws IOException
*/
public static Properties getSystemEnvVars( boolean caseSensitive )
throws IOException
{
Process p = null;
Properties envVars = new Properties();
Runtime r = Runtime.getRuntime();
String os = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
//If this is windows set the shell to command.com or cmd.exe with correct arguments.
if ( os.indexOf( "windows" ) != -1 )
{
if ( os.indexOf( "95" ) != -1 || os.indexOf( "98" ) != -1 || os.indexOf( "Me" ) != -1 )
{
p = r.exec( "command.com /c set" );
}
else
{
p = r.exec( "cmd.exe /c set" );
}
}
else
{
p = r.exec( "env" );
}
BufferedReader br = new BufferedReader( new InputStreamReader( p.getInputStream() ) );
String line;
String lastKey = null;
String lastVal = null;
while ( ( line = br.readLine() ) != null )
{
int idx = line.indexOf( '=' );
if ( idx > 1 )
{
lastKey = line.substring( 0, idx );
if ( !caseSensitive )
{
lastKey = lastKey.toUpperCase();
}
lastVal = line.substring( idx + 1 );
envVars.setProperty( lastKey, lastVal );
}
else if ( lastKey != null )
{
lastVal += "\n" + line;
envVars.setProperty( lastKey, lastVal );
}
}
return envVars;
}
/**
* Kill a process launched by executeCommandLine methods
* Doesn't work correctly on windows, only the cmd process will be destroy but not the sub process (Bug ID 4770092)
*
* @param pid The pid of command return by Commandline.getPid()
*/
public static void killProcess( long pid )
{
Process p = (Process) processes.get( new Long( pid ) );
if ( p != null )
{
p.destroy();
System.out.println( "killed." );
processes.remove( new Long( pid ) );
}
else
{
System.out.println( "don't exist." );
}
}
public static boolean isAlive( long pid )
{
return ( processes.get( new Long( pid ) ) != null );
}
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/StreamConsumer.java 0000644 0001750 0001750 00000006672 10514207144 027766 0 ustar twerner twerner package org.apache.maven.it.util.cli;
/*
* The MIT License
*
* Copyright (c) 2004, The Codehaus
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/********************************************************************************
* CruiseControl, a Continuous Integration Toolkit
* Copyright (c) 2003, ThoughtWorks, Inc.
* 651 W Washington Ave. Suite 500
* Chicago, IL 60661 USA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* + Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* + 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.
*
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
* names of its contributors may be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS 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 REGENTS OR
* 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.
********************************************************************************/
/**
* Works in concert with the StreamPumper class to
* allow implementations to gain access to the lines being
* "Pumped".
*
* @author Florin Vancea
* @author Paul Julius
*/
public interface StreamConsumer
{
/**
* Called when the StreamPumper pumps a line from the Stream.
*/
public void consumeLine( String line );
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/util/cli/DefaultConsumer.java 0000644 0001750 0001750 00000004312 10517750507 030115 0 ustar twerner twerner package org.apache.maven.it.util.cli;
/*
* The MIT License
*
* Copyright (c) 2004, The Codehaus
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/* ====================================================================
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ====================================================================
*/
/**
* @author Emmanuel Venisse
* @version $Id: DefaultConsumer.java 467764 2006-10-25 21:04:07Z jvanzyl $
*/
public class DefaultConsumer
implements StreamConsumer
{
public void consumeLine( String line )
{
System.out.println( line );
}
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/util/SelectorUtils.java 0000644 0001750 0001750 00000055016 11020006575 027043 0 ustar twerner twerner /*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2002-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.apache.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 apache@apache.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
* This is a utility class used by selectors and DirectoryScanner. The * functionality more properly belongs just to selectors, but unfortunately * DirectoryScanner exposed these as protected methods. Thus we have to * support any subclasses of DirectoryScanner that may access these methods. *
*This is a Singleton.
* * @author Arnout J. Kuiper * ajkuiper@wxs.nl * @author Magesh Umasankar * @author Bruce Atherton * @since 1.5 */ public final class SelectorUtils { private static SelectorUtils instance = new SelectorUtils(); /** * Private Constructor */ private SelectorUtils() { } /** * Retrieves the manager of the Singleton. */ public static SelectorUtils getInstance() { return instance; } /** * Tests whether or not a given path matches the start of a given * pattern up to the first "**". *
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, pattern=**\a
* and str=b
will yield true
.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
*
* @return whether or not a given path matches the start of a given
* pattern up to the first "**".
*/
public static boolean matchPatternStart( String pattern, String str )
{
return matchPatternStart( pattern, str, true );
}
/**
* Tests whether or not a given path matches the start of a given
* pattern up to the first "**".
*
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, pattern=**\a
* and str=b
will yield true
.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
* @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 "**".
*/
public static boolean matchPatternStart( String pattern, String str,
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;
}
Vector patDirs = tokenizePath( pattern );
Vector strDirs = tokenizePath( str );
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.elementAt( patIdxStart );
if ( patDir.equals( "**" ) )
{
break;
}
if ( !match( patDir, (String) strDirs.elementAt( 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;
}
}
/**
* Tests whether or not a given path matches a given pattern.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
*
* @return true
if the pattern matches against the string,
* or false
otherwise.
*/
public static boolean matchPath( String pattern, String str )
{
return matchPath( pattern, str, true );
}
/**
* Tests whether or not a given path matches a given pattern.
*
* @param pattern The pattern to match against. Must not be
* null
.
* @param str The path to match, as a String. Must not be
* null
.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
* @return true
if the pattern matches against the string,
* or false
otherwise.
*/
public static boolean matchPath( String pattern, String str,
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;
}
Vector patDirs = tokenizePath( pattern );
Vector strDirs = tokenizePath( str );
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.elementAt( patIdxStart );
if ( patDir.equals( "**" ) )
{
break;
}
if ( !match( patDir, (String) strDirs.elementAt( strIdxStart ),
isCaseSensitive ) )
{
patDirs = null;
strDirs = null;
return false;
}
patIdxStart++;
strIdxStart++;
}
if ( strIdxStart > strIdxEnd )
{
// String is exhausted
for ( int i = patIdxStart; i <= patIdxEnd; i++ )
{
if ( !patDirs.elementAt( i ).equals( "**" ) )
{
patDirs = null;
strDirs = null;
return false;
}
}
return true;
}
else
{
if ( patIdxStart > patIdxEnd )
{
// String not exhausted, but pattern is. Failure.
patDirs = null;
strDirs = null;
return false;
}
}
// up to last '**'
while ( patIdxStart <= patIdxEnd && strIdxStart <= strIdxEnd )
{
String patDir = (String) patDirs.elementAt( patIdxEnd );
if ( patDir.equals( "**" ) )
{
break;
}
if ( !match( patDir, (String) strDirs.elementAt( strIdxEnd ),
isCaseSensitive ) )
{
patDirs = null;
strDirs = null;
return false;
}
patIdxEnd--;
strIdxEnd--;
}
if ( strIdxStart > strIdxEnd )
{
// String is exhausted
for ( int i = patIdxStart; i <= patIdxEnd; i++ )
{
if ( !patDirs.elementAt( i ).equals( "**" ) )
{
patDirs = null;
strDirs = null;
return false;
}
}
return true;
}
while ( patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd )
{
int patIdxTmp = -1;
for ( int i = patIdxStart + 1; i <= patIdxEnd; i++ )
{
if ( patDirs.elementAt( 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.elementAt( patIdxStart + j + 1 );
String subStr = (String) strDirs.elementAt( strIdxStart + i + j );
if ( !match( subPat, subStr, isCaseSensitive ) )
{
continue strLoop;
}
}
foundIdx = strIdxStart + i;
break;
}
if ( foundIdx == -1 )
{
patDirs = null;
strDirs = null;
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx + patLength;
}
for ( int i = patIdxStart; i <= patIdxEnd; i++ )
{
if ( !patDirs.elementAt( i ).equals( "**" ) )
{
patDirs = null;
strDirs = null;
return false;
}
}
return true;
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:
* '*' means zero or more characters
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be null
.
* @param str The string which must be matched against the pattern.
* Must not be null
.
*
* @return true
if the string matches against the pattern,
* or false
otherwise.
*/
public static boolean match( String pattern, String str )
{
return match( pattern, str, true );
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:
* '*' means zero or more characters
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be null
.
* @param str The string which must be matched against the pattern.
* Must not be null
.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
*
*
* @return true
if the string matches against the pattern,
* or false
otherwise.
*/
public static boolean match( String pattern, String str,
boolean isCaseSensitive )
{
char[] patArr = pattern.toCharArray();
char[] strArr = str.toCharArray();
int patIdxStart = 0;
int patIdxEnd = patArr.length - 1;
int strIdxStart = 0;
int strIdxEnd = strArr.length - 1;
char ch;
boolean containsStar = false;
for ( int i = 0; i < patArr.length; i++ )
{
if ( patArr[i] == '*' )
{
containsStar = true;
break;
}
}
if ( !containsStar )
{
// No '*'s, so we make a shortcut
if ( patIdxEnd != strIdxEnd )
{
return false; // Pattern and string do not have the same size
}
for ( int i = 0; i <= patIdxEnd; i++ )
{
ch = patArr[i];
if ( 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;
}
/**
* Breaks a path up into a Vector of path elements, tokenizing on
* File.separator
.
*
* @param path Path to tokenize. Must not be null
.
*
* @return a Vector of path elements from the tokenized path
*/
public static Vector tokenizePath( String path )
{
Vector ret = new Vector();
StringTokenizer st = new StringTokenizer( path, File.separator );
while ( st.hasMoreTokens() )
{
ret.addElement( st.nextToken() );
}
return ret;
}
/**
* Returns dependency information on these two files. If src has been
* modified later than target, it returns true. If target doesn't exist,
* it likewise returns true. Otherwise, target is newer than src and
* is not out of date, thus the method returns false. It also returns
* false if the src file doesn't even exist, since how could the
* target then be out of date.
*
* @param src the original file
* @param target the file being compared against
* @param granularity the amount in seconds of slack we will give in
* determining out of dateness
* @return whether the target is out of date
*/
public static boolean isOutOfDate( File src, File target, int granularity )
{
if ( !src.exists() )
{
return false;
}
if ( !target.exists() )
{
return true;
}
if ( ( src.lastModified() - granularity ) > target.lastModified() )
{
return true;
}
return false;
}
/**
* "Flattens" a string by removing all whitespace (space, tab, linefeed,
* carriage return, and formfeed). This uses StringTokenizer and the
* default set of tokens as documented in the single arguement constructor.
*
* @param input a String to remove all whitespace.
* @return a String that has had all whitespace removed.
*/
public static String removeWhitespace( String input )
{
StringBuffer result = new StringBuffer();
if ( input != null )
{
StringTokenizer st = new StringTokenizer( input );
while ( st.hasMoreTokens() )
{
result.append( st.nextToken() );
}
}
return result.toString();
}
}
maven-verifier-1.2/src/main/java/org/apache/maven/it/Verifier.java 0000644 0001750 0001750 00000172307 11243011323 025035 0 ustar twerner twerner package org.apache.maven.it;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.it.util.FileUtils;
import org.apache.maven.it.util.IOUtil;
import org.apache.maven.it.util.StringUtils;
import org.apache.maven.it.util.cli.CommandLineException;
import org.apache.maven.it.util.cli.CommandLineUtils;
import org.apache.maven.it.util.cli.Commandline;
import org.apache.maven.it.util.cli.StreamConsumer;
import org.apache.maven.it.util.cli.WriterStreamConsumer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Writer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.AccessControlException;
import java.security.Permission;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import junit.framework.Assert;
/**
* @author Jason van Zyl
* @author Brett Porter
* @version $Id: Verifier.java 805828 2009-08-19 14:57:23Z bentmann $
* @noinspection UseOfSystemOutOrSystemErr,RefusedBequest
*/
public class Verifier
{
private static final String LOG_FILENAME = "log.txt";
public String localRepo;
private final String basedir;
private final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
private final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
private PrintStream originalOut;
private PrintStream originalErr;
private List cliOptions = new ArrayList();
private Properties systemProperties = new Properties();
private Properties verifierProperties = new Properties();
private boolean autoclean = true;
// TODO: needs to be configurable
private static String localRepoLayout = "default";
private boolean debug;
private boolean forkJvm = true;
private String logFileName = LOG_FILENAME;
private String defaultMavenHome;
// will launch mvn with --debug
private boolean mavenDebug = false;
public Verifier( String basedir, String settingsFile )
throws VerificationException
{
this( basedir, settingsFile, false );
}
public Verifier( String basedir, String settingsFile, boolean debug )
throws VerificationException
{
this( basedir, settingsFile, debug, true );
}
public Verifier( String basedir, String settingsFile, boolean debug, boolean forkJvm )
throws VerificationException
{
this.basedir = basedir;
this.debug = debug;
this.forkJvm = forkJvm;
if ( !debug )
{
originalOut = System.out;
System.setOut( new PrintStream( outStream ) );
originalErr = System.err;
System.setErr( new PrintStream( errStream ) );
}
findLocalRepo( settingsFile );
findDefaultMavenHome();
}
private void findDefaultMavenHome()
throws VerificationException
{
defaultMavenHome = System.getProperty( "maven.home" );
if ( defaultMavenHome == null )
{
try
{
Properties envVars = CommandLineUtils.getSystemEnvVars();
defaultMavenHome = envVars.getProperty( "M2_HOME" );
}
catch ( IOException e )
{
throw new VerificationException( "Cannot read system environment variables.", e );
}
}
}
public Verifier( String basedir )
throws VerificationException
{
this( basedir, null );
}
public Verifier( String basedir, boolean debug )
throws VerificationException
{
this( basedir, null, debug );
}
public void setLocalRepo( String localRepo )
{
this.localRepo = localRepo;
}
public void resetStreams()
{
if ( !debug )
{
System.setOut( originalOut );
System.setErr( originalErr );
}
}
public void displayStreamBuffers()
{
String out = outStream.toString();
if ( out != null && out.trim().length() > 0 )
{
System.out.println( "----- Standard Out -----" );
System.out.println( out );
}
String err = errStream.toString();
if ( err != null && err.trim().length() > 0 )
{
System.err.println( "----- Standard Error -----" );
System.err.println( err );
}
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
public void verify( boolean chokeOnErrorOutput )
throws VerificationException
{
List lines = loadFile( getBasedir(), "expected-results.txt", false );
for ( Iterator i = lines.iterator(); i.hasNext(); )
{
String line = (String) i.next();
verifyExpectedResult( line );
}
if ( chokeOnErrorOutput )
{
verifyErrorFreeLog();
}
}
public void verifyErrorFreeLog()
throws VerificationException
{
List lines;
lines = loadFile( getBasedir(), getLogFileName(), false );
for ( Iterator i = lines.iterator(); i.hasNext(); )
{
String line = (String) i.next();
// A hack to keep stupid velocity resource loader errors from triggering failure
if ( line.indexOf( "[ERROR]" ) >= 0 && !isVelocityError( line ) )
{
throw new VerificationException( "Error in execution: " + line );
}
}
}
/**
* Checks whether the specified line is just an error message from Velocity. Especially old versions of Doxia employ
* a very noisy Velocity instance.
*
* @param line The log line to check, must not be null
.
* @return true
if the line appears to be a Velocity error, false
otherwise.
*/
private static boolean isVelocityError( String line )
{
if ( line.indexOf( "VM_global_library.vm" ) >= 0 )
{
return true;
}
if ( line.indexOf( "VM #" ) >= 0 && line.indexOf( "macro" ) >= 0 )
{
// [ERROR] VM #displayTree: error : too few arguments to macro. Wanted 2 got 0
return true;
}
return false;
}
/**
* Throws an exception if the text is not present in the log.
* @param text
* @throws VerificationException
*/
public void verifyTextInLog( String text )
throws VerificationException
{
List lines;
lines = loadFile( getBasedir(), getLogFileName(), false );
boolean result = false;
for ( Iterator i = lines.iterator(); i.hasNext(); )
{
String line = (String) i.next();
if ( line.indexOf( text ) >= 0)
{
result = true;
break;
}
}
if (!result)
{
throw new VerificationException( "Text not found in log: " + text );
}
}
public Properties loadProperties( String filename )
throws VerificationException
{
Properties properties = new Properties();
try
{
File propertiesFile = new File( getBasedir(), filename );
if ( propertiesFile.exists() )
{
FileInputStream fis = new FileInputStream( propertiesFile );
try
{
properties.load( fis );
}
finally
{
fis.close();
}
}
}
catch ( FileNotFoundException e )
{
throw new VerificationException( "Error reading properties file", e );
}
catch ( IOException e )
{
throw new VerificationException( "Error reading properties file", e );
}
return properties;
}
/**
* Loads the (non-empty) lines of the specified text file.
*
* @param filename The path to the text file to load, relative to the base directory, must not be null
.
* @param encoding The character encoding of the file, may be null
or empty to use the platform default
* encoding.
* @return The list of (non-empty) lines from the text file, can be empty but never null
.
* @throws IOException If the file could not be loaded.
* @since 1.2
*/
public List loadLines( String filename, String encoding )
throws IOException
{
List lines = new ArrayList();
File file = new File( getBasedir(), filename );
BufferedReader reader = null;
try
{
if ( StringUtils.isNotEmpty( encoding ) )
{
reader = new BufferedReader( new InputStreamReader( new FileInputStream( file ), encoding ) );
}
else
{
reader = new BufferedReader( new FileReader( file ) );
}
String line;
while ( ( line = reader.readLine() ) != null )
{
if ( line.length() > 0 )
{
lines.add( line );
}
}
}
finally
{
IOUtil.close( reader );
}
return lines;
}
public List loadFile( String basedir, String filename, boolean hasCommand )
throws VerificationException
{
return loadFile( new File( basedir, filename ), hasCommand );
}
public List loadFile( File file, boolean hasCommand )
throws VerificationException
{
List lines = new ArrayList();
if ( file.exists() )
{
try
{
BufferedReader reader = new BufferedReader( new FileReader( file ) );
String line = reader.readLine();
while ( line != null )
{
line = line.trim();
if ( !line.startsWith( "#" ) && line.length() != 0 )
{
lines.addAll( replaceArtifacts( line, hasCommand ) );
}
line = reader.readLine();
}
reader.close();
}
catch ( FileNotFoundException e )
{
throw new VerificationException( e );
}
catch ( IOException e )
{
throw new VerificationException( e );
}
}
return lines;
}
private List replaceArtifacts( String line, boolean hasCommand )
{
String MARKER = "${artifact:";
int index = line.indexOf( MARKER );
if ( index >= 0 )
{
String newLine = line.substring( 0, index );
index = line.indexOf( "}", index );
if ( index < 0 )
{
throw new IllegalArgumentException( "line does not contain ending artifact marker: '" + line + "'" );
}
String artifact = line.substring( newLine.length() + MARKER.length(), index );
newLine += getArtifactPath( artifact );
newLine += line.substring( index + 1 );
List l = new ArrayList();
l.add( newLine );
int endIndex = newLine.lastIndexOf( '/' );
String command = null;
String filespec;
if ( hasCommand )
{
int startIndex = newLine.indexOf( ' ' );
command = newLine.substring( 0, startIndex );
filespec = newLine.substring( startIndex + 1, endIndex );
}
else
{
filespec = newLine;
}
File dir = new File( filespec );
addMetadataToList( dir, hasCommand, l, command );
addMetadataToList( dir.getParentFile(), hasCommand, l, command );
return l;
}
else
{
return Collections.singletonList( line );
}
}
private static void addMetadataToList( File dir, boolean hasCommand, List l, String command )
{
if ( dir.exists() && dir.isDirectory() )
{
String[] files = dir.list( new FilenameFilter()
{
public boolean accept( File dir, String name )
{
return name.startsWith( "maven-metadata" ) && name.endsWith( ".xml" );
}
} );
for ( int i = 0; i < files.length; i++ )
{
if ( hasCommand )
{
l.add( command + " " + new File( dir, files[i] ).getPath() );
}
else
{
l.add( new File( dir, files[i] ).getPath() );
}
}
}
}
private String getArtifactPath( String artifact )
{
StringTokenizer tok = new StringTokenizer( artifact, ":" );
if ( tok.countTokens() != 4 )
{
throw new IllegalArgumentException( "Artifact must have 4 tokens: '" + artifact + "'" );
}
String[] a = new String[4];
for ( int i = 0; i < 4; i++ )
{
a[i] = tok.nextToken();
}
String org = a[0];
String name = a[1];
String version = a[2];
String ext = a[3];
return getArtifactPath( org, name, version, ext );
}
public String getArtifactPath( String org, String name, String version, String ext )
{
if ( "maven-plugin".equals( ext ) )
{
ext = "jar";
}
String classifier = null;
if ( "coreit-artifact".equals( ext ) )
{
ext = "jar";
classifier = "it";
}
if ( "test-jar".equals( ext ) )
{
ext = "jar";
classifier = "tests";
}
String repositoryPath;
if ( "legacy".equals( localRepoLayout ) )
{
repositoryPath = org + "/" + ext + "s/" + name + "-" + version + "." + ext;
}
else if ( "default".equals( localRepoLayout ) )
{
repositoryPath = org.replace( '.', '/' );
repositoryPath = repositoryPath + "/" + name + "/" + version;
repositoryPath = repositoryPath + "/" + name + "-" + version;
if ( classifier != null )
{
repositoryPath = repositoryPath + "-" + classifier;
}
repositoryPath = repositoryPath + "." + ext;
}
else
{
throw new IllegalStateException( "Unknown layout: " + localRepoLayout );
}
return localRepo + "/" + repositoryPath;
}
public List getArtifactFileNameList( String org, String name, String version, String ext )
{
List files = new ArrayList();
String artifactPath = getArtifactPath( org, name, version, ext );
File dir = new File( artifactPath );
files.add( artifactPath );
addMetadataToList( dir, false, files, null );
addMetadataToList( dir.getParentFile(), false, files, null );
return files;
}
/**
* Gets the path to the local artifact metadata. Note that the method does not check whether the returned path
* actually points to existing metadata.
*
* @param gid The group id, must not be null
.
* @param aid The artifact id, must not be null
.
* @param version The artifact version, must not be null
.
* @return The (absolute) path to the local artifact metadata, never null
.
*/
public String getArtifactMetadataPath( String gid, String aid, String version )
{
StringBuffer buffer = new StringBuffer( 256 );
buffer.append( localRepo );
buffer.append( '/' );
if ( "default".equals( localRepoLayout ) )
{
buffer.append( gid.replace( '.', '/' ) );
buffer.append( '/' );
buffer.append( aid );
buffer.append( '/' );
if ( version != null )
{
buffer.append( version );
buffer.append( '/' );
}
buffer.append( "maven-metadata-local.xml" );
}
else
{
throw new IllegalStateException( "Unsupported repository layout: " + localRepoLayout );
}
return buffer.toString();
}
/**
* Gets the path to the local artifact metadata. Note that the method does not check whether the returned path
* actually points to existing metadata.
*
* @param gid The group id, must not be null
.
* @param aid The artifact id, must not be null
.
* @return The (absolute) path to the local artifact metadata, never null
.
*/
public String getArtifactMetadataPath( String gid, String aid )
{
return getArtifactMetadataPath( gid, aid, null );
}
public void executeHook( String filename )
throws VerificationException
{
try
{
File f = new File( getBasedir(), filename );
if ( !f.exists() )
{
return;
}
List lines = loadFile( f, true );
for ( Iterator i = lines.iterator(); i.hasNext(); )
{
String line = resolveCommandLineArg( (String) i.next() );
executeCommand( line );
}
}
catch ( VerificationException e )
{
throw e;
}
catch ( Exception e )
{
throw new VerificationException( e );
}
}
private void executeCommand( String line )
throws VerificationException
{
int index = line.indexOf( " " );
String cmd;
String args = null;
if ( index >= 0 )
{
cmd = line.substring( 0, index );
args = line.substring( index + 1 );
}
else
{
cmd = line;
}
if ( "rm".equals( cmd ) )
{
System.out.println( "Removing file: " + args );
File f = new File( args );
if ( f.exists() && !f.delete() )
{
throw new VerificationException( "Error removing file - delete failed" );
}
}
else if ( "rmdir".equals( cmd ) )
{
System.out.println( "Removing directory: " + args );
try
{
File f = new File( args );
FileUtils.deleteDirectory( f );
}
catch ( IOException e )
{
throw new VerificationException( "Error removing directory - delete failed" );
}
}
else if ( "svn".equals( cmd ) )
{
launchSubversion( line, getBasedir() );
}
else
{
throw new VerificationException( "unknown command: " + cmd );
}
}
public static void launchSubversion( String line, String basedir )
throws VerificationException
{
try
{
Commandline cli = new Commandline( line );
cli.setWorkingDirectory( basedir );
Writer logWriter = new FileWriter( new File( basedir, LOG_FILENAME ) );
StreamConsumer out = new WriterStreamConsumer( logWriter );
StreamConsumer err = new WriterStreamConsumer( logWriter );
System.out.println( "Command: " + Commandline.toString( cli.getCommandline() ) );
int ret = CommandLineUtils.executeCommandLine( cli, out, err );
logWriter.close();
if ( ret > 0 )
{
System.err.println( "Exit code: " + ret );
throw new VerificationException();
}
}
catch ( CommandLineException e )
{
throw new VerificationException( e );
}
catch ( IOException e )
{
throw new VerificationException( e );
}
}
private static String retrieveLocalRepo( String settingsXmlPath )
throws VerificationException
{
UserModelReader userModelReader = new UserModelReader();
String userHome = System.getProperty( "user.home" );
File userXml;
String repo = null;
if ( settingsXmlPath != null )
{
System.out.println( "Using settings from " + settingsXmlPath );
userXml = new File( settingsXmlPath );
}
else
{
userXml = new File( userHome, ".m2/settings.xml" );
}
if ( userXml.exists() )
{
userModelReader.parse( userXml );
String localRepository = userModelReader.getLocalRepository();
if ( localRepository != null )
{
repo = new File( localRepository ).getAbsolutePath();
}
}
return repo;
}
public void deleteArtifact( String org, String name, String version, String ext )
throws IOException
{
List files = getArtifactFileNameList( org, name, version, ext );
for ( Iterator i = files.iterator(); i.hasNext(); )
{
String fileName = (String) i.next();
FileUtils.forceDelete( new File( fileName ) );
}
}
/**
* Deletes all artifacts in the specified group id from the local repository.
*
* @param gid The group id whose artifacts should be deleted, must not be null
.
* @throws IOException If the artifacts could not be deleted.
* @since 1.2
*/
public void deleteArtifacts( String gid )
throws IOException
{
String path;
if ( "default".equals( localRepoLayout ) )
{
path = gid.replace( '.', '/' );
}
else if ( "legacy".equals( localRepoLayout ) )
{
path = gid;
}
else
{
throw new IllegalStateException( "Unsupported repository layout: " + localRepoLayout );
}
FileUtils.deleteDirectory( new File( localRepo, path ) );
}
/**
* Deletes the specified directory.
*
* @param path The path to the directory to delete, relative to the base directory, must not be null
.
* @throws IOException If the directory could not be deleted.
* @since 1.2
*/
public void deleteDirectory( String path )
throws IOException
{
FileUtils.deleteDirectory( new File( getBasedir(), path ) );
}
/**
* Writes a text file with the specified contents. The contents will be encoded using UTF-8.
*
* @param path The path to the file, relative to the base directory, must not be null
.
* @param contents The contents to write, must not be null
.
* @throws IOException If the file could not be written.
* @since 1.2
*/
public void writeFile( String path, String contents )
throws IOException
{
FileUtils.fileWrite( new File( getBasedir(), path ).getAbsolutePath(), "UTF-8", contents );
}
/**
* Filters a text file by replacing some user-defined tokens.
*
* @param srcPath The path to the input file, relative to the base directory, must not be null
.
* @param dstPath The path to the output file, relative to the base directory and possibly equal to the input file,
* must not be null
.
* @param fileEncoding The file encoding to use, may be null
or empty to use the platform's default
* encoding.
* @param filterProperties The mapping from tokens to replacement values, must not be null
.
* @return The path to the filtered output file, never null
.
* @throws IOException If the file could not be filtered.
* @since 1.2
*/
public File filterFile( String srcPath, String dstPath, String fileEncoding, Map filterProperties )
throws IOException
{
File srcFile = new File( getBasedir(), srcPath );
String data = FileUtils.fileRead( srcFile, fileEncoding );
for ( Iterator it = filterProperties.keySet().iterator(); it.hasNext(); )
{
String token = (String) it.next();
String value = String.valueOf( filterProperties.get( token ) );
data = StringUtils.replace( data, token, value );
}
File dstFile = new File( getBasedir(), dstPath );
FileUtils.fileWrite( dstFile.getPath(), fileEncoding, data );
return dstFile;
}
/**
* Gets a new copy of the default filter properties. These default filter properties map the tokens "@basedir@" and
* "@baseurl@" to the test's base directory and its base file:
URL, respectively.
*
* @return The (modifiable) map with the default filter properties, never null
.
* @since 1.2
*/
public Properties newDefaultFilterProperties()
{
Properties filterProperties = new Properties();
String basedir = new File( getBasedir() ).getAbsolutePath();
filterProperties.put( "@basedir@", basedir );
/*
* NOTE: Maven fails to properly handle percent-encoded "file:" URLs (WAGON-111) so don't use File.toURI() here
* and just do it the simple way.
*/
String baseurl = basedir;
if ( !baseurl.startsWith( "/" ) )
{
baseurl = '/' + baseurl;
}
baseurl = "file://" + baseurl.replace( '\\', '/' );
filterProperties.put( "@baseurl@", baseurl );
return filterProperties;
}
public void assertFilePresent( String file )
{
try
{
verifyExpectedResult( file, true );
}
catch ( VerificationException e )
{
Assert.fail( e.getMessage() );
}
}
/**
* Check that given file's content matches an regular expression. Note this method also checks that the file exists
* and is readable.
*
* @param file the file to check.
* @param regex a regular expression.
* @see Pattern
*/
public void assertFileMatches( String file, String regex )
{
assertFilePresent( file );
try
{
String content = FileUtils.fileRead( file );
if ( !Pattern.matches( regex, content ) )
{
Assert.fail( "Content of " + file + " does not match " + regex );
}
}
catch ( IOException e )
{
Assert.fail( e.getMessage() );
}
}
public void assertFileNotPresent( String file )
{
try
{
verifyExpectedResult( file, false );
}
catch ( VerificationException e )
{
Assert.fail( e.getMessage() );
}
}
private void verifyArtifactPresence( boolean wanted, String org, String name, String version, String ext )
{
List files = getArtifactFileNameList( org, name, version, ext );
for ( Iterator i = files.iterator(); i.hasNext(); )
{
String fileName = (String) i.next();
try
{
verifyExpectedResult( fileName, wanted );
}
catch ( VerificationException e )
{
Assert.fail( e.getMessage() );
}
}
}
public void assertArtifactPresent( String org, String name, String version, String ext )
{
verifyArtifactPresence( true, org, name, version, ext );
}
public void assertArtifactNotPresent( String org, String name, String version, String ext )
{
verifyArtifactPresence( false, org, name, version, ext );
}
private void verifyExpectedResult( String line )
throws VerificationException
{
boolean wanted = true;
if ( line.startsWith( "!" ) )
{
line = line.substring( 1 );
wanted = false;
}
verifyExpectedResult( line, wanted );
}
private void verifyExpectedResult( String line, boolean wanted )
throws VerificationException
{
if ( line.indexOf( "!/" ) > 0 )
{
String urlString = "jar:file:" + getBasedir() + "/" + line;
InputStream is = null;
try
{
URL url = new URL( urlString );
is = url.openStream();
if ( is == null )
{
if ( wanted )
{
throw new VerificationException( "Expected JAR resource was not found: " + line );
}
}
else
{
if ( !wanted )
{
throw new VerificationException( "Unwanted JAR resource was found: " + line );
}
}
}
catch ( MalformedURLException e )
{
throw new VerificationException( "Error looking for JAR resource", e );
}
catch ( IOException e )
{
throw new VerificationException( "Error looking for JAR resource", e );
}
finally
{
if ( is != null )
{
try
{
is.close();
}
catch ( IOException e )
{
System.err.println( "WARN: error closing stream: " + e );
}
}
}
}
else
{
File expectedFile = new File( line );
// NOTE: On Windows, a path with a leading (back-)slash is relative to the current drive
if ( !expectedFile.isAbsolute() && !expectedFile.getPath().startsWith( File.separator ) )
{
expectedFile = new File( getBasedir(), line );
}
if ( line.indexOf( '*' ) > -1 )
{
File parent = expectedFile.getParentFile();
if ( !parent.exists() )
{
if ( wanted )
{
throw new VerificationException( "Expected file pattern was not found: " + expectedFile.getPath() );
}
}
else
{
String shortNamePattern = expectedFile.getName().replaceAll( "\\*", ".*" );
String[] candidates = parent.list();
boolean found = false;
if ( candidates != null )
{
for ( int i = 0; i < candidates.length; i++ )
{
if ( candidates[i].matches( shortNamePattern ) )
{
found = true;
break;
}
}
}
if ( !found && wanted )
{
throw new VerificationException(
"Expected file pattern was not found: " + expectedFile.getPath() );
}
else if ( found && !wanted )
{
throw new VerificationException( "Unwanted file pattern was found: " + expectedFile.getPath() );
}
}
}
else
{
if ( !expectedFile.exists() )
{
if ( wanted )
{
throw new VerificationException( "Expected file was not found: " + expectedFile.getPath() );
}
}
else
{
if ( !wanted )
{
throw new VerificationException( "Unwanted file was found: " + expectedFile.getPath() );
}
}
}
}
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
public void executeGoal( String goal )
throws VerificationException
{
executeGoal( goal, Collections.EMPTY_MAP );
}
public void executeGoal( String goal, Map envVars )
throws VerificationException
{
executeGoals( Arrays.asList( new String[] { goal } ), envVars );
}
public void executeGoals( List goals )
throws VerificationException
{
executeGoals( goals, Collections.EMPTY_MAP );
}
public String getExecutable()
{
// Use a strategy for finding the maven executable, John has a simple method like this
// but a little strategy + chain of command would be nicer.
String mavenHome = defaultMavenHome;
if ( mavenHome != null )
{
return mavenHome + "/bin/mvn";
}
else
{
File f = new File( System.getProperty( "user.home" ), "m2/bin/mvn" );
if ( f.exists() )
{
return f.getAbsolutePath();
}
else
{
return "mvn";
}
}
}
public void executeGoals( List goals, Map envVars )
throws VerificationException
{
if ( goals.size() == 0 )
{
throw new VerificationException( "No goals specified" );
}
List allGoals = new ArrayList();
if ( autoclean )
{
/*
* NOTE: Neither test lifecycle binding nor prefix resolution here but call the goal directly.
*/
allGoals.add( "org.apache.maven.plugins:maven-clean-plugin:clean" );
}
allGoals.addAll( goals );
Commandline cli = null;
int ret;
File logFile = new File( getBasedir(), getLogFileName() );
try
{
cli = createCommandLine();
for ( Iterator i = envVars.keySet().iterator(); i.hasNext(); )
{
String key = (String) i.next();
cli.addEnvironment( key, (String) envVars.get( key ) );
/* What was the point of this? It doesn't work on windows.
* try
{
FileUtils.fileWrite( "/tmp/foo.txt", "setting envar[ " + key + " = " + envVars.get( key ) );
}
catch ( IOException e )
{
e.printStackTrace(); // To change body of catch statement use File | Settings | File Templates.
}*/
// System.out.println();
}
if ( envVars.get( "JAVA_HOME" ) == null )
{
cli.addEnvironment( "JAVA_HOME", System.getProperty( "java.home" ) );
}
cli.addEnvironment( "MAVEN_TERMINATE_CMD", "on" );
cli.setWorkingDirectory( getBasedir() );
for ( Iterator it = cliOptions.iterator(); it.hasNext(); )
{
String key = String.valueOf( it.next() );
String resolvedArg = resolveCommandLineArg( key );
cli.createArgument().setLine( resolvedArg );
}
cli.createArgument().setValue( "-e" );
cli.createArgument().setValue( "--batch-mode" );
if ( this.mavenDebug )
{
cli.createArgument().setValue( "--debug" );
}
for ( Iterator i = systemProperties.keySet().iterator(); i.hasNext(); )
{
String key = (String) i.next();
String value = systemProperties.getProperty( key );
cli.createArgument().setValue( "-D" + key + "=" + value );
}
/*
* NOTE: Unless explicitly requested by the caller, the forked builds should use the current local
* repository. Otherwise, the forked builds would in principle leave the sandbox environment which has been
* setup for the current build. In particular, using "maven.repo.local" will make sure the forked builds use
* the same local repo as the parent build even if a custom user settings is provided.
*/
boolean useMavenRepoLocal =
Boolean.valueOf( verifierProperties.getProperty( "use.mavenRepoLocal", "true" ) ).booleanValue();
if ( useMavenRepoLocal )
{
cli.createArgument().setValue( "-Dmaven.repo.local=" + localRepo );
}
for ( Iterator i = allGoals.iterator(); i.hasNext(); )
{
cli.createArgument().setValue( (String) i.next() );
}
// System.out.println( "Command: " + Commandline.toString( cli.getCommandline() ) );
ret = runCommandLine( cli, logFile );
}
catch ( CommandLineException e )
{
throw new VerificationException( "Failed to execute Maven: " + cli, e );
}
catch ( IOException e )
{
throw new VerificationException( e );
}
if ( ret > 0 )
{
System.err.println( "Exit code: " + ret );
throw new VerificationException( "Exit code was non-zero: " + ret + "; command line and log = \n" + cli
+ "\n" + getLogContents( logFile ) );
}
}
public String getMavenVersion()
throws VerificationException
{
Commandline cmd = createCommandLine();
cmd.addArguments( new String[] { "--version" } );
File log;
try
{
log = File.createTempFile( "maven", "log" );
}
catch ( IOException e )
{
throw new VerificationException( "Error creating temp file", e );
}
try
{
runCommandLine( cmd, log );
}
catch ( CommandLineException e )
{
throw new VerificationException( "Error running commandline " + cmd.toString(), e );
}
catch ( IOException e )
{
throw new VerificationException( "IO Error communicating with commandline " + cmd.toString(), e );
}
String version = null;
List logLines = loadFile( log, false );
log.delete();
for ( Iterator it = logLines.iterator(); version == null && it.hasNext(); )
{
String line = (String) it.next();
final String MAVEN_VERSION = "Maven version: ";
// look out for "Maven version: 3.0-SNAPSHOT built on unknown"
if ( line.regionMatches( true, 0, MAVEN_VERSION, 0, MAVEN_VERSION.length() ) )
{
version = line.substring( MAVEN_VERSION.length() ).trim();
if ( version.indexOf( ' ' ) >= 0 )
{
version = version.substring( 0, version.indexOf( ' ' ) );
}
}
final String NEW_MAVEN_VERSION = "Apache Maven ";
// look out for "Apache Maven 2.1.0-M2-SNAPSHOT (rXXXXXX; date)"
if ( line.regionMatches( true, 0, NEW_MAVEN_VERSION, 0, NEW_MAVEN_VERSION.length() ) )
{
version = line.substring( NEW_MAVEN_VERSION.length() ).trim();
if ( version.indexOf( ' ' ) >= 0 )
{
version = version.substring( 0, version.indexOf( ' ' ) );
}
}
}
if ( version == null )
{
throw new VerificationException( "Illegal maven output: String 'Maven version: ' not found in the following output:\n"
+ StringUtils.join( logLines.iterator(), "\n" ) );
}
else
{
return version;
}
}
private Commandline createCommandLine()
{
Commandline cmd = new Commandline();
String executable = getExecutable();
if ( executable.endsWith( "/bin/mvn" ) )
{
cmd.addEnvironment( "M2_HOME", executable.substring( 0, executable.length() - 8 ) );
}
cmd.setExecutable( executable );
return cmd;
}
private int runCommandLine( Commandline cli, File logFile )
throws CommandLineException, IOException
{
if ( forkJvm )
{
Writer logWriter = new FileWriter( logFile );
StreamConsumer out = new WriterStreamConsumer( logWriter );
StreamConsumer err = new WriterStreamConsumer( logWriter );
try
{
return CommandLineUtils.executeCommandLine( cli, out, err );
}
finally
{
logWriter.close();
}
}
String mavenHome = defaultMavenHome;
if ( mavenHome == null )
{
mavenHome = System.getProperty( "user.home" ) + "/local/apache-maven-2.1-SNAPSHOT";
}
File coreDir = new File( mavenHome, "core/boot" );
File[] files = coreDir.listFiles();
File classWorldFile = null;
for ( int i = 0; files != null && i < files.length; i++ )
{
if ( files[i].getName().indexOf( "plexus-classworlds" ) >= 0 )
{
classWorldFile = files[i];
break;
}
}
if ( classWorldFile == null )
{
throw new CommandLineException( "Cannot find plexus-classworlds in " + coreDir );
}
URLClassLoader cl;
try
{
cl = new URLClassLoader( new URL[] { classWorldFile.toURI().toURL() }, null );
}
catch ( MalformedURLException e )
{
throw new CommandLineException( "Cannot conver to url: " + classWorldFile, e );
}
class ExitSecurityException
extends SecurityException
{
private int status;
public ExitSecurityException( int status )
{
this.status = status;
}
public int getStatus()
{
return status;
}
}
try
{
Class c = cl.loadClass( "org.codehaus.plexus.classworlds.launcher.Launcher" );
Method m = c.getMethod( "mainWithExitCode", new Class[] { String[].class } );
SecurityManager oldSm = System.getSecurityManager();
try
{
System.setSecurityManager( new SecurityManager()
{
public void checkPermission( Permission perm )
{
// ok
}
public void checkExit( int status )
{
throw new ExitSecurityException( status );
}
} );
}
catch ( AccessControlException e )
{
throw new CommandLineException( "Error isntalling securitymanager", e );
}
cli.createArgument().setValue( "-f" );
cli.createArgument().setValue( cli.getWorkingDirectory().getAbsolutePath() + "/pom.xml" );
PrintStream oldOut = System.out;
PrintStream oldErr = System.err;
String oldCwConf = System.getProperty( "classworlds.conf" );
String oldMavenHome = System.getProperty( "maven.home" );
ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
try
{
Thread.currentThread().setContextClassLoader( cl );// ClassLoader.getSystemClassLoader() );
FileOutputStream logWriter = new FileOutputStream( logFile );
System.setOut( new PrintStream( logWriter ) );
System.setErr( new PrintStream( logWriter ) );
System.setProperty( "classworlds.conf", new File( mavenHome, "bin/m2.conf" ).getAbsolutePath() );
System.setProperty( "maven.home", mavenHome );
return ( (Integer) m.invoke( null, new Object[] { cli.getArguments() } ) ).intValue();
}
catch ( ExitSecurityException e )
{
oldOut.println( "exit security exception caught: status=" + e.getStatus() );
return e.getStatus();
}
finally
{
System.setOut( oldOut );
System.setErr( oldErr );
if ( oldCwConf == null )
{
System.getProperties().remove( "classworlds.conf" );
}
else
{
System.setProperty( "classworlds.conf", oldCwConf );
}
if ( oldMavenHome == null )
{
System.getProperties().remove( "maven.home" );
}
else
{
System.setProperty( "maven.home", oldMavenHome );
}
Thread.currentThread().setContextClassLoader( oldCl );
System.setSecurityManager( oldSm );
}
}
catch ( ClassNotFoundException e )
{
throw new CommandLineException( "Cannot load classworlds launcher", e );
}
catch ( NoSuchMethodException e )
{
throw new CommandLineException( "Cannot find classworlds launcher's main method", e );
}
catch ( IllegalArgumentException e )
{
throw new CommandLineException( "Error executing classworlds launcher's main method", e );
}
catch ( InvocationTargetException e )
{
if ( e.getCause() instanceof ExitSecurityException )
{
return ( (ExitSecurityException) e.getCause() ).getStatus();
}
throw new CommandLineException( "Error executing classworlds launcher's main method", e );
}
catch ( IllegalAccessException e )
{
throw new CommandLineException( "Error executing classworlds launcher's main method", e );
}
}
private static String getLogContents( File logFile )
{
try
{
return FileUtils.fileRead( logFile );
}
catch ( IOException e )
{
// ignore
return "(Error reading log contents: " + e.getMessage() + ")";
}
}
private String resolveCommandLineArg( String key )
{
String result = key.replaceAll( "\\$\\{basedir\\}", getBasedir() );
if ( result.indexOf( "\\\\" ) >= 0 )
{
result = result.replaceAll( "\\\\", "\\" );
}
result = result.replaceAll( "\\/\\/", "\\/" );
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:" );
try
{
BufferedReader reader = new BufferedReader( new FileReader( new File( getBasedir(), getLogFileName() ) ) );
String line = reader.readLine();
while ( line != null )
{
System.out.println( line );
line = reader.readLine();
}
reader.close();
}
catch ( FileNotFoundException e )
{
System.err.println( "Error: " + e );
}
catch ( IOException e )
{
System.err.println( "Error: " + e );
}
}
// ----------------------------------------------------------------------
//
// ----------------------------------------------------------------------
public static void main( String args[] )
throws VerificationException
{
String basedir = System.getProperty( "user.dir" );
List tests = null;
List argsList = new ArrayList();
String settingsFile = null;
// skip options
for ( int i = 0; i < args.length; i++ )
{
if ( args[i].startsWith( "-D" ) )
{
int index = args[i].indexOf( "=" );
if ( index >= 0 )
{
System.setProperty( args[i].substring( 2, index ), args[i].substring( index + 1 ) );
}
else
{
System.setProperty( args[i].substring( 2 ), "true" );
}
}
else if ( "-s".equals( args[i] ) || "--settings".equals( args[i] ) )
{
if ( i == args.length - 1 )
{
// should have been detected before
throw new IllegalStateException( "missing argument to -s" );
}
i += 1;
settingsFile = args[i];
}
else if ( args[i].startsWith( "-" ) )
{
System.out.println( "skipping unrecognised argument: " + args[i] );
}
else
{
argsList.add( args[i] );
}
}
if ( argsList.size() == 0 )
{
if ( FileUtils.fileExists( basedir + File.separator + "integration-tests.txt" ) )
{
try
{
tests = FileUtils.loadFile( new File( basedir, "integration-tests.txt" ) );
}
catch ( IOException e )
{
System.err.println( "Unable to load integration tests file" );
System.err.println( e.getMessage() );
System.exit( 2 );
}
}
else
{
tests = discoverIntegrationTests( "." );
}
}
else
{
tests = new ArrayList( argsList.size() );
NumberFormat fmt = new DecimalFormat( "0000" );
for ( int i = 0; i < argsList.size(); i++ )
{
String test = (String) argsList.get( i );
if ( test.endsWith( "," ) )
{
test = test.substring( 0, test.length() - 1 );
}
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() )
{
tests.addAll( discoverIntegrationTests( test ) );
}
else
{
System.err.println(
"[WARNING] rejecting " + test + " as an invalid test or test source directory" );
}
}
}
if ( tests.size() == 0 )
{
System.out.println( "No tests to run" );
}
int exitCode = 0;
List failed = new ArrayList();
for ( Iterator i = tests.iterator(); i.hasNext(); )
{
String test = (String) i.next();
System.out.print( test + "... " );
String dir = basedir + "/" + test;
if ( !new File( dir, "goals.txt" ).exists() )
{
System.err.println( "Test " + test + " in " + dir + " does not exist" );
System.exit( 2 );
}
Verifier verifier = new Verifier( dir );
verifier.findLocalRepo( settingsFile );
System.out.println( "Using default local repository: " + verifier.localRepo );
try
{
runIntegrationTest( verifier );
}
catch ( Throwable e )
{
verifier.resetStreams();
System.out.println( "FAILED" );
verifier.displayStreamBuffers();
System.out.println( ">>>>>> Error Stacktrace:" );
e.printStackTrace( System.out );
System.out.println( "<<<<<< Error Stacktrace" );
verifier.displayLogFile();
exitCode = 1;
failed.add( test );
}
}
System.out.println( tests.size() - failed.size() + "/" + tests.size() + " passed" );
if ( !failed.isEmpty() )
{
System.out.println( "Failed tests: " + failed );
}
System.exit( exitCode );
}
private void findLocalRepo( String settingsFile )
throws VerificationException
{
if ( localRepo == null )
{
localRepo = System.getProperty( "maven.repo.local" );
}
if ( localRepo == null )
{
localRepo = retrieveLocalRepo( settingsFile );
}
if ( localRepo == null )
{
localRepo = System.getProperty( "user.home" ) + "/.m2/repository";
}
File repoDir = new File( localRepo );
if ( !repoDir.exists() )
{
repoDir.mkdirs();
}
// normalize path
localRepo = repoDir.getAbsolutePath();
}
private static void runIntegrationTest( Verifier verifier )
throws VerificationException
{
verifier.executeHook( "prebuild-hook.txt" );
Properties properties = verifier.loadProperties( "system.properties" );
Properties controlProperties = verifier.loadProperties( "verifier.properties" );
boolean chokeOnErrorOutput =
Boolean.valueOf( controlProperties.getProperty( "failOnErrorOutput", "true" ) ).booleanValue();
List goals = verifier.loadFile( verifier.getBasedir(), "goals.txt", false );
List cliOptions = verifier.loadFile( verifier.getBasedir(), "cli-options.txt", false );
verifier.setCliOptions( cliOptions );
verifier.setSystemProperties( properties );
verifier.setVerifierProperties( controlProperties );
verifier.executeGoals( goals );
verifier.executeHook( "postbuild-hook.txt" );
System.out.println( "*** Verifying: fail when [ERROR] detected? " + chokeOnErrorOutput + " ***" );
verifier.verify( chokeOnErrorOutput );
verifier.resetStreams();
System.out.println( "OK" );
}
public void assertArtifactContents( String org, String artifact, String version, String type, String contents )
throws IOException
{
String fileName = getArtifactPath( org, artifact, version, type );
Assert.assertEquals( contents, FileUtils.fileRead( fileName ) );
}
static class UserModelReader
extends DefaultHandler
{
private String localRepository;
private StringBuffer currentBody = new StringBuffer();
public void parse( File file )
throws VerificationException
{
try
{
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();
InputSource is = new InputSource( new FileInputStream( file ) );
parser.parse( is, this );
}
catch ( FileNotFoundException e )
{
throw new VerificationException( e );
}
catch ( IOException e )
{
throw new VerificationException( e );
}
catch ( ParserConfigurationException e )
{
throw new VerificationException( e );
}
catch ( SAXException e )
{
throw new VerificationException( e );
}
}
public void warning( SAXParseException spe )
{
printParseError( "Warning", spe );
}
public void error( SAXParseException spe )
{
printParseError( "Error", spe );
}
public void fatalError( SAXParseException spe )
{
printParseError( "Fatal Error", spe );
}
private final void printParseError( String type, SAXParseException spe )
{
System.err.println(
type + " [line " + spe.getLineNumber() + ", row " + spe.getColumnNumber() + "]: " + spe.getMessage() );
}
public String getLocalRepository()
{
return localRepository;
}
public void characters( char[] ch, int start, int length )
throws SAXException
{
currentBody.append( ch, start, length );
}
public void endElement( String uri, String localName, String rawName )
throws SAXException
{
if ( "localRepository".equals( rawName ) )
{
if ( notEmpty( currentBody.toString() ) )
{
localRepository = currentBody.toString().trim();
}
else
{
throw new SAXException(
"Invalid mavenProfile entry. Missing one or more " + "fields: {localRepository}." );
}
}
currentBody = new StringBuffer();
}
private boolean notEmpty( String test )
{
return test != null && test.trim().length() > 0;
}
public void reset()
{
currentBody = null;
localRepository = null;
}
}
public List getCliOptions()
{
return cliOptions;
}
public void setCliOptions( List cliOptions )
{
this.cliOptions = cliOptions;
}
public Properties getSystemProperties()
{
return systemProperties;
}
public void setSystemProperties( Properties systemProperties )
{
this.systemProperties = systemProperties;
}
public Properties getVerifierProperties()
{
return verifierProperties;
}
public void setVerifierProperties( Properties verifierProperties )
{
this.verifierProperties = verifierProperties;
}
public boolean isAutoclean()
{
return autoclean;
}
public void setAutoclean( boolean autoclean )
{
this.autoclean = autoclean;
}
public String getBasedir()
{
return basedir;
}
/**
* Gets the name of the file used to log build output.
*
* @return The name of the log file, relative to the base directory, never null
.
* @since 1.2
*/
public String getLogFileName()
{
return this.logFileName;
}
/**
* Sets the name of the file used to log build output.
*
* @param logFileName The name of the log file, relative to the base directory, must not be empty or
* null
.
* @since 1.2
*/
public void setLogFileName( String logFileName )
{
if ( StringUtils.isEmpty( logFileName ) )
{
throw new IllegalArgumentException( "log file name unspecified" );
}
this.logFileName = logFileName;
}
public void setDebug( boolean debug )
{
this.debug = debug;
}
public boolean isMavenDebug()
{
return mavenDebug;
}
public void setMavenDebug( boolean mavenDebug )
{
this.mavenDebug = mavenDebug;
}
}