org.codehaus.mojo.exec.AbstractExecMojo Maven / Gradle / Ivy
package org.codehaus.mojo.exec;
/*
* Copyright 2006 The Codehaus.
*
* 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.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
/**
* This class is used for unifying functionality between the 2 mojo exec plugins ('java' and 'exec').
* It handles parsing the arguments and adding source/test folders.
*
* @author Philippe Jacot (PJA)
* @author Jerome Lacoste
*/
public abstract class AbstractExecMojo extends AbstractMojo
{
/**
* The enclosing project.
*
* @parameter expression="${project}"
* @required
* @readonly
*/
protected MavenProject project;
/**
* This folder is added to the list of those folders
* containing source to be compiled. Use this if your
* plugin generates source code.
*
* @parameter expression="${sourceRoot}"
*/
private File sourceRoot;
/**
* This folder is added to the list of those folders
* containing source to be compiled for testing. Use this if your
* plugin generates test source code.
*
* @parameter expression="${testSourceRoot}"
*/
private File testSourceRoot;
/**
* Arguments for the executed program
*
* @parameter expression="${exec.args}"
*/
private String commandlineArgs;
/**
* Defines the scope of the classpath passed to the plugin. Set to compile,test,runtime or system depending
* on your needs.
* @parameter expression="${exec.classpathScope}" default-value="compile"
*/
protected String classpathScope;
/** @see #parseCommandlineArgs */
private static final char PARAMETER_DELIMITER = ' ';
/** @see #parseCommandlineArgs */
private static final char STRING_WRAPPER = '"';
/** @see #parseCommandlineArgs */
private static final char ESCAPE_CHAR = '\\';
/**
* Collects the project artifacts in the specified List and the project specific classpath
* (build output and build test output) Files in the specified List, depending on the plugin classpathScope value.
* @param artifacts the list where to collect the scope specific artifacts
* @param theClasspathFiles the list where to collect the scope specific output directories
* @throws NullPointerException if at least one of the parameter is null
*/
protected void collectProjectArtifactsAndClasspath( List artifacts, List theClasspathFiles )
{
if ( "compile".equals( classpathScope ) )
{
artifacts.addAll( project.getCompileArtifacts() );
theClasspathFiles.add( new File( project.getBuild().getOutputDirectory() ) );
}
else if ( "test".equals( classpathScope ) )
{
artifacts.addAll( project.getTestArtifacts() );
theClasspathFiles.add( new File( project.getBuild().getTestOutputDirectory() ) );
theClasspathFiles.add( new File( project.getBuild().getOutputDirectory() ) );
}
else if ( "runtime".equals( classpathScope ) )
{
artifacts.addAll( project.getRuntimeArtifacts() );
}
else if ( "system".equals( classpathScope ) )
{
artifacts.addAll( project.getSystemArtifacts() );
}
else
{
throw new IllegalStateException( "Invalid classpath scope: " + classpathScope );
}
getLog().debug( "Collected project artifacts " + artifacts );
getLog().debug( "Collected project classpath " + theClasspathFiles );
}
/**
* Parses the argument string given by the user. Strings are recognized as everything between STRING_WRAPPER.
* PARAMETER_DELIMITER is ignored inside a string. STRING_WRAPPER and PARAMETER_DELIMITER can be escaped using
* ESCAPE_CHAR.
*
* @return Array of String representing the arguments
* @throws MojoExecutionException
* for wrong formatted arguments
*/
protected String[] parseCommandlineArgs() throws MojoExecutionException
{
if ( commandlineArgs == null )
{
return null;
}
boolean inString = false;
String arguments = commandlineArgs.trim();
List argumentList = new LinkedList();
int chr = 0;
char curChar;
StringBuffer arg = new StringBuffer();
while ( chr < arguments.length() )
{
curChar = arguments.charAt( chr );
if ( curChar == ESCAPE_CHAR )
{
// A char is escaped, replace and skip one char
if ( arguments.length() == chr + 1 )
{
// ESCAPE_CHAR is the last character... this should be an error (?)
// char is just ignored by now
getLog().warn( ESCAPE_CHAR
+ " was the last character in your command line arguments. Verify your parameters." );
}
else
{
// In a string only STRING_WRAPPER is escaped
if ( !inString || arguments.charAt( chr + 1 ) == STRING_WRAPPER )
{
chr++;
}
arg.append( arguments.charAt( chr ) );
}
}
else if ( curChar == PARAMETER_DELIMITER && !inString )
{
// Next parameter begins here
argumentList.add( arg.toString() );
arg.delete( 0, arg.length() );
}
else if ( curChar == STRING_WRAPPER )
{
// Entering or leaving a string
inString = !inString;
}
else
{
// Append this char to the current parameter
arg.append( curChar );
}
chr++;
}
if ( inString )
{
// Error string not terminated
throw new MojoExecutionException( "args contains not properly formatted string" );
}
else
{
// Append last parameter
argumentList.add( arg.toString() );
}
Iterator it = argumentList.listIterator();
String[] result = new String[argumentList.size()];
int index = 0;
while ( it.hasNext() )
{
result[index] = (String) it.next();
index++;
}
getLog().debug( "Args:" );
it = argumentList.listIterator();
while ( it.hasNext() )
{
getLog().debug( " <" + (String) it.next() + ">" );
}
getLog().debug( " parsed from <" + commandlineArgs + ">" );
return result;
}
/**
* @return true of the mojo has command line arguments
*/
protected boolean hasCommandlineArgs()
{
return ( commandlineArgs != null );
}
/**
* Register compile and compile tests source roots if necessary
*/
protected void registerSourceRoots()
{
if ( sourceRoot != null )
{
getLog().info( "Registering compile source root " + sourceRoot );
project.addCompileSourceRoot( sourceRoot.toString() );
}
if ( testSourceRoot != null )
{
getLog().info( "Registering compile test source root " + testSourceRoot );
project.addTestCompileSourceRoot( testSourceRoot.toString() );
}
}
}