You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@maven.apache.org by jd...@apache.org on 2005/05/12 20:59:55 UTC
svn commit: r169873 - in /maven/components/trunk:
maven-site/src/site/xdoc/developers/mojo-api-specification.xml
maven-site/src/site/xdoc/developers/plugin-overview.xml
sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java
Author: jdcasey
Date: Thu May 12 11:59:54 2005
New Revision: 169873
URL: http://svn.apache.org/viewcvs?rev=169873&view=rev
Log:
o Added support to RewritePhase of repoclean to copy -SNAPSHOT.version.txt and -RELEASE.version.txt (or whatever it's called) using ArtifactMetadata, where these files exist in the source repo.
o Reformatted mojo annotation doco to tabular format.
o Committed a start to the plugin-overview (developer's PoV on this)...it's just an outline with an incomplete introduction for now, but it's still a start.
Added:
maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml (with props)
Modified:
maven/components/trunk/maven-site/src/site/xdoc/developers/mojo-api-specification.xml
maven/components/trunk/sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java
Modified: maven/components/trunk/maven-site/src/site/xdoc/developers/mojo-api-specification.xml
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-site/src/site/xdoc/developers/mojo-api-specification.xml?rev=169873&r1=169872&r2=169873&view=diff
==============================================================================
--- maven/components/trunk/maven-site/src/site/xdoc/developers/mojo-api-specification.xml (original)
+++ maven/components/trunk/maven-site/src/site/xdoc/developers/mojo-api-specification.xml Thu May 12 11:59:54 2005
@@ -91,13 +91,15 @@
</lt>
<li>
<code>
- void setLog( org.apache.maven.monitor.logging.Log )
+ void setLog( org.apache.maven.monitor.logging.Log )
</code>
<p>Inject a standard Maven logging mechanism to allow this Mojo
to communicate events and feedback to the user.</p>
</li>
<li>
- <code>void execute() throws org.apache.maven.plugin.MojoExecutionException</code>
+ <code>
+ void execute() throws org.apache.maven.plugin.MojoExecutionException
+ </code>
<p>Perform whatever build-process behavior this Mojo implements.
This is the main trigger for the Mojo inside the Maven system,
and allows the Mojo to communicate fatal errors by throwing an
@@ -128,7 +130,7 @@
</lt>
<li>
<code>
- public void setLog( org.apache.maven.monitor.logging.Log )
+ public void setLog( org.apache.maven.monitor.logging.Log )
</code>
<p>
<b>[IMPLEMENTED]</b>
@@ -146,7 +148,7 @@
</li>
<li>
<code>
- void execute() throws org.apache.maven.plugin.MojoExecutionException
+ void execute() throws org.apache.maven.plugin.MojoExecutionException
</code>
<p>
<b>[ABSTRACT]</b>
@@ -178,7 +180,7 @@
</li>
<li>
<code>
- void debug( java.lang.CharSequence, java.lang.Throwable )
+ void debug( java.lang.CharSequence, java.lang.Throwable )
</code>
<p>Send a message (and accompanying exception) to the user in the
<b>debug</b> error level. The error's stacktrace will be output
@@ -196,7 +198,7 @@
</li>
<li>
<code>
- void info( java.lang.CharSequence, java.lang.Throwable )
+ void info( java.lang.CharSequence, java.lang.Throwable )
</code>
<p>Send a message (and accompanying exception) to the user in the
<b>info</b> error level. The error's stacktrace will be output
@@ -214,7 +216,7 @@
</li>
<li>
<code>
- void warn( java.lang.CharSequence, java.lang.Throwable )
+ void warn( java.lang.CharSequence, java.lang.Throwable )
</code>
<p>Send a message (and accompanying exception) to the user in the
<b>warn</b> error level. The error's stacktrace will be output
@@ -232,7 +234,7 @@
</li>
<li>
<code>
- void error( java.lang.CharSequence, java.lang.Throwable )
+ void error( java.lang.CharSequence, java.lang.Throwable )
</code>
<p>Send a message (and accompanying exception) to the user in the
<b>error</b> error level. The error's stacktrace will be output
@@ -262,71 +264,127 @@
element name along with a javadoc annotation (if applicable) supporting
that piece of the plugin descriptor. A couple of examples are:
<b>someElement
- (@annotation parameterName="parameterValue")</b> or
+ (@annotation parameterName="parameterValue")</b> or
<b>someOtherElement (@annotation <rawAnnotationValue>)</b>.</p>
<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
following:</p>
<p>
- <ul>
- <li><b>mojos</b> - Descriptors for each Mojo provided by
- the plugin, each inside a <b>mojo</b> sub-element. Mojo descriptors
- are covered in detail below.</li>
- <li><b>dependencies</b> - A set of dependencies which the
- plugin requires in order to function. Each dependency is provided
- inside a <b>dependency</b> sub-element. Dependency specifications
- are covered below. <i>Using the plugin toolset, these dependencies
- can be extracted from the POM's dependencies.</i></li>
- </ul>
+ <table>
+ <tr>
+ <th>Descriptor Element</th>
+ <th>Required?</th>
+ <th>Notes</th>
+ </tr>
+ <tr>
+ <td>mojos</td>
+ <td>Yes</td>
+ <td>Descriptors for each Mojo provided by the plugin, each inside a
+ <b>mojo</b> sub-element. Mojo descriptors are covered in detail
+ below. Obviously, a plugin without any declared mojos doesn't
+ make sense, so the <b>mojos</b> element is required, along with
+ at least one <b>mojo</b> sub-element.</td>
+ </tr>
+ <tr>
+ <td>dependencies</td>
+ <td>Yes</td>
+ <td>A set of dependencies which the plugin requires in order to
+ function. Each dependency is provided inside a <b>dependency</b>
+ sub-element. Dependency specifications are covered below. Since
+ all plugins must have a dependency on
+ <code>maven-plugin-api</code>, this element is effectively
+ required. <i>Using the plugin toolset, these dependencies can be
+ extracted from the POM's dependencies.</i></td>
+ </tr>
+ </table>
</p>
<p>Each Mojo specified inside a plugin descriptor must provide the
- following:</p>
+ following (annotations specified here are at the class level):</p>
<p>
- <ul>
- <li><b>goal. (@goal <goalName>)</b> - The name for
- the Mojo that users will reference from the command line to execute
- the Mojo directly, or inside a POM in order to provide
- Mojo-specific configuration.</li>
- <li><b>implementation (detected)</b> - The
- Mojo's fully-qualified class name.</li>
- <li><b>language (detected)</b> - The implementation
- language for this Mojo (marmalade, java, etc.). <i>Optional,
- default is java.</i></li>
- <li><b>configurator (detected)</b> - The configurator type
- used to inject parameters into the Mojo. <i>Optional; will only be
- used in very special cases, with a highly controlled vocabulary of
- possible values. (Elements like this are why it's a good idea to
- use the descriptor tools.)</i></li>
- <li><b>phase
- (@phase <phaseName>)</b> - Specifies to which
- phase in the standard build lifecycle this Mojo binds. <i>Optional;
- only required if this Mojo participates in the standard build
- process.</i></li>
- <li><b>executePhase
- (@executePhase <phaseName>)</b> - Specifies
- the last phase in the standard build lifecycle to execute before
- executing this Mojo, when the Mojo's goal is invoked directly.
- <i>Optional.</i></li>
- <li><b>instantiationStrategy
- (@instantiationStrategy <strategyName>)</b> - Specifies
- the method Maven should use in instantiating this Mojo before it is
- executed, which has implications for the Mojo's state and instance
- reuse. <i>Optional. Currently, only "per-lookup" is suppported.
- (<b>Brett:</b> Can we deprecate this before alpha-2
- release?)</i></li>
- <li><b>requiresDependencyResolution
- (@requiresDependencyResolution <requiredScope>)</b> - Flags
- this Mojo as requiring the specified scope of dependencies to be
- resolved before it can execute. <i>Optional; Currently supports
- "compile", "runtime", and "test" scopes.</i></li>
- <li><b>description (detected)</b> - The description of the
- Mojo's functionality. <i>Using the toolset, this will be the
- class-level javadoc description provided.</i></li>
- <li><b>parameters</b> - Specifications for the parameters
- which this Mojo uses. Each parameter is specified in a
- <b>parameter</b> sub-element. Parameters are discusses in
- detail below.</li>
- </ul>
+ <table>
+ <tr>
+ <th>Descriptor Element</th>
+ <th>Annotation</th>
+ <th>Required?</th>
+ <th>Notes</th>
+ </tr>
+ <tr>
+ <td>goal</td>
+ <td>@goal <goalName></td>
+ <td>Yes</td>
+ <td>The name for the Mojo that users will reference from the
+ command line to execute the Mojo directly, or inside a POM in
+ order to provide Mojo-specific configuration.</td>
+ </tr>
+ <tr>
+ <td>implementation</td>
+ <td>none (detected)</td>
+ <td>Yes</td>
+ <td>The Mojo's fully-qualified class name (or script path in
+ the case of non-java mojos).</td>
+ </tr>
+ <tr>
+ <td>language</td>
+ <td>none (detected)</td>
+ <td>No. Default: <code>java</code></td>
+ <td>The implementation language for this Mojo (marmalade, java,
+ beanshell, etc.).</td>
+ </tr>
+ <tr>
+ <td>configurator</td>
+ <td>none (detected)</td>
+ <td>No</td>
+ <td>The configurator type to use when injecting parameter values
+ into this Mojo. <i>NOTE: This will only be used in very special
+ cases, using a highly controlled vocabulary of possible values.
+ (Elements like this are why it's a good idea to use the
+ descriptor tools.)</i></td>
+ </tr>
+ <tr>
+ <td>phase</td>
+ <td>@phase <phaseName></td>
+ <td>No</td>
+ <td>Binds this Mojo to a particular phase of the standard build
+ lifecycle, if specified. <i>NOTE: This is only required if this
+ Mojo is to participate in the standard build process.</i></td>
+ </tr>
+ <tr>
+ <td>executePhase</td>
+ <td>@executePhase <phaseName></td>
+ <td>No</td>
+ <td>When this Mojo's goal is invoked directly from the command
+ line, <b>executePhase</b> specifies the last phase in the
+ standard build lifecycle to execute before this Mojo
+ executes.</td>
+ </tr>
+ <tr>
+ <td>requiresDependencyResolution</td>
+ <td>@requiresDependencyResolution <requiredScope></td>
+ <td>No</td>
+ <td>Flags this Mojo as requiring the dependencies in the specified
+ scope (or an implied scope) to be resolved before it can execute.
+ <i>NOTE: Currently supports <b>compile</b>,
+ <b>runtime</b>, and <b>test</b> scopes.</i></td>
+ </tr>
+ <tr>
+ <td>description</td>
+ <td>none (detected)</td>
+ <td>No</td>
+ <td>The description of this Mojo's functionality. <i>Using the
+ toolset, this will be the class-level javadoc description
+ provided. NOTE: While this is not a required part of the mojo
+ specification, it SHOULD be provided to enable future
+ tool support for browsing, etc. and for clarity.</i></td>
+ </tr>
+ <tr>
+ <td>parameters</td>
+ <td>N/A</td>
+ <td>No</td>
+ <td>Specifications for the parameters which this Mojo uses will be
+ provided in <b>parameter</b> sub-elements in this section.
+ <i>NOTE: Parameters are discussed in more detail below.</i></td>
+ </tr>
+ </table>
</p>
<p>Each Mojo specifies the parameters that it expects to be able to work
with. These parameters are the Mojo's link to the outside world, and
@@ -344,63 +402,104 @@
<p>Each parameter for a Mojo must be specified in the
plugin descriptor as follows:</p>
<p>
- <ul>
- <li><b>name (detected)</b> - The name of the parameter, to
- be used in configuring this parameter from the Mojo's declared
- defaults (discussed below) or from the POM. <i>Using the toolset,
- this is detected as the java field name. It cannot be
- specified in an annotation.</i></li>
- <li><b>alias (@parameter alias="myAlias")</b> - Specifies
- an alias which can be used to configure this parameter from the
- POM. This is primarily useful to improve user-friendliness, where
- Mojo field names are not intuitive to the user.
- <i>Optional.</i></li>
- <li><b>type (detected)</b> - The type of this parameter.
- This is used to validate the result of any expressions used to
- calculate the value which should be injected into the Mojo for this
- parameter. <i>Using the toolset, this is detected as the class of
- this parameter's java field. It cannot be specified in an
- annotation.</i></li>
- <li><b>required (@required)</b> - Whether this parameter is
- required for the Mojo to function. This is used to validate the
- configuration for a Mojo before it is injected, and before the Mojo
- is executed from some half-state. <i>Optional. Specification of
- this annotation flags the parameter as required; there is
- no true/false value.</i></li>
- <li><b>editable (@readonly)</b> - Specifies that this
- parameter cannot be configured directly by the user (as in the case
- of POM-specified configuration). This is useful when you want to
- force the user to use common POM elements rather than plugin
- configurations, as in the case where you want to use the artifact's
- final name as a parameter. In this case, you want the user to
- modify <build><finalName/></build> rather than
- specifying a value for finalName directly in the plugin
- configuration section. It is also useful to ensure that - for
- example - a List-typed parameter which expects items of type
- Artifact doesn't get a List full of Strings. <i>Optional.
- Specification of this annotation flags the parameter as
- non-editable; there is no true/false value.</i></li>
- <li><b>description (detected)</b> - The description for
- what this parameter is used for inside the Mojo. <i>Using the
- toolset, this is detected as the javadoc description for
- the field. It cannot be specified as an annotation.</i></li>
- <li><b>expression
- (@parameter expression="${someExpression}")</b> - Specifies
- the expression used to calculate the value to be injected into this
- parameter of the Mojo at buildtime. This is commonly used to refer
- to specific elements in the POM, such as
- ${project.build.resources}, which refers to the List of resources
- meant to accompany the classes in the resulting jar file.
- <i>Optional. If not specified, an expression of ${<name>} is
- assumed, which can only be satisfied from POM configuration or
- System properties. The use of '${' and '}' is required to
- delimit actual expressions which may be evaluated.</i></li>
- <li><b>deprecated (@deprecated)</b> - Marks a parameter as
- deprecated. The rules on deprecation are the same as normal java
- with language elements. This will trigger a warning when a user
- tries to configure a parameter marked as deprecated.
- <i>Optional.</i></li>
- </ul>
+ <table>
+ <tr>
+ <th>Descriptor Element</th>
+ <th>Annotation</th>
+ <th>Required?</th>
+ <th>Notes</th>
+ </tr>
+ <tr>
+ <td>name</td>
+ <td>none (detected)</td>
+ <td>Yes</td>
+ <td>The name of the parameter, to be used in configuring this
+ parameter from the Mojo's declared defaults (discussed below) or
+ from the POM. <i>Using the toolset, this is detected as the
+ java field name.</i></td>
+ </tr>
+ <tr>
+ <td>alias</td>
+ <td>@parameter alias="myAlias"</td>
+ <td>No</td>
+ <td>Specifies an alias which can be used to configure this
+ parameter from the POM. This is primarily useful to improve
+ user-friendliness, where Mojo field names are not intuitive to
+ the user or are otherwise not conducive to configuration via
+ the POM.</td>
+ </tr>
+ <tr>
+ <td>type</td>
+ <td>none (detected)</td>
+ <td>Yes</td>
+ <td>The java type for this parameter. This is used to validate the
+ result of any expressions used to calculate the value which
+ should be injected into the Mojo for this parameter. <i>Using the
+ toolset, this is detected as the class of the java field
+ corresponding to this parameter.</i></td>
+ </tr>
+ <tr>
+ <td>required</td>
+ <td>@required</td>
+ <td>No</td>
+ <td>Whether this parameter is required for the Mojo to function.
+ This is used to validate the configuration for a Mojo before it
+ is injected, and before the Mojo is executed from some
+ half-state. <i>NOTE: Specification of this annotation flags
+ the parameter as required; there is no true/false value.</i></td>
+ </tr>
+ <tr>
+ <td>editable</td>
+ <td>@readonly</td>
+ <td>No</td>
+ <td>Specifies that this parameter cannot be configured directly by
+ the user (as in the case of POM-specified configuration). This is
+ useful when you want to force the user to use common POM elements
+ rather than plugin configurations, as in the case where you want
+ to use the artifact's final name as a parameter. In this case,
+ you want the user to modify
+ <build><finalName/></build> rather than
+ specifying a value for finalName directly in the plugin
+ configuration section. It is also useful to ensure that - for
+ example - a List-typed parameter which expects items of type
+ Artifact doesn't get a List full of Strings. <i>NOTE:
+ Specification of this annotation flags the parameter as
+ non-editable; there is no true/false value.</i></td>
+ </tr>
+ <tr>
+ <td>description</td>
+ <td>none (detected)</td>
+ <td>No</td>
+ <td>The description of this parameter's use inside the Mojo.
+ <i>Using the toolset, this is detected as the javadoc description
+ for the field. NOTE: While this is not a required part of the
+ parameter specification, it SHOULD be provided to enable future
+ tool support for browsing, etc. and for clarity.</i></td>
+ </tr>
+ <tr>
+ <td>expression</td>
+ <td>@parameter expression="${someExpression}"</td>
+ <td>No</td>
+ <td>Specifies the expression used to calculate the value to be
+ injected into this parameter of the Mojo at buildtime. This is
+ commonly used to refer to specific elements in the POM, such as
+ ${project.build.resources}, which refers to the List of resources
+ meant to accompany the classes in the resulting jar file.
+ <i>NOTE: If not specified, an expression of ${<name>} is
+ assumed, which can only be satisfied from POM configuration or
+ System properties. The use of '${' and '}' is required to delimit
+ actual expressions which may be evaluated.</i></td>
+ </tr>
+ <tr>
+ <td>deprecated</td>
+ <td>@deprecated</td>
+ <td>No</td>
+ <td>Marks a parameter as deprecated. The rules on deprecation are
+ the same as normal java with language elements. This will trigger
+ a warning when a user tries to configure a parameter marked as
+ deprecated. </td>
+ </tr>
+ </table>
</p>
<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
@@ -413,14 +512,17 @@
</section>
<section name="Plugin Tools">
<p>By now, we've mentioned the plugin tools several times without telling
- you what they are or how to use them. instead of writing (and
- maintaining) this metadata file by hand, Maven 2.0 ships with some
- tools to aid developers in this task. In fact, the only thing a plugin
- developer needs to do is declare his project to be a plugin from within
- the POM. Once this is done, Maven will call the appropriate descriptor
+ you what they are or how to use them. Instead of manually writing (and
+ maintaining) the metadata detailed above, Maven 2.0 ships with some
+ tools to aid in this task. In fact, the only thing a plugin developer
+ needs to do is declare his project to be a plugin from within the POM.
+ Once this is done, Maven will call the appropriate descriptor
generators, etc. to produce an artifact that is ready for use within
- Maven builds. The section below describes the changes to the POM
- which are necessary to create plugin artifacts.</p>
+ Maven builds. Optional metadata can be injected via javadoc annotation
+ (and possibly jdk5 annotations in the future) as described above,
+ enabling richer interactions between the Mojo and the user. The
+ section below describes the changes to the POM which are necessary to
+ create plugin artifacts.</p>
</section>
<section name="Project Descriptor (POM) Requirements">
<p>From the POM, Maven plugin projects look quite similar to any other
@@ -428,30 +530,52 @@
for script-based plugins. The following details the POM elements
which are necessary to build a Maven plugin artifact.</p>
<p>
- <ul>
- <li><b>packaging Element.</b> The POM must declare a packaging
- element which describes this project as a Maven plugin project. The
- element is specified as:
- <code><packaging>maven-plugin</packaging></code></li>
- <li><b>scriptSourceDirectory Element.</b> In the case of script-based
- Mojos (which are not covered in detail within this document), the
- POM must include an additional element to distinguish script
- sources from (optional) java supporting classes. This element is
- the scriptSourceDirectory, inside the build section. It is
- specified as:
- <code><scriptSourceDirectory>src/main/scripts</scriptSourceDirectory></code>.
- This directory is included in the list of resources which accompany
- any compiled code in the resulting artifact. It is specified
- separately from the resources in the build section to denote its
- special status as an alternate source directory for scripts.</li>
- </ul>
+ <table>
+ <tr>
+ <th>POM Element</th>
+ <th>Required for Java Mojos?</th>
+ <th>Sample Declaration</th>
+ <th>Notes</th>
+ </tr>
+ <tr>
+ <td>packaging</td>
+ <td>Yes</td>
+ <td><code><packaging>maven-plugin</packaging></code></td>
+ <td>The POM must declare a packaging element which describes this
+ project as a Maven plugin project.</td>
+ </tr>
+ <tr>
+ <td>scriptSourceDirectory</td>
+ <td>No</td>
+ <td><code><scriptSourceDirectory>src/main/scripts</scriptSourceDirectory></code></td>
+ <td>In the case of script-based Mojos (which are not covered in
+ detail within this document), the POM must include an additional
+ element to distinguish script sources from (optional) java
+ supporting classes. This element is the scriptSourceDirectory,
+ inside the build section. This directory is included in the list
+ of resources which accompany any compiled code in the resulting
+ artifact. It is specified separately from the resources in the
+ build section to denote its special status as an alternate source
+ directory for scripts.</td>
+ </tr>
+ </table>
</p>
- <p>After making the changes above, the developer can simply call <code>m2
- install</code> to install the plugin to the local repository. (Any of
- the other standard lifecycle targets like package, deploy, etc. are
- also available in like fashion.)</p>
+ <p>After making the changes above, the developer can simply call
+ <br/><br/><code>m2 install</code><br/><br/> to install the plugin to
+ the local repository. (Any of the other standard lifecycle targets like
+ package, deploy, etc. are also available in like fashion.)</p>
</section>
<section name="Resources">
+ <p>This section simply gives a listing of pointers for more
+ information.</p>
+ <p>
+ <ul>
+ <li>M2 Plugin Overview [<a
+ href="plugin-overview.html">link</a>]</li>
+ <li>QDox Project (javadoc annotations) [<a
+ href="http://qdox.codehaus.org">link</a>]</li>
+ </ul>
+ </p>
</section>
</body>
</document>
Added: maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml
URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml?rev=169873&view=auto
==============================================================================
--- maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml (added)
+++ maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml Thu May 12 11:59:54 2005
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+ <properties>
+ <title>Maven 2.0 Plugin Development</title>
+ <author email="jdcasey@apache.org">John Casey</author>
+ </properties>
+
+ <body>
+ <section name="Introduction">
+ <subsection name="Similarities to Maven 1.x">
+ <p> Maven 2.0 is similar to its predecessor in that it has two main
+ functions. First, it organizes project data into a coherent whole,
+ and exposes this data for use within the build process. Second, Maven
+ marshals a set of plugins to do the heavy lifting and execute the
+ actual steps of the build. </p>
+ <p> Many things in Maven 2 will have at least superficial familiarity
+ to users of Maven 1, and the plugin system is no exception. Maven 2
+ plugins appear to behave much as their 1.x counterparts do. Like 1.x
+ plugins, they use both project information and custom-defined
+ configurations to perform their work. Also, Maven 2 plugins are
+ organized and executed in a coherent way by the build engine itself -
+ that is to say, the engine is still responsible for organizing and
+ fulfilling a plugin's requirements before executing the plugin
+ itself. </p>
+ <p>Operationally, Maven 2.0 should feel very much like a more
+ performant big brother of Maven 1.x. While the POM has definitely
+ changed, it has the same basic layout and features (with notable
+ additions). However, this is where the similarity ends. Maven 2.0 is
+ a complete redesign and reimplementation of the Maven build concept.
+ As such, it has a much different - and more evolved, at least to
+ our minds ;-) - architecture.</p>
+ </subsection>
+ <subsection name="Differences from Maven 1.x">
+ <p> However similar the architectures may seem, Maven 2 offers a much
+ richer environment for its plugins than Maven 1 ever did. The new
+ architecture offers a managed lifecycle, multiple implementation
+ languages, reusability outside of the build system, and many more
+ advantages. Arguably the biggest advantage is the ability to write
+ Maven plugins entirely in Java, which allows developers to tap into a
+ rich landscape of development and testing tools to aid in their
+ efforts. </p>
+ <p> Prior to Maven 2.0, the build system organized relevant plugins
+ into a loosely defined lifecycle, which was determined based on goal
+ prerequisites and decoration via preGoals and postGoals. That
+ experience was critical for the Maven community. It taught us that
+ even though there may be a million different build scenarios out
+ there, most of the activities in those builds fit into just a few
+ broad categories. Moreover, the category to which a goal fits serves
+ as an accurate predictor for where in the build process the goal
+ should execute. Drawing on this experience, Maven 2.0 defines a
+ lifecycle within which plugins are managed according to their
+ relative position within this lifecycle </p>
+ <p> Starting with Maven 2.0, plugins implemented in different
+ programming or scripting languages can coexist within the same build
+ process. This removes the requirement that plugin developers learn a
+ particular scripting language in order to interact with Maven. It
+ also reduced the risk associated with the stability or richness of
+ any particular scripting language. </p>
+ <p>Also starting with Maven 2.0 is an effort to integrate multiproject
+ builds directly into the core architecture. In Maven 1.x, many large
+ projects were fragmented into smaller builds to sidestep issues such
+ as conditional compilation of a subset of classes; separation
+ of client-server code; or cyclical dependencies between
+ distinct application libraries.</p>
+ </subsection>
+ <subsection name="Why Change the Plugin Architecture?">
+ </subsection>
+ </section>
+ <section name="Definitions">
+ <subsection name="What is a Plugin?">
+ </subsection>
+ <subsection name="What is a Mojo (And Why the H--- is it Named 'Mojo')?">
+ </subsection>
+ <subsection name="What is the Build Lifecycle?">
+ </subsection>
+ </section>
+ <section name="Building a Plugin (in Java)">
+ <subsection name="Write the Mojo">
+ </subsection>
+ <subsection name="Annotate the Mojo">
+ </subsection>
+ <subsection name="Build the Plugin (Including POM Modifications)">
+ </subsection>
+ </section>
+ <section name="Plugins in the Build">
+ <subsection name="I Want My preReqs!">
+ </subsection>
+ <subsection name="Decorating Existing Builds (What About pre/postGoals?)">
+ </subsection>
+ <subsection
+ name="Getting Information into the Plugin (Plugin Configuration)">
+ </subsection>
+ </section>
+ <section name="Plugins in the Wild">
+ <subsection name="Why Might a Plugin Be Maven-Centric?">
+ </subsection>
+ <subsection name="Curing Dependence on Maven">
+ </subsection>
+ <subsection name="Injecting Configuration into a Plugin">
+ </subsection>
+ </section>
+ <section name="Resources">
+ <ul>
+ <li>
+ <a href="../plugin-management.html">Managing plugin configuration in
+ large projects</a>
+ </li>
+ </ul>
+ </section>
+ </body>
+</document>
\ No newline at end of file
Propchange: maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml
------------------------------------------------------------------------------
svn:keywords = "Date Rev Author"
Propchange: maven/components/trunk/maven-site/src/site/xdoc/developers/plugin-overview.xml
------------------------------------------------------------------------------
svn:mime-type = text/xml
Modified: maven/components/trunk/sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java
URL: http://svn.apache.org/viewcvs/maven/components/trunk/sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java?rev=169873&r1=169872&r2=169873&view=diff
==============================================================================
--- maven/components/trunk/sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java (original)
+++ maven/components/trunk/sandbox/repoclean/src/main/java/org/apache/maven/tools/repoclean/phase/RewritePhase.java Thu May 12 11:59:54 2005
@@ -2,10 +2,13 @@
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.metadata.ArtifactMetadata;
+import org.apache.maven.artifact.metadata.ReleaseArtifactMetadata;
+import org.apache.maven.artifact.metadata.SnapshotArtifactMetadata;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
import org.apache.maven.tools.repoclean.RepositoryCleanerConfiguration;
import org.apache.maven.tools.repoclean.artifact.metadata.ProjectMetadata;
+import org.apache.maven.tools.repoclean.digest.DigestException;
import org.apache.maven.tools.repoclean.digest.DigestVerifier;
import org.apache.maven.tools.repoclean.report.FileReporter;
import org.apache.maven.tools.repoclean.report.ReportWriteException;
@@ -15,6 +18,7 @@
import org.apache.maven.tools.repoclean.transaction.RollbackException;
import org.codehaus.plexus.PlexusConstants;
import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
import org.codehaus.plexus.context.Context;
import org.codehaus.plexus.context.ContextException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
@@ -70,238 +74,313 @@
{
Logger logger = getLogger();
- ArtifactPomRewriter artifactPomRewriter = null;
-
List rewritten = new ArrayList();
- try
+ File sourceBase = new File( new URL( sourceRepo.getUrl() ).getPath() );
+
+ File targetBase = new File( new URL( targetRepo.getUrl() ).getPath() );
+
+ for ( Iterator it = artifacts.iterator(); it.hasNext(); )
{
- File sourceBase = new File( new URL( sourceRepo.getUrl() ).getPath() );
+ Artifact artifact = (Artifact) it.next();
+
+ RewriteTransaction transaction = new RewriteTransaction( artifact );
- File targetBase = new File( new URL( targetRepo.getUrl() ).getPath() );
+ String artifactReportPath = buildArtifactReportPath( artifact );
- for ( Iterator it = artifacts.iterator(); it.hasNext(); )
+ FileReporter artifactReporter = null;
+ try
{
- Artifact artifact = (Artifact) it.next();
+ artifactReporter = new FileReporter( reportsBase, artifactReportPath );
- RewriteTransaction transaction = new RewriteTransaction( artifact );
+ boolean errorOccurred = false;
- String artifactReportPath = buildArtifactReportPath( artifact );
+ File artifactSource = new File( sourceRepo.getBasedir(), sourceRepo.pathOf( artifact ) );
+ File artifactTarget = new File( targetRepo.getBasedir(), targetRepo.pathOf( artifact ).replace( '+',
+ '-' ) );
- FileReporter artifactReporter = null;
- try
- {
- artifactReporter = new FileReporter( reportsBase, artifactReportPath );
+ transaction.addFile( artifactTarget );
- boolean errorOccurred = false;
+ artifact.setFile( artifactSource );
- File artifactSource = new File( sourceRepo.getBasedir(), sourceRepo.pathOf( artifact ) );
- File artifactTarget = new File( targetRepo.getBasedir(), targetRepo.pathOf( artifact )
- .replace( '+', '-' ) );
+ boolean targetMissingOrOlder = !artifactTarget.exists()
+ || artifactTarget.lastModified() < artifactSource.lastModified();
+ if ( artifactSource.exists() && ( configuration.force() || targetMissingOrOlder ) )
+ {
transaction.addFile( artifactTarget );
- artifact.setFile( artifactSource );
-
- boolean targetMissingOrOlder = !artifactTarget.exists()
- || artifactTarget.lastModified() < artifactSource.lastModified();
-
- if ( artifactSource.exists() && ( configuration.force() || targetMissingOrOlder ) )
+ try
{
- transaction.addFile( artifactTarget );
-
- try
+ if ( !configuration.reportOnly() )
{
- if ( !configuration.reportOnly() )
+ if ( logger.isDebugEnabled() )
{
- if ( logger.isDebugEnabled() )
- {
- logger.debug( "sourceRepo basedir is: \'" + sourceRepo.getBasedir() + "\'" );
- logger.debug( "targetRepo basedir is: \'" + targetRepo.getBasedir() + "\'" );
- }
-
- File targetParent = artifactTarget.getParentFile();
- if ( !targetParent.exists() )
- {
- targetParent.mkdirs();
- }
-
- if ( logger.isDebugEnabled() )
- {
- logger.debug( "Copying artifact[" + artifact.getId() + "] from \'" + artifactSource
- + "\' to \'" + artifactTarget + "\'." );
- }
+ logger.debug( "sourceRepo basedir is: \'" + sourceRepo.getBasedir() + "\'" );
+ logger.debug( "targetRepo basedir is: \'" + targetRepo.getBasedir() + "\'" );
+ }
- copyArtifact( artifact, artifactTarget, artifactReporter );
+ File targetParent = artifactTarget.getParentFile();
+ if ( !targetParent.exists() )
+ {
+ targetParent.mkdirs();
}
- }
- catch ( Exception e )
- {
- repoReporter.error( "Error transferring artifact[" + artifact.getId()
- + "] to the target repository.", e );
- throw e;
- }
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "Copying artifact[" + artifact.getId() + "] from \'" + artifactSource
+ + "\' to \'" + artifactTarget + "\'." );
+ }
- if ( logger.isDebugEnabled() )
- {
- logger.debug( "working on digest for artifact[" + artifact.getId() + "] with groupId: \'"
- + artifact.getGroupId() + "\'" );
+ copyArtifact( artifact, artifactTarget, artifactReporter );
}
+ }
+ catch ( Exception e )
+ {
+ repoReporter.error( "Error transferring artifact[" + artifact.getId()
+ + "] to the target repository.", e );
- try
- {
- digestVerifier.verifyDigest( artifactSource, artifactTarget, transaction, artifactReporter,
- configuration.reportOnly() );
- }
- catch ( Exception e )
- {
- repoReporter.error( "Error verifying digest for artifact[" + artifact.getId() + "]", e );
+ throw e;
+ }
- throw e;
- }
+ if ( logger.isDebugEnabled() )
+ {
+ logger.debug( "working on digest for artifact[" + artifact.getId() + "] with groupId: \'"
+ + artifact.getGroupId() + "\'" );
+ }
- ArtifactMetadata pom = new ProjectMetadata( artifact );
+ try
+ {
+ digestVerifier.verifyDigest( artifactSource, artifactTarget, transaction, artifactReporter,
+ configuration.reportOnly() );
+ }
+ catch ( Exception e )
+ {
+ repoReporter.error( "Error verifying digest for artifact[" + artifact.getId() + "]", e );
- File sourcePom = new File( sourceBase, sourceRepo.pathOfMetadata( pom ) );
+ throw e;
+ }
- String pomContents = null;
-
- String pomVersion = ArtifactPomRewriter.V3_POM;
+ try
+ {
+ rewriteMetadata( artifact, transaction, sourceBase, sourceRepo, targetBase, targetRepo,
+ artifactReporter, configuration.reportOnly() );
+ }
+ catch ( Exception e )
+ {
+ repoReporter.error( "Error rewriting POM for artifact[" + artifact.getId()
+ + "] into the target repository.\n Error message: " + e.getMessage() );
- if ( sourcePom.exists() )
- {
- pomContents = readPomContents( sourcePom );
-
- if ( pomContents.indexOf( "modelVersion" ) > -1 )
- {
- pomVersion = ArtifactPomRewriter.V4_POM;
- }
- }
+ throw e;
+ }
- artifactPomRewriter = (ArtifactPomRewriter) container.lookup( ArtifactPomRewriter.ROLE,
- pomVersion );
+ rewritten.add( artifact );
+ }
+ else if ( !targetMissingOrOlder )
+ {
+ artifactReporter.warn( "Target file for artifact is present and not stale. (Artifact: \'"
+ + artifact.getId() + "\' in path: \'" + artifactSource + "\' with target path: "
+ + artifactTarget + ")." );
+ }
+ else
+ {
+ artifactReporter.error( "Cannot find source file for artifact: \'" + artifact.getId()
+ + "\' under path: \'" + artifactSource + "\'" );
+ }
- File targetPom = new File( targetBase, targetRepo.pathOfMetadata( pom ).replace( '+', '-' ) );
+ if ( artifactReporter.hasError() )
+ {
+ repoReporter.warn( "Error(s) occurred while rewriting artifact: \'" + artifact.getId()
+ + "\' or its POM." );
+ }
+ }
+ catch ( Exception e )
+ {
+ if ( !configuration.force() )
+ {
+ repoReporter.warn( "Rolling back conversion for: " + artifact );
+ try
+ {
+ transaction.rollback();
+ }
+ catch ( RollbackException re )
+ {
+ repoReporter.error( "Error rolling back conversion transaction.", re );
+ }
+ }
+ else
+ {
+ repoReporter.warn( "NOT Rolling back conversion for: " + artifact + "; we are in --force mode." );
+ }
- transaction.addFile( targetPom );
+ artifactReporter.error( "Error while rewriting file or POM for artifact: \'" + artifact.getId()
+ + "\'. See report at: \'" + artifactReportPath + "\'.", e );
+ }
+ finally
+ {
+ if ( artifactReporter != null )
+ {
+ artifactReporter.close();
+ }
+ }
+ }
- File bridgedTargetPom = new File( targetBase, bridgingLayout.pathOfMetadata( pom )
- .replace( '+', '-' ) );
+ logger.info( "Actual number of artifacts rewritten: " + rewritten.size() + " (" + ( rewritten.size() * 2 )
+ + " including POMs)." );
- transaction.addFile( bridgedTargetPom );
+ return rewritten;
+ }
- try
- {
- File targetPomParent = targetPom.getParentFile();
- if ( !targetPomParent.exists() )
- {
- targetPomParent.mkdirs();
- }
+ private void rewriteMetadata( Artifact artifact, RewriteTransaction transaction, File sourceBase,
+ ArtifactRepository sourceRepo, File targetBase, ArtifactRepository targetRepo,
+ Reporter artifactReporter, boolean reportOnly )
+ throws Exception
+ {
+ // SNAPSHOT metadata
+ ArtifactMetadata snapshot = new SnapshotArtifactMetadata( artifact );
- FileWriter to = null;
- try
- {
- StringReader from = null;
- if ( pomContents != null )
- {
- from = new StringReader( pomContents );
- }
+ File snapshotSource = new File( sourceBase, sourceRepo.pathOfMetadata( snapshot ) );
+ File snapshotTarget = new File( targetBase, targetRepo.pathOfMetadata( snapshot ) );
- to = new FileWriter( targetPom );
+ freshenSupplementalMetadata( snapshot, snapshotSource, snapshotTarget, transaction, artifactReporter,
+ reportOnly );
- artifactPomRewriter.rewrite( artifact, from, to, artifactReporter, configuration
- .reportOnly() );
- }
- finally
- {
- IOUtil.close( to );
- }
+ // RELEASE metadata
+ ArtifactMetadata release = new ReleaseArtifactMetadata( artifact );
- boolean wroteBridge = bridgePomLocations( targetPom, bridgedTargetPom, artifactReporter );
+ File releaseSource = new File( sourceBase, sourceRepo.pathOfMetadata( release ) );
+ File releaseTarget = new File( targetBase, targetRepo.pathOfMetadata( release ) );
- digestVerifier.verifyDigest( sourcePom, targetPom, transaction, artifactReporter,
- configuration.reportOnly() );
+ freshenSupplementalMetadata( release, releaseSource, releaseTarget, transaction, artifactReporter, reportOnly );
- if ( wroteBridge )
- {
- digestVerifier.verifyDigest( sourcePom, bridgedTargetPom, transaction,
- artifactReporter, configuration.reportOnly() );
- }
+ // The rest is for POM metadata - translation and bridging of locations in the target repo may be required.
+ ArtifactMetadata pom = new ProjectMetadata( artifact );
- }
- catch ( Exception e )
- {
- repoReporter.error( "Error rewriting POM for artifact[" + artifact.getId()
- + "] into the target repository.\n Error message: " + e.getMessage() );
+ File sourcePom = new File( sourceBase, sourceRepo.pathOfMetadata( pom ) );
+ File targetPom = new File( targetBase, targetRepo.pathOfMetadata( pom ).replace( '+', '-' ) );
- throw e;
- }
+ String pomContents = null;
+
+ boolean pomNeedsRewriting = true;
+
+ if ( sourcePom.exists() )
+ {
+ pomContents = readPomContents( sourcePom );
+
+ if ( pomContents.indexOf( "modelVersion" ) > -1 )
+ {
+ pomNeedsRewriting = false;
+
+ freshenSupplementalMetadata( pom, sourcePom, targetPom, transaction, artifactReporter, reportOnly );
+ }
+ }
+
+ if ( pomNeedsRewriting )
+ {
+ ArtifactPomRewriter artifactPomRewriter = null;
+
+ try
+ {
+ artifactPomRewriter = (ArtifactPomRewriter) container.lookup( ArtifactPomRewriter.ROLE,
+ ArtifactPomRewriter.V3_POM );
+
+ transaction.addFile( targetPom );
+
+ File bridgedTargetPom = new File( targetBase, bridgingLayout.pathOfMetadata( pom ).replace( '+', '-' ) );
- rewritten.add( artifact );
+ transaction.addFile( bridgedTargetPom );
+
+ try
+ {
+ File targetPomParent = targetPom.getParentFile();
+ if ( !targetPomParent.exists() )
+ {
+ targetPomParent.mkdirs();
}
- else if ( !targetMissingOrOlder )
+
+ FileWriter to = null;
+ try
{
- artifactReporter.warn( "Target file for artifact is present and not stale. (Artifact: \'"
- + artifact.getId() + "\' in path: \'" + artifactSource + "\' with target path: "
- + artifactTarget + ")." );
+ StringReader from = null;
+ if ( pomContents != null )
+ {
+ from = new StringReader( pomContents );
+ }
+
+ to = new FileWriter( targetPom );
+
+ artifactPomRewriter.rewrite( artifact, from, to, artifactReporter, reportOnly );
}
- else
+ finally
{
- artifactReporter.error( "Cannot find source file for artifact: \'" + artifact.getId()
- + "\' under path: \'" + artifactSource + "\'" );
+ IOUtil.close( to );
}
- if ( artifactReporter.hasError() )
+ boolean wroteBridge = bridgePomLocations( pom, targetPom, bridgedTargetPom, artifactReporter,
+ transaction, reportOnly );
+
+ digestVerifier.verifyDigest( sourcePom, targetPom, transaction, artifactReporter, reportOnly );
+
+ if ( wroteBridge )
{
- repoReporter.warn( "Error(s) occurred while rewriting artifact: \'" + artifact.getId()
- + "\' or its POM." );
+ digestVerifier.verifyDigest( sourcePom, bridgedTargetPom, transaction, artifactReporter,
+ reportOnly );
}
+
}
catch ( Exception e )
{
- if ( !configuration.force() )
- {
- repoReporter.warn( "Rolling back conversion for: " + artifact );
- try
- {
- transaction.rollback();
- }
- catch ( RollbackException re )
- {
- repoReporter.error( "Error rolling back conversion transaction.", re );
- }
- }
- else
- {
- repoReporter
- .warn( "NOT Rolling back conversion for: " + artifact + "; we are in --force mode." );
- }
-
- artifactReporter.error( "Error while rewriting file or POM for artifact: \'" + artifact.getId()
- + "\'. See report at: \'" + artifactReportPath + "\'.", e );
+ throw e;
}
- finally
+ }
+ finally
+ {
+ if ( artifactPomRewriter != null )
{
- if ( artifactReporter != null )
+ try
+ {
+ container.release( artifactPomRewriter );
+ }
+ catch ( ComponentLifecycleException e )
{
- artifactReporter.close();
}
}
}
-
- logger.info( "Actual number of artifacts rewritten: " + rewritten.size() + " (" + ( rewritten.size() * 2 )
- + " including POMs)." );
}
- finally
+ }
+
+ private void freshenSupplementalMetadata( ArtifactMetadata metadata, File source, File target,
+ RewriteTransaction transaction, Reporter artifactReporter,
+ boolean reportOnly )
+ throws IOException, DigestException, ReportWriteException
+ {
+ if ( source.exists() )
{
- if ( artifactPomRewriter != null )
+ File targetParent = target.getParentFile();
+ if ( !targetParent.exists() )
{
- container.release( artifactPomRewriter );
+ targetParent.mkdirs();
}
- }
- return rewritten;
+ FileReader reader = null;
+ FileWriter writer = null;
+
+ try
+ {
+ reader = new FileReader( source );
+ writer = new FileWriter( target );
+
+ IOUtil.copy( reader, writer );
+ }
+ finally
+ {
+ IOUtil.close( reader );
+ IOUtil.close( writer );
+ }
+
+ digestVerifier.verifyDigest( source, target, transaction, artifactReporter, reportOnly );
+
+ }
}
private String readPomContents( File sourcePom )
@@ -377,8 +456,9 @@
}
}
- private boolean bridgePomLocations( File targetPom, File bridgedTargetPom, Reporter reporter )
- throws IOException, ReportWriteException
+ private boolean bridgePomLocations( ArtifactMetadata pom, File targetPom, File bridgedTargetPom, Reporter reporter,
+ RewriteTransaction transaction, boolean reportOnly )
+ throws IOException, ReportWriteException, DigestException
{
if ( targetPom.equals( bridgedTargetPom ) )
{
@@ -388,21 +468,7 @@
return false;
}
- FileInputStream in = null;
- FileOutputStream out = null;
-
- try
- {
- in = new FileInputStream( targetPom );
- out = new FileOutputStream( bridgedTargetPom );
-
- IOUtil.copy( in, out );
- }
- finally
- {
- IOUtil.close( in );
- IOUtil.close( out );
- }
+ freshenSupplementalMetadata( pom, targetPom, bridgedTargetPom, transaction, reporter, reportOnly );
return true;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@maven.apache.org
For additional commands, e-mail: dev-help@maven.apache.org