mirror of https://github.com/apache/maven.git
Using Trygve's cli stuff to execute m2 and capture the output so that it can be logged for subsequent perusal.
{issue: MNG-81} git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@163236 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
aa438b8137
commit
fe59dcf689
|
@ -1,29 +1,25 @@
|
|||
package org.apache.maven.it;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import org.apache.xpath.XPathAPI;
|
||||
import org.apache.maven.it.cli.Commandline;
|
||||
import org.apache.maven.it.cli.CommandLineUtils;
|
||||
import org.apache.maven.it.cli.StreamConsumer;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import org.apache.xml.utils.DOMBuilder;
|
||||
import org.apache.xpath.XPathAPI;
|
||||
import org.w3c.dom.Document;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.Writer;
|
||||
import java.io.FileWriter;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
|
||||
|
@ -37,6 +33,7 @@ public class Verifier
|
|||
private final String basedir;
|
||||
|
||||
private final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
|
||||
private final ByteArrayOutputStream errStream = new ByteArrayOutputStream();
|
||||
|
||||
private final PrintStream originalOut;
|
||||
|
@ -47,31 +44,38 @@ public class Verifier
|
|||
this.basedir = basedir;
|
||||
|
||||
originalOut = System.out;
|
||||
|
||||
System.setOut( new PrintStream( outStream ) );
|
||||
|
||||
originalErr = System.err;
|
||||
|
||||
System.setErr( new PrintStream( errStream ) );
|
||||
}
|
||||
|
||||
public void resetStreams()
|
||||
{
|
||||
System.setOut( originalOut );
|
||||
|
||||
System.setErr( originalErr );
|
||||
}
|
||||
|
||||
public void displayStreamBuffers()
|
||||
{
|
||||
String out = outStream.toString();
|
||||
|
||||
if ( out != null && out.trim().length() > 0 )
|
||||
{
|
||||
System.out.println( "----- Standard Out -----" );
|
||||
|
||||
System.out.println( out );
|
||||
}
|
||||
|
||||
String err = errStream.toString();
|
||||
|
||||
if ( err != null && err.trim().length() > 0 )
|
||||
{
|
||||
System.err.println( "----- Standard Error -----" );
|
||||
|
||||
System.err.println( err );
|
||||
}
|
||||
}
|
||||
|
@ -83,9 +87,11 @@ public class Verifier
|
|||
public void verify() throws VerificationException
|
||||
{
|
||||
List lines = loadFile( basedir, "expected-results.txt" );
|
||||
|
||||
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
||||
{
|
||||
String line = ( String ) i.next();
|
||||
|
||||
verifyExpectedResult( line );
|
||||
}
|
||||
}
|
||||
|
@ -108,12 +114,14 @@ public class Verifier
|
|||
while ( (line = reader.readLine()) != null )
|
||||
{
|
||||
line = line.trim();
|
||||
|
||||
if ( line.startsWith( "#" ) || line.length() == 0 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
line = replace( line, "${localRepository}", localRepo );
|
||||
|
||||
lines.add( line );
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +137,7 @@ public class Verifier
|
|||
try
|
||||
{
|
||||
File f = new File( basedir, filename );
|
||||
|
||||
if ( !f.exists() )
|
||||
{
|
||||
return;
|
||||
|
@ -139,6 +148,7 @@ public class Verifier
|
|||
for ( Iterator i = lines.iterator(); i.hasNext(); )
|
||||
{
|
||||
String line = ( String ) i.next();
|
||||
|
||||
executeCommand( line );
|
||||
}
|
||||
}
|
||||
|
@ -155,11 +165,15 @@ public class Verifier
|
|||
private static void executeCommand( String line ) throws VerificationException
|
||||
{
|
||||
int index = line.indexOf( " " );
|
||||
|
||||
String cmd;
|
||||
|
||||
String args = null;
|
||||
|
||||
if ( index >= 0 )
|
||||
{
|
||||
cmd = line.substring( 0, index );
|
||||
|
||||
args = line.substring( index + 1 );
|
||||
}
|
||||
else
|
||||
|
@ -170,7 +184,9 @@ public class Verifier
|
|||
if ( cmd.equals( "rm" ) )
|
||||
{
|
||||
System.out.println( "Removing file: " + args );
|
||||
|
||||
File f = new File( args );
|
||||
|
||||
if ( f.exists() && !f.delete() )
|
||||
{
|
||||
throw new VerificationException( "Error removing file - delete failed" );
|
||||
|
@ -185,15 +201,18 @@ public class Verifier
|
|||
private static String retrieveLocalRepo()
|
||||
{
|
||||
String repo = System.getProperty( "maven.repo.local" );
|
||||
|
||||
if ( repo == null )
|
||||
{
|
||||
try
|
||||
{
|
||||
// parse ~/.m2/override.xml for it...
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
|
||||
File pom = new File( System.getProperty( "user.home" ), ".m2/override.xml" );
|
||||
|
||||
Document dom = builder.parse( pom );
|
||||
|
||||
repo = XPathAPI.selectSingleNode( dom, "/project/local/repository/text()" ).getNodeValue();
|
||||
|
@ -235,6 +254,7 @@ public class Verifier
|
|||
else
|
||||
{
|
||||
File expectedFile = new File( line );
|
||||
|
||||
if ( !expectedFile.isAbsolute() && !line.startsWith( "/" ) )
|
||||
{
|
||||
expectedFile = new File( basedir, line );
|
||||
|
@ -269,10 +289,13 @@ public class Verifier
|
|||
}
|
||||
|
||||
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 )
|
||||
|
@ -280,40 +303,58 @@ public class Verifier
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf.append( text.substring( start ) );
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public void executeGoals( String filename ) throws VerificationException
|
||||
{
|
||||
String mavenHome = System.getProperty( "maven.home" );
|
||||
|
||||
if ( mavenHome == null )
|
||||
{
|
||||
throw new VerificationException( "maven.home has not been specified" );
|
||||
}
|
||||
|
||||
List goals = loadFile( basedir, filename );
|
||||
|
||||
if ( goals.size() == 0 )
|
||||
{
|
||||
throw new VerificationException( "No goals specified" );
|
||||
}
|
||||
|
||||
List allGoals = new ArrayList();
|
||||
|
||||
allGoals.add( "clean:clean" );
|
||||
|
||||
allGoals.addAll( goals );
|
||||
|
||||
int ret = 0;
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
String prevUserDir = System.getProperty( "user.dir" );
|
||||
System.setProperty( "user.dir", basedir );
|
||||
System.setProperty( "classworlds.conf", mavenHome + "/bin/classworlds.conf" );
|
||||
URL classWorldsUrl = new URL( "file:" + mavenHome + "/core/boot/classworlds-1.1-SNAPSHOT.jar" );
|
||||
ClassLoader cl = URLClassLoader.newInstance( new URL[] { classWorldsUrl } );
|
||||
Class c = Class.forName( "org.codehaus.classworlds.Launcher", true, cl );
|
||||
Method m = c.getMethod( "mainWithExitCode", new Class[] { String[].class } );
|
||||
Object o = m.invoke( null, new Object[] { allGoals.toArray( new String[0] ) } );
|
||||
System.setProperty( "user.dir", prevUserDir );
|
||||
ret = ( ( Integer ) o ).intValue();
|
||||
Commandline cli = new Commandline();
|
||||
|
||||
cli.setWorkingDirectory( basedir );
|
||||
|
||||
cli.setExecutable( "m2" );
|
||||
|
||||
for ( Iterator i = allGoals.iterator(); i.hasNext(); )
|
||||
{
|
||||
cli.createArgument().setValue( (String) i.next() );
|
||||
}
|
||||
|
||||
Writer logWriter = new FileWriter( new File( basedir, "log.txt" ) );
|
||||
|
||||
StreamConsumer out = new WriterStreamConsumer( logWriter );
|
||||
|
||||
StreamConsumer err = new WriterStreamConsumer( logWriter );
|
||||
|
||||
ret = CommandLineUtils.executeCommandLine( cli, out, err );
|
||||
|
||||
logWriter.close();
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
|
@ -323,6 +364,7 @@ public class Verifier
|
|||
if ( ret > 0 )
|
||||
{
|
||||
System.err.println( "Exit code: " + ret );
|
||||
|
||||
throw new VerificationException();
|
||||
}
|
||||
}
|
||||
|
@ -334,17 +376,21 @@ public class Verifier
|
|||
public static void main( String args[] )
|
||||
{
|
||||
String basedir = System.getProperty( "user.dir" );
|
||||
|
||||
localRepo = retrieveLocalRepo();
|
||||
|
||||
List tests = null;
|
||||
try
|
||||
|
||||
try
|
||||
{
|
||||
tests = loadFile( basedir, "integration-tests.txt" );
|
||||
}
|
||||
catch ( VerificationException e )
|
||||
{
|
||||
System.err.println( "Unable to load integration tests file" );
|
||||
|
||||
System.err.println( e.getMessage() );
|
||||
|
||||
System.exit( 2 );
|
||||
}
|
||||
|
||||
|
@ -357,7 +403,7 @@ public class Verifier
|
|||
|
||||
for ( Iterator i = tests.iterator(); i.hasNext(); )
|
||||
{
|
||||
String test = ( String ) i.next();
|
||||
String test = ( String ) i.next();
|
||||
|
||||
System.out.print( test + "... " );
|
||||
|
||||
|
@ -366,9 +412,11 @@ public class Verifier
|
|||
try
|
||||
{
|
||||
verifier.executeHook( "prebuild-hook.txt" );
|
||||
|
||||
verifier.executeGoals( "goals.txt" );
|
||||
|
||||
verifier.executeHook( "postbuild-hook.txt" );
|
||||
|
||||
|
||||
verifier.verify();
|
||||
|
||||
verifier.resetStreams();
|
||||
|
@ -384,9 +432,11 @@ public class Verifier
|
|||
verifier.displayStreamBuffers();
|
||||
|
||||
e.printStackTrace();
|
||||
|
||||
exitCode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
System.exit( exitCode );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
package org.apache.maven.it;
|
||||
|
||||
import org.apache.maven.it.cli.StreamConsumer;
|
||||
|
||||
import java.io.Writer;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class WriterStreamConsumer
|
||||
implements StreamConsumer
|
||||
{
|
||||
private PrintWriter writer;
|
||||
|
||||
public WriterStreamConsumer( Writer writer )
|
||||
{
|
||||
this.writer = new PrintWriter( writer );
|
||||
}
|
||||
|
||||
public void consumeLine( String s )
|
||||
{
|
||||
writer.println( s );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class CommandLineException
|
||||
extends Exception
|
||||
{
|
||||
public CommandLineException( String message )
|
||||
{
|
||||
super( message );
|
||||
}
|
||||
|
||||
public CommandLineException( String message, Throwable cause )
|
||||
{
|
||||
super( message, cause );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl </a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public abstract class CommandLineUtils
|
||||
{
|
||||
public static class StringStreamConsumer
|
||||
implements StreamConsumer
|
||||
{
|
||||
private StringBuffer string = new StringBuffer();
|
||||
|
||||
private String ls = System.getProperty( "line.separator" );
|
||||
|
||||
public void consumeLine( String line )
|
||||
{
|
||||
string.append( line + ls );
|
||||
}
|
||||
|
||||
public String getOutput()
|
||||
{
|
||||
return string.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static int executeCommandLine( Commandline cl, StreamConsumer systemOut, StreamConsumer systemErr )
|
||||
throws CommandLineException
|
||||
{
|
||||
return executeCommandLine( cl, null, systemOut, systemErr );
|
||||
}
|
||||
|
||||
public static int executeCommandLine( Commandline cl, InputStream systemIn, StreamConsumer systemOut, StreamConsumer systemErr )
|
||||
throws CommandLineException
|
||||
{
|
||||
if ( cl == null )
|
||||
{
|
||||
throw new IllegalArgumentException( "cl cannot be null." );
|
||||
}
|
||||
|
||||
Process p;
|
||||
|
||||
p = cl.execute();
|
||||
|
||||
StreamFeeder inputFeeder = null;
|
||||
|
||||
if ( systemIn != null )
|
||||
{
|
||||
inputFeeder = new StreamFeeder( systemIn, p.getOutputStream() );
|
||||
}
|
||||
|
||||
StreamPumper outputPumper = new StreamPumper( p.getInputStream(), systemOut );
|
||||
|
||||
StreamPumper errorPumper = new StreamPumper( p.getErrorStream(), systemErr );
|
||||
|
||||
if ( inputFeeder != null )
|
||||
{
|
||||
inputFeeder.start();
|
||||
}
|
||||
|
||||
outputPumper.start();
|
||||
|
||||
errorPumper.start();
|
||||
|
||||
try
|
||||
{
|
||||
int returnValue = p.waitFor();
|
||||
|
||||
if ( inputFeeder != null )
|
||||
{
|
||||
synchronized ( inputFeeder )
|
||||
{
|
||||
if ( !inputFeeder.isDone() )
|
||||
{
|
||||
inputFeeder.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( outputPumper != null)
|
||||
{
|
||||
synchronized ( outputPumper )
|
||||
{
|
||||
if ( !outputPumper.isDone() )
|
||||
{
|
||||
outputPumper.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( errorPumper != null )
|
||||
{
|
||||
synchronized ( errorPumper )
|
||||
{
|
||||
if ( !errorPumper.isDone() )
|
||||
{
|
||||
errorPumper.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
catch ( InterruptedException ex )
|
||||
{
|
||||
throw new CommandLineException( "Error while executing external command.", ex );
|
||||
}
|
||||
finally
|
||||
{
|
||||
if ( inputFeeder != null )
|
||||
{
|
||||
inputFeeder.close();
|
||||
}
|
||||
|
||||
outputPumper.close();
|
||||
|
||||
errorPumper.close();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,650 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/********************************************************************************
|
||||
* CruiseControl, a Continuous Integration Toolkit
|
||||
* Copyright (c) 2001-2003, ThoughtWorks, Inc.
|
||||
* 651 W Washington Ave. Suite 500
|
||||
* Chicago, IL 60661 USA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* + Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* + Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
********************************************************************************/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2003-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import 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>
|
||||
* <someelement><br>
|
||||
* <acommandline executable="/executable/to/run"><br>
|
||||
* <argument value="argument 1" /><br>
|
||||
* <argument line="argument_1 argument_2 argument_3" /><br>
|
||||
* <argument value="argument 4" /><br>
|
||||
* </acommandline><br>
|
||||
* </someelement><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();
|
||||
protected String executable = null;
|
||||
protected 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 <execon> and <transform> - 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 CommandLineException if the argument contains both, single
|
||||
* and double quotes.
|
||||
*/
|
||||
public static String quoteArgument( String argument ) throws CommandLineException
|
||||
{
|
||||
if ( argument.indexOf( "\"" ) > -1 )
|
||||
{
|
||||
if ( argument.indexOf( "\'" ) > -1 )
|
||||
{
|
||||
throw new CommandLineException( "Can't handle single and double quotes in same argument" );
|
||||
}
|
||||
else
|
||||
{
|
||||
return '\'' + argument + '\'';
|
||||
}
|
||||
}
|
||||
else if ( argument.indexOf( "\'" ) > -1 || argument.indexOf( " " ) > -1 )
|
||||
{
|
||||
return '\"' + argument + '\"';
|
||||
}
|
||||
else
|
||||
{
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
|
||||
public static String toString( String[] line )
|
||||
{
|
||||
// empty path return empty string
|
||||
if ( line == null || line.length == 0 )
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// path containing one or more elements
|
||||
final StringBuffer result = new StringBuffer();
|
||||
for ( int i = 0; i < line.length; i++ )
|
||||
{
|
||||
if ( i > 0 )
|
||||
{
|
||||
result.append( ' ' );
|
||||
}
|
||||
try
|
||||
{
|
||||
result.append( quoteArgument( line[i] ) );
|
||||
}
|
||||
catch ( Exception e )
|
||||
{
|
||||
System.err.println( "Error quoting argument." );
|
||||
}
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String[] translateCommandline( String toProcess ) throws Exception
|
||||
{
|
||||
if ( toProcess == null || toProcess.length() == 0 )
|
||||
{
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
// parse with a simple finite state machine
|
||||
|
||||
final int normal = 0;
|
||||
final int inQuote = 1;
|
||||
final int inDoubleQuote = 2;
|
||||
int state = normal;
|
||||
StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true );
|
||||
Vector v = new Vector();
|
||||
StringBuffer current = new StringBuffer();
|
||||
|
||||
while ( tok.hasMoreTokens() )
|
||||
{
|
||||
String nextTok = tok.nextToken();
|
||||
switch ( state )
|
||||
{
|
||||
case inQuote:
|
||||
if ( "\'".equals( nextTok ) )
|
||||
{
|
||||
state = normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
current.append( nextTok );
|
||||
}
|
||||
break;
|
||||
case inDoubleQuote:
|
||||
if ( "\"".equals( nextTok ) )
|
||||
{
|
||||
state = normal;
|
||||
}
|
||||
else
|
||||
{
|
||||
current.append( nextTok );
|
||||
}
|
||||
break;
|
||||
default :
|
||||
if ( "\'".equals( nextTok ) )
|
||||
{
|
||||
state = inQuote;
|
||||
}
|
||||
else if ( "\"".equals( nextTok ) )
|
||||
{
|
||||
state = inDoubleQuote;
|
||||
}
|
||||
else if ( " ".equals( nextTok ) )
|
||||
{
|
||||
if ( current.length() != 0 )
|
||||
{
|
||||
v.addElement( current.toString() );
|
||||
current.setLength( 0 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
current.append( nextTok );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( current.length() != 0 )
|
||||
{
|
||||
v.addElement( current.toString() );
|
||||
}
|
||||
|
||||
if ( state == inQuote || state == inDoubleQuote )
|
||||
{
|
||||
throw new CommandLineException( "unbalanced quotes in " + toProcess );
|
||||
}
|
||||
|
||||
String[] args = new String[v.size()];
|
||||
v.copyInto( args );
|
||||
return args;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return getCommandline().length;
|
||||
}
|
||||
|
||||
public Object clone()
|
||||
{
|
||||
Commandline c = new Commandline();
|
||||
c.setExecutable( executable );
|
||||
c.addArguments( getArguments() );
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the whole command line. */
|
||||
public void clear()
|
||||
{
|
||||
executable = null;
|
||||
arguments.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear out the arguments but leave the executable in place for another operation.
|
||||
*/
|
||||
public void clearArgs()
|
||||
{
|
||||
arguments.removeAllElements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a marker.
|
||||
*
|
||||
* <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 CommandLineException
|
||||
{
|
||||
Process process = null;
|
||||
|
||||
try
|
||||
{
|
||||
if ( workingDir == null )
|
||||
{
|
||||
process = Runtime.getRuntime().exec( getShellCommandline() );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !workingDir.exists() )
|
||||
{
|
||||
throw new CommandLineException( "Working directory \"" + workingDir.getPath() + "\" does not exist!" );
|
||||
}
|
||||
else if ( !workingDir.isDirectory() )
|
||||
{
|
||||
throw new CommandLineException( "Path \"" + workingDir.getPath() + "\" does not specify a directory." );
|
||||
}
|
||||
|
||||
process = Runtime.getRuntime().exec( getShellCommandline(), null, workingDir );
|
||||
}
|
||||
}
|
||||
catch( IOException ex )
|
||||
{
|
||||
throw new CommandLineException( "Error while executing process.", ex );
|
||||
}
|
||||
|
||||
return process;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2003-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class DefaultConsumer
|
||||
implements StreamConsumer
|
||||
{
|
||||
public void consumeLine(String line)
|
||||
{
|
||||
System.out.println(line);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2003-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* The java.util.StringTokenizer is horribly broken.
|
||||
* Given the string 1,,,3,,4 (, delim)
|
||||
* It will return 1,3,4
|
||||
* Which is clearly wrong - 1,EMPTY,EMPTY,3,EMPTY,4 is what it should return
|
||||
*/
|
||||
public final class EnhancedStringTokenizer
|
||||
{
|
||||
private StringTokenizer cst = null;
|
||||
String cdelim;
|
||||
final boolean cdelimSingleChar;
|
||||
final char cdelimChar;
|
||||
boolean creturnDelims;
|
||||
String lastToken = null;
|
||||
boolean delimLast = true;
|
||||
|
||||
public EnhancedStringTokenizer(String str)
|
||||
{
|
||||
this(str, " \t\n\r\f", false);
|
||||
}
|
||||
|
||||
public EnhancedStringTokenizer(String str, String delim)
|
||||
{
|
||||
this(str, delim, false);
|
||||
}
|
||||
|
||||
public EnhancedStringTokenizer(String str, String delim, boolean returnDelims)
|
||||
{
|
||||
cst = new StringTokenizer(str, delim, true);
|
||||
cdelim = delim;
|
||||
creturnDelims = returnDelims;
|
||||
cdelimSingleChar = (delim.length() == 1);
|
||||
cdelimChar = delim.charAt(0);
|
||||
}
|
||||
|
||||
public boolean hasMoreTokens()
|
||||
{
|
||||
return cst.hasMoreTokens();
|
||||
}
|
||||
|
||||
private String internalNextToken()
|
||||
{
|
||||
if (lastToken != null)
|
||||
{
|
||||
String last = lastToken;
|
||||
lastToken = null;
|
||||
return last;
|
||||
}
|
||||
|
||||
String token = cst.nextToken();
|
||||
if (isDelim(token))
|
||||
{
|
||||
if (delimLast)
|
||||
{
|
||||
lastToken = token;
|
||||
return "";
|
||||
}
|
||||
else
|
||||
{
|
||||
delimLast = true;
|
||||
return token;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
delimLast = false;
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
public String nextToken()
|
||||
{
|
||||
String token = internalNextToken();
|
||||
if (creturnDelims)
|
||||
return token;
|
||||
if (isDelim(token))
|
||||
return hasMoreTokens() ? internalNextToken() : "";
|
||||
else
|
||||
return token;
|
||||
}
|
||||
|
||||
private boolean isDelim(String str)
|
||||
{
|
||||
if (str.length() == 1)
|
||||
{
|
||||
char ch = str.charAt(0);
|
||||
if (cdelimSingleChar)
|
||||
{
|
||||
if (cdelimChar == ch)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cdelim.indexOf(ch) >= 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/********************************************************************************
|
||||
* CruiseControl, a Continuous Integration Toolkit
|
||||
* Copyright (c) 2003, ThoughtWorks, Inc.
|
||||
* 651 W Washington Ave. Suite 500
|
||||
* Chicago, IL 60661 USA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* + Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* + Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
********************************************************************************/
|
||||
|
||||
/**
|
||||
* Works in concert with the StreamPumper class to
|
||||
* allow implementations to gain access to the lines being
|
||||
* "Pumped".
|
||||
*
|
||||
* @author <a href="mailto:fvancea@maxiq.com">Florin Vancea</a>
|
||||
* @author <a href="mailto:pj@thoughtworks.com">Paul Julius</a>
|
||||
*/
|
||||
public interface StreamConsumer
|
||||
{
|
||||
/**
|
||||
* Called when the StreamPumper pumps a line from the Stream.
|
||||
*/
|
||||
public void consumeLine( String line );
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:trygvis@inamo.no">Trygve Laugstøl</a>
|
||||
* @version $Id$
|
||||
*/
|
||||
public class StreamFeeder
|
||||
extends Thread
|
||||
{
|
||||
private InputStream input;
|
||||
|
||||
private OutputStream output;
|
||||
|
||||
private boolean done;
|
||||
|
||||
public StreamFeeder( InputStream input, OutputStream output )
|
||||
{
|
||||
this.input = input;
|
||||
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Runnable implementation
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
feed();
|
||||
}
|
||||
catch ( Throwable ex )
|
||||
{
|
||||
// Catched everything so the streams will be closed and flagged as done.
|
||||
}
|
||||
finally
|
||||
{
|
||||
close();
|
||||
|
||||
done = true;
|
||||
|
||||
synchronized ( this )
|
||||
{
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
public void close()
|
||||
{
|
||||
if ( input != null )
|
||||
{
|
||||
synchronized ( input )
|
||||
{
|
||||
try
|
||||
{
|
||||
input.close();
|
||||
}
|
||||
catch ( IOException ex )
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
input = null;
|
||||
}
|
||||
}
|
||||
|
||||
if ( output != null )
|
||||
{
|
||||
synchronized ( output )
|
||||
{
|
||||
try
|
||||
{
|
||||
output.close();
|
||||
}
|
||||
catch ( IOException ex )
|
||||
{
|
||||
// ignore
|
||||
}
|
||||
|
||||
output = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
return done;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
//
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
private void feed()
|
||||
throws IOException
|
||||
{
|
||||
int data = input.read();
|
||||
|
||||
while ( !done && data != -1 )
|
||||
{
|
||||
synchronized ( output )
|
||||
{
|
||||
output.write( data );
|
||||
|
||||
data = input.read();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,225 @@
|
|||
package org.apache.maven.it.cli;
|
||||
|
||||
/*
|
||||
* The MIT License
|
||||
*
|
||||
* Copyright (c) 2004, The Codehaus
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
* of the Software, and to permit persons to whom the Software is furnished to do
|
||||
* so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/********************************************************************************
|
||||
* CruiseControl, a Continuous Integration Toolkit
|
||||
* Copyright (c) 2001-2003, ThoughtWorks, Inc.
|
||||
* 651 W Washington Ave. Suite 500
|
||||
* Chicago, IL 60661 USA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* + Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* + Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
*
|
||||
* + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
|
||||
* names of its contributors may be used to endorse or promote
|
||||
* products derived from this software without specific prior
|
||||
* written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
********************************************************************************/
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright 2003-2004 The Apache Software Foundation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* ====================================================================
|
||||
*/
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* Class to pump the error stream during Process's runtime. Copied from the Ant
|
||||
* built-in task.
|
||||
*
|
||||
* @author <a href="mailto:fvancea@maxiq.com">Florin Vancea </a>
|
||||
* @author <a href="mailto:pj@thoughtworks.com">Paul Julius </a>
|
||||
* @since June 11, 2001
|
||||
*/
|
||||
public class StreamPumper
|
||||
extends Thread
|
||||
{
|
||||
private BufferedReader in;
|
||||
|
||||
private StreamConsumer consumer = null;
|
||||
|
||||
private PrintWriter out = null;
|
||||
|
||||
private static final int SIZE = 1024;
|
||||
|
||||
boolean done;
|
||||
|
||||
public StreamPumper( InputStream in )
|
||||
{
|
||||
this.in = new BufferedReader( new InputStreamReader( in ), SIZE );
|
||||
}
|
||||
|
||||
public StreamPumper( InputStream in, StreamConsumer consumer )
|
||||
{
|
||||
this( in );
|
||||
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public StreamPumper( InputStream in, PrintWriter writer )
|
||||
{
|
||||
this( in );
|
||||
|
||||
out = writer;
|
||||
}
|
||||
|
||||
public StreamPumper( InputStream in, PrintWriter writer, StreamConsumer consumer )
|
||||
{
|
||||
this( in );
|
||||
this.out = writer;
|
||||
this.consumer = consumer;
|
||||
}
|
||||
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
String s = in.readLine();
|
||||
|
||||
while ( s != null )
|
||||
{
|
||||
consumeLine( s );
|
||||
|
||||
if ( out != null )
|
||||
{
|
||||
out.println( s );
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
s = in.readLine();
|
||||
}
|
||||
}
|
||||
catch ( Throwable e )
|
||||
{
|
||||
// Catched everything so the streams will be closed and flagged as done.
|
||||
}
|
||||
finally
|
||||
{
|
||||
closeInputStream( in );
|
||||
|
||||
done = true;
|
||||
|
||||
synchronized ( this )
|
||||
{
|
||||
this.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void flush()
|
||||
{
|
||||
if ( out != null )
|
||||
{
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
closeOutputStream( out );
|
||||
}
|
||||
|
||||
protected void closeInputStream( Reader in )
|
||||
{
|
||||
if ( in == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
in.close();
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
protected void closeOutputStream( PrintWriter out )
|
||||
{
|
||||
if ( out == null )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
out.close();
|
||||
}
|
||||
|
||||
|
||||
public boolean isDone()
|
||||
{
|
||||
return done;
|
||||
}
|
||||
|
||||
private void consumeLine( String line )
|
||||
{
|
||||
if ( consumer != null )
|
||||
{
|
||||
consumer.consumeLine( line );
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue