PR: MNG-817

add goal="..." to @execute

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@292125 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-09-28 05:09:14 +00:00
parent 86d1a481f5
commit ddfcc65d55
11 changed files with 657 additions and 360 deletions

View File

@ -0,0 +1,54 @@
package org.apache.maven.plugin.coreit;
/*
* 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 org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
/**
* @goal fork-goal
*
* @execute goal="touch"
*/
public class CoreItGoalForkerMojo
extends AbstractMojo
{
/**
* @parameter expression="${project}"
*/
private MavenProject project;
/**
* @parameter expression="${executedProject}"
*/
private MavenProject executedProject;
public void execute()
throws MojoExecutionException
{
if ( !executedProject.getBuild().getFinalName().equals( "coreitified" ) )
{
throw new MojoExecutionException( "Unexpected result, final name of executed project is " + executedProject.getBuild().getFinalName() );
}
if ( project.getBuild().getFinalName().equals( "coreitified" ) )
{
throw new MojoExecutionException( "forked project was polluted" );
}
}
}

View File

@ -487,7 +487,7 @@ public class DefaultLifecycleExecutor
MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor();
if ( mojoDescriptor.getExecutePhase() != null ) if ( mojoDescriptor.getExecutePhase() != null || mojoDescriptor.getExecuteGoal() != null )
{ {
forkLifecycle( mojoDescriptor, session, project ); forkLifecycle( mojoDescriptor, session, project );
} }
@ -661,73 +661,83 @@ public class DefaultLifecycleExecutor
String targetPhase = mojoDescriptor.getExecutePhase(); String targetPhase = mojoDescriptor.getExecutePhase();
// Create new lifecycle Map lifecycleMappings = null;
Map lifecycleMappings = constructLifecycleMappings( session, targetPhase, project ); if ( targetPhase != null )
String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
if ( executeLifecycle != null )
{ {
Lifecycle lifecycleOverlay; // Create new lifecycle
try lifecycleMappings = constructLifecycleMappings( session, targetPhase, project );
{
lifecycleOverlay = mojoDescriptor.getPluginDescriptor().getLifecycleMapping( executeLifecycle );
}
catch ( IOException e )
{
throw new LifecycleExecutionException( "Unable to read lifecycle mapping file", e );
}
catch ( XmlPullParserException e )
{
throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file", e );
}
if ( lifecycleOverlay == null ) String executeLifecycle = mojoDescriptor.getExecuteLifecycle();
if ( executeLifecycle != null )
{ {
throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" ); Lifecycle lifecycleOverlay;
} try
for ( Iterator i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
{
Phase phase = (Phase) i.next();
for ( Iterator j = phase.getExecutions().iterator(); j.hasNext(); )
{ {
Execution e = (Execution) j.next(); lifecycleOverlay = mojoDescriptor.getPluginDescriptor().getLifecycleMapping( executeLifecycle );
}
catch ( IOException e )
{
throw new LifecycleExecutionException( "Unable to read lifecycle mapping file", e );
}
catch ( XmlPullParserException e )
{
throw new LifecycleExecutionException( "Unable to parse lifecycle mapping file", e );
}
for ( Iterator k = e.getGoals().iterator(); k.hasNext(); ) if ( lifecycleOverlay == null )
{
throw new LifecycleExecutionException( "Lifecycle '" + executeLifecycle + "' not found in plugin" );
}
for ( Iterator i = lifecycleOverlay.getPhases().iterator(); i.hasNext(); )
{
Phase phase = (Phase) i.next();
for ( Iterator j = phase.getExecutions().iterator(); j.hasNext(); )
{ {
String goal = (String) k.next(); Execution e = (Execution) j.next();
MojoDescriptor desc = mojoDescriptor.getPluginDescriptor().getMojo( goal );
if ( desc == null ) for ( Iterator k = e.getGoals().iterator(); k.hasNext(); )
{ {
String message = "Required goal '" + goal + "' not found in plugin '" + String goal = (String) k.next();
mojoDescriptor.getPluginDescriptor().getGoalPrefix() + "'"; MojoDescriptor desc = mojoDescriptor.getPluginDescriptor().getMojo( goal );
int index = goal.indexOf( ':' );
if ( index >= 0 )
{
String prefix = goal.substring( index + 1 );
if ( prefix.equals( mojoDescriptor.getPluginDescriptor().getGoalPrefix() ) )
{
message = message + " (goals should not be prefixed - try '" + prefix + "')";
}
}
throw new LifecycleExecutionException( message );
}
MojoExecution mojoExecution = new MojoExecution( desc, (Xpp3Dom) e.getConfiguration() ); if ( desc == null )
addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution, {
session.getSettings() ); String message = "Required goal '" + goal + "' not found in plugin '" +
mojoDescriptor.getPluginDescriptor().getGoalPrefix() + "'";
int index = goal.indexOf( ':' );
if ( index >= 0 )
{
String prefix = goal.substring( index + 1 );
if ( prefix.equals( mojoDescriptor.getPluginDescriptor().getGoalPrefix() ) )
{
message = message + " (goals should not be prefixed - try '" + prefix + "')";
}
}
throw new LifecycleExecutionException( message );
}
MojoExecution mojoExecution = new MojoExecution( desc, (Xpp3Dom) e.getConfiguration() );
addToLifecycleMappings( lifecycleMappings, phase.getId(), mojoExecution,
session.getSettings() );
}
} }
} }
} }
removeFromLifecycle( mojoDescriptor, lifecycleMappings );
} }
removeFromLifecycle( mojoDescriptor, lifecycleMappings );
MavenProject executionProject = new MavenProject( project ); MavenProject executionProject = new MavenProject( project );
executeGoalWithLifecycle( targetPhase, session, lifecycleMappings, executionProject ); if ( targetPhase != null )
{
executeGoalWithLifecycle( targetPhase, session, lifecycleMappings, executionProject );
}
else
{
executeStandaloneGoal( mojoDescriptor.getExecuteGoal(), session, executionProject );
}
project.setExecutionProject( executionProject ); project.setExecutionProject( executionProject );
} }
private void removeFromLifecycle( MojoDescriptor mojoDescriptor, Map lifecycleMappings ) private void removeFromLifecycle( MojoDescriptor mojoDescriptor, Map lifecycleMappings )

View File

@ -58,6 +58,8 @@ public class MojoDescriptor
private String executePhase; private String executePhase;
private String executeGoal;
private String executeLifecycle; private String executeLifecycle;
private String deprecated; private String deprecated;
@ -425,4 +427,14 @@ public class MojoDescriptor
{ {
this.requiresReports = requiresReports; this.requiresReports = requiresReports;
} }
public void setExecuteGoal( String executeGoal )
{
this.executeGoal = executeGoal;
}
public String getExecuteGoal()
{
return executeGoal;
}
} }

View File

@ -142,6 +142,13 @@ public class PluginDescriptorBuilder
mojo.setExecutePhase( executePhase ); mojo.setExecutePhase( executePhase );
} }
String executeMojo = c.getChild( "executeGoal" ).getValue();
if ( executeMojo != null )
{
mojo.setExecuteGoal( executeMojo );
}
String executeLifecycle = c.getChild( "executeLifecycle" ).getValue(); String executeLifecycle = c.getChild( "executeLifecycle" ).getValue();
if ( executeLifecycle != null ) if ( executeLifecycle != null )

View File

@ -177,6 +177,11 @@ public class PluginDescriptorGenerator
element( w, "executePhase", mojoDescriptor.getExecutePhase() ); element( w, "executePhase", mojoDescriptor.getExecutePhase() );
} }
if ( mojoDescriptor.getExecuteGoal() != null )
{
element( w, "executeGoal", mojoDescriptor.getExecuteGoal() );
}
if ( mojoDescriptor.getExecuteLifecycle() != null ) if ( mojoDescriptor.getExecuteLifecycle() != null )
{ {
element( w, "executeLifecycle", mojoDescriptor.getExecuteLifecycle() ); element( w, "executeLifecycle", mojoDescriptor.getExecuteLifecycle() );

View File

@ -15,6 +15,7 @@ this.descriptionPattern = Pattern.compile( "(?s)\\r?\\n\\s*\\*" );
this.typePattern = Pattern.compile( "type\\s*=\\s*\"(.*?)\"" ); this.typePattern = Pattern.compile( "type\\s*=\\s*\"(.*?)\"" );
this.expressionPattern = Pattern.compile( "expression\\s*=\\s*\"(.*?)\"" ); this.expressionPattern = Pattern.compile( "expression\\s*=\\s*\"(.*?)\"" );
this.phasePattern = Pattern.compile( "phase\\s*=\\s*\"(.*?)\"" ); this.phasePattern = Pattern.compile( "phase\\s*=\\s*\"(.*?)\"" );
this.goalPattern = Pattern.compile( "goal\\s*=\\s*\"(.*?)\"" );
this.lifecyclePattern = Pattern.compile( "lifecycle\\s*=\\s*\"(.*?)\"" ); this.lifecyclePattern = Pattern.compile( "lifecycle\\s*=\\s*\"(.*?)\"" );
this.rolePattern = Pattern.compile( "role\\s*=\\s*\"(.*?)\"" ); this.rolePattern = Pattern.compile( "role\\s*=\\s*\"(.*?)\"" );
this.roleHintPattern = Pattern.compile( "roleHint\\s*=\\s*\"(.*?)\"" ); this.roleHintPattern = Pattern.compile( "roleHint\\s*=\\s*\"(.*?)\"" );
@ -182,15 +183,31 @@ extract( file, mojoDescriptor )
{ {
mojoDescriptor.setExecutePhase( m.group( 1 ) ); mojoDescriptor.setExecutePhase( m.group( 1 ) );
} }
else
m = goalPattern.matcher( value );
if ( m.find() )
{ {
throw new InvalidPluginDescriptorException( "@execute must have a phase" ); mojoDescriptor.setExecuteGoal( m.group( 1 ) );
}
if ( mojoDescriptor.getExecutePhase() == null || mojoDescriptor.getExecuteGoal() == null )
{
throw new InvalidPluginDescriptorException( "@execute must have a phase or goal" );
}
if ( mojoDescriptor.getExecutePhase() != null && mojoDescriptor.getExecuteGoal() != null )
{
throw new InvalidPluginDescriptorException( "@execute must have only one of a phase or goal" );
} }
m = lifecyclePattern.matcher( value ); m = lifecyclePattern.matcher( value );
if ( m.find() ) if ( m.find() )
{ {
mojoDescriptor.setExecuteLifecycle( m.group( 1 ) ); mojoDescriptor.setExecuteLifecycle( m.group( 1 ) );
if ( mojoDescriptor.getExecuteGoal() != null )
{
throw new InvalidPluginDescriptorException( "@execute lifecycle requires a phase instead of a goal" );
}
} }
} }
} }

View File

@ -217,18 +217,30 @@ public class JavaMojoDescriptorExtractor
if ( execute != null ) if ( execute != null )
{ {
String executePhase = execute.getNamedParameter( "phase" ); String executePhase = execute.getNamedParameter( "phase" );
String executeGoal = execute.getNamedParameter( "goal" );
if ( executePhase == null ) if ( executePhase == null && executeGoal == null )
{ {
throw new InvalidPluginDescriptorException( "@execute tag requires a 'phase' parameter" ); throw new InvalidPluginDescriptorException( "@execute tag requires a 'phase' or 'goal' parameter" );
}
else if ( executePhase != null && executeGoal != null )
{
throw new InvalidPluginDescriptorException(
"@execute tag can have only one of a 'phase' or 'goal' parameter" );
} }
mojoDescriptor.setExecutePhase( executePhase ); mojoDescriptor.setExecutePhase( executePhase );
mojoDescriptor.setExecuteGoal( executeGoal );
String lifecycle = execute.getNamedParameter( "lifecycle" ); String lifecycle = execute.getNamedParameter( "lifecycle" );
if ( lifecycle != null ) if ( lifecycle != null )
{ {
mojoDescriptor.setExecuteLifecycle( lifecycle ); mojoDescriptor.setExecuteLifecycle( lifecycle );
if ( mojoDescriptor.getExecuteGoal() != null )
{
throw new InvalidPluginDescriptorException(
"@execute lifecycle requires a phase instead of a goal" );
}
} }
} }

View File

@ -29,18 +29,18 @@
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-tools-api</artifactId> <artifactId>maven-plugin-tools-api</artifactId>
<version>2.0-beta-2</version> <version>2.0-beta-3-SNAPSHOT</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-tools-java</artifactId> <artifactId>maven-plugin-tools-java</artifactId>
<version>2.0-beta-2</version> <version>2.0-beta-3-SNAPSHOT</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-tools-beanshell</artifactId> <artifactId>maven-plugin-tools-beanshell</artifactId>
<version>2.0-beta-2</version> <version>2.0-beta-3-SNAPSHOT</version>
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -48,11 +48,5 @@
<artifactId>maven-reporting-impl</artifactId> <artifactId>maven-reporting-impl</artifactId>
<version>2.0-beta-3-SNAPSHOT</version> <version>2.0-beta-3-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-tools-marmalade</artifactId>
<version>2.0-beta-2</version>
<scope>runtime</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -0,0 +1,35 @@
package org.apache.maven.script.marmalade.tags;
/*
* 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.codehaus.marmalade.runtime.MarmaladeExecutionException;
/**
* @author jdcasey Created on Feb 8, 2005
*/
public class ExecuteGoalTag
extends AbstractStringValuedBodyTag
{
protected void setValue( String value )
throws MarmaladeExecutionException
{
MetadataTag metadataTag = (MetadataTag) requireParent( MetadataTag.class );
metadataTag.setExecuteGoal( value );
}
}

View File

@ -59,6 +59,8 @@ public class MetadataTag
private String executePhase; private String executePhase;
private String executeGoal;
private String executeLifecycle; private String executeLifecycle;
private String lifecyclePhase; private String lifecyclePhase;
@ -121,6 +123,11 @@ public class MetadataTag
descriptor.setExecutePhase( executePhase ); descriptor.setExecutePhase( executePhase );
} }
if ( notEmpty( executeGoal ) )
{
descriptor.setExecutePhase( executeGoal );
}
if ( notEmpty( lifecyclePhase ) ) if ( notEmpty( lifecyclePhase ) )
{ {
descriptor.setPhase( lifecyclePhase ); descriptor.setPhase( lifecyclePhase );
@ -236,4 +243,9 @@ public class MetadataTag
{ {
this.requiresReports = requiresReports; this.requiresReports = requiresReports;
} }
public void setExecuteGoal( String executeGoal )
{
this.executeGoal = executeGoal;
}
} }

View File

@ -51,24 +51,33 @@
<p>While this will satisfy the requirements for execution as a Mojo <p>While this will satisfy the requirements for execution as a Mojo
inside Maven, it is recommended that Mojos implement inside Maven, it is recommended that Mojos implement
--> Basically, these Mojo requirements are embodied by the --> Basically, these Mojo requirements are embodied by the
<code>org.apache.maven.plugin.Mojo</code> interface, which the Mojo <code>org.apache.maven.plugin.Mojo</code>
interface, which the Mojo
must implement (or else extend its abstract base class counterpart must implement (or else extend its abstract base class counterpart
<code>org.apache.maven.plugin.AbstractMojo</code>). This interface <code>org.apache.maven.plugin.AbstractMojo</code>
). This interface
guarantees the correct execution contract for the mojo: no parameters, guarantees the correct execution contract for the mojo: no parameters,
void return type, and a throws clause that allows only void return type, and a throws clause that allows only
<code>org.apache.maven.plugin.MojoExecutionException</code> and its <code>org.apache.maven.plugin.MojoExecutionException</code>
and its
derivatives. It also guarantees that the Mojo will have access to the derivatives. It also guarantees that the Mojo will have access to the
standard Maven user-feedback mechanism, standard Maven user-feedback mechanism,
<code>org.apache.maven.monitor.logging.Log</code>, so the Mojo can <code>org.apache.maven.monitor.logging.Log</code>
, so the Mojo can
communicate important events to the console or other log sink.<!-- Using the communicate important events to the console or other log sink.<!-- Using the
Plugin/Mojo API will give that Mojo access to the Maven-integrated Log, Plugin/Mojo API will give that Mojo access to the Maven-integrated Log,
along with tighter integration into the Maven build. --></p> along with tighter integration into the Maven build. -->
</p>
<p>As mentioned before, each Plugin - or packaged set of Mojos - must <p>As mentioned before, each Plugin - or packaged set of Mojos - must
provide a descriptor called <code>plugin.xml</code> under the path provide a descriptor called
<code>META-INF/maven</code> inside the Plugin jar file. Fortunately, <code>plugin.xml</code>
under the path
<code>META-INF/maven</code>
inside the Plugin jar file. Fortunately,
Maven also provides a set of javadoc annotations and tools to generate Maven also provides a set of javadoc annotations and tools to generate
this descriptor, so developers don't have to worry about directly this descriptor, so developers don't have to worry about directly
authoring or maintaining a separate XML metadata file.</p> authoring or maintaining a separate XML metadata file.
</p>
<p>To serve as a quick reference for the developer, the rest of this page <p>To serve as a quick reference for the developer, the rest of this page
will document these features (the API, along with the annotations) will document these features (the API, along with the annotations)
which are considered the best practice for developing Mojos.</p> which are considered the best practice for developing Mojos.</p>
@ -76,14 +85,20 @@
<section name="API Documentation"> <section name="API Documentation">
<subsection name="org.apache.maven.plugin.Mojo"> <subsection name="org.apache.maven.plugin.Mojo">
<p>This interface forms the contract required for Mojos to interact <p>This interface forms the contract required for Mojos to interact
with the Maven infrastructure. It features an <code>execute()</code> with the Maven infrastructure. It features an
<code>execute()</code>
method, which trigger's the Mojo's build-process behavior, and can method, which trigger's the Mojo's build-process behavior, and can
throw a <code>MojoExecutionException</code> if an error condition throw a
<code>MojoExecutionException</code>
if an error condition
occurs. See below for a discussion on proper use of this occurs. See below for a discussion on proper use of this
<code>Exception</code> class. Also included is the <code>Exception</code>
<code>setLog(..)</code> method, which simply allows Maven to inject a class. Also included is the
<code>setLog(..)</code>
method, which simply allows Maven to inject a
logging mechanism which will allow the Mojo to communicate to the logging mechanism which will allow the Mojo to communicate to the
outside world through standard Maven channels.</p> outside world through standard Maven channels.
</p>
<p> <p>
<ul> <ul>
<lt> <lt>
@ -92,19 +107,24 @@
<li> <li>
<code> <code>
void setLog( org.apache.maven.monitor.logging.Log ) void setLog( org.apache.maven.monitor.logging.Log )
</code> </code>
<p>Inject a standard Maven logging mechanism to allow this Mojo <p>Inject a standard Maven logging mechanism to allow this Mojo
to communicate events and feedback to the user.</p> to communicate events and feedback to the user.</p>
</li> </li>
<li> <li>
<code> <code>
void execute() throws org.apache.maven.plugin.MojoExecutionException void execute() throws org.apache.maven.plugin.MojoExecutionException
</code> </code>
<p>Perform whatever build-process behavior this Mojo implements. <p>Perform whatever build-process behavior this Mojo implements.
This is the main trigger for the Mojo inside the Maven system, This is the main trigger for the Mojo inside the Maven system,
and allows the Mojo to communicate fatal errors by throwing an and allows the Mojo to communicate fatal errors by throwing an
instance of <code>MojoExecutionException</code>.</p> instance of
<p>The <code>MojoExecutionException</code> (and all error <code>MojoExecutionException</code>
.
</p>
<p>The
<code>MojoExecutionException</code>
(and all error
conditions inside the Mojo) should be handled very carefully. conditions inside the Mojo) should be handled very carefully.
The simple wrapping of lower-level exceptions without providing The simple wrapping of lower-level exceptions without providing
any indication of a user-friendly probable cause is strictly any indication of a user-friendly probable cause is strictly
@ -113,7 +133,9 @@
coherent step within the Mojo's execution. Developers are then coherent step within the Mojo's execution. Developers are then
in a much better position to diagnose the cause of any error, in a much better position to diagnose the cause of any error,
and provide user-friendly feedback in the message of the and provide user-friendly feedback in the message of the
<code>MojoExecutionException</code>.</p> <code>MojoExecutionException</code>
.
</p>
</li> </li>
</ul> </ul>
</p> </p>
@ -121,8 +143,13 @@
<subsection name="org.apache.maven.plugin.AbstractMojo"> <subsection name="org.apache.maven.plugin.AbstractMojo">
<p>Currently, this abstract base class simply takes care of managing <p>Currently, this abstract base class simply takes care of managing
the Maven log for concrete derivations. In keeping with this, it the Maven log for concrete derivations. In keeping with this, it
provides a <code>protected</code> method, <code>getLog():Log</code>, provides a
to furnish Log access to these concrete implementations.</p> <code>protected</code>
method,
<code>getLog():Log</code>
,
to furnish Log access to these concrete implementations.
</p>
<p> <p>
<ul> <ul>
<lt> <lt>
@ -131,7 +158,7 @@
<li> <li>
<code> <code>
public void setLog( org.apache.maven.monitor.logging.Log ) public void setLog( org.apache.maven.monitor.logging.Log )
</code> </code>
<p> <p>
<b>[IMPLEMENTED]</b> <b>[IMPLEMENTED]</b>
</p> </p>
@ -149,13 +176,16 @@
<li> <li>
<code> <code>
void execute() throws org.apache.maven.plugin.MojoExecutionException void execute() throws org.apache.maven.plugin.MojoExecutionException
</code> </code>
<p> <p>
<b>[ABSTRACT]</b> <b>[ABSTRACT]</b>
</p> </p>
<p>Perform whatever build-process behavior this Mojo implements. <p>Perform whatever build-process behavior this Mojo implements.
See the documentation for <code>Mojo</code> above for more See the documentation for
information.</p> <code>Mojo</code>
above for more
information.
</p>
</li> </li>
</ul> </ul>
</p> </p>
@ -164,87 +194,125 @@
<p>This interface supplies the API for providing feedback to the user <p>This interface supplies the API for providing feedback to the user
from the Mojo, using standard Maven channels. There should be no big from the Mojo, using standard Maven channels. There should be no big
surprises here, although you may notice that the methods accept surprises here, although you may notice that the methods accept
<code>java.lang.CharSequence</code> rather than <code>java.lang.CharSequence</code>
<code>java.lang.String</code>. This is provided mainly as a rather than
<code>java.lang.String</code>
. This is provided mainly as a
convenience, to enable developers to pass things like convenience, to enable developers to pass things like
<code>StringBuffer</code> directly into the logger, rather than <code>StringBuffer</code>
formatting first by calling <code>toString()</code>.</p> directly into the logger, rather than
formatting first by calling
<code>toString()</code>
.
</p>
<p> <p>
<ul> <ul>
<lt> <lt>
<b>Method Summary:</b> <b>Method Summary:</b>
</lt> </lt>
<li> <li>
<code> void debug( java.lang.CharSequence ) </code> <code>void debug( java.lang.CharSequence )</code>
<p>Send a message to the user in the <b>debug</b> error level.</p> <p>Send a message to the user in the
<b>debug</b>
error level.
</p>
</li> </li>
<li> <li>
<code> <code>
void debug( java.lang.CharSequence, java.lang.Throwable ) void debug( java.lang.CharSequence, java.lang.Throwable )
</code> </code>
<p>Send a message (and accompanying exception) to the user in the <p>Send a message (and accompanying exception) to the user in the
<b>debug</b> error level. The error's stacktrace will be output <b>debug</b>
when this error level is enabled.</p> error level. The error's stacktrace will be output
when this error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void debug( java.lang.Throwable ) </code> <code>void debug( java.lang.Throwable )</code>
<p>Send an exception to the user in the <b>debug</b> error level. <p>Send an exception to the user in the
<b>debug</b>
error level.
The stack trace for this exception will be output when this The stack trace for this exception will be output when this
error level is enabled.</p> error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void info( java.lang.CharSequence ) </code> <code>void info( java.lang.CharSequence )</code>
<p>Send a message to the user in the <b>info</b> error level.</p> <p>Send a message to the user in the
<b>info</b>
error level.
</p>
</li> </li>
<li> <li>
<code> <code>
void info( java.lang.CharSequence, java.lang.Throwable ) void info( java.lang.CharSequence, java.lang.Throwable )
</code> </code>
<p>Send a message (and accompanying exception) to the user in the <p>Send a message (and accompanying exception) to the user in the
<b>info</b> error level. The error's stacktrace will be output <b>info</b>
when this error level is enabled.</p> error level. The error's stacktrace will be output
when this error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void info( java.lang.CharSequence ) </code> <code>void info( java.lang.CharSequence )</code>
<p>Send an exception to the user in the <b>info</b> error level. <p>Send an exception to the user in the
<b>info</b>
error level.
The stack trace for this exception will be output when this The stack trace for this exception will be output when this
error level is enabled.</p> error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void warn( java.lang.CharSequence ) </code> <code>void warn( java.lang.CharSequence )</code>
<p>Send a message to the user in the <b>warn</b> error level.</p> <p>Send a message to the user in the
<b>warn</b>
error level.
</p>
</li> </li>
<li> <li>
<code> <code>
void warn( java.lang.CharSequence, java.lang.Throwable ) void warn( java.lang.CharSequence, java.lang.Throwable )
</code> </code>
<p>Send a message (and accompanying exception) to the user in the <p>Send a message (and accompanying exception) to the user in the
<b>warn</b> error level. The error's stacktrace will be output <b>warn</b>
when this error level is enabled.</p> error level. The error's stacktrace will be output
when this error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void warn( java.lang.CharSequence ) </code> <code>void warn( java.lang.CharSequence )</code>
<p>Send an exception to the user in the <b>warn</b> error level. <p>Send an exception to the user in the
<b>warn</b>
error level.
The stack trace for this exception will be output when this The stack trace for this exception will be output when this
error level is enabled.</p> error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void error( java.lang.CharSequence ) </code> <code>void error( java.lang.CharSequence )</code>
<p>Send a message to the user in the <b>error</b> error level.</p> <p>Send a message to the user in the
<b>error</b>
error level.
</p>
</li> </li>
<li> <li>
<code> <code>
void error( java.lang.CharSequence, java.lang.Throwable ) void error( java.lang.CharSequence, java.lang.Throwable )
</code> </code>
<p>Send a message (and accompanying exception) to the user in the <p>Send a message (and accompanying exception) to the user in the
<b>error</b> error level. The error's stacktrace will be output <b>error</b>
when this error level is enabled.</p> error level. The error's stacktrace will be output
when this error level is enabled.
</p>
</li> </li>
<li> <li>
<code> void error( java.lang.CharSequence ) </code> <code>void error( java.lang.CharSequence )</code>
<p>Send an exception to the user in the <b>error</b> error level. <p>Send an exception to the user in the
<b>error</b>
error level.
The stack trace for this exception will be output when this The stack trace for this exception will be output when this
error level is enabled.</p> error level is enabled.
</p>
</li> </li>
</ul> </ul>
</p> </p>
@ -264,11 +332,17 @@
element name along with a javadoc annotation (if applicable) supporting element name along with a javadoc annotation (if applicable) supporting
that piece of the plugin descriptor. A couple of examples are: that piece of the plugin descriptor. A couple of examples are:
<b>someElement <b>someElement
(@annotation parameterName="parameterValue")</b> or (@annotation parameterName="parameterValue")</b>
<b>someOtherElement (@annotation &lt;rawAnnotationValue&gt;)</b>.</p> or
<b>someOtherElement (@annotation &lt;rawAnnotationValue&gt;)</b>
.
</p>
<p>The plugin descriptor must be provided in a jar resource with the <p>The plugin descriptor must be provided in a jar resource with the
path: <code>META-INF/maven/plugin.xml</code>, and it must contain the path:
following:</p> <code>META-INF/maven/plugin.xml</code>
, and it must contain the
following:
</p>
<p> <p>
<table> <table>
<tr> <tr>
@ -280,21 +354,31 @@
<td>mojos</td> <td>mojos</td>
<td>Yes</td> <td>Yes</td>
<td>Descriptors for each Mojo provided by the plugin, each inside a <td>Descriptors for each Mojo provided by the plugin, each inside a
<b>mojo</b> sub-element. Mojo descriptors are covered in detail <b>mojo</b>
sub-element. Mojo descriptors are covered in detail
below. Obviously, a plugin without any declared mojos doesn't below. Obviously, a plugin without any declared mojos doesn't
make sense, so the <b>mojos</b> element is required, along with make sense, so the
at least one <b>mojo</b> sub-element.</td> <b>mojos</b>
element is required, along with
at least one
<b>mojo</b>
sub-element.
</td>
</tr> </tr>
<tr> <tr>
<td>dependencies</td> <td>dependencies</td>
<td>Yes</td> <td>Yes</td>
<td>A set of dependencies which the plugin requires in order to <td>A set of dependencies which the plugin requires in order to
function. Each dependency is provided inside a <b>dependency</b> function. Each dependency is provided inside a
<b>dependency</b>
sub-element. Dependency specifications are covered below. Since sub-element. Dependency specifications are covered below. Since
all plugins must have a dependency on all plugins must have a dependency on
<code>maven-plugin-api</code>, this element is effectively <code>maven-plugin-api</code>
required. <i>Using the plugin toolset, these dependencies can be , this element is effectively
extracted from the POM's dependencies.</i></td> required.
<i>Using the plugin toolset, these dependencies can be
extracted from the POM's dependencies.</i>
</td>
</tr> </tr>
</table> </table>
</p> </p>
@ -326,7 +410,9 @@
<tr> <tr>
<td>language</td> <td>language</td>
<td>none (detected)</td> <td>none (detected)</td>
<td>No. Default: <code>java</code></td> <td>No. Default:
<code>java</code>
</td>
<td>The implementation language for this Mojo (marmalade, java, <td>The implementation language for this Mojo (marmalade, java,
beanshell, etc.).</td> beanshell, etc.).</td>
</tr> </tr>
@ -339,26 +425,34 @@
Mojo's implementation language, but can be specified to Mojo's implementation language, but can be specified to
allow a custom ComponentConfigurator implementation to be used. allow a custom ComponentConfigurator implementation to be used.
<i>NOTE: This will only be used in very special <i>NOTE: This will only be used in very special
cases, using a highly controlled vocabulary of possible values. cases, using a highly controlled vocabulary of possible values.
(Elements like this are why it's a good idea to use the (Elements like this are why it's a good idea to use the
descriptor tools.)</i></td> descriptor tools.)</i>
</td>
</tr> </tr>
<tr> <tr>
<td>phase</td> <td>phase</td>
<td>@phase &lt;phaseName&gt;</td> <td>@phase &lt;phaseName&gt;</td>
<td>No</td> <td>No</td>
<td>Binds this Mojo to a particular phase of the standard build <td>Binds this Mojo to a particular phase of the standard build
lifecycle, if specified. <i>NOTE: This is only required if this lifecycle, if specified.
Mojo is to participate in the standard build process.</i></td> <i>NOTE: This is only required if this
Mojo is to participate in the standard build process.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>executePhase</td> <td>execute</td>
<td>@executePhase &lt;phaseName&gt;</td> <td>@execute [phase=&lt;phaseName&gt;|goal=&lt;goalName&gt;] [lifecycle=&lt;lifecycleId&gt;]</td>
<td>No</td> <td>No</td>
<td>When this Mojo's goal is invoked directly from the command <td>When this goal is invoked, it will first invoke a parallel lifecycle, ending at the given phase.
line, <b>executePhase</b> specifies the last phase in the If a goal is provided instead of a phase, that goal will be executed in isolation. The execution of either
standard build lifecycle to execute before this Mojo will not affect the current project, but instead make available the
executes.</td> <code>${executedProject}</code>
expression if required. An alternate lifecycle can also be provided: for more information see the
documentation on the
<a href="/lifecycle.html">build lifecycle</a>
.
</td>
</tr> </tr>
<tr> <tr>
<td>requiresDependencyResolution</td> <td>requiresDependencyResolution</td>
@ -366,26 +460,38 @@
<td>No</td> <td>No</td>
<td>Flags this Mojo as requiring the dependencies in the specified <td>Flags this Mojo as requiring the dependencies in the specified
scope (or an implied scope) to be resolved before it can execute. scope (or an implied scope) to be resolved before it can execute.
<i>NOTE: Currently supports <b>compile</b>, <i>NOTE: Currently supports
<b>runtime</b>, and <b>test</b> scopes.</i></td> <b>compile</b>
,
<b>runtime</b>
, and
<b>test</b>
scopes.
</i>
</td>
</tr> </tr>
<tr> <tr>
<td>description</td> <td>description</td>
<td>none (detected)</td> <td>none (detected)</td>
<td>No</td> <td>No</td>
<td>The description of this Mojo's functionality. <i>Using the <td>The description of this Mojo's functionality.
toolset, this will be the class-level javadoc description <i>Using the
provided. NOTE: While this is not a required part of the mojo toolset, this will be the class-level javadoc description
specification, it SHOULD be provided to enable future provided. NOTE: While this is not a required part of the mojo
tool support for browsing, etc. and for clarity.</i></td> specification, it SHOULD be provided to enable future
tool support for browsing, etc. and for clarity.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>parameters</td> <td>parameters</td>
<td>N/A</td> <td>N/A</td>
<td>No</td> <td>No</td>
<td>Specifications for the parameters which this Mojo uses will be <td>Specifications for the parameters which this Mojo uses will be
provided in <b>parameter</b> sub-elements in this section. provided in
<i>NOTE: Parameters are discussed in more detail below.</i></td> <b>parameter</b>
sub-elements in this section.
<i>NOTE: Parameters are discussed in more detail below.</i>
</td>
</tr> </tr>
</table> </table>
</p> </p>
@ -399,9 +505,11 @@
for that parameter. Duplicate annotation declarations in this section for that parameter. Duplicate annotation declarations in this section
will be used to detail each parameter of an annotation separately.</p> will be used to detail each parameter of an annotation separately.</p>
<p>NOTE[2]: In many cases, simply annotating a Mojo field with <p>NOTE[2]: In many cases, simply annotating a Mojo field with
<b>@parameter</b> will be enough to allow injection of a value for that <b>@parameter</b>
will be enough to allow injection of a value for that
parameter using POM configuration elements. The discussion below parameter using POM configuration elements. The discussion below
shows advanced usage for this annotation, along with others.</p> shows advanced usage for this annotation, along with others.
</p>
<p>Each parameter for a Mojo must be specified in the <p>Each parameter for a Mojo must be specified in the
plugin descriptor as follows:</p> plugin descriptor as follows:</p>
<p> <p>
@ -418,8 +526,10 @@
<td>Yes</td> <td>Yes</td>
<td>The name of the parameter, to be used in configuring this <td>The name of the parameter, to be used in configuring this
parameter from the Mojo's declared defaults (discussed below) or parameter from the Mojo's declared defaults (discussed below) or
from the POM. <i>Using the toolset, this is detected as the from the POM.
java field name.</i></td> <i>Using the toolset, this is detected as the
java field name.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>alias</td> <td>alias</td>
@ -437,9 +547,11 @@
<td>Yes</td> <td>Yes</td>
<td>The java type for this parameter. This is used to validate the <td>The java type for this parameter. This is used to validate the
result of any expressions used to calculate the value which result of any expressions used to calculate the value which
should be injected into the Mojo for this parameter. <i>Using the should be injected into the Mojo for this parameter.
toolset, this is detected as the class of the java field <i>Using the
corresponding to this parameter.</i></td> toolset, this is detected as the class of the java field
corresponding to this parameter.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>required</td> <td>required</td>
@ -448,8 +560,10 @@
<td>Whether this parameter is required for the Mojo to function. <td>Whether this parameter is required for the Mojo to function.
This is used to validate the configuration for a Mojo before it This is used to validate the configuration for a Mojo before it
is injected, and before the Mojo is executed from some is injected, and before the Mojo is executed from some
half-state. <i>NOTE: Specification of this annotation flags half-state.
the parameter as required; there is no true/false value.</i></td> <i>NOTE: Specification of this annotation flags
the parameter as required; there is no true/false value.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>editable</td> <td>editable</td>
@ -465,9 +579,11 @@
specifying a value for finalName directly in the plugin specifying a value for finalName directly in the plugin
configuration section. It is also useful to ensure that - for configuration section. It is also useful to ensure that - for
example - a List-typed parameter which expects items of type example - a List-typed parameter which expects items of type
Artifact doesn't get a List full of Strings. <i>NOTE: Artifact doesn't get a List full of Strings.
Specification of this annotation flags the parameter as <i>NOTE:
non-editable; there is no true/false value.</i></td> Specification of this annotation flags the parameter as
non-editable; there is no true/false value.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>description</td> <td>description</td>
@ -475,9 +591,10 @@
<td>No</td> <td>No</td>
<td>The description of this parameter's use inside the Mojo. <td>The description of this parameter's use inside the Mojo.
<i>Using the toolset, this is detected as the javadoc description <i>Using the toolset, this is detected as the javadoc description
for the field. NOTE: While this is not a required part of the for the field. NOTE: While this is not a required part of the
parameter specification, it SHOULD be provided to enable future parameter specification, it SHOULD be provided to enable future
tool support for browsing, etc. and for clarity.</i></td> tool support for browsing, etc. and for clarity.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>configuration</td> <td>configuration</td>
@ -488,11 +605,14 @@
commonly used to refer to specific elements in the POM, such as commonly used to refer to specific elements in the POM, such as
${project.build.resources}, which refers to the List of resources ${project.build.resources}, which refers to the List of resources
meant to accompany the classes in the resulting jar file. meant to accompany the classes in the resulting jar file.
The default value is used when the expression evaluates to <code>null</code>. The default value is used when the expression evaluates to
<code>null</code>
.
<i>NOTE: If not specified, an expression of ${&lt;name&gt;} is <i>NOTE: If not specified, an expression of ${&lt;name&gt;} is
assumed, which can only be satisfied from POM configuration or assumed, which can only be satisfied from POM configuration or
System properties. The use of '${' and '}' is required to delimit System properties. The use of '${' and '}' is required to delimit
actual expressions which may be evaluated.</i></td> actual expressions which may be evaluated.</i>
</td>
</tr> </tr>
<tr> <tr>
<td>deprecated</td> <td>deprecated</td>
@ -501,18 +621,21 @@
<td>Marks a parameter as deprecated. The rules on deprecation are <td>Marks a parameter as deprecated. The rules on deprecation are
the same as normal java with language elements. This will trigger the same as normal java with language elements. This will trigger
a warning when a user tries to configure a parameter marked as a warning when a user tries to configure a parameter marked as
deprecated. </td> deprecated.</td>
</tr> </tr>
</table> </table>
</p> </p>
<p>The final component of a plugin descriptor is the dependencies. This <p>The final component of a plugin descriptor is the dependencies. This
enables the plugin to function independently of it's POM (or at least enables the plugin to function independently of it's POM (or at least
to declare the libraries it needs to run). Dependencies are taken from to declare the libraries it needs to run). Dependencies are taken from
the <b>runtime</b> scope of the plugin's calculated dependencies (from the
<b>runtime</b>
scope of the plugin's calculated dependencies (from
the POM). Dependencies are specified in exactly the same manner as in the POM). Dependencies are specified in exactly the same manner as in
the POM, except for the &lt;scope&gt; element (all dependencies in the the POM, except for the &lt;scope&gt; element (all dependencies in the
plugin descriptor are assumed to be runtime, because this is a plugin descriptor are assumed to be runtime, because this is a
runtime profile for the plugin).</p> runtime profile for the plugin).
</p>
</section> </section>
<section name="Plugin Tools"> <section name="Plugin Tools">
<p>By now, we've mentioned the plugin tools several times without telling <p>By now, we've mentioned the plugin tools several times without telling
@ -544,14 +667,18 @@
<tr> <tr>
<td>packaging</td> <td>packaging</td>
<td>Yes</td> <td>Yes</td>
<td><code>&lt;packaging&gt;maven-plugin&lt;/packaging&gt;</code></td> <td>
<code>&lt;packaging&gt;maven-plugin&lt;/packaging&gt;</code>
</td>
<td>The POM must declare a packaging element which describes this <td>The POM must declare a packaging element which describes this
project as a Maven plugin project.</td> project as a Maven plugin project.</td>
</tr> </tr>
<tr> <tr>
<td>scriptSourceDirectory</td> <td>scriptSourceDirectory</td>
<td>No</td> <td>No</td>
<td><code>&lt;scriptSourceDirectory&gt;src/main/scripts&lt;/scriptSourceDirectory&gt;</code></td> <td>
<code>&lt;scriptSourceDirectory&gt;src/main/scripts&lt;/scriptSourceDirectory&gt;</code>
</td>
<td>In the case of script-based Mojos (which are not covered in <td>In the case of script-based Mojos (which are not covered in
detail within this document), the POM must include an additional detail within this document), the POM must include an additional
element to distinguish script sources from (optional) java element to distinguish script sources from (optional) java
@ -565,19 +692,31 @@
</table> </table>
</p> </p>
<p>After making the changes above, the developer can simply call <p>After making the changes above, the developer can simply call
<br/><br/><code>m2 install</code><br/><br/> to install the plugin to <br/>
<br/>
<code>m2 install</code>
<br/>
<br/>
to install the plugin to
the local repository. (Any of the other standard lifecycle targets like the local repository. (Any of the other standard lifecycle targets like
package, deploy, etc. are also available in like fashion.)</p> package, deploy, etc. are also available in like fashion.)
</p>
</section> </section>
<section name="Resources"> <section name="Resources">
<p>This section simply gives a listing of pointers for more <p>This section simply gives a listing of pointers for more
information.</p> information.</p>
<p> <p>
<ul> <ul>
<li>M2 Plugin Overview [<a <li>M2 Plugin Overview [
href="plugin-overview.html">link</a>]</li> <a
<li>QDox Project (javadoc annotations) [<a href="plugin-overview.html">link</a>
href="http://qdox.codehaus.org">link</a>]</li> ]
</li>
<li>QDox Project (javadoc annotations) [
<a
href="http://qdox.codehaus.org">link</a>
]
</li>
</ul> </ul>
</p> </p>
</section> </section>