so long mboot2, you were a good friend

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@345826 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-11-21 04:29:15 +00:00
parent d69207adea
commit 88091f6d63
32 changed files with 0 additions and 10166 deletions

View File

@ -1,16 +0,0 @@
#!/bin/sh
buildDir=target
classesDir=${buildDir}/classes
srcDir=src/main/java
rm -rf ${buildDir} > /dev/null 2>&1
mkdir -p ${classesDir}
#javac -d ${classesDir} ${srcDir}/*.java
"$JAVA_HOME/bin/javac" -g -d ${classesDir} `find ${srcDir} -name '*.java'`
( cd ${classesDir} ; "$JAVA_HOME/bin/jar" -cfm ../mboot.jar ../../manifest.txt * )
cp ${buildDir}/mboot.jar ..

View File

@ -1,21 +0,0 @@
@echo off
set buildDir=target
set classesDir=%buildDir%\classes
set srcDir=src\main\java
if exist %classesDir% rmdir /S/Q %buildDir%
if exist %buildDir% rmdir /S/Q %buildDir%
mkdir %buildDir%
mkdir %classesDir%
dir /B /s %srcDir%\*.java >sources
"%JAVA_HOME%\bin\javac" -d %classesDir% @sources
del /F/Q sources
cd %classesDir%
"%JAVA_HOME%\bin\jar" -cfm ..\mboot.jar ..\..\manifest.txt *.*
cd ..\..
copy %buildDir%\mboot.jar ..

View File

@ -1,3 +0,0 @@
Manifest-Version: 1.0
Created-By: Grand Master Pooky Mook
Main-Class: MBoot

View File

@ -1,35 +0,0 @@
<model xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>maven</artifactId>
<groupId>org.apache.maven</groupId>
<version>2.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-mboot</artifactId>
<version>2.0.1-SNAPSHOT</version>
<name>Maven MBoot</name>
<description>Tool used to bootstrap m2.</description>
<dependencies>
<dependency>
<groupId>org.codehaus.modello</groupId>
<artifactId>modello-plugin-xpp3</artifactId>
<version>1.0-alpha-6</version>
<scope>runtime</scope>
</dependency>
<!-- Just for install... possibly not needed here? -->
<dependency>
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
<version>1.1-alpha-2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
</model>

File diff suppressed because it is too large Load Diff

View File

@ -1,170 +0,0 @@
package compile;
import util.DirectoryScanner;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
* @author <a href="mailto:michal.maczka@dimatics.com">Michal Maczka </a>
* @version $Id$
*/
public abstract class AbstractCompiler
implements Compiler
{
private static String PS = System.getProperty( "path.separator" );
public String getPathString( List pathElements )
throws Exception
{
StringBuffer sb = new StringBuffer();
for ( Iterator it = pathElements.iterator(); it.hasNext(); )
{
String element = (String) it.next();
sb.append( element ).append( PS );
}
return sb.toString();
}
protected String[] getSourceFiles( CompilerConfiguration config )
{
Set sources = new HashSet();
Set sourceFiles = config.getSourceFiles();
if ( sourceFiles != null && !sourceFiles.isEmpty() )
{
for ( Iterator it = sourceFiles.iterator(); it.hasNext(); )
{
File sourceFile = (File) it.next();
sources.add( sourceFile.getAbsolutePath() );
}
}
else
{
for ( Iterator it = config.getSourceLocations().iterator(); it.hasNext(); )
{
String sourceLocation = (String) it.next();
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( sourceLocation );
Set includes = config.getIncludes();
if ( includes != null && !includes.isEmpty() )
{
String[] inclStrs = (String[]) includes.toArray( new String[includes.size()] );
scanner.setIncludes( inclStrs );
}
else
{
scanner.setIncludes( new String[]{"**/*.java"} );
}
Set excludes = config.getExcludes();
if ( excludes != null && !excludes.isEmpty() )
{
String[] exclStrs = (String[]) excludes.toArray( new String[excludes.size()] );
scanner.setIncludes( exclStrs );
}
scanner.scan();
String[] sourceDirectorySources = scanner.getIncludedFiles();
for ( int j = 0; j < sourceDirectorySources.length; j++ )
{
File f = new File( sourceLocation, sourceDirectorySources[j] );
sources.add( f.getPath() );
}
}
}
String[] result = null;
if ( sources.isEmpty() )
{
result = new String[0];
}
else
{
result = (String[]) sources.toArray( new String[sources.size()] );
}
return result;
}
protected String makeClassName( String fileName, String sourceDir )
throws IOException
{
File origFile = new File( fileName );
String canonical = null;
if ( origFile.exists() )
{
canonical = origFile.getCanonicalPath().replace( '\\', '/' );
}
String str = fileName;
str = str.replace( '\\', '/' );
if ( sourceDir != null )
{
String prefix = new File( sourceDir ).getCanonicalPath().replace( '\\', '/' );
if ( canonical != null )
{
if ( canonical.startsWith( prefix ) )
{
String result = canonical.substring( prefix.length() + 1, canonical.length() - 5 );
result = result.replace( '/', '.' );
return result;
}
}
else
{
File t = new File( sourceDir, fileName );
if ( t.exists() )
{
str = t.getCanonicalPath().replace( '\\', '/' );
String result = str.substring( prefix.length() + 1, str.length() - 5 ).replace( '/', '.' );
return result;
}
}
}
if ( fileName.endsWith( ".java" ) )
{
fileName = fileName.substring( 0, fileName.length() - 5 );
}
fileName = fileName.replace( '\\', '.' );
return fileName.replace( '/', '.' );
}
protected String[] toStringArray( List arguments )
{
String[] args = new String[arguments.size()];
for ( int i = 0; i < arguments.size(); i++ )
{
args[i] = (String) arguments.get( i );
}
return args;
}
}

View File

@ -1,20 +0,0 @@
package compile;
import java.util.List;
import java.util.Map;
/**
*
*
* @author <a href="mailto:jason@plexus.org">Jason van Zyl</a>
*
* @version $Id$
*/
public interface Compiler
{
static String ROLE = Compiler.class.getName();
List compile( CompilerConfiguration configuration )
throws Exception;
}

View File

@ -1,145 +0,0 @@
/* Created on Oct 4, 2004 */
package compile;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* @author jdcasey
*/
public class CompilerConfiguration
{
private String outputLocation;
private List classpathEntries = new LinkedList();
private List sourceLocations = new LinkedList();
private Set includes = new HashSet();
private Set excludes = new HashSet();
private Map compilerOptions = new TreeMap();
private boolean debug = false;
private Set sourceFiles = new HashSet();
private boolean noWarn;
public void setSourceFiles(Set sourceFiles)
{
this.sourceFiles = sourceFiles;
}
public Set getSourceFiles()
{
return sourceFiles;
}
public void setOutputLocation(String outputLocation)
{
this.outputLocation = outputLocation;
}
public String getOutputLocation()
{
return outputLocation;
}
public void addClasspathEntry(String classpathEntry)
{
this.classpathEntries.add(classpathEntry);
}
public void setClasspathEntries(List classpathEntries) {
this.classpathEntries = new LinkedList(classpathEntries);
}
public List getClasspathEntries() {
return Collections.unmodifiableList(classpathEntries);
}
public void addSourceLocation(String sourceLocation) {
this.sourceLocations.add(sourceLocation);
}
public void setSourceLocations(List sourceLocations) {
this.sourceLocations = new LinkedList(sourceLocations);
}
public List getSourceLocations() {
return Collections.unmodifiableList(sourceLocations);
}
public void addInclude(String include) {
this.includes.add(include);
}
public void setIncludes(Set includes) {
this.includes = new HashSet(includes);
}
public Set getIncludes() {
return Collections.unmodifiableSet(includes);
}
public void addExclude(String exclude) {
this.excludes.add(exclude);
}
public void setExcludes(Set excludes) {
this.excludes = new HashSet(excludes);
}
public Set getExcludes() {
return Collections.unmodifiableSet(excludes);
}
public void addCompilerOption(String optionName, String optionValue) {
this.compilerOptions.put(optionName, optionValue);
}
public void setCompilerOptions(Map compilerOptions) {
this.compilerOptions = new TreeMap(compilerOptions);
}
public Map getCompilerOptions() {
return Collections.unmodifiableMap(compilerOptions);
}
/**
* @param debug The debug to set.
*/
public void setDebug( boolean debug )
{
this.debug = debug;
}
/**
* Compile with debug info
*
* @return Returns the debug.
*/
public boolean isDebug()
{
return debug;
}
public void setNoWarn( boolean noWarn )
{
this.noWarn = noWarn;
}
public boolean isNoWarn()
{
return noWarn;
}
}

View File

@ -1,197 +0,0 @@
/**
*
* Copyright 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.
*/
package compile;
/**
* This class encapsulates an error message produced by a programming language
* processor (whether interpreted or compiled)
*
* @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a>
* @version CVS $Id$
* @since 2.0
*/
public class CompilerError
{
/**
* Is this a severe error or a warning?
*/
private boolean error;
/**
* The start line number of the offending program text
*/
private int startline;
/**
* The start column number of the offending program text
*/
private int startcolumn;
/**
* The end line number of the offending program text
*/
private int endline;
/**
* The end column number of the offending program text
*/
private int endcolumn;
/**
* The name of the file containing the offending program text
*/
private String file;
/**
* The actual error text produced by the language processor
*/
private String message;
/**
* The error message constructor.
*
* @param file The name of the file containing the offending program text
* @param error The actual error text produced by the language processor
* @param startline The start line number of the offending program text
* @param startcolumn The start column number of the offending program text
* @param endline The end line number of the offending program text
* @param endcolumn The end column number of the offending program text
* @param message The actual error text produced by the language processor
*/
public CompilerError(
String file,
boolean error,
int startline,
int startcolumn,
int endline,
int endcolumn,
String message
)
{
this.file = file;
this.error = error;
this.startline = startline;
this.startcolumn = startcolumn;
this.endline = endline;
this.endcolumn = endcolumn;
this.message = message;
}
/**
* The error message constructor.
*
* @param message The actual error text produced by the language processor
*/
public CompilerError( String message )
{
this.message = message;
}
/**
* The error message constructor.
*
* @param message The actual error text produced by the language processor
* @param error whether it was an error or informational
*/
public CompilerError( String message, boolean error )
{
this.message = message;
this.error = error;
}
/**
* Return the filename associated with this compiler error.
*
* @return The filename associated with this compiler error
*/
public String getFile()
{
return file;
}
/**
* Assert whether this is a severe error or a warning
*
* @return Whether the error is severe
*/
public boolean isError()
{
return error;
}
/**
* Return the starting line number of the program text originating this error
*
* @return The starting line number of the program text originating this error
*/
public int getStartLine()
{
return startline;
}
/**
* Return the starting column number of the program text originating this
* error
*
* @return The starting column number of the program text originating this
* error
*/
public int getStartColumn()
{
return startcolumn;
}
/**
* Return the ending line number of the program text originating this error
*
* @return The ending line number of the program text originating this error
*/
public int getEndLine()
{
return endline;
}
/**
* Return the ending column number of the program text originating this
* error
*
* @return The ending column number of the program text originating this
* error
*/
public int getEndColumn()
{
return endcolumn;
}
/**
* Return the message produced by the language processor
*
* @return The message produced by the language processor
*/
public String getMessage()
{
return message;
}
public String toString()
{
if ( file != null )
{
return file + ":" + "[" + startline + "," + startcolumn + "] " + message;
}
else
{
return message;
}
}
}

View File

@ -1,255 +0,0 @@
/**
*
* Copyright 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.
*/
package compile;
import util.IsolatedClassLoader;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.StringTokenizer;
public class JavacCompiler
extends AbstractCompiler
{
static final int OUTPUT_BUFFER_SIZE = 1024;
public JavacCompiler()
{
}
public List compile( CompilerConfiguration config )
throws Exception
{
File destinationDir = new File( config.getOutputLocation() );
if ( !destinationDir.exists() )
{
destinationDir.mkdirs();
}
String[] sources = getSourceFiles( config );
if ( sources.length == 0 )
{
return Collections.EMPTY_LIST;
}
System.out.println( "Compiling " + sources.length + " source file" + ( sources.length == 1 ? "" : "s" ) +
" to " + destinationDir.getAbsolutePath() );
Map compilerOptions = config.getCompilerOptions();
List args = new ArrayList( sources.length + 5 + compilerOptions.size() * 2 );
args.add( "-d" );
args.add( destinationDir.getAbsolutePath() );
if ( config.isNoWarn() )
{
args.add( "-nowarn" );
}
List classpathEntries = config.getClasspathEntries();
if ( classpathEntries != null && !classpathEntries.isEmpty() )
{
args.add( "-classpath" );
args.add( getPathString( classpathEntries ) );
}
if ( config.isDebug() )
{
args.add( "-g" );
}
List sourceLocations = config.getSourceLocations();
if ( sourceLocations != null && !sourceLocations.isEmpty() )
{
args.add( "-sourcepath" );
args.add( getPathString( sourceLocations ) );
}
// TODO: this could be much improved
if ( !compilerOptions.containsKey( "-target" ) )
{
if ( !compilerOptions.containsKey( "-source" ) )
{
// If omitted, later JDKs complain about a 1.1 target
args.add( "-source" );
args.add( "1.3" );
}
// Required, or it defaults to the target of your JDK (eg 1.5)
args.add( "-target" );
args.add( "1.1" );
}
Iterator it = compilerOptions.entrySet().iterator();
while ( it.hasNext() )
{
Map.Entry entry = (Map.Entry) it.next();
args.add( entry.getKey() );
if ( ( entry.getValue() != null ) )
{
args.add( entry.getValue() );
}
}
for ( int i = 0; i < sources.length; i++ )
{
args.add( sources[i] );
}
IsolatedClassLoader cl = new IsolatedClassLoader();
File toolsJar = new File( System.getProperty( "java.home" ), "../lib/tools.jar" );
if ( toolsJar.exists() )
{
cl.addURL( toolsJar.toURL() );
}
Class c = cl.loadClass( "com.sun.tools.javac.Main" );
ByteArrayOutputStream err = new ByteArrayOutputStream();
Method compile = c.getMethod( "compile", new Class[]{String[].class} );
Integer ok = (Integer) compile.invoke( null, new Object[]{args.toArray( new String[0] )} );
List messages = parseModernStream(
new BufferedReader( new InputStreamReader( new ByteArrayInputStream( err.toByteArray() ) ) ) );
if ( ok.intValue() != 0 && messages.isEmpty() )
{
// TODO: exception?
messages.add( new CompilerError(
"Failure executing javac, but could not parse the error:\n\n" + err.toString(), true ) );
}
return messages;
}
protected List parseModernStream( BufferedReader input )
throws IOException
{
List errors = new ArrayList();
String line;
StringBuffer buffer;
while ( true )
{
// cleanup the buffer
buffer = new StringBuffer(); // this is quicker than clearing it
// most errors terminate with the '^' char
do
{
if ( ( line = input.readLine() ) == null )
{
return errors;
}
// TODO: there should be a better way to parse these
if ( buffer.length() == 0 && line.startsWith( "error: " ) )
{
errors.add( new CompilerError( line, true ) );
}
else if ( buffer.length() == 0 && line.startsWith( "Note: " ) )
{
// skip this one - it is JDK 1.5 telling us that the interface is deprecated.
}
else
{
buffer.append( line );
buffer.append( '\n' );
}
}
while ( !line.endsWith( "^" ) );
// add the error bean
errors.add( parseModernError( buffer.toString() ) );
}
}
private CompilerError parseModernError( String error )
{
StringTokenizer tokens = new StringTokenizer( error, ":" );
try
{
String file = tokens.nextToken();
if ( file.length() == 1 )
{
file = new StringBuffer( file ).append( ":" ).append( tokens.nextToken() ).toString();
}
int line = Integer.parseInt( tokens.nextToken() );
String message = tokens.nextToken( "\n" ).substring( 1 );
String context = tokens.nextToken( "\n" );
String pointer = tokens.nextToken( "\n" );
int startcolumn = pointer.indexOf( "^" );
int endcolumn = context.indexOf( " ", startcolumn );
if ( endcolumn == -1 )
{
endcolumn = context.length();
}
return new CompilerError( file, true, line, startcolumn, line, endcolumn, message );
}
catch ( NoSuchElementException nse )
{
// TODO: exception?
return new CompilerError( "no more tokens - could not parse error message: " + error, true );
}
catch ( Exception nse )
{
// TODO: exception?
return new CompilerError( "could not parse error message: " + error, true );
}
}
public String toString()
{
return "Sun Javac Compiler";
}
}

View File

@ -1,328 +0,0 @@
package download;
import model.Dependency;
import model.Repository;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import util.FileUtils;
import util.StringUtils;
public class ArtifactDownloader
{
public static final String SNAPSHOT_SIGNATURE = "-SNAPSHOT";
private boolean useTimestamp = true;
private boolean ignoreErrors = false;
private String proxyHost;
private String proxyPort;
private String proxyUserName;
private String proxyPassword;
private Repository localRepository;
private static final String REPO_URL = "http://repo1.maven.org/maven2";
private Map downloadedArtifacts = new HashMap();
private List remoteRepositories;
public ArtifactDownloader( Repository localRepository )
throws Exception
{
if ( localRepository == null )
{
System.err.println( "local repository not specified" );
System.exit( 1 );
}
this.localRepository = localRepository;
}
public void setProxy( String host, String port, String userName, String password )
{
proxyHost = host;
proxyPort = port;
proxyUserName = userName;
proxyPassword = password;
System.out.println( "Using the following proxy : " + proxyHost + "/" + proxyPort );
}
public void downloadDependencies( Collection dependencies )
throws DownloadFailedException
{
for ( Iterator j = dependencies.iterator(); j.hasNext(); )
{
Dependency dep = (Dependency) j.next();
String dependencyConflictId = dep.getDependencyConflictId();
if ( !downloadedArtifacts.containsKey( dependencyConflictId ) )
{
File destinationFile = localRepository.getArtifactFile( dep );
// The directory structure for this project may
// not exists so create it if missing.
File directory = destinationFile.getParentFile();
if ( !directory.exists() )
{
directory.mkdirs();
}
boolean snapshot = isSnapshot( dep );
if ( "org.apache.maven".equals( dep.getGroupId() ) && snapshot )
{
//skip our own
continue;
}
if ( !getRemoteArtifact( dep, destinationFile ) )
{
throw new DownloadFailedException( "Failed to download " + dep );
}
downloadedArtifacts.put( dependencyConflictId, dep );
}
else
{
Dependency d = (Dependency) downloadedArtifacts.get( dependencyConflictId );
dep.setResolvedVersion( d.getResolvedVersion() );
}
}
}
private static boolean isSnapshot( Dependency dep )
{
return dep.getVersion().indexOf( SNAPSHOT_SIGNATURE ) >= 0;
}
private boolean getRemoteArtifact( Dependency dep, File destinationFile )
{
boolean fileFound = false;
for ( Iterator i = getRemoteRepositories().iterator(); i.hasNext(); )
{
Repository remoteRepo = (Repository) i.next();
boolean snapshot = isSnapshot( dep );
if ( snapshot && !remoteRepo.isSnapshots() )
{
continue;
}
if ( !snapshot && !remoteRepo.isReleases() )
{
continue;
}
// The username and password parameters are not being used here.
String url = remoteRepo.getBasedir() + "/" + remoteRepo.getArtifactPath( dep );
// Attempt to retrieve the artifact and set the checksum if retrieval
// of the checksum file was successful.
try
{
String version = dep.getVersion();
if ( snapshot )
{
String filename = "maven-metadata-" + remoteRepo.getId() + ".xml";
File localFile = localRepository.getMetadataFile( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), dep.getType(),
"maven-metadata-local.xml" );
File remoteFile = localRepository.getMetadataFile( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), dep.getType(), filename );
String metadataPath = remoteRepo.getMetadataPath( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), dep.getType(),
"maven-metadata.xml" );
String metaUrl = remoteRepo.getBasedir() + "/" + metadataPath;
log( "Downloading " + metaUrl );
try
{
HttpUtils.getFile( metaUrl, remoteFile, ignoreErrors, true, proxyHost, proxyPort, proxyUserName,
proxyPassword, false );
}
catch ( IOException e )
{
log( "WARNING: remote metadata version not found, using local: " + e.getMessage() );
remoteFile.delete();
}
File file = localFile;
if ( remoteFile.exists() )
{
if ( !localFile.exists() )
{
file = remoteFile;
}
else
{
RepositoryMetadata localMetadata = RepositoryMetadata.read( localFile );
RepositoryMetadata remoteMetadata = RepositoryMetadata.read( remoteFile );
if ( remoteMetadata.getLastUpdatedUtc() > localMetadata.getLastUpdatedUtc() )
{
file = remoteFile;
}
else
{
file = localFile;
}
}
}
if ( file.exists() )
{
log( "Using metadata: " + file );
RepositoryMetadata metadata = RepositoryMetadata.read( file );
if ( !file.equals( localFile ) )
{
version = metadata.constructVersion( version );
}
log( "Resolved version: " + version );
dep.setResolvedVersion( version );
if ( !version.endsWith( "SNAPSHOT" ) )
{
String ver = version.substring(
version.lastIndexOf( "-", version.lastIndexOf( "-" ) - 1 ) + 1 );
String extension = url.substring( url.length() - 4 );
url = getSnapshotMetadataFile( url, ver + extension );
}
else if ( destinationFile.exists() )
{
// It's already there
return true;
}
}
}
if ( !"pom".equals( dep.getType() ) )
{
String name = dep.getArtifactId() + "-" + dep.getResolvedVersion() + ".pom";
File file = localRepository.getMetadataFile( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), dep.getType(), name );
file.getParentFile().mkdirs();
if ( !file.exists() || version.indexOf( "SNAPSHOT" ) >= 0 )
{
String filename = dep.getArtifactId() + "-" + version + ".pom";
String metadataPath = remoteRepo.getMetadataPath( dep.getGroupId(), dep.getArtifactId(),
dep.getVersion(), dep.getType(), filename );
String metaUrl = remoteRepo.getBasedir() + "/" + metadataPath;
log( "Downloading " + metaUrl );
try
{
HttpUtils.getFile( metaUrl, file, ignoreErrors, false, proxyHost, proxyPort, proxyUserName,
proxyPassword, false );
}
catch ( IOException e )
{
log( "Couldn't find POM - ignoring: " + e.getMessage() );
}
}
}
destinationFile = localRepository.getArtifactFile( dep );
if ( !destinationFile.exists() )
{
log( "Downloading " + url );
HttpUtils.getFile( url, destinationFile, ignoreErrors, useTimestamp, proxyHost, proxyPort,
proxyUserName, proxyPassword, true );
if ( dep.getVersion().indexOf( "SNAPSHOT" ) >= 0 )
{
String name = StringUtils.replace( destinationFile.getName(), version, dep.getVersion() );
FileUtils.copyFile( destinationFile, new File( destinationFile.getParentFile(), name ) );
}
}
// Artifact was found, continue checking additional remote repos (if any)
// in case there is a newer version (i.e. snapshots) in another repo
fileFound = true;
}
catch ( FileNotFoundException e )
{
log( "Artifact not found at [" + url + "]" );
// Ignore
}
catch ( Exception e )
{
// If there are additional remote repos, then ignore exception
// as artifact may be found in another remote repo. If there
// are no more remote repos to check and the artifact wasn't found in
// a previous remote repo, then artifactFound is false indicating
// that the artifact could not be found in any of the remote repos
//
// arguably, we need to give the user better control (another command-
// line switch perhaps) of what to do in this case? Maven already has
// a command-line switch to work in offline mode, but what about when
// one of two or more remote repos is unavailable? There may be multiple
// remote repos for redundancy, in which case you probably want the build
// to continue. There may however be multiple remote repos because some
// artifacts are on one, and some are on another. In this case, you may
// want the build to break.
//
// print a warning, in any case, so user catches on to mistyped
// hostnames, or other snafus
log( "Error retrieving artifact from [" + url + "]: " + e );
}
}
return fileFound;
}
private static String getSnapshotMetadataFile( String filename, String s )
{
int index = filename.lastIndexOf( "SNAPSHOT" );
return filename.substring( 0, index ) + s;
}
private void log( String message )
{
System.out.println( message );
}
public Repository getLocalRepository()
{
return localRepository;
}
public List getRemoteRepositories()
{
if ( remoteRepositories == null )
{
remoteRepositories = new ArrayList();
}
if ( remoteRepositories.isEmpty() )
{
// TODO: use super POM?
remoteRepositories.add( new Repository( "central", REPO_URL, Repository.LAYOUT_DEFAULT, false, true ) );
// TODO: use maven root POM?
remoteRepositories.add( new Repository( "snapshots", "http://snapshots.maven.codehaus.org/maven2/",
Repository.LAYOUT_DEFAULT, true, false ) );
}
return remoteRepositories;
}
public void setRemoteRepositories( List remoteRepositories )
{
this.remoteRepositories = remoteRepositories;
}
}

View File

@ -1,388 +0,0 @@
package download;
/*
* ====================================================================
* Copyright 2001-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.io.ByteArrayOutputStream;
// import org.apache.commons.logging.Log;
// import org.apache.commons.logging.LogFactory;
/**
* Encode/Decode Base-64.
*
* @author John Casey
*/
public final class Base64
{
// private static final Log LOG = LogFactory.getLog( Base64.class );
private static final String CRLF = System.getProperty( "line.separator" );
private static final int LINE_END = 64;
public static String encode( byte[] data )
{
return Base64.encode( data, true );
}
public static String encode( byte[] data, boolean useLineDelimiter )
{
if ( data == null )
{
return null;
}
else if ( data.length == 0 )
{
return "";
}
int padding = 3 - ( data.length % 3 );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "padding = " + padding + "characters." );
// }
StringBuffer buffer = new StringBuffer();
for ( int i = 0; i < data.length; i += 3 )
{
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "iteration base offset = " + i );
// }
int neutral = ( data[i] < 0 ? data[i] + 256 : data[i] );
int block = ( neutral & 0xff );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "after first byte, block = " + Integer.toBinaryString( block ) );
// }
boolean inLastSegment = false;
block <<= 8;
if ( i + 1 < data.length )
{
neutral = ( data[i + 1] < 0 ? data[i + 1] + 256 : data[i + 1] );
block |= ( neutral & 0xff );
}
else
{
inLastSegment = true;
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "after second byte, block = " + Integer.toBinaryString( block ) + "; inLastSegment = "
// + inLastSegment );
// }
block <<= 8;
if ( i + 2 < data.length )
{
neutral = ( data[i + 2] < 0 ? data[i + 2] + 256 : data[i + 2] );
block |= ( neutral & 0xff );
}
else
{
inLastSegment = true;
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "after third byte, block = " + Integer.toBinaryString( block ) + "; inLastSegment = "
// + inLastSegment );
// }
char[] encoded = new char[4];
int encIdx = 0;
encoded[0] = toBase64Char( ( block >>> 18 ) & 0x3f );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "first character = " + encoded[0] );
// }
encoded[1] = toBase64Char( ( block >>> 12 ) & 0x3f );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "second character = " + encoded[1] );
// }
if ( inLastSegment && padding > 1 )
{
encoded[2] = '=';
}
else
{
encoded[2] = toBase64Char( ( block >>> 6 ) & 0x3f );
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "third character = " + encoded[2] );
// }
if ( inLastSegment && padding > 0 )
{
encoded[3] = '=';
}
else
{
encoded[3] = toBase64Char( block & 0x3f );
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "fourth character = " + encoded[3] );
// }
buffer.append( encoded );
}
if ( useLineDelimiter )
{
return canonicalize( buffer.toString() );
}
else
{
return buffer.toString();
}
}
public static byte[] decode( String src )
{
return Base64.decode( src, true );
}
public static byte[] decode( String src, boolean useLineDelimiter )
{
if ( src == null )
{
return null;
}
else if ( src.length() < 1 )
{
return new byte[0];
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "pre-canonicalization = \n" + src );
// }
String data = src;
if ( useLineDelimiter )
{
data = deCanonicalize( src );
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "post-canonicalization = \n" + data );
// }
ByteArrayOutputStream baos = new ByteArrayOutputStream();
char[] input = data.toCharArray();
int index = 0;
for ( int i = 0; i < input.length; i += 4 )
{
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "iteration base offset = " + i );
// }
int block = ( toBase64Int( input[i] ) & 0x3f );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "block after first char [" + input[i] + "] = " + Integer.toBinaryString( block ) );
// }
block <<= 6;
block |= ( toBase64Int( input[i + 1] ) & 0x3f );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "block after second char [" + input[i + 1] + "] = " + Integer.toBinaryString( block ) );
// }
boolean inPadding = false;
boolean twoCharPadding = false;
block <<= 6;
if ( input[i + 2] != '=' )
{
block |= ( toBase64Int( input[i + 2] ) & 0x3f );
}
else
{
twoCharPadding = true;
inPadding = true;
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "block after third char [" + input[i + 2] + "] = " + Integer.toBinaryString( block ) );
// }
block <<= 6;
if ( input[i + 3] != '=' )
{
block |= ( toBase64Int( input[i + 3] ) & 0x3f );
}
else
{
inPadding = true;
}
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "block after fourth char [" + input[i + 3] + "] = " + Integer.toBinaryString( block ) );
// }
baos.write( ( block >>> 16 ) & 0xff );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( ( block >>> 16 ) & 0xff ) );
// }
if ( !inPadding || !twoCharPadding )
{
baos.write( ( block >>> 8 ) & 0xff );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( ( block >>> 8 ) & 0xff ) );
// }
}
if ( !inPadding )
{
baos.write( block & 0xff );
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "byte[" + ( index++ ) + "] = " + ( block & 0xff ) );
// }
}
}
byte[] result = baos.toByteArray();
// if ( LOG.isDebugEnabled() )
// {
// LOG.debug( "byte array is " + result.length + " bytes long." );
// }
return result;
}
private static char toBase64Char( int input )
{
if ( input > -1 && input < 26 )
{
return (char) ( 'A' + input );
}
else if ( input > 25 && input < 52 )
{
return (char) ( 'a' + input - 26 );
}
else if ( input > 51 && input < 62 )
{
return (char) ( '0' + input - 52 );
}
else if ( input == 62 )
{
return '+';
}
else if ( input == 63 )
{
return '/';
}
else
{
return '?';
}
}
private static int toBase64Int( char input )
{
if ( input >= 'A' && input <= 'Z' )
{
return input - 'A';
}
else if ( input >= 'a' && input <= 'z' )
{
return input + 26 - 'a';
}
else if ( input >= '0' && input <= '9' )
{
return input + 52 - '0';
}
else if ( input == '+' )
{
return 62;
}
else if ( input == '/' )
{
return 63;
}
else
{
return 0;
}
}
private static String deCanonicalize( String data )
{
if ( data == null )
{
return null;
}
StringBuffer buffer = new StringBuffer( data.length() );
for ( int i = 0; i < data.length(); i++ )
{
char c = data.charAt( i );
if ( c != '\r' && c != '\n' )
{
buffer.append( c );
}
}
return buffer.toString();
}
private static String canonicalize( String data )
{
StringBuffer buffer = new StringBuffer( (int) ( data.length() * 1.1 ) );
int col = 0;
for ( int i = 0; i < data.length(); i++ )
{
if ( col == LINE_END )
{
buffer.append( CRLF );
col = 0;
}
buffer.append( data.charAt( i ) );
col++;
}
buffer.append( CRLF );
return buffer.toString();
}
}

View File

@ -1,31 +0,0 @@
package download;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Failed download.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class DownloadFailedException extends Exception
{
public DownloadFailedException( String message )
{
super( message );
}
}

View File

@ -1,360 +0,0 @@
package download;
/* ====================================================================
* Copyright 2001-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.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.net.URLConnection;
/**
* Http utils for retrieving files.
*
* @author costin@dnt.ro
* @author gg@grtmail.com (Added Java 1.1 style HTTP basic auth)
* @author <a href="mailto:jason@zenplex.com">Jason van Zyl</a>
*/
public class HttpUtils
{
/**
* Use a proxy to bypass the firewall with or without authentication
*
* @param proxyHost Proxy Host (if proxy is required), or null
* @param proxyPort Proxy Port (if proxy is required), or null
* @param proxyUserName Proxy Username (if authentification is required),
* or null
* @param proxyPassword Proxy Password (if authentification is required),
* or null
* @throws SecurityException if an operation is not authorized by the
* SecurityManager
*/
public static void useProxyUser( final String proxyHost, final String proxyPort, final String proxyUserName,
final String proxyPassword )
{
if ( proxyHost != null && proxyPort != null )
{
System.getProperties().put( "proxySet", "true" );
System.getProperties().put( "proxyHost", proxyHost );
System.getProperties().put( "proxyPort", proxyPort );
if ( proxyUserName != null )
{
Authenticator.setDefault( new Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication( proxyUserName, proxyPassword == null ? new char[0]
: proxyPassword.toCharArray() );
}
} );
}
}
}
/**
* Retrieve a remote file. Throws an Exception on errors unless the
* ifnoreErrors flag is set to True
*
* @param url the of the file to retrieve
* @param destinationFile where to store it
* @param ignoreErrors whether to ignore errors during I/O or throw an
* exception when they happen
* @param useTimestamp whether to check the modified timestamp on the
* <code>destinationFile</code> against the remote <code>source</code>
* @param proxyHost Proxy Host (if proxy is required), or null
* @param proxyPort Proxy Port (if proxy is required), or null
* @param proxyUserName Proxy Username (if authentification is required),
* or null.
* @param proxyPassword Proxy Password (if authentification is required),
* or null.
* @param useChecksum Flag to indicate the use of the checksum for the retrieved
* artifact if it is available.
* @throws IOException If an I/O exception occurs.
*/
public static void getFile( String url, File destinationFile, boolean ignoreErrors, boolean useTimestamp,
String proxyHost, String proxyPort, String proxyUserName, String proxyPassword,
boolean useChecksum )
throws IOException
{
// Get the requested file.
getFile( url, destinationFile, ignoreErrors, useTimestamp, proxyHost, proxyPort, proxyUserName, proxyPassword );
// Get the checksum if requested.
if ( useChecksum )
{
File checksumFile = new File( destinationFile + ".md5" );
try
{
getFile( url + ".md5", checksumFile, ignoreErrors, useTimestamp, proxyHost, proxyPort, proxyUserName,
proxyPassword );
}
catch ( Exception e )
{
// do nothing we will check later in the process
// for the checksums.
}
}
}
/**
* Retrieve a remote file. Throws an Exception on errors unless the
* ifnoreErrors flag is set to True
*
* @param url the of the file to retrieve
* @param destinationFile where to store it
* @param ignoreErrors whether to ignore errors during I/O or throw an
* exception when they happen
* @param useTimestamp whether to check the modified timestamp on the
* <code>destinationFile</code> against the remote <code>source</code>
* @param proxyHost Proxy Host (if proxy is required), or null
* @param proxyPort Proxy Port (if proxy is required), or null
* @param proxyUserName Proxy Username (if authentification is required),
* or null
* @param proxyPassword Proxy Password (if authentification is required),
* or null
* @throws IOException If an I/O exception occurs.
*/
public static void getFile( String url, File destinationFile, boolean ignoreErrors, boolean useTimestamp,
String proxyHost, String proxyPort, String proxyUserName, String proxyPassword )
throws IOException
{
//set the timestamp to the file date.
long timestamp = -1;
if ( useTimestamp && destinationFile.exists() )
{
timestamp = destinationFile.lastModified();
}
try
{
getFile( url, destinationFile, timestamp, proxyHost, proxyPort, proxyUserName, proxyPassword );
}
catch ( IOException ex )
{
if ( !ignoreErrors )
{
throw ex;
}
}
}
/**
* Retrieve a remote file.
*
* @param url the URL of the file to retrieve
* @param destinationFile where to store it
* @param timestamp if provided, the remote URL is only retrieved if it was
* modified more recently than timestamp. Otherwise, negative value indicates that
* the remote URL should be retrieved unconditionally.
* @param proxyHost Proxy Host (if proxy is required), or null
* @param proxyPort Proxy Port (if proxy is required), or null
* @param proxyUserName Proxy Username (if authentification is required),
* or null
* @param proxyPassword Proxy Password (if authentification is required),
* or null
* @throws IOException If an I/O exception occurs.
*/
public static void getFile( String url, File destinationFile, long timestamp, String proxyHost, String proxyPort,
String proxyUserName, String proxyPassword )
throws IOException
{
String[] s = parseUrl( url );
String username = s[0];
String password = s[1];
String parsedUrl = s[2];
URL source = new URL( parsedUrl );
//set proxy connection
useProxyUser( proxyHost, proxyPort, proxyUserName, proxyPassword );
//set up the URL connection
URLConnection connection = source.openConnection();
//modify the headers
if ( timestamp >= 0 )
{
connection.setIfModifiedSince( timestamp );
}
// prepare Java 1.1 style credentials
if ( username != null || password != null )
{
String up = username + ":" + password;
String encoding = Base64.encode( up.getBytes(), false );
connection.setRequestProperty( "Authorization", "Basic " + encoding );
}
connection.setRequestProperty( "Pragma", "no-cache" );
//connect to the remote site (may take some time)
connection.connect();
//next test for a 304 result (HTTP only)
if ( connection instanceof HttpURLConnection )
{
HttpURLConnection httpConnection = (HttpURLConnection) connection;
// although HTTPUrlConnection javadocs says FileNotFoundException should be
// thrown on a 404 error, that certainly does not appear to be the case, so
// test for 404 ourselves, and throw FileNotFoundException as needed
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND )
{
throw new FileNotFoundException( url.toString() + " (HTTP Error: " + httpConnection.getResponseCode() +
" " + httpConnection.getResponseMessage() + ")" );
}
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED )
{
return;
}
// test for 401 result (HTTP only)
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED )
{
throw new IOException( "Not authorized." );
}
// test for 407 result (HTTP only)
if ( httpConnection.getResponseCode() == HttpURLConnection.HTTP_PROXY_AUTH )
{
throw new IOException( "Not authorized by proxy." );
}
}
// REVISIT: at this point even non HTTP connections may support the
// if-modified-since behaviour - we just check the date of the
// content and skip the write if it is not newer.
// Some protocols (FTP) dont include dates, of course.
InputStream is = null;
IOException isException = null;
for ( int i = 0; i < 3; i++ )
{
try
{
is = connection.getInputStream();
break;
}
catch ( IOException ex )
{
isException = ex;
}
}
if ( is == null )
{
throw isException;
}
if ( connection.getLastModified() <= timestamp && connection.getLastModified() != 0 )
{
return;
}
FileOutputStream fos = new FileOutputStream( destinationFile );
byte[] buffer = new byte[100 * 1024];
int length;
while ( ( length = is.read( buffer ) ) >= 0 )
{
fos.write( buffer, 0, length );
System.out.print( "." );
}
System.out.println();
fos.close();
is.close();
// if (and only if) the use file time option is set, then the
// saved file now has its timestamp set to that of the downloaded
// file
if ( timestamp >= 0 )
{
long remoteTimestamp = connection.getLastModified();
if ( remoteTimestamp != 0 )
{
touchFile( destinationFile, remoteTimestamp );
}
}
}
/**
* Parse an url which might contain a username and password. If the
* given url doesn't contain a username and password then return the
* origin url unchanged.
*
* @param url The url to parse.
* @return The username, password and url.
* @throws RuntimeException if the url is (very) invalid
*/
static String[] parseUrl( String url )
{
String[] parsedUrl = new String[3];
parsedUrl[0] = null;
parsedUrl[1] = null;
parsedUrl[2] = url;
// We want to be able to deal with Basic Auth where the username
// and password are part of the URL. An example of the URL string
// we would like to be able to parse is like the following:
//
// http://username:password@repository.mycompany.com
int i = url.indexOf( "@" );
if ( i > 0 )
{
String protocol = url.substring( 0, url.indexOf( "://" ) ) + "://";
String s = url.substring( protocol.length(), i );
int j = s.indexOf( ":" );
parsedUrl[0] = s.substring( 0, j );
parsedUrl[1] = s.substring( j + 1 );
parsedUrl[2] = protocol + url.substring( i + 1 );
}
return parsedUrl;
}
/**
* set the timestamp of a named file to a specified time.
*
* @param file the file to touch
* @param timemillis in milliseconds since the start of the era
* @return true if it succeeded. False means that this is a java1.1 system
* and that file times can not be set
* @throws RuntimeException Thrown in unrecoverable error. Likely this
* comes from file access failures.
*/
private static boolean touchFile( File file, long timemillis )
{
long modifiedTime;
if ( timemillis < 0 )
{
modifiedTime = System.currentTimeMillis();
}
else
{
modifiedTime = timemillis;
}
file.setLastModified( modifiedTime );
return true;
}
}

View File

@ -1,395 +0,0 @@
package download;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import util.AbstractReader;
import util.StringUtils;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.TimeZone;
/**
* I/O for repository metadata.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class RepositoryMetadata
{
private String snapshotTimestamp;
private int snapshotBuildNumber;
private String releaseVersion;
private String groupId;
private String artifactId;
private String version;
private List versions = new ArrayList();
private String latestVersion;
private boolean localCopy;
private String lastUpdated;
public String getSnapshotTimestamp()
{
return snapshotTimestamp;
}
public void setSnapshotTimestamp( String snapshotTimestamp )
{
this.snapshotTimestamp = snapshotTimestamp;
}
public int getSnapshotBuildNumber()
{
return snapshotBuildNumber;
}
public void setSnapshotBuildNumber( int snapshotBuildNumber )
{
this.snapshotBuildNumber = snapshotBuildNumber;
}
public String getGroupId()
{
return groupId;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public String getArtifactId()
{
return artifactId;
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public String getVersion()
{
return version;
}
public void setVersion( String version )
{
this.version = version;
}
public List getVersions()
{
return versions;
}
public void setVersions( List versions )
{
this.versions = versions;
}
public String getReleaseVersion()
{
return releaseVersion;
}
public void setReleaseVersion( String releaseVersion )
{
this.releaseVersion = releaseVersion;
}
public String getLatestVersion()
{
return latestVersion;
}
public void setLatestVersion( String latestVersion )
{
this.latestVersion = latestVersion;
}
public void addVersion( String version )
{
versions.add( version );
}
public boolean isLocalCopy()
{
return localCopy;
}
public void setLocalCopy( boolean localCopy )
{
this.localCopy = localCopy;
}
public static RepositoryMetadata read( File file )
throws IOException, ParserConfigurationException, SAXException
{
RepositoryMetadata metadata = new RepositoryMetadata();
new Reader( metadata ).parse( file );
return metadata;
}
public void write( File file )
throws IOException
{
new Writer( this ).write( file );
}
public String constructVersion( String baseVersion )
{
if ( snapshotTimestamp != null )
{
baseVersion = StringUtils.replace( baseVersion, "SNAPSHOT", snapshotTimestamp + "-" + snapshotBuildNumber );
}
return baseVersion;
}
public long getLastUpdatedUtc()
{
TimeZone timezone = TimeZone.getTimeZone( "UTC" );
DateFormat fmt = new SimpleDateFormat( "yyyyMMddHHmmss" );
try
{
return fmt.parse( lastUpdated ).getTime();
}
catch ( ParseException e )
{
return -1;
}
}
public void setLastUpdated( String lastUpdated )
{
this.lastUpdated = lastUpdated;
}
public String getLastUpdated()
{
return lastUpdated;
}
static class Reader
extends AbstractReader
{
private boolean insideVersioning;
private StringBuffer bodyText = new StringBuffer();
private boolean insideSnapshot;
private final RepositoryMetadata metadata;
private boolean insideVersions;
public Reader( RepositoryMetadata metadata )
{
this.metadata = metadata;
}
public void startElement( String uri, String localName, String rawName, Attributes attributes )
{
if ( insideVersioning )
{
if ( "snapshot".equals( rawName ) )
{
insideSnapshot = true;
}
else if ( "versions".equals( rawName ) )
{
insideVersions = true;
}
}
else
{
// root element
if ( "versioning".equals( rawName ) )
{
insideVersioning = true;
}
}
}
public void characters( char buffer[], int start, int length )
{
bodyText.append( buffer, start, length );
}
private String getBodyText()
{
return bodyText.toString().trim();
}
public void endElement( String uri, String localName, String rawName )
throws SAXException
{
if ( insideVersioning )
{
if ( "versioning".equals( rawName ) )
{
insideVersioning = false;
}
else if ( insideSnapshot )
{
if ( "snapshot".equals( rawName ) )
{
insideSnapshot = false;
}
else if ( "buildNumber".equals( rawName ) )
{
try
{
metadata.setSnapshotBuildNumber( Integer.valueOf( getBodyText() ).intValue() );
}
catch ( NumberFormatException e )
{
// Ignore
}
}
else if ( "timestamp".equals( rawName ) )
{
metadata.setSnapshotTimestamp( getBodyText() );
}
else if ( "localCopy".equals( rawName ) )
{
metadata.setLocalCopy( Boolean.valueOf( getBodyText() ).booleanValue() );
}
}
else if ( insideVersions )
{
if ( "versions".equals( rawName ) )
{
insideVersions = false;
}
else if ( "version".equals( rawName ) )
{
metadata.addVersion( getBodyText() );
}
}
else if ( "latest".equals( rawName ) )
{
metadata.setLatestVersion( getBodyText() );
}
else if ( "release".equals( rawName ) )
{
metadata.setReleaseVersion( getBodyText() );
}
else if ( "lastUpdated".equals( rawName ) )
{
metadata.setLastUpdated( getBodyText() );
}
}
else if ( "groupId".equals( rawName ) )
{
metadata.setGroupId( getBodyText() );
}
else if ( "artifactId".equals( rawName ) )
{
metadata.setArtifactId( getBodyText() );
}
else if ( "version".equals( rawName ) )
{
metadata.setVersion( getBodyText() );
}
bodyText = new StringBuffer();
}
}
static class Writer
{
private final RepositoryMetadata metadata;
public Writer( RepositoryMetadata metadata )
{
this.metadata = metadata;
}
public void write( File file )
throws IOException
{
PrintWriter w = new PrintWriter( new FileWriter( file ) );
try
{
w.println( "<metadata>" );
writeLine( w, " ", "groupId", metadata.getGroupId() );
writeLine( w, " ", "artifactId", metadata.getArtifactId() );
writeLine( w, " ", "version", metadata.getVersion() );
w.println( " <versioning>" );
writeLine( w, " ", "latest", metadata.getLatestVersion() );
writeLine( w, " ", "release", metadata.getReleaseVersion() );
writeLine( w, " ", "lastUpdated", metadata.getLastUpdated() );
w.println( " <snapshot>" );
if ( metadata.isLocalCopy() )
{
writeLine( w, " ", "localCopy", "true" );
}
if ( metadata.getSnapshotBuildNumber() > 0 )
{
writeLine( w, " ", "buildNumber", String.valueOf( metadata.getSnapshotBuildNumber() ) );
}
writeLine( w, " ", "timestamp", metadata.getSnapshotTimestamp() );
w.println( " </snapshot>" );
w.println( " <versions>" );
for ( Iterator i = metadata.getVersions().iterator(); i.hasNext(); )
{
writeLine( w, " ", "version", (String) i.next() );
}
w.println( " </versions>" );
w.println( " </versioning>" );
w.println( "</metadata>" );
}
finally
{
w.close();
}
}
private void writeLine( PrintWriter w, String indent, String tag, String content )
{
if ( content != null )
{
w.println( indent + ( "<" + tag + ">" + content + "</" + tag + ">" ) );
}
}
}
}

View File

@ -1,210 +0,0 @@
package jar;
import util.DirectoryScanner;
import util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
import java.util.jar.Manifest;
public class JarMojo
{
private byte[] buffer = new byte[4096];
public void execute( File basedir, String outputDirectory, String jarName )
throws Exception
{
File jarFile = new File( new File( outputDirectory ), jarName + ".jar" );
Map includes = new LinkedHashMap();
addDirectory( includes, "**/**", "**/package.html,**/.svn/**", "", basedir );
createJar( jarFile, includes );
}
/**
* Add all files in the specified directory to the archive.
*
* @param includes a map <String, File> of items to be include in the outpur
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, File baseDir ) throws IOException
{
addDirectory( includes, "", baseDir );
}
/**
* Add all files in the specified directory to the archive.
*
* @param includes a map <String, File> of items to be include in the outpur
* @param prefix value to be added to the front of jar entry names
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, String prefix, File baseDir ) throws IOException
{
addDirectory( includes, null, null, prefix, baseDir );
}
/**
* Add all files in the specified directory to the archive.
*
* @param includes a map <String, File> of items to be include in the outpur
* @param includesPattern Sets the list of include patterns to use
* @param excludesPattern Sets the list of exclude patterns to use
* @param prefix value to be added to the front of jar entry names
* @param baseDir the directory to add
*/
protected void addDirectory( Map includes, String includesPattern, String excludesPattern, String prefix, File baseDir )
throws IOException
{
if ( !baseDir.exists() )
{
return;
}
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( baseDir );
if ( includesPattern != null )
{
scanner.setIncludes( StringUtils.split( includesPattern, "," ) );
}
if ( excludesPattern != null )
{
scanner.setExcludes( StringUtils.split( excludesPattern, "," ) );
}
scanner.scan();
String[] files = scanner.getIncludedFiles();
for ( int i = 0; i < files.length; i++ )
{
String file = files[i];
file = file.replace( '\\', '/' ); // todo shouldn't the scanner return platform independent names?
includes.put( prefix + file, new File( baseDir, file ) );
}
}
/**
* Create the jar file specified and include the listed files.
*
* @param jarFile the jar file to create
* @param includes a Map<String, File>of items to include; the key is the jar entry name
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void createJar( File jarFile, Map includes ) throws IOException
{
File parentJarFile = jarFile.getParentFile();
if ( !parentJarFile.exists() )
{
parentJarFile.mkdirs();
}
JarOutputStream jos = createJar( jarFile, createManifest() );
try
{
addEntries( jos, includes );
}
finally
{
jos.close();
}
}
/**
* Create a manifest for the jar file
*
* @return a default manifest; the Manifest-Version and Created-By attributes are initialized
*/
protected Manifest createManifest()
{
Manifest mf = new Manifest();
Attributes attrs = mf.getMainAttributes();
attrs.putValue( Attributes.Name.MANIFEST_VERSION.toString(), "1.0" );
attrs.putValue( "Created-By", "2.0 (Apache Maven)" );
return mf;
}
/**
* Create the specified jar file and return a JarOutputStream to it
*
* @param jarFile the jar file to create
* @param mf the manifest to use
* @return a JarOutputStream that can be used to write to that file
* @throws IOException if there was a problem opening the file
*/
protected JarOutputStream createJar( File jarFile, Manifest mf ) throws IOException
{
jarFile.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream( jarFile );
try
{
return new JarOutputStream( fos, mf );
}
catch ( IOException e )
{
try
{
fos.close();
jarFile.delete();
}
catch ( IOException e1 )
{
// ignore
}
throw e;
}
}
/**
* Add all entries in the supplied Map to the jar
*
* @param jos a JarOutputStream that can be used to write to the jar
* @param includes a Map<String, File> of entries to add
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void addEntries( JarOutputStream jos, Map includes ) throws IOException
{
for ( Iterator i = includes.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry) i.next();
String name = (String) entry.getKey();
File file = (File) entry.getValue();
addEntry( jos, name, file );
}
}
/**
* Add a single entry to the jar
*
* @param jos a JarOutputStream that can be used to write to the jar
* @param name the entry name to use; must be '/' delimited
* @param source the file to add
* @throws IOException if there is a problem writing the archive or reading the sources
*/
protected void addEntry( JarOutputStream jos, String name, File source ) throws IOException
{
FileInputStream fis = new FileInputStream( source );
try
{
jos.putNextEntry( new JarEntry( name ) );
int count;
while ( ( count = fis.read( buffer ) ) > 0 )
{
jos.write( buffer, 0, count );
}
jos.closeEntry();
}
finally
{
fis.close();
}
}
}

View File

@ -1,304 +0,0 @@
package model;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Describes a dependency.
*
* @version $Id$
*/
public class Dependency
{
private String id;
private String version;
private String url;
private String jar;
private String artifactId;
private String groupId;
private String type = "jar";
private String scope = SCOPE_COMPILE;
private String resolvedVersion;
public static final String SCOPE_TEST = "test";
public static final String SCOPE_COMPILE = "compile";
public static final String SCOPE_RUNTIME = "runtime";
private Set exclusions = new HashSet();
private List chain;
public Dependency( List chain )
{
this.chain = new ArrayList( chain );
this.chain.add( this );
}
public Dependency( String groupId, String artifactId, String version, String type, List chain )
{
this( chain );
this.version = version;
this.artifactId = artifactId;
this.groupId = groupId;
this.type = type;
}
public void setId( String id )
{
this.id = id;
}
public String getId()
{
if ( isValid( getGroupId() ) && isValid( getArtifactId() ) )
{
return getGroupId() + ":" + getArtifactId();
}
return id;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public String getGroupId()
{
return groupId;
}
public String getArtifactDirectory()
{
if ( isValid( getGroupId() ) )
{
return getGroupId();
}
return getId();
}
public String getArtifactId()
{
return artifactId;
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public String getArtifact()
{
// If the jar name has been explicty set then use that. This
// is when the <jar/> element is explicity used in the POM.
if ( jar != null )
{
return jar;
}
String artifact;
if ( isValid( getArtifactId() ) )
{
artifact = getArtifactId() + "-" + getResolvedVersion() + ".";
}
else
{
artifact = getId() + "-" + getResolvedVersion() + ".";
}
if ( "jar".equals( getType() ) || "maven-plugin".equals( getType() ) )
{
artifact += "jar";
}
else
{
artifact += getType();
}
return artifact;
}
public void setVersion( String version )
{
this.version = version;
}
public String getVersion()
{
return version;
}
public void setJar( String jar )
{
// This is a check we need because of the jelly interpolation
// process. If we don't check an empty string will be set and
// screw up getArtifact() above.
if ( jar.trim().length() == 0 )
{
return;
}
this.jar = jar;
}
public String getJar()
{
return jar;
}
public String getScope()
{
return scope;
}
public void setScope( String scope )
{
this.scope = scope;
}
public void setUrl( String url )
{
this.url = url;
}
public String getUrl()
{
return url;
}
public String getType()
{
return type;
}
public void setType( String type )
{
this.type = type;
}
private boolean isValid( String value )
{
if ( value != null && value.trim().equals( "" ) == false )
{
return true;
}
return false;
}
public String toString()
{
return getId() + ":" + getVersion() + ":" + getType();
}
public int hashCode()
{
int result = 17;
result = 37 * result + groupId.hashCode();
result = 37 * result + artifactId.hashCode();
result = 37 * result + type.hashCode();
result = 37 * result + version.hashCode();
return result;
}
public boolean equals( Object o )
{
if ( o == this )
{
return true;
}
if ( !( o instanceof Dependency ) )
{
return false;
}
Dependency d = (Dependency) o;
if ( !d.getGroupId().equals( groupId ) )
{
return false;
}
else if ( !d.getArtifactId().equals( artifactId ) )
{
return false;
}
else if ( !d.getVersion().equals( version ) )
{
return false;
}
else if ( !d.getType().equals( type ) )
{
return false;
}
return true;
}
public String getConflictId()
{
return getGroupId() + ":" + getArtifactId() + ":" + getType();
}
public String getDependencyConflictId()
{
return getGroupId() + ":" + getArtifactId() + ":" + getType() + ":" + getVersion();
}
public void setResolvedVersion( String resolvedVersion )
{
this.resolvedVersion = resolvedVersion;
}
public String getResolvedVersion()
{
if ( resolvedVersion == null )
{
resolvedVersion = getVersion();
}
return resolvedVersion;
}
public void addExclusion( Exclusion currentExclusion )
{
exclusions.add( currentExclusion.getConflictId() );
}
public Set getExclusions()
{
return exclusions;
}
public List getChain()
{
return chain;
}
}

View File

@ -1,55 +0,0 @@
package model;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Excluded dependency.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class Exclusion
{
private String groupId;
private String artifactId;
public String getGroupId()
{
return groupId;
}
public void setGroupId( String groupId )
{
this.groupId = groupId;
}
public String getArtifactId()
{
return artifactId;
}
public void setArtifactId( String artifactId )
{
this.artifactId = artifactId;
}
public String getConflictId()
{
return groupId + ":" + artifactId + ":jar";
}
}

View File

@ -1,589 +0,0 @@
package model;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import download.ArtifactDownloader;
import download.DownloadFailedException;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import util.AbstractReader;
import javax.xml.parsers.ParserConfigurationException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.io.IOException;
/**
* Parse a POM.
*
* @version $Id$
*/
public class ModelReader
extends AbstractReader
{
private int depth = 0;
private String artifactId;
private String version;
private String groupId;
private String packaging = "jar";
private String parentGroupId;
private String parentArtifactId;
private String parentVersion;
private Map dependencies = new HashMap();
private List repositories = new ArrayList();
private List resources = new ArrayList();
private List testResources = new ArrayList();
private Map managedDependencies = new HashMap();
private Dependency currentDependency;
private Resource currentResource;
private boolean insideParent = false;
private boolean insideDependency = false;
private boolean insideResource = false;
private boolean insideRepository = false;
private StringBuffer bodyText = new StringBuffer();
private final boolean resolveTransitiveDependencies;
private Repository currentRepository;
private final ArtifactDownloader downloader;
private static Set inProgress = new HashSet();
private Map parentDependencies = new HashMap();
private Map transitiveDependencies = new HashMap();
private boolean insideDependencyManagement = false;
private boolean insideReleases;
private boolean insideSnapshots;
private boolean insideExclusion;
private Exclusion currentExclusion;
private final Set excluded;
private final List chain;
private final String inheritedScope;
public ModelReader( ArtifactDownloader downloader, boolean resolveTransitiveDependencies )
{
this( downloader, null, resolveTransitiveDependencies, Collections.EMPTY_SET, Collections.EMPTY_LIST );
}
public ModelReader( ArtifactDownloader downloader, String inheritedScope, boolean resolveTransitiveDependencies,
Set excluded, List chain )
{
this.downloader = downloader;
this.resolveTransitiveDependencies = resolveTransitiveDependencies;
this.excluded = excluded;
this.inheritedScope = inheritedScope;
this.chain = chain;
}
public List getRemoteRepositories()
{
return repositories;
}
public Collection getDependencies()
{
Map m = new HashMap();
m.putAll( transitiveDependencies );
m.putAll( parentDependencies );
m.putAll( dependencies );
return m.values();
}
public Collection getManagedDependencies()
{
Map m = new HashMap();
m.putAll( managedDependencies );
return m.values();
}
public List getResources()
{
return resources;
}
public void startElement( String uri, String localName, String rawName, Attributes attributes )
{
if ( rawName.equals( "parent" ) )
{
insideParent = true;
}
else if ( rawName.equals( "repository" ) )
{
currentRepository = new Repository();
insideRepository = true;
}
else if ( rawName.equals( "dependency" ) )
{
List chain =
Collections.singletonList( new Dependency( groupId, artifactId, version, packaging, this.chain ) );
currentDependency = new Dependency( chain );
insideDependency = true;
}
else if ( rawName.equals( "dependencyManagement" ) )
{
insideDependencyManagement = true;
}
else if ( rawName.equals( "resource" ) )
{
currentResource = new Resource();
insideResource = true;
}
else if ( rawName.equals( "testResource" ) )
{
currentResource = new Resource();
insideResource = true;
}
else if ( rawName.equals( "snapshots" ) && insideRepository )
{
insideSnapshots = true;
}
else if ( rawName.equals( "releases" ) && insideRepository )
{
insideReleases = true;
}
else if ( rawName.equals( "exclusion" ) && insideDependency )
{
insideExclusion = true;
currentExclusion = new Exclusion();
}
depth++;
}
public void characters( char buffer[], int start, int length )
{
bodyText.append( buffer, start, length );
}
private String getBodyText()
{
return bodyText.toString().trim();
}
public void endElement( String uri, String localName, String rawName )
throws SAXException
{
// support both v3 <extend> and v4 <parent>
if ( rawName.equals( "parent" ) )
{
if ( parentArtifactId == null || parentArtifactId.trim().length() == 0 )
{
throw new SAXException( "Missing required element in <parent>: artifactId." );
}
if ( parentGroupId == null || parentGroupId.trim().length() == 0 )
{
throw new SAXException( "Missing required element in <parent>: groupId." );
}
if ( parentVersion == null || parentVersion.trim().length() == 0 )
{
throw new SAXException( "Missing required element in <parent>: version." );
}
if ( groupId == null )
{
groupId = parentGroupId;
}
if ( version == null )
{
version = parentVersion;
}
// actually, these should be transtive (see MNG-77) - but some projects have circular deps that way
ModelReader p = retrievePom( parentGroupId, parentArtifactId, parentVersion, "pom", inheritedScope, false,
excluded, Collections.EMPTY_LIST );
addDependencies( p.getDependencies(), parentDependencies, inheritedScope, excluded );
addDependencies( p.getManagedDependencies(), managedDependencies, inheritedScope, Collections.EMPTY_SET );
resources.addAll( p.getResources() );
insideParent = false;
}
else if ( rawName.equals( "dependency" ) )
{
insideDependency = false;
if ( insideDependencyManagement )
{
managedDependencies.put( currentDependency.getConflictId(), currentDependency );
}
else
{
dependencies.put( currentDependency.getConflictId(), currentDependency );
}
}
else if ( rawName.equals( "exclusion" ) )
{
currentDependency.addExclusion( currentExclusion );
insideExclusion = false;
}
else if ( rawName.equals( "dependencyManagement" ) )
{
insideDependencyManagement = false;
}
else if ( rawName.equals( "resource" ) )
{
resources.add( currentResource );
insideResource = false;
}
else if ( rawName.equals( "testResource" ) )
{
testResources.add( currentResource );
insideResource = false;
}
else if ( rawName.equals( "repository" ) )
{
repositories.add( currentRepository );
insideRepository = false;
}
else if ( insideParent )
{
if ( rawName.equals( "groupId" ) )
{
parentGroupId = getBodyText();
}
else if ( rawName.equals( "artifactId" ) )
{
parentArtifactId = getBodyText();
}
else if ( rawName.equals( "version" ) )
{
parentVersion = getBodyText();
}
}
else if ( insideDependency )
{
if ( insideExclusion )
{
if ( rawName.equals( "groupId" ) )
{
currentExclusion.setGroupId( getBodyText() );
}
else if ( rawName.equals( "artifactId" ) )
{
currentExclusion.setArtifactId( getBodyText() );
}
}
else if ( rawName.equals( "id" ) )
{
currentDependency.setId( getBodyText() );
}
else if ( rawName.equals( "version" ) )
{
currentDependency.setVersion( getBodyText() );
}
else if ( rawName.equals( "jar" ) )
{
currentDependency.setJar( getBodyText() );
}
else if ( rawName.equals( "type" ) )
{
currentDependency.setType( getBodyText() );
}
else if ( rawName.equals( "groupId" ) )
{
currentDependency.setGroupId( getBodyText() );
}
else if ( rawName.equals( "artifactId" ) )
{
currentDependency.setArtifactId( getBodyText() );
}
else if ( rawName.equals( "scope" ) )
{
currentDependency.setScope( getBodyText() );
}
}
else if ( insideResource )
{
if ( rawName.equals( "directory" ) )
{
currentResource.setDirectory( getBodyText() );
}
else if ( rawName.equals( "include" ) )
{
currentResource.addInclude( getBodyText() );
}
else if ( rawName.equals( "exclude" ) )
{
currentResource.addExclude( getBodyText() );
}
}
else if ( insideRepository )
{
if ( rawName.equals( "id" ) )
{
currentRepository.setId( getBodyText() );
}
else if ( rawName.equals( "url" ) )
{
currentRepository.setBasedir( getBodyText() );
}
else if ( rawName.equals( "layout" ) )
{
currentRepository.setLayout( getBodyText() );
}
else if ( rawName.equals( "enabled" ) )
{
if ( insideSnapshots )
{
currentRepository.setSnapshots( Boolean.valueOf( getBodyText() ).booleanValue() );
}
else if ( insideReleases )
{
currentRepository.setReleases( Boolean.valueOf( getBodyText() ).booleanValue() );
}
}
else if ( rawName.equals( "snapshots" ) )
{
insideSnapshots = false;
}
else if ( rawName.equals( "releases" ) )
{
insideReleases = false;
}
}
else if ( depth == 2 )
{
if ( rawName.equals( "artifactId" ) )
{
artifactId = getBodyText();
}
else if ( rawName.equals( "version" ) )
{
version = getBodyText();
}
else if ( rawName.equals( "groupId" ) )
{
groupId = getBodyText();
}
else if ( rawName.equals( "packaging" ) )
{
packaging = getBodyText();
}
}
else if ( depth == 1 ) // model / project
{
resolveDependencies();
}
bodyText = new StringBuffer();
depth--;
}
private void resolveDependencies()
throws SAXException
{
for ( Iterator it = dependencies.values().iterator(); it.hasNext(); )
{
Dependency dependency = (Dependency) it.next();
if ( !excluded.contains( dependency.getConflictId() ) )
{
if ( !dependency.getScope().equals( Dependency.SCOPE_TEST ) || inheritedScope == null )
{
if ( dependency.getVersion() == null )
{
Dependency managedDependency =
(Dependency) managedDependencies.get( dependency.getConflictId() );
if ( managedDependency == null )
{
throw new NullPointerException( "[" + groupId + ":" + artifactId + ":" + packaging + ":" +
version + "] " + "Dependency " + dependency.getConflictId() +
" is missing a version, and nothing is found in dependencyManagement. " );
}
dependency.setVersion( managedDependency.getVersion() );
}
if ( resolveTransitiveDependencies )
{
Set excluded = new HashSet( this.excluded );
excluded.addAll( dependency.getExclusions() );
ModelReader p = retrievePom( dependency.getGroupId(), dependency.getArtifactId(),
dependency.getVersion(), dependency.getType(),
dependency.getScope(), resolveTransitiveDependencies, excluded,
dependency.getChain() );
addDependencies( p.getDependencies(), transitiveDependencies, dependency.getScope(), excluded );
}
}
}
}
}
private void addDependencies( Collection dependencies, Map target, String inheritedScope, Set excluded )
{
for ( Iterator i = dependencies.iterator(); i.hasNext(); )
{
Dependency d = (Dependency) i.next();
// skip test deps
if ( !Dependency.SCOPE_TEST.equals( d.getScope() ) )
{
// Do we care about runtime here?
if ( Dependency.SCOPE_TEST.equals( inheritedScope ) )
{
d.setScope( Dependency.SCOPE_TEST );
}
if ( !hasDependency( d, target ) && !excluded.contains( d.getConflictId() ) )
{
if ( "plexus".equals( d.getGroupId() ) && ( "plexus-utils".equals( d.getArtifactId() ) ||
"plexus-container-default".equals( d.getArtifactId() ) ) )
{
throw new IllegalStateException( d.getConflictId() + " found in chain " + d.getChain() );
}
target.put( d.getConflictId(), d );
}
}
}
}
private boolean hasDependency( Dependency d, Map dependencies )
{
String conflictId = d.getConflictId();
if ( dependencies.containsKey( conflictId ) )
{
// We only care about pushing in compile scope dependencies I think
// if not, we'll need to be able to get the original and pick the appropriate scope
if ( d.getScope().equals( Dependency.SCOPE_COMPILE ) )
{
dependencies.remove( conflictId );
}
else
{
return true;
}
}
return false;
}
private ModelReader retrievePom( String groupId, String artifactId, String version, String type,
String inheritedScope, boolean resolveTransitiveDependencies, Set excluded,
List chain )
throws SAXException
{
String key = groupId + ":" + artifactId + ":" + version;
if ( inProgress.contains( key ) )
{
throw new SAXException( "Circular dependency found, looking for " + key + "\nIn progress:" + inProgress );
}
inProgress.add( key );
ModelReader p = new ModelReader( downloader, inheritedScope, resolveTransitiveDependencies, excluded, chain );
try
{
Dependency pom = new Dependency( groupId, artifactId, version, type, chain );
downloader.downloadDependencies( Collections.singletonList( pom ) );
Repository localRepository = downloader.getLocalRepository();
p.parse( localRepository.getMetadataFile( groupId, artifactId, version, type,
artifactId + "-" + pom.getResolvedVersion() + ".pom" ) );
}
catch ( IOException e )
{
throw new SAXException( "Error getting parent POM", e );
}
catch ( ParserConfigurationException e )
{
throw new SAXException( "Error getting parent POM", e );
}
catch ( DownloadFailedException e )
{
throw new SAXException( "Error getting parent POM", e );
}
inProgress.remove( key );
return p;
}
public String getArtifactId()
{
return artifactId;
}
public String getVersion()
{
return version;
}
public String getGroupId()
{
return groupId;
}
public String getPackaging()
{
return packaging;
}
}

View File

@ -1,180 +0,0 @@
package model;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.File;
import java.util.Collections;
/**
* Repository path management.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class Repository
{
public static final String LAYOUT_LEGACY = "legacy";
public static final String LAYOUT_DEFAULT = "default";
private String basedir;
private String layout;
private String id;
private boolean releases;
private boolean snapshots;
public Repository()
{
}
public Repository( String id, String basedir, String layout, boolean snapshots, boolean releases )
{
this.id = id;
this.basedir = basedir;
this.layout = layout;
this.snapshots = snapshots;
this.releases = releases;
}
public File getArtifactFile( String groupId, String artifactId, String version, String type )
{
Dependency d = new Dependency( groupId, artifactId, version, type, Collections.EMPTY_LIST );
return getArtifactFile( d );
}
public File getArtifactFile( Dependency dependency )
{
String repositoryPath = getArtifactPath( dependency );
return new File( basedir, repositoryPath );
}
public String getArtifactPath( Dependency dependency )
{
String repositoryPath;
if ( LAYOUT_LEGACY.equals( layout ) )
{
repositoryPath = dependency.getArtifactDirectory() + "/" + dependency.getType() + "s/" +
dependency.getArtifact();
}
else if ( LAYOUT_DEFAULT.equals( layout ) )
{
repositoryPath = dependency.getGroupId().replace( '.', '/' );
repositoryPath = repositoryPath + "/" + dependency.getArtifactId() + "/" + dependency.getVersion();
repositoryPath = repositoryPath + "/" + dependency.getArtifact();
}
else
{
throw new IllegalStateException( "Unknown layout: " + layout );
}
return repositoryPath;
}
public File getMetadataFile( String groupId, String artifactId, String version, String type, String filename )
{
String repositoryPath = getMetadataPath( groupId, artifactId, version, type, filename );
return new File( basedir, repositoryPath );
}
public String getMetadataPath( String groupId, String artifactId, String version, String type, String filename )
{
Dependency dependency = new Dependency( groupId, artifactId, version, type, Collections.EMPTY_LIST );
String repositoryPath;
if ( LAYOUT_LEGACY.equals( layout ) )
{
repositoryPath = dependency.getArtifactDirectory() + "/poms/" + filename;
}
else if ( LAYOUT_DEFAULT.equals( layout ) )
{
repositoryPath = dependency.getGroupId().replace( '.', '/' );
repositoryPath = repositoryPath + "/" + dependency.getArtifactId();
if ( version != null )
{
repositoryPath = repositoryPath + "/" + dependency.getVersion();
}
repositoryPath = repositoryPath + "/" + filename;
}
else
{
throw new IllegalStateException( "Unknown layout: " + layout );
}
return repositoryPath;
}
public String toString()
{
return basedir;
}
public String getBasedir()
{
return basedir;
}
public void setBasedir( String basedir )
{
this.basedir = basedir;
}
public void setLayout( String layout )
{
this.layout = layout;
}
public String getId()
{
return id;
}
public void setId( String id )
{
this.id = id;
}
public String getLayout()
{
return layout;
}
public void setReleases( boolean releases )
{
this.releases = releases;
}
public void setSnapshots( boolean snapshots )
{
this.snapshots = snapshots;
}
public boolean isReleases()
{
return releases;
}
public boolean isSnapshots()
{
return snapshots;
}
}

View File

@ -1,66 +0,0 @@
package model;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Describes a resource.
*
* @version $Id$
*/
public class Resource
implements Serializable
{
private String directory;
private List includes = new ArrayList();
private List excludes = new ArrayList();
public void addInclude( String pattern )
{
this.includes.add( pattern );
}
public void addExclude( String pattern )
{
this.excludes.add( pattern );
}
public List getIncludes()
{
return this.includes;
}
public List getExcludes()
{
return this.excludes;
}
public void setDirectory( String directory )
{
this.directory = directory;
}
public String getDirectory()
{
return this.directory;
}
}

View File

@ -1,88 +0,0 @@
package test;
import util.IsolatedClassLoader;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class SurefireBooter
{
private List batteries = new ArrayList();
private List reports = new ArrayList();
private List classpathUrls = new ArrayList();
private String reportsDir;
public SurefireBooter()
{
}
public void setReportsDirectory( String reportsDirectory )
{
this.reportsDir = reportsDirectory;
}
public void addBattery( String battery, Object[] params )
{
batteries.add( new Object[]{battery, params} );
}
public void addBattery( String battery )
{
batteries.add( new Object[]{battery, null} );
}
public void addReport( String report )
{
reports.add( report );
}
public void addClassPathUrl( String path )
{
if ( !classpathUrls.contains( path ) )
{
classpathUrls.add( path );
}
}
public boolean run()
throws Exception
{
IsolatedClassLoader surefireClassLoader = new IsolatedClassLoader();
for ( Iterator i = classpathUrls.iterator(); i.hasNext(); )
{
String url = (String) i.next();
if ( url != null )
{
surefireClassLoader.addURL( new File( url ).toURL() );
}
}
Class batteryExecutorClass = surefireClassLoader.loadClass( "org.codehaus.surefire.Surefire" );
Object batteryExecutor = batteryExecutorClass.newInstance();
Method run = batteryExecutorClass.getMethod( "run",
new Class[]{List.class, List.class, ClassLoader.class,
String.class} );
ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader( surefireClassLoader );
Boolean result = (Boolean) run.invoke( batteryExecutor,
new Object[]{reports, batteries, surefireClassLoader, reportsDir} );
Thread.currentThread().setContextClassLoader( oldContextClassLoader );
return result.booleanValue();
}
}

View File

@ -1,33 +0,0 @@
package test;
import java.io.File;
import java.util.Iterator;
import java.util.List;
public class SurefirePlugin
{
public boolean execute( String basedir, List includes, List excludes, List classpathElements,
String reportsDirectory )
throws Exception
{
System.setProperty( "basedir", basedir );
SurefireBooter surefireBooter = new SurefireBooter();
surefireBooter.addBattery( "org.codehaus.surefire.battery.DirectoryBattery",
new Object[]{new File( basedir, "target/test-classes" ), includes, excludes} );
for ( Iterator i = classpathElements.iterator(); i.hasNext(); )
{
surefireBooter.addClassPathUrl( (String) i.next() );
}
surefireBooter.setReportsDirectory( reportsDirectory );
surefireBooter.addReport( "org.codehaus.surefire.report.ConsoleReporter" );
surefireBooter.addReport( "org.codehaus.surefire.report.FileReporter" );
return surefireBooter.run();
}
}

View File

@ -1,92 +0,0 @@
package util;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.ext.LexicalHandler;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.io.FileReader;
import java.io.StringReader;
import java.util.Arrays;
/**
* Parse an XML file.
*
* @version $Id$
*/
public abstract class AbstractReader
extends DefaultHandler
{
private SAXParserFactory saxFactory;
public void parse( File file )
throws ParserConfigurationException, SAXException, IOException
{
saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();
// Cheap and cheerful. Please add more to skip if the parser chokes (or use the actual
StringWriter output = new StringWriter();
IOUtil.copy( new FileReader( file ), output);
String out = output.toString();
out = StringUtils.replace( out, "&oslash;", "\u00f8" );
InputSource is = new InputSource( new StringReader( out ) );
try
{
parser.parse( is, this );
}
catch ( SAXException e )
{
System.err.println( "Error reading POM: " + file );
throw 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() );
}
}

View File

@ -1,573 +0,0 @@
package util;
import java.io.File;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* Commandline objects help handling command lines specifying processes to
* execute.
*
* The class can be used to define a command line as nested elements or as a
* helper to define a command line by an application.
* <p>
* <code>
* &lt;someelement&gt;<br>
* &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
* &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
* &nbsp;&nbsp;&lt;/acommandline&gt;<br>
* &lt;/someelement&gt;<br>
* </code>
* The element <code>someelement</code> must provide a method
* <code>createAcommandline</code> which returns an instance of this class.
*
* @author thomas.haas@softwired-inc.com
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
*/
public class Commandline implements Cloneable
{
protected static final String OS_NAME = "os.name";
protected static final String WINDOWS = "Windows";
private String shell = null;
private Vector shellArgs = new Vector();
private String executable = null;
private Vector arguments = new Vector();
private File workingDir = null;
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] );
}
}
}
public Commandline()
{
super();
setDefaultShell();
}
/**
* 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 )
{
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.
*/
// <p>This class is there to support the srcfile and targetfile
// elements of &lt;execon&gt; and &lt;transform&gt; - don't know
// whether there might be additional use cases.</p> --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.
*
* <p>The name of the executable - if set - is counted as the
* very first argument.</p>
*/
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;
}
}
/**
* <p>Sets the shell or command-line interpretor for the detected operating system,
* and the shell arguments.</p>
*/
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)
{
shell = "COMMAND.COM";
shellArgs.add("/C");
}
else
{
shell = "CMD.EXE";
shellArgs.add("/X");
shellArgs.add("/C");
}
}
}
/**
* Creates an argument object.
*
* <p>Each commandline object has at most one instance of the
* argument class. This method calls
* <code>this.createArgument(false)</code>.</p>
*
* @see #createArgument(boolean)
* @return the argument object.
*/
public Argument createArgument()
{
return this.createArgument( false );
}
/**
* Creates an argument object and adds it to our list of args.
*
* <p>Each commandline object has at most one instance of the
* argument class.</p>
*
* @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] );
}
}
/**
* 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()
{
int shellCount = 0;
int arrayPos = 0;
if ( shell != null )
{
shellCount = 1;
}
shellCount += shellArgs.size();
final String[] args = getArguments();
String[] result = new String[shellCount + args.length + (( executable == null )? 0:1)];
//Build shell and arguments into result
if ( shell != null )
{
result[0] = shell;
arrayPos++;
}
System.arraycopy( shellArgs.toArray(), 0, result, arrayPos, shellArgs.size() );
arrayPos += shellArgs.size();
//Build excutable and arguments into result
if ( executable != null )
{
result[arrayPos] = executable;
arrayPos++;
}
System.arraycopy( args, 0, result, arrayPos, args.length );
return result;
}
/**
* Returns all arguments defined by <code>addLine</code>,
* <code>addValue</code> 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.
*
* <p>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.</p>
*
* @exception Exception if the argument contains both, single
* and double quotes.
*/
public static String quoteArgument( String argument ) throws Exception
{
if ( argument.indexOf( "\"" ) > -1 )
{
if ( argument.indexOf( "\'" ) > -1 )
{
throw new Exception( "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 Exception( "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.
*
* <p>This marker can be used to locate a position on the
* commandline - to insert something for example - when all
* parameters have been set.</p>
*/
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 IOException
{
Process process = null;
if ( workingDir == null )
{
System.err.println( "Executing \"" + this + "\"" );
process = Runtime.getRuntime().exec( getShellCommandline() );
}
else
{
if ( !workingDir.exists() )
{
throw new IOException(
"Working directory \"" + workingDir.getPath() + "\" does not exist!" );
}
else if ( !workingDir.isDirectory() )
{
throw new IOException(
"Path \"" + workingDir.getPath() + "\" does not specify a directory." );
}
System.err.println(
"Executing \""
+ this
+ "\" in directory "
+ ( workingDir != null ? workingDir.getAbsolutePath() : null ) );
process = Runtime.getRuntime().exec( getShellCommandline(), null, workingDir );
}
return process;
}
}

View File

@ -1,994 +0,0 @@
package util;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
/**
* Class for scanning a directory for files/directories which match certain
* criteria.
* <p/>
* These criteria consist of selectors and patterns which have been specified.
* With the selectors you can select which files you want to have included.
* Files which are not selected are excluded. With patterns you can include
* or exclude files based on their filename.
* <p/>
* The idea is simple. A given directory is recursively scanned for all files
* and directories. Each file/directory is matched against a set of selectors,
* including special support for matching against filenames with include and
* and exclude patterns. Only files/directories which match at least one
* pattern of the include pattern list or other file selector, and don't match
* any pattern of the exclude pattern list or fail to match against a required
* selector will be placed in the list of files/directories found.
* <p/>
* When no list of include patterns is supplied, "**" will be used, which
* means that everything will be matched. When no list of exclude patterns is
* supplied, an empty list is used, such that nothing will be excluded. When
* no selectors are supplied, none are applied.
* <p/>
* The filename pattern matching is done as follows:
* The name to be matched is split up in path segments. A path segment is the
* name of a directory or file, which is bounded by
* <code>File.separator</code> ('/' under UNIX, '\' under Windows).
* For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
* "def","ghi" and "xyz.java".
* The same is done for the pattern against which should be matched.
* <p/>
* The segments of the name and the pattern are then matched against each
* other. When '**' is used for a path segment in the pattern, it matches
* zero or more path segments of the name.
* <p/>
* There is a special case regarding the use of <code>File.separator</code>s
* at the beginning of the pattern and the string to match:<br>
* When a pattern starts with a <code>File.separator</code>, the string
* to match must also start with a <code>File.separator</code>.
* When a pattern does not start with a <code>File.separator</code>, the
* string to match may not start with a <code>File.separator</code>.
* When one of these rules is not obeyed, the string will not
* match.
* <p/>
* When a name path segment is matched against a pattern path segment, the
* following special characters can be used:<br>
* '*' matches zero or more characters<br>
* '?' matches one character.
* <p/>
* Examples:
* <p/>
* "**\*.class" matches all .class files/dirs in a directory tree.
* <p/>
* "test\a??.java" matches all files/dirs which start with an 'a', then two
* more characters and then ".java", in a directory called test.
* <p/>
* "**" matches everything in a directory tree.
* <p/>
* "**\test\**\XYZ*" matches all files/dirs which start with "XYZ" and where
* there is a parent directory called test (e.g. "abc\test\def\ghi\XYZ123").
* <p/>
* Case sensitivity may be turned off if necessary. By default, it is
* turned on.
* <p/>
* Example of usage:
* <pre>
* String[] includes = {"**\\*.class"};
* String[] excludes = {"modules\\*\\**"};
* ds.setIncludes(includes);
* ds.setExcludes(excludes);
* ds.setBasedir(new File("test"));
* ds.setCaseSensitive(true);
* ds.scan();
* <p/>
* System.out.println("FILES:");
* String[] files = ds.getIncludedFiles();
* for (int i = 0; i < files.length; i++) {
* System.out.println(files[i]);
* }
* </pre>
* This will scan a directory called test for .class files, but excludes all
* files in all proper subdirectories of a directory called "modules"
*
* @author Arnout J. Kuiper
* <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
* @author Magesh Umasankar
* @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
* @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
*/
public class DirectoryScanner
{
/**
* Patterns which should be excluded by default.
*
* @see #addDefaultExcludes()
*/
protected static final String[] DEFAULTEXCLUDES = {
// Miscellaneous typical temporary files
"**/*~",
"**/#*#",
"**/.#*",
"**/%*%",
"**/._*",
// CVS
"**/CVS",
"**/CVS/**",
"**/.cvsignore",
// SCCS
"**/SCCS",
"**/SCCS/**",
// Visual SourceSafe
"**/vssver.scc",
// Subversion
"**/.svn",
"**/.svn/**",
// Mac
"**/.DS_Store"
};
/**
* The base directory to be scanned.
*/
protected File basedir;
/**
* The patterns for the files to be included.
*/
protected String[] includes;
/**
* The patterns for the files to be excluded.
*/
protected String[] excludes;
/**
* The files which matched at least one include and no excludes
* and were selected.
*/
protected Vector filesIncluded;
/**
* The files which did not match any includes or selectors.
*/
protected Vector filesNotIncluded;
/**
* The files which matched at least one include and at least
* one exclude.
*/
protected Vector filesExcluded;
/**
* The directories which matched at least one include and no excludes
* and were selected.
*/
protected Vector dirsIncluded;
/**
* The directories which were found and did not match any includes.
*/
protected Vector dirsNotIncluded;
/**
* The directories which matched at least one include and at least one
* exclude.
*/
protected Vector dirsExcluded;
/**
* The files which matched at least one include and no excludes and
* which a selector discarded.
*/
protected Vector filesDeselected;
/**
* The directories which matched at least one include and no excludes
* but which a selector discarded.
*/
protected Vector dirsDeselected;
/**
* Whether or not our results were built by a slow scan.
*/
protected boolean haveSlowResults = false;
/**
* Whether or not the file system should be treated as a case sensitive
* one.
*/
protected boolean isCaseSensitive = true;
/**
* Whether or not symbolic links should be followed.
*
* @since Ant 1.5
*/
private boolean followSymlinks = true;
/**
* Whether or not everything tested so far has been included.
*/
protected boolean everythingIncluded = true;
/**
* Sole constructor.
*/
public DirectoryScanner()
{
}
/**
* Tests whether or not a given path matches the start of a given
* pattern up to the first "**".
* <p/>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @return whether or not a given path matches the start of a given
* pattern up to the first "**".
*/
protected static boolean matchPatternStart( String pattern, String str )
{
return SelectorUtils.matchPatternStart( pattern, str );
}
/**
* Tests whether or not a given path matches the start of a given
* pattern up to the first "**".
* <p/>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return whether or not a given path matches the start of a given
* pattern up to the first "**".
*/
protected static boolean matchPatternStart( String pattern, String str,
boolean isCaseSensitive )
{
return SelectorUtils.matchPatternStart( pattern, str, isCaseSensitive );
}
/**
* Tests whether or not a given path matches a given pattern.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
protected static boolean matchPath( String pattern, String str )
{
return SelectorUtils.matchPath( pattern, str );
}
/**
* Tests whether or not a given path matches a given pattern.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
protected static boolean matchPath( String pattern, String str,
boolean isCaseSensitive )
{
return SelectorUtils.matchPath( pattern, str, isCaseSensitive );
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> otherwise.
*/
public static boolean match( String pattern, String str )
{
return SelectorUtils.match( pattern, str );
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> otherwise.
*/
protected static boolean match( String pattern, String str,
boolean isCaseSensitive )
{
return SelectorUtils.match( pattern, str, isCaseSensitive );
}
/**
* Sets the base directory to be scanned. This is the directory which is
* scanned recursively. All '/' and '\' characters are replaced by
* <code>File.separatorChar</code>, so the separator used need not match
* <code>File.separatorChar</code>.
*
* @param basedir The base directory to scan.
* Must not be <code>null</code>.
*/
public void setBasedir( String basedir )
{
setBasedir( new File( basedir.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar ) ) );
}
/**
* Sets the base directory to be scanned. This is the directory which is
* scanned recursively.
*
* @param basedir The base directory for scanning.
* Should not be <code>null</code>.
*/
public void setBasedir( File basedir )
{
this.basedir = basedir;
}
/**
* Returns the base directory to be scanned.
* This is the directory which is scanned recursively.
*
* @return the base directory to be scanned
*/
public File getBasedir()
{
return basedir;
}
/**
* Sets whether or not the file system should be regarded as case sensitive.
*
* @param isCaseSensitive whether or not the file system should be
* regarded as a case sensitive one
*/
public void setCaseSensitive( boolean isCaseSensitive )
{
this.isCaseSensitive = isCaseSensitive;
}
/**
* Sets whether or not symbolic links should be followed.
*
* @param followSymlinks whether or not symbolic links should be followed
*/
public void setFollowSymlinks( boolean followSymlinks )
{
this.followSymlinks = followSymlinks;
}
/**
* Sets the list of include patterns to use. All '/' and '\' characters
* are replaced by <code>File.separatorChar</code>, so the separator used
* need not match <code>File.separatorChar</code>.
* <p/>
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param includes A list of include patterns.
* May be <code>null</code>, indicating that all files
* should be included. If a non-<code>null</code>
* list is given, all elements must be
* non-<code>null</code>.
*/
public void setIncludes( String[] includes )
{
if ( includes == null )
{
this.includes = null;
}
else
{
this.includes = new String[includes.length];
for ( int i = 0; i < includes.length; i++ )
{
String pattern;
pattern = includes[i].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
if ( pattern.endsWith( File.separator ) )
{
pattern += "**";
}
this.includes[i] = pattern;
}
}
}
/**
* Sets the list of exclude patterns to use. All '/' and '\' characters
* are replaced by <code>File.separatorChar</code>, so the separator used
* need not match <code>File.separatorChar</code>.
* <p/>
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param excludes A list of exclude patterns.
* May be <code>null</code>, indicating that no files
* should be excluded. If a non-<code>null</code> list is
* given, all elements must be non-<code>null</code>.
*/
public void setExcludes( String[] excludes )
{
if ( excludes == null )
{
this.excludes = null;
}
else
{
this.excludes = new String[excludes.length];
for ( int i = 0; i < excludes.length; i++ )
{
String pattern;
pattern = excludes[i].replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
if ( pattern.endsWith( File.separator ) )
{
pattern += "**";
}
this.excludes[i] = pattern;
}
}
}
/**
* Returns whether or not the scanner has included all the files or
* directories it has come across so far.
*
* @return <code>true</code> if all files and directories which have
* been found so far have been included.
*/
public boolean isEverythingIncluded()
{
return everythingIncluded;
}
/**
* Scans the base directory for files which match at least one include
* pattern and don't match any exclude patterns. If there are selectors
* then the files must pass muster there, as well.
*
* @throws IllegalStateException if the base directory was set
* incorrectly (i.e. if it is <code>null</code>, doesn't exist,
* or isn't a directory).
*/
public void scan() throws IllegalStateException
{
if ( basedir == null )
{
throw new IllegalStateException( "No basedir set" );
}
if ( !basedir.exists() )
{
throw new IllegalStateException( "basedir " + basedir
+ " does not exist" );
}
if ( !basedir.isDirectory() )
{
throw new IllegalStateException( "basedir " + basedir
+ " is not a directory" );
}
if ( includes == null )
{
// No includes supplied, so set it to 'matches all'
includes = new String[1];
includes[0] = "**";
}
if ( excludes == null )
{
excludes = new String[0];
}
filesIncluded = new Vector();
filesNotIncluded = new Vector();
filesExcluded = new Vector();
filesDeselected = new Vector();
dirsIncluded = new Vector();
dirsNotIncluded = new Vector();
dirsExcluded = new Vector();
dirsDeselected = new Vector();
if ( isIncluded( "" ) )
{
if ( !isExcluded( "" ) )
{
if ( isSelected( "", basedir ) )
{
dirsIncluded.addElement( "" );
}
else
{
dirsDeselected.addElement( "" );
}
}
else
{
dirsExcluded.addElement( "" );
}
}
else
{
dirsNotIncluded.addElement( "" );
}
scandir( basedir, "", true );
}
/**
* Top level invocation for a slow scan. A slow scan builds up a full
* list of excluded/included files/directories, whereas a fast scan
* will only have full results for included files, as it ignores
* directories which can't possibly hold any included files/directories.
* <p/>
* Returns immediately if a slow scan has already been completed.
*/
protected void slowScan()
{
if ( haveSlowResults )
{
return;
}
String[] excl = new String[dirsExcluded.size()];
dirsExcluded.copyInto( excl );
String[] notIncl = new String[dirsNotIncluded.size()];
dirsNotIncluded.copyInto( notIncl );
for ( int i = 0; i < excl.length; i++ )
{
if ( !couldHoldIncluded( excl[i] ) )
{
scandir( new File( basedir, excl[i] ),
excl[i] + File.separator, false );
}
}
for ( int i = 0; i < notIncl.length; i++ )
{
if ( !couldHoldIncluded( notIncl[i] ) )
{
scandir( new File( basedir, notIncl[i] ),
notIncl[i] + File.separator, false );
}
}
haveSlowResults = true;
}
/**
* Scans the given directory for files and directories. Found files and
* directories are placed in their respective collections, based on the
* matching of includes, excludes, and the selectors. When a directory
* is found, it is scanned recursively.
*
* @param dir The directory to scan. Must not be <code>null</code>.
* @param vpath The path relative to the base directory (needed to
* prevent problems with an absolute path when using
* dir). Must not be <code>null</code>.
* @param fast Whether or not this call is part of a fast scan.
* @see #filesIncluded
* @see #filesNotIncluded
* @see #filesExcluded
* @see #dirsIncluded
* @see #dirsNotIncluded
* @see #dirsExcluded
* @see #slowScan
*/
protected void scandir( File dir, String vpath, boolean fast )
{
String[] newfiles = dir.list();
if ( newfiles == null )
{
/*
* two reasons are mentioned in the API docs for File.list
* (1) dir is not a directory. This is impossible as
* we wouldn't get here in this case.
* (2) an IO error occurred (why doesn't it throw an exception
* then???)
*/
//throw new Exception( "IO error scanning directory " + dir.getAbsolutePath() );
}
if ( !followSymlinks )
{
Vector noLinks = new Vector();
for ( int i = 0; i < newfiles.length; i++ )
{
try
{
if ( isSymbolicLink( dir, newfiles[i] ) )
{
String name = vpath + newfiles[i];
File file = new File( dir, newfiles[i] );
if ( file.isDirectory() )
{
dirsExcluded.addElement( name );
}
else
{
filesExcluded.addElement( name );
}
}
else
{
noLinks.addElement( newfiles[i] );
}
}
catch ( IOException ioe )
{
String msg = "IOException caught while checking "
+ "for links, couldn't get cannonical path!";
// will be caught and redirected to Ant's logging system
System.err.println( msg );
noLinks.addElement( newfiles[i] );
}
}
newfiles = new String[noLinks.size()];
noLinks.copyInto( newfiles );
}
for ( int i = 0; i < newfiles.length; i++ )
{
String name = vpath + newfiles[i];
File file = new File( dir, newfiles[i] );
if ( file.isDirectory() )
{
if ( isIncluded( name ) )
{
if ( !isExcluded( name ) )
{
if ( isSelected( name, file ) )
{
dirsIncluded.addElement( name );
if ( fast )
{
scandir( file, name + File.separator, fast );
}
}
else
{
everythingIncluded = false;
dirsDeselected.addElement( name );
if ( fast && couldHoldIncluded( name ) )
{
scandir( file, name + File.separator, fast );
}
}
}
else
{
everythingIncluded = false;
dirsExcluded.addElement( name );
if ( fast && couldHoldIncluded( name ) )
{
scandir( file, name + File.separator, fast );
}
}
}
else
{
everythingIncluded = false;
dirsNotIncluded.addElement( name );
if ( fast && couldHoldIncluded( name ) )
{
scandir( file, name + File.separator, fast );
}
}
if ( !fast )
{
scandir( file, name + File.separator, fast );
}
}
else if ( file.isFile() )
{
if ( isIncluded( name ) )
{
if ( !isExcluded( name ) )
{
if ( isSelected( name, file ) )
{
filesIncluded.addElement( name );
}
else
{
everythingIncluded = false;
filesDeselected.addElement( name );
}
}
else
{
everythingIncluded = false;
filesExcluded.addElement( name );
}
}
else
{
everythingIncluded = false;
filesNotIncluded.addElement( name );
}
}
}
}
/**
* Tests whether or not a name matches against at least one include
* pattern.
*
* @param name The name to match. Must not be <code>null</code>.
* @return <code>true</code> when the name matches against at least one
* include pattern, or <code>false</code> otherwise.
*/
protected boolean isIncluded( String name )
{
for ( int i = 0; i < includes.length; i++ )
{
if ( matchPath( includes[i], name, isCaseSensitive ) )
{
return true;
}
}
return false;
}
/**
* Tests whether or not a name matches the start of at least one include
* pattern.
*
* @param name The name to match. Must not be <code>null</code>.
* @return <code>true</code> when the name matches against the start of at
* least one include pattern, or <code>false</code> otherwise.
*/
protected boolean couldHoldIncluded( String name )
{
for ( int i = 0; i < includes.length; i++ )
{
if ( matchPatternStart( includes[i], name, isCaseSensitive ) )
{
return true;
}
}
return false;
}
/**
* Tests whether or not a name matches against at least one exclude
* pattern.
*
* @param name The name to match. Must not be <code>null</code>.
* @return <code>true</code> when the name matches against at least one
* exclude pattern, or <code>false</code> otherwise.
*/
protected boolean isExcluded( String name )
{
for ( int i = 0; i < excludes.length; i++ )
{
if ( matchPath( excludes[i], name, isCaseSensitive ) )
{
return true;
}
}
return false;
}
/**
* Tests whether a name should be selected.
*
* @param name the filename to check for selecting
* @param file the java.io.File object for this filename
* @return <code>false</code> when the selectors says that the file
* should not be selected, <code>true</code> otherwise.
*/
protected boolean isSelected( String name, File file )
{
return true;
}
/**
* Returns the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the files which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedFiles()
{
String[] files = new String[filesIncluded.size()];
filesIncluded.copyInto( files );
return files;
}
/**
* Returns the names of the files which matched none of the include
* patterns. The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.
*
* @return the names of the files which matched none of the include
* patterns.
* @see #slowScan
*/
public String[] getNotIncludedFiles()
{
slowScan();
String[] files = new String[filesNotIncluded.size()];
filesNotIncluded.copyInto( files );
return files;
}
/**
* Returns the names of the files which matched at least one of the
* include patterns and at least one of the exclude patterns.
* The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.
*
* @return the names of the files which matched at least one of the
* include patterns and at at least one of the exclude patterns.
* @see #slowScan
*/
public String[] getExcludedFiles()
{
slowScan();
String[] files = new String[filesExcluded.size()];
filesExcluded.copyInto( files );
return files;
}
/**
* <p>Returns the names of the files which were selected out and
* therefore not ultimately included.</p>
* <p/>
* <p>The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.</p>
*
* @return the names of the files which were deselected.
* @see #slowScan
*/
public String[] getDeselectedFiles()
{
slowScan();
String[] files = new String[filesDeselected.size()];
filesDeselected.copyInto( files );
return files;
}
/**
* Returns the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
* The names are relative to the base directory.
*
* @return the names of the directories which matched at least one of the
* include patterns and none of the exclude patterns.
*/
public String[] getIncludedDirectories()
{
String[] directories = new String[dirsIncluded.size()];
dirsIncluded.copyInto( directories );
return directories;
}
/**
* Returns the names of the directories which matched none of the include
* patterns. The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.
*
* @return the names of the directories which matched none of the include
* patterns.
* @see #slowScan
*/
public String[] getNotIncludedDirectories()
{
slowScan();
String[] directories = new String[dirsNotIncluded.size()];
dirsNotIncluded.copyInto( directories );
return directories;
}
/**
* Returns the names of the directories which matched at least one of the
* include patterns and at least one of the exclude patterns.
* The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.
*
* @return the names of the directories which matched at least one of the
* include patterns and at least one of the exclude patterns.
* @see #slowScan
*/
public String[] getExcludedDirectories()
{
slowScan();
String[] directories = new String[dirsExcluded.size()];
dirsExcluded.copyInto( directories );
return directories;
}
/**
* <p>Returns the names of the directories which were selected out and
* therefore not ultimately included.</p>
* <p/>
* <p>The names are relative to the base directory. This involves
* performing a slow scan if one has not already been completed.</p>
*
* @return the names of the directories which were deselected.
* @see #slowScan
*/
public String[] getDeselectedDirectories()
{
slowScan();
String[] directories = new String[dirsDeselected.size()];
dirsDeselected.copyInto( directories );
return directories;
}
/**
* Adds default exclusions to the current exclusions set.
*/
public void addDefaultExcludes()
{
int excludesLength = excludes == null ? 0 : excludes.length;
String[] newExcludes;
newExcludes = new String[excludesLength + DEFAULTEXCLUDES.length];
if ( excludesLength > 0 )
{
System.arraycopy( excludes, 0, newExcludes, 0, excludesLength );
}
for ( int i = 0; i < DEFAULTEXCLUDES.length; i++ )
{
newExcludes[i + excludesLength] = DEFAULTEXCLUDES[i].replace( '/',
File.separatorChar ).replace( '\\', File.separatorChar );
}
excludes = newExcludes;
}
/**
* Checks whether a given file is a symbolic link.
* <p/>
* <p>It doesn't really test for symbolic links but whether the
* canonical and absolute paths of the file are identical - this
* may lead to false positives on some platforms.</p>
*
* @param parent the parent directory of the file to test
* @param name the name of the file to test.
* @since Ant 1.5
*/
public boolean isSymbolicLink( File parent, String name )
throws IOException
{
File resolvedParent = new File( parent.getCanonicalPath() );
File toTest = new File( resolvedParent, name );
return !toTest.getAbsolutePath().equals( toTest.getCanonicalPath() );
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,782 +0,0 @@
package util;
/*
* Copyright 2001-2005 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
/**
* General IO Stream manipulation.
* <p/>
* This class provides static utility methods for input/output operations, particularly buffered
* copying between sources (<code>InputStream</code>, <code>Reader</code>, <code>String</code> and
* <code>byte[]</code>) and destinations (<code>OutputStream</code>, <code>Writer</code>,
* <code>String</code> and <code>byte[]</code>).
* </p>
* <p/>
* <p>Unless otherwise noted, these <code>copy</code> methods do <em>not</em> 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' <code>close()</code> 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 <a href="http://www.unixreview.com/articles/1998/9804/9804ja/ja.htm">this
* UnixReview article</a></p>
* <p/>
* <p>For each <code>copy</code> 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 -&gt; faster" does not hold, even for large data
* transfers.</p>
* <p/>
* <p>For byte-to-char methods, a <code>copy</code> variant allows the encoding to be selected
* (otherwise the platform default is used).</p>
* <p/>
* <p>The <code>copy</code> methods use an internal buffer when copying. It is therefore advisable
* <em>not</em> to deliberately wrap the stream arguments to the <code>copy</code> methods in
* <code>Buffered*</code> streams. For example, don't do the
* following:</p>
* <p/>
* <code>copy( new BufferedInputStream( in ), new BufferedOutputStream( out ) );</code>
* <p/>
* <p>The rationale is as follows:</p>
* <p/>
* <p>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 <code>read</code> requests can inexpensively get
* their data (until the buffer runs out).</p>
* <p>However, the <code>copy</code> 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).</p>
*
* @author <a href="mailto:peter@codehaus.org">Peter Donald</a>
* @author <a href="mailto:jefft@codehaus.org">Jeff Turner</a>
* @version CVS $Revision$ $Date$
* @since 4.0
*/
/*
* Behold, intrepid explorers; a map of this class:
*
* Method Input Output Dependency
* ------ ----- ------ -------
* 1 copy InputStream OutputStream (primitive)
* 2 copy Reader Writer (primitive)
*
* 3 copy InputStream Writer 2
* 4 toString InputStream String 3
* 5 toByteArray InputStream byte[] 1
*
* 6 copy Reader OutputStream 2
* 7 toString Reader String 2
* 8 toByteArray Reader byte[] 6
*
* 9 copy String OutputStream 2
* 10 copy String Writer (trivial)
* 11 toByteArray String byte[] 9
*
* 12 copy byte[] Writer 3
* 13 toString byte[] String 12
* 14 copy byte[] OutputStream (trivial)
*
*
* Note that only the first two methods shuffle bytes; the rest use these two, or (if possible) copy
* using native Java copy methods. As there are method variants to specify buffer size and encoding,
* each row may correspond to up to 4 methods.
*
*/
public final class IOUtil
{
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
/**
* Private constructor to prevent instantiation.
*/
private IOUtil()
{
}
///////////////////////////////////////////////////////////////
// Core copy methods
///////////////////////////////////////////////////////////////
/**
* Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
*/
public static void copy( final InputStream input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
*
* @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 <code>Reader</code> to a <code>Writer</code>.
*/
public static void copy( final Reader input, final Writer output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy chars from a <code>Reader</code> to a <code>Writer</code>.
*
* @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 <code>InputStream</code> to chars on a
* <code>Writer</code>.
* 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 <code>InputStream</code> to chars on a
* <code>Writer</code>.
* 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 <code>InputStream</code> to chars on a
* <code>Writer</code>, using the specified encoding.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>InputStream</code> to chars on a
* <code>Writer</code>, using the specified encoding.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>InputStream</code> 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 <code>InputStream</code> 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 <code>InputStream</code> as a String.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>InputStream</code> as a String.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>InputStream</code> as a <code>byte[]</code>.
*/
public static byte[] toByteArray( final InputStream input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of an <code>InputStream</code> as a <code>byte[]</code>.
*
* @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 <code>Reader</code> to bytes on an <code>OutputStream</code>, and
* flush the <code>OutputStream</code>.
*/
public static void copy( final Reader input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Serialize chars from a <code>Reader</code> to bytes on an <code>OutputStream</code>, and
* flush the <code>OutputStream</code>.
*
* @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 <code>Reader</code> as a String.
*/
public static String toString( final Reader input )
throws IOException
{
return toString( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a <code>Reader</code> 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 <code>Reader</code> as a <code>byte[]</code>.
*/
public static byte[] toByteArray( final Reader input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a <code>Reader</code> as a <code>byte[]</code>.
*
* @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 <code>String</code> to bytes on an <code>OutputStream</code>, and
* flush the <code>OutputStream</code>.
*/
public static void copy( final String input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Serialize chars from a <code>String</code> to bytes on an <code>OutputStream</code>, and
* flush the <code>OutputStream</code>.
*
* @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 <code>String</code> to a <code>Writer</code>.
*/
public static void copy( final String input, final Writer output )
throws IOException
{
output.write( input );
}
/**
* Copy bytes from an <code>InputStream</code> to an
* <code>OutputStream</code>, 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 <code>String</code> as a <code>byte[]</code>.
*/
public static byte[] toByteArray( final String input )
throws IOException
{
return toByteArray( input, DEFAULT_BUFFER_SIZE );
}
/**
* Get the contents of a <code>String</code> as a <code>byte[]</code>.
*
* @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 <code>byte[]</code> to chars on a
* <code>Writer</code>.
* 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 <code>byte[]</code> to chars on a
* <code>Writer</code>.
* 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 <code>byte[]</code> to chars on a
* <code>Writer</code>, using the specified encoding.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>byte[]</code> to chars on a
* <code>Writer</code>, using the specified encoding.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>byte[]</code> 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 <code>byte[]</code> 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 <code>byte[]</code> as a String.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>byte[]</code> as a String.
*
* @param encoding The name of a supported character encoding. See the
* <a href="http://www.iana.org/assignments/character-sets">IANA
* Charset Registry</a> 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 <code>byte[]</code> to an <code>OutputStream</code>.
*/
public static void copy( final byte[] input, final OutputStream output )
throws IOException
{
copy( input, output, DEFAULT_BUFFER_SIZE );
}
/**
* Copy bytes from a <code>byte[]</code> to an <code>OutputStream</code>.
*
* @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
}
}
}

View File

@ -1,58 +0,0 @@
package util;
import java.net.URL;
import java.net.URLClassLoader;
public class IsolatedClassLoader
extends URLClassLoader
{
private ClassLoader parent;
public IsolatedClassLoader()
{
this( ClassLoader.getSystemClassLoader() );
}
public IsolatedClassLoader( ClassLoader parent )
{
super( new URL[0] );
this.parent = parent;
}
public void addURL( URL url )
{
super.addURL( url );
}
public synchronized Class loadClass( String className )
throws ClassNotFoundException
{
Class c = findLoadedClass( className );
ClassNotFoundException ex = null;
if ( c == null )
{
try
{
c = findClass( className );
}
catch ( ClassNotFoundException e )
{
ex = e;
if ( parent != null )
{
c = parent.loadClass( className );
}
}
}
if ( c == null )
{
throw ex;
}
return c;
}
}

View File

@ -1,255 +0,0 @@
package util;
import java.util.Locale;
/**
* Condition that tests the OS type.
*
* @author Stefan Bodewig
* @author Magesh Umasankar
* @since Ant 1.4
* @version $Revision$
*/
public class Os
{
private static final String OS_NAME = System.getProperty( "os.name" ).toLowerCase( Locale.US );
private static final String OS_ARCH = System.getProperty( "os.arch" ).toLowerCase( Locale.US );
private static final String OS_VERSION = System.getProperty( "os.version" ).toLowerCase( Locale.US );
private static final String PATH_SEP = System.getProperty( "path.separator" );
private String family;
private String name;
private String version;
private String arch;
/**
* Default constructor
*
*/
public Os()
{
}
/**
* Constructor that sets the family attribute
*
* @param family a String value
*/
public Os( String family )
{
setFamily( family );
}
/**
* Sets the desired OS family type
*
* @param f The OS family type desired<br />
* Possible values:<br />
* <ul>
* <li>dos</li>
* <li>mac</li>
* <li>netware</li>
* <li>os/2</li>
* <li>tandem</li>
* <li>unix</li>
* <li>windows</li>
* <li>win9x</li>
* <li>z/os</li>
* <li>os/400</li>
* </ul>
*/
public void setFamily( String f )
{
family = f.toLowerCase( Locale.US );
}
/**
* Sets the desired OS name
*
* @param name The OS name
*/
public void setName( String name )
{
this.name = name.toLowerCase( Locale.US );
}
/**
* Sets the desired OS architecture
*
* @param arch The OS architecture
*/
public void setArch( String arch )
{
this.arch = arch.toLowerCase( Locale.US );
}
/**
* Sets the desired OS version
*
* @param version The OS version
*/
public void setVersion( String version )
{
this.version = version.toLowerCase( Locale.US );
}
/**
* Determines if the OS on which Ant is executing matches the type of
* that set in setFamily.
* @see Os#setFamily(String)
*/
public boolean eval() throws Exception
{
return isOs( family, name, arch, version );
}
/**
* Determines if the OS on which Ant is executing matches the
* given OS family.
* @param family the family to check for
* @return true if the OS matches
* @since 1.5
*/
public static boolean isFamily( String family )
{
return isOs( family, null, null, null );
}
/**
* Determines if the OS on which Ant is executing matches the
* given OS name.
*
* @param name the OS name to check for
* @return true if the OS matches
* @since 1.7
*/
public static boolean isName( String name )
{
return isOs( null, name, null, null );
}
/**
* Determines if the OS on which Ant is executing matches the
* given OS architecture.
*
* @param arch the OS architecture to check for
* @return true if the OS matches
* @since 1.7
*/
public static boolean isArch( String arch )
{
return isOs( null, null, arch, null );
}
/**
* Determines if the OS on which Ant is executing matches the
* given OS version.
*
* @param version the OS version to check for
* @return true if the OS matches
* @since 1.7
*/
public static boolean isVersion( String version )
{
return isOs( null, null, null, version );
}
/**
* Determines if the OS on which Ant is executing matches the
* given OS family, name, architecture and version
*
* @param family The OS family
* @param name The OS name
* @param arch The OS architecture
* @param version The OS version
* @return true if the OS matches
* @since 1.7
*/
public static boolean isOs( String family, String name, String arch,
String version )
{
boolean retValue = false;
if ( family != null || name != null || arch != null
|| version != null )
{
boolean isFamily = true;
boolean isName = true;
boolean isArch = true;
boolean isVersion = true;
if ( family != null )
{
if ( family.equals( "windows" ) )
{
isFamily = OS_NAME.indexOf( "windows" ) > -1;
}
else if ( family.equals( "os/2" ) )
{
isFamily = OS_NAME.indexOf( "os/2" ) > -1;
}
else if ( family.equals( "netware" ) )
{
isFamily = OS_NAME.indexOf( "netware" ) > -1;
}
else if ( family.equals( "dos" ) )
{
isFamily = PATH_SEP.equals( ";" ) && !isFamily( "netware" );
}
else if ( family.equals( "mac" ) )
{
isFamily = OS_NAME.indexOf( "mac" ) > -1;
}
else if ( family.equals( "tandem" ) )
{
isFamily = OS_NAME.indexOf( "nonstop_kernel" ) > -1;
}
else if ( family.equals( "unix" ) )
{
isFamily = PATH_SEP.equals( ":" )
&& !isFamily( "openvms" )
&& ( !isFamily( "mac" ) || OS_NAME.endsWith( "x" ) );
}
else if ( family.equals( "win9x" ) )
{
isFamily = isFamily( "windows" )
&& ( OS_NAME.indexOf( "95" ) >= 0
|| OS_NAME.indexOf( "98" ) >= 0
|| OS_NAME.indexOf( "me" ) >= 0
|| OS_NAME.indexOf( "ce" ) >= 0 );
}
else if ( family.equals( "z/os" ) )
{
isFamily = OS_NAME.indexOf( "z/os" ) > -1
|| OS_NAME.indexOf( "os/390" ) > -1;
}
else if ( family.equals( "os/400" ) )
{
isFamily = OS_NAME.indexOf( "os/400" ) > -1;
}
else if ( family.equals( "openvms" ) )
{
isFamily = OS_NAME.indexOf( "openvms" ) > -1;
}
}
if ( name != null )
{
isName = name.equals( OS_NAME );
}
if ( arch != null )
{
isArch = arch.equals( OS_ARCH );
}
if ( version != null )
{
isVersion = version.equals( OS_VERSION );
}
retValue = isFamily && isName && isArch && isVersion;
}
return retValue;
}
}

View File

@ -1,610 +0,0 @@
package util;
import java.io.File;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* <p>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.
* </p>
* <p>This is a Singleton.</p>
*
* @author Arnout J. Kuiper
* <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
* @author Magesh Umasankar
* @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
* @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 "**".
* <p/>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @return whether or not a given path matches the start of a given
* pattern up to the first "**".
*/
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 "**".
* <p/>
* This is not a general purpose test and should only be used if you
* can live with false positives. For example, <code>pattern=**\a</code>
* and <code>str=b</code> will yield <code>true</code>.
*
* @param pattern The pattern to match against. Must not be
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return whether or not a given path matches the start of a given
* pattern up to the first "**".
*/
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
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
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
* <code>null</code>.
* @param str The path to match, as a String. Must not be
* <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return <code>true</code> if the pattern matches against the string,
* or <code>false</code> otherwise.
*/
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:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> otherwise.
*/
public static boolean match( String pattern, String str )
{
return match( pattern, str, true );
}
/**
* Tests whether or not a string matches against a pattern.
* The pattern may contain two special characters:<br>
* '*' means zero or more characters<br>
* '?' means one and only one character
*
* @param pattern The pattern to match against.
* Must not be <code>null</code>.
* @param str The string which must be matched against the pattern.
* Must not be <code>null</code>.
* @param isCaseSensitive Whether or not matching should be performed
* case sensitively.
* @return <code>true</code> if the string matches against the pattern,
* or <code>false</code> otherwise.
*/
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
* <code>File.separator</code>.
*
* @param path Path to tokenize. Must not be <code>null</code>.
* @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();
}
}

View File

@ -1,120 +0,0 @@
package util;
import java.util.Iterator;
import java.util.Map;
import java.util.StringTokenizer;
public class StringUtils
{
public static String[] split( String str )
{
return split( str, null, -1 );
}
public static String[] split( String text, String separator )
{
return split( text, separator, -1 );
}
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;
}
public static String replaceOnce( String text, String repl, String with )
{
return replace( text, repl, with, 1 );
}
public static String replace( String text, String repl, String with )
{
return replace( text, repl, with, -1 );
}
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();
}
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 );
String value = obj.toString();
text = StringUtils.replace( text, "${" + key + "}", value );
if ( key.indexOf( " " ) == -1 )
{
text = StringUtils.replace( text, "$" + key, value );
}
}
return text;
}
}