merge annotations branch



git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/trunk@1337500 13f79535-47bb-0310-9956-ffa450edef68
master
Olivier Lamy 2012-05-12 10:27:50 +00:00
commit aa3154917c
99 changed files with 6280 additions and 971 deletions

View File

@ -0,0 +1,31 @@
<?xml version='1.0' encoding='UTF-8'?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>maven-plugin-tools</artifactId>
<groupId>org.apache.maven.plugin-tools</groupId>
<version>3.0-SNAPSHOT</version>
</parent>
<artifactId>maven-plugin-annotations</artifactId>
</project>

View File

@ -0,0 +1,41 @@
package org.apache.maven.plugins.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.FIELD, ElementType.METHOD } )
@Inherited
public @interface Component
{
String role() default "";
String roleHint() default "";
}

View File

@ -0,0 +1,43 @@
package org.apache.maven.plugins.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
@Inherited
public @interface Execute
{
LifecyclePhase phase() default LifecyclePhase.NONE;
String goal() default "";
String lifecycle() default "";
}

View File

@ -0,0 +1,75 @@
package org.apache.maven.plugins.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Olivier Lamy
* @since 3.0
*/
public enum LifecyclePhase
{
VALIDATE( "validate" ),
INITIALIZE( "initialize" ),
GENERATE_SOURCES( "generate-sources" ),
PROCESS_SOURCES( "process-sources" ),
GENERATE_RESOURCES( "generate-resources" ),
PROCESS_RESOURCES( "process-resources" ),
COMPILE( "compile" ),
PROCESS_CLASSES( "process-classes" ),
GENERATE_TEST_SOURCES( "generate-test-sources" ),
PROCESS_TEST_SOURCES( "process-test-sources" ),
GENERATE_TEST_RESOURCES( "generate-test-resources" ),
PROCESS_TEST_RESOURCES( "process-test-resources" ),
TEST_COMPILE( "test-compile" ),
PROCESS_TEST_CLASSES( "process-test-classes" ),
TEST( "test" ),
PREPARE_PACKAGE( "prepare-package" ),
PACKAGE( "package" ),
PRE_INTEGRATION_TEST( "pre-integration-test" ),
INTEGRATION_TEST( "integration-test" ),
POST_INTEGRATION_TEST( "post-integration-test" ),
VERIFY( "verify" ),
INSTALL( "install" ),
DEPLOY( "deploy" ),
PRE_CLEAN( "pre-clean" ),
CLEAN( "clean" ),
POST_CLEAN( "post-clean" ),
PRE_SITE( "pre-site" ),
SITE( "site" ),
POST_SITE( "post-site" ),
SITE_DEPLOY( "site-deploy" ),
NONE( "" );
private final String id;
LifecyclePhase( String id )
{
this.id = id;
}
public String id()
{
return this.id;
}
}

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugins.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
@Inherited
public @interface Mojo
{
String name();
LifecyclePhase defaultPhase() default LifecyclePhase.NONE;
String requiresDependencyResolution() default "runtime";
String requiresDependencyCollection() default "";
String instantiationStrategy() default "per-lookup";
String executionStrategy() default "once-per-session";
boolean requiresProject() default true;
boolean requiresReports() default false;
boolean aggregator() default false;
boolean requiresDirectInvocation() default false;
boolean requiresOnline() default false;
boolean inheritByDefault() default true;
String configurator() default "";
boolean threadSafe() default false;
}

View File

@ -0,0 +1,47 @@
package org.apache.maven.plugins.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author Olivier Lamy
* @since 3.0
*/
@Documented
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.FIELD, ElementType.METHOD } )
@Inherited
public @interface Parameter
{
String alias() default "";
String expression() default "";
String defaultValue() default "";
boolean required() default false;
boolean readonly() default false;
}

View File

@ -28,7 +28,7 @@
</parent> </parent>
<artifactId>maven-plugin-plugin</artifactId> <artifactId>maven-plugin-plugin</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>Maven Plugin Plugin</name> <name>Maven Plugin Plugin</name>
@ -59,10 +59,10 @@
</distributionManagement> </distributionManagement>
<properties> <properties>
<mavenVersion>2.0.6</mavenVersion>
<pluginToolsVersion>2.10-SNAPSHOT</pluginToolsVersion>
<doxiaVersion>1.2</doxiaVersion> <doxiaVersion>1.2</doxiaVersion>
<doxia-sitetoolsVersion>1.2</doxia-sitetoolsVersion> <doxia-sitetoolsVersion>1.2</doxia-sitetoolsVersion>
<mavenVersion>2.0.6</mavenVersion>
<it.debug>true</it.debug>
</properties> </properties>
<!-- Copy from project up --> <!-- Copy from project up -->
@ -72,22 +72,27 @@
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-api</artifactId> <artifactId>maven-plugin-tools-api</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-model</artifactId> <artifactId>maven-plugin-tools-model</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-java</artifactId> <artifactId>maven-plugin-tools-java</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-beanshell</artifactId> <artifactId>maven-plugin-tools-beanshell</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
@ -101,6 +106,29 @@
<artifactId>plexus-utils</artifactId> <artifactId>plexus-utils</artifactId>
<version>2.0.5</version> <version>2.0.5</version>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-velocity</artifactId>
<version>1.1.8</version>
<exclusions>
<exclusion>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- other -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
@ -161,6 +189,7 @@
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-api</artifactId> <artifactId>maven-plugin-tools-api</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
<artifactId>maven-artifact-manager</artifactId> <artifactId>maven-artifact-manager</artifactId>
@ -196,11 +225,34 @@
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<scope>runtime</scope>
</dependency>
<!-- plexus --> <!-- plexus -->
<dependency> <dependency>
<groupId>org.codehaus.plexus</groupId> <groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId> <artifactId>plexus-utils</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-velocity</artifactId>
<exclusions>
<exclusion>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- other -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
@ -229,6 +281,15 @@
</configuration> </configuration>
</plugin> </plugin>
</plugins> </plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>2.9</version>
</plugin>
</plugins>
</pluginManagement>
</build> </build>
<profiles> <profiles>
@ -277,10 +338,13 @@
<pluginManagement> <pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId> <artifactId>maven-invoker-plugin</artifactId>
<version>1.6-SNAPSHOT</version>
<configuration> <configuration>
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo> <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath> <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
<debug>${it.debug}</debug>
<filterProperties> <filterProperties>
<sitePluginVersion>3.0</sitePluginVersion> <sitePluginVersion>3.0</sitePluginVersion>
</filterProperties> </filterProperties>
@ -292,6 +356,14 @@
</plugins> </plugins>
</pluginManagement> </pluginManagement>
</build> </build>
<dependencies>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<version>${project.version}</version>
<classifier>tests</classifier>
</dependency>
</dependencies>
</profile> </profile>
</profiles> </profiles>
</project> </project>

View File

@ -0,0 +1,3 @@
invoker.goals.1 = install
invoker.goals.2 = org.apache.maven.its.annotation-with-inheritance-from-deps:annotation-with-inheritance-from-deps:1.0-SNAPSHOT:first
invoker.goals.3 = org.apache.maven.its.annotation-with-inheritance-from-deps:annotation-with-inheritance-from-deps:1.0-SNAPSHOT:help

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.annotation-with-inheritance-from-deps</groupId>
<artifactId>annotation-with-inheritance-from-deps</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Maven Integration Test :: annotation-with-inheritance-from-deps</name>
<description>
Test plugin-plugin, which tests maven-plugin-tools-api and
maven-plugin-tools-java. This will generate a plugin descriptor from
java-based mojo sources, install the plugin, and then use it.
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plexusCompilerVersion>1.8.6</plexusCompilerVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>@mavenVersion@</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>@project.version@</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<version>@project.version@</version>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-manager</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,73 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.tools.plugin.annotations.FooMojo;
/**
* Touches a test file.
*
* @since 1.2
* @deprecated Don't use!
*/
@Mojo( name = "first", requiresDependencyResolution = "test", defaultPhase = LifecyclePhase.INTEGRATION_TEST )
public class FirstMojo
extends FooMojo
{
/**
* @since 0.1
* @deprecated As of 0.2
*/
@Parameter( alias = "alias" )
private String aliasedParam;
@Component( role = "org.apache.maven.project.MavenProjectHelper" )// , roleHint = "default"
private Object projectHelper;
public void execute()
throws MojoExecutionException
{
if (bar == null)
{
throw new MojoExecutionException( "bar == null" );
}
if (beer == null)
{
throw new MojoExecutionException( "beer == null" );
}
if ( projectHelper == null )
{
throw new MojoExecutionException( "projectHelper == null" );
}
if ( compilerManager == null )
{
throw new MojoExecutionException( "compilerManager == null" );
}
}
}

View File

@ -0,0 +1,17 @@
<lifecycles>
<lifecycle>
<id>my-lifecycle</id>
<phases>
<phase>
<id>process-classes</id>
</phase>
<phase>
<id>test</id>
<configuration>
<classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</phase>
</phases>
</lifecycle>
</lifecycles>

View File

@ -0,0 +1,81 @@
File descriptorFile = new File( basedir, "target/classes/META-INF/maven/plugin.xml" );
assert descriptorFile.isFile()
File oldHelpClass = new File( basedir, "target/classes/HelpMojo.class" );
assert !oldHelpClass.exists()
File newHelpClass = new File( basedir, "target/classes/org/apache/maven/plugin/coreit/HelpMojo.class" );
assert newHelpClass.exists()
def pluginDescriptor = new XmlParser().parse( descriptorFile );
def mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "first"}[0]
assert mojo.goal.text() == 'first'
assert mojo.implementation.text() == 'org.apache.maven.plugin.coreit.FirstMojo'
assert mojo.language.text() == 'java'
assert mojo.description.text() == 'Touches a test file.'
assert mojo.deprecated.text() == "Don't use!"
assert mojo.requiresDependencyResolution.text() == 'test'
assert mojo.requiresDependencyCollection.text() == ''
assert mojo.requiresProject.text() == 'true'
assert mojo.requiresOnline.text() == 'false'
assert mojo.requiresDirectInvocation.text() == 'false'
assert mojo.aggregator.text() == 'false'
assert mojo.threadSafe.text() == 'false'
assert mojo.phase.text() == 'integration-test'
assert mojo.executePhase.text() == 'package'
assert mojo.executeLifecycle.text() == 'my-lifecycle'
assert mojo.configuration.bar[0].text() == '${thebar}'
assert mojo.configuration.bar[0].'@implementation' == 'java.lang.String'
assert mojo.configuration.bar[0].'@default-value' == 'coolbar'
assert mojo.configuration.beer[0].text() == '${thebeer}'
assert mojo.configuration.beer[0].'@implementation' == 'java.lang.String'
assert mojo.configuration.beer[0].'@default-value' == 'coolbeer'
assert mojo.requirements.requirement.size() == 3
assert mojo.requirements.requirement[1].role.text() == 'org.codehaus.plexus.compiler.manager.CompilerManager'
assert mojo.requirements.requirement[1].'role-hint'.text() == ''
assert mojo.requirements.requirement[1].'field-name'.text() == 'compilerManager'
assert mojo.requirements.requirement[2].role.text() == 'org.apache.maven.project.MavenProjectHelper'
//assert mojo.requirements.requirement[2].'role-hint'.text() == 'default'
assert mojo.requirements.requirement[2].'field-name'.text() == 'projectHelper'
assert mojo.parameters.parameter.size() == 3
def parameter = mojo.parameters.parameter.findAll{ it.name.text() == "aliasedParam"}[0]
assert parameter.name.text() == 'aliasedParam'
assert parameter.alias.text() == 'alias'
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.text() == 'As of 0.2'
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "beer"}[0]
assert parameter.name.text() == 'beer'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.text() == "wine is better"
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == 'beer for non french folks'
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "bar"}[0]
assert parameter.name.text() == 'bar'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'true'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == 'the cool bar to go'
return true;

View File

@ -0,0 +1,3 @@
invoker.goals.1 = clean install -DskipTests
invoker.goals.2 = org.apache.maven.its.annotation-with-inheritance-reactor:module-mojo:1.0-SNAPSHOT:it0014
invoker.goals.3 = org.apache.maven.its.annotation-with-inheritance-reactor:module-mojo:1.0-SNAPSHOT:first

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.its.annotation-with-inheritance-reactor</groupId>
<artifactId>annotation-with-inheritance-reactor</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>module-abstract-mojo</artifactId>
</project>

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugins;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.compiler.manager.CompilerManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import java.io.File;
/**
* Touches a test file.
*
*/
public abstract class AbstractFirstMojo
extends AbstractMojo
{
/**
* Project directory.
*/
@Parameter( defaultValue = "${basedir}", readonly = true )
protected File basedir;
@Parameter( expression = "${first.touchFile}", defaultValue = "${project.build.directory}/touch.txt",
required = true )
protected File touchFile;
/**
* Plexus compiler manager.
*/
@Component
protected CompilerManager compilerManager;
/**
*
*/
@Component(role = "org.apache.maven.artifact.metadata.ArtifactMetadataSource", roleHint = "maven")
protected ArtifactMetadataSource artifactMetadataSource;
}

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.its.annotation-with-inheritance-reactor</groupId>
<artifactId>annotation-with-inheritance-reactor</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<packaging>maven-plugin</packaging>
<artifactId>module-mojo</artifactId>
<dependencies>
<dependency>
<groupId>org.apache.maven.its.annotation-with-inheritance-reactor</groupId>
<artifactId>module-abstract-mojo</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.io.File;
import java.io.IOException;
/**
* Touches a test file.
*
*/
@Mojo( name = "it0014")
public class CoreIt0014Mojo
extends AbstractMojo
{
@Parameter(expression ="${project.build.directory}", required = true)
private String outputDirectory;
public void execute()
throws MojoExecutionException
{
getLog().info( "outputDirectory = " + outputDirectory );
File f = new File( outputDirectory );
if ( !f.exists() )
{
f.mkdirs();
}
File touch = new File( f, "touch.txt" );
try
{
touch.createNewFile();
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error writing verification file.", e );
}
}
}

View File

@ -0,0 +1,74 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.AbstractFirstMojo;
/**
* Touches a test file.
*
* @since 1.2
* @deprecated Don't use!
*/
@Mojo( name = "first", requiresDependencyResolution = "test", defaultPhase = LifecyclePhase.INTEGRATION_TEST )
@Execute( phase = LifecyclePhase.GENERATE_SOURCES, lifecycle = "cobertura" )
public class FirstMojo
extends AbstractFirstMojo
{
/**
* @since 0.1
* @deprecated As of 0.2
*/
@Parameter( alias = "alias" )
private String aliasedParam;
@Component( role = "org.apache.maven.project.MavenProjectHelper")
private Object projectHelper;
public void execute()
throws MojoExecutionException
{
if (basedir == null)
{
throw new MojoExecutionException( "basedir == null" );
}
if (touchFile == null)
{
throw new MojoExecutionException( "touchFile == null" );
}
if ( projectHelper == null )
{
throw new MojoExecutionException( "projectHelper == null" );
}
if ( compilerManager == null )
{
throw new MojoExecutionException( "compilerManager == null" );
}
}
}

View File

@ -0,0 +1,38 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
/**
* Does nothing special.
*
*/
@Mojo( name = "second",requiresDependencyCollection = "compile", threadSafe = true)
public class SecondMojo
extends AbstractMojo
{
public void execute()
{
}
}

View File

@ -0,0 +1,17 @@
<lifecycles>
<lifecycle>
<id>cobertura</id>
<phases>
<phase>
<id>process-classes</id>
</phase>
<phase>
<id>test</id>
<configuration>
<classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</phase>
</phases>
</lifecycle>
</lifecycles>

View File

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.annotation-with-inheritance-reactor</groupId>
<artifactId>annotation-with-inheritance-reactor</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Maven Integration Test :: annotation-with-inheritance</name>
<packaging>pom</packaging>
<modules>
<module>module-abstract-mojo</module>
<module>module-mojo</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plexusCompilerVersion>1.8.6</plexusCompilerVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<version>@project.version@</version>
<classifier>tests</classifier>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>@mavenVersion@</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>@project.version@</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-manager</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,80 @@
File touchFile = new File( basedir, "module-mojo/target/touch.txt" )
assert touchFile.isFile()
File descriptorFile = new File( basedir, "module-mojo/target/classes/META-INF/maven/plugin.xml" );
assert descriptorFile.isFile()
def pluginDescriptor = new XmlParser().parse( descriptorFile );
assert pluginDescriptor.mojos.mojo.size() == 3
def mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "first"}[0]
assert mojo.goal.text() == 'first'
assert mojo.implementation.text() == 'org.apache.maven.plugin.coreit.FirstMojo'
assert mojo.language.text() == 'java'
assert mojo.description.text() == 'Touches a test file.'
assert mojo.deprecated.text() == "Don't use!"
assert mojo.requiresDependencyResolution.text() == 'test'
assert mojo.requiresDependencyCollection.text() == ''
assert mojo.requiresProject.text() == 'true'
assert mojo.requiresOnline.text() == 'false'
assert mojo.requiresDirectInvocation.text() == 'false'
assert mojo.aggregator.text() == 'false'
assert mojo.threadSafe.text() == 'false'
assert mojo.phase.text() == 'integration-test'
assert mojo.executePhase.text() == 'generate-sources'
assert mojo.executeLifecycle.text() == 'cobertura'
assert mojo.configuration.basedir[0].text() == ''
assert mojo.configuration.basedir[0].'@implementation' == 'java.io.File'
assert mojo.configuration.basedir[0].'@default-value' == '${basedir}'
assert mojo.configuration.touchFile[0].text() == '${first.touchFile}'
assert mojo.configuration.touchFile[0].'@implementation' == 'java.io.File'
assert mojo.configuration.touchFile[0].'@default-value' == '${project.build.directory}/touch.txt'
assert mojo.requirements.requirement.size() == 3
assert mojo.requirements.requirement[2].role.text() == 'org.apache.maven.project.MavenProjectHelper'
//assert mojo.requirements.requirement[2].'role-hint'.text() == 'default'
assert mojo.requirements.requirement[2].'field-name'.text() == 'projectHelper'
assert mojo.parameters.parameter.size() == 3
def parameter = mojo.parameters.parameter.findAll{ it.name.text() == "aliasedParam"}[0]
assert parameter.name.text() == 'aliasedParam'
assert parameter.alias.text() == 'alias'
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.text() == 'As of 0.2'
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "touchFile"}[0]
assert parameter.name.text() == 'touchFile'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'true'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "basedir"}[0]
assert parameter.name.text() == 'basedir'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'false'
assert parameter.description.text() == 'Project directory.'
mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "second"}[0]
assert mojo.requiresDependencyCollection.text() == 'compile'
assert mojo.threadSafe.text() == 'true'
return true;

View File

@ -0,0 +1,4 @@
invoker.goals.1 = clean install -DskipTests
invoker.goals.2 = org.apache.maven.its.annotation-with-inheritance:annotation-with-inheritance:1.0-SNAPSHOT:it0014
invoker.goals.3 = org.apache.maven.its.annotation-with-inheritance:annotation-with-inheritance:1.0-SNAPSHOT:first
invoker.goals.4 = org.apache.maven.its.annotation-with-inheritance:annotation-with-inheritance:1.0-SNAPSHOT:help

View File

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.annotation-with-inheritance</groupId>
<artifactId>annotation-with-inheritance</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Maven Integration Test :: annotation-with-inheritance</name>
<description>
Test plugin-plugin, which tests maven-plugin-tools-api and
maven-plugin-tools-java. This will generate a plugin descriptor from
java-based mojo sources, install the plugin, and then use it.
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plexusCompilerVersion>1.8.6</plexusCompilerVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
<version>@mavenVersion@</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>@project.version@</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-manager</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-javac</artifactId>
<version>${plexusCompilerVersion}</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.compiler.manager.CompilerManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import java.io.File;
/**
* Touches a test file.
*
*/
public abstract class AbstractFirstMojo
extends AbstractMojo
{
/**
* Project directory.
*/
@Parameter( defaultValue = "${basedir}", readonly = true )
protected File basedir;
@Parameter( expression = "${first.touchFile}", defaultValue = "${project.build.directory}/touch.txt",
required = true )
protected File touchFile;
/**
* Plexus compiler manager.
*/
@Component
protected CompilerManager compilerManager;
/**
*
*/
@Component(role = "org.apache.maven.artifact.metadata.ArtifactMetadataSource", roleHint = "maven")
protected ArtifactMetadataSource artifactMetadataSource;
}

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.io.File;
import java.io.IOException;
/**
* Touches a test file.
*
*/
@Mojo( name = "it0014")
public class CoreIt0014Mojo
extends AbstractMojo
{
@Parameter(expression ="${project.build.directory}", required = true)
private String outputDirectory;
public void execute()
throws MojoExecutionException
{
getLog().info( "outputDirectory = " + outputDirectory );
File f = new File( outputDirectory );
if ( !f.exists() )
{
f.mkdirs();
}
File touch = new File( f, "touch.txt" );
try
{
touch.createNewFile();
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error writing verification file.", e );
}
}
}

View File

@ -0,0 +1,73 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
/**
* Touches a test file.
*
* @since 1.2
* @deprecated Don't use!
*/
@Mojo( name = "first", requiresDependencyResolution = "test", defaultPhase = LifecyclePhase.INTEGRATION_TEST)
@Execute( phase = LifecyclePhase.GENERATE_SOURCES, lifecycle = "cobertura" )
public class FirstMojo
extends AbstractFirstMojo
{
/**
* @since 0.1
* @deprecated As of 0.2
*/
@Parameter( alias = "alias" )
private String aliasedParam;
@Component( role = "org.apache.maven.project.MavenProjectHelper" )//, roleHint = "default"
private Object projectHelper;
public void execute()
throws MojoExecutionException
{
if (basedir == null)
{
throw new MojoExecutionException( "basedir == null" );
}
if (touchFile == null)
{
throw new MojoExecutionException( "touchFile == null" );
}
if ( projectHelper == null )
{
throw new MojoExecutionException( "projectHelper == null" );
}
if ( compilerManager == null )
{
throw new MojoExecutionException( "compilerManager == null" );
}
}
}

View File

@ -0,0 +1,38 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
/**
* Does nothing special.
*
*/
@Mojo( name = "second",requiresDependencyCollection = "compile", threadSafe = true)
public class SecondMojo
extends AbstractMojo
{
public void execute()
{
}
}

View File

@ -0,0 +1,17 @@
<lifecycles>
<lifecycle>
<id>cobertura</id>
<phases>
<phase>
<id>process-classes</id>
</phase>
<phase>
<id>test</id>
<configuration>
<classesDirectory>${project.build.directory}/generated-classes/cobertura</classesDirectory>
<testFailureIgnore>true</testFailureIgnore>
</configuration>
</phase>
</phases>
</lifecycle>
</lifecycles>

View File

@ -0,0 +1,84 @@
File touchFile = new File( basedir, "target/touch.txt" )
assert touchFile.isFile()
File descriptorFile = new File( basedir, "target/classes/META-INF/maven/plugin.xml" );
assert descriptorFile.isFile()
File oldHelpClass = new File( basedir, "target/classes/HelpMojo.class" );
assert !oldHelpClass.exists()
File newHelpClass = new File( basedir, "target/classes/org/apache/maven/plugin/coreit/HelpMojo.class" );
assert newHelpClass.exists()
def pluginDescriptor = new XmlParser().parse( descriptorFile );
def mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "first"}[0]
assert mojo.goal.text() == 'first'
assert mojo.implementation.text() == 'org.apache.maven.plugin.coreit.FirstMojo'
assert mojo.language.text() == 'java'
assert mojo.description.text() == 'Touches a test file.'
assert mojo.deprecated.text() == "Don't use!"
assert mojo.requiresDependencyResolution.text() == 'test'
assert mojo.requiresDependencyCollection.text() == ''
assert mojo.requiresProject.text() == 'true'
assert mojo.requiresOnline.text() == 'false'
assert mojo.requiresDirectInvocation.text() == 'false'
assert mojo.aggregator.text() == 'false'
assert mojo.threadSafe.text() == 'false'
assert mojo.phase.text() == 'integration-test'
assert mojo.executePhase.text() == 'generate-sources'
assert mojo.executeLifecycle.text() == 'cobertura'
assert mojo.configuration.basedir[0].text() == ''
assert mojo.configuration.basedir[0].'@implementation' == 'java.io.File'
assert mojo.configuration.basedir[0].'@default-value' == '${basedir}'
assert mojo.configuration.touchFile[0].text() == '${first.touchFile}'
assert mojo.configuration.touchFile[0].'@implementation' == 'java.io.File'
assert mojo.configuration.touchFile[0].'@default-value' == '${project.build.directory}/touch.txt'
assert mojo.requirements.requirement.size() == 3
assert mojo.requirements.requirement[2].role.text() == 'org.apache.maven.project.MavenProjectHelper'
//assert mojo.requirements.requirement[2].'role-hint'.text() == 'default'
assert mojo.requirements.requirement[2].'field-name'.text() == 'projectHelper'
assert mojo.parameters.parameter.size() == 3
def parameter = mojo.parameters.parameter.findAll{ it.name.text() == "aliasedParam"}[0]
assert parameter.name.text() == 'aliasedParam'
assert parameter.alias.text() == 'alias'
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.text() == 'As of 0.2'
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "touchFile"}[0]
assert parameter.name.text() == 'touchFile'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'true'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "basedir"}[0]
assert parameter.name.text() == 'basedir'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'false'
assert parameter.description.text() == 'Project directory.'
mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "second"}[0]
assert mojo.requiresDependencyCollection.text() == 'compile'
assert mojo.threadSafe.text() == 'true'
return true;

View File

@ -1,2 +1,2 @@
invoker.goals.1 = install invoker.goals.1 = clean install -DskipTests
invoker.goals.2 = org.apache.maven.its.plugin:help:1.0:help invoker.goals.2 = org.apache.maven.its.plugin:help:1.0-SNAPSHOT:help

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>help</artifactId> <artifactId>help</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<description> <description>
@ -41,9 +41,24 @@ under the License.
<artifactId>maven-plugin-api</artifactId> <artifactId>maven-plugin-api</artifactId>
<version>2.0</version> <version>2.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -1 +1 @@
invoker.goals = compile invoker.goals = clean compile

View File

@ -23,8 +23,8 @@ under the License.
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>help</artifactId> <artifactId>help-package</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<description> <description>
@ -41,9 +41,24 @@ under the License.
<artifactId>maven-plugin-api</artifactId> <artifactId>maven-plugin-api</artifactId>
<version>2.0</version> <version>2.0</version>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -25,7 +25,7 @@ under the License.
<parent> <parent>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr</artifactId> <artifactId>ipcr</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>ipcr-dep-a</artifactId> <artifactId>ipcr-dep-a</artifactId>

View File

@ -25,7 +25,7 @@ under the License.
<parent> <parent>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr</artifactId> <artifactId>ipcr</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>ipcr-dep-b</artifactId> <artifactId>ipcr-dep-b</artifactId>
@ -42,7 +42,7 @@ under the License.
<dependency> <dependency>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr-dep-a</artifactId> <artifactId>ipcr-dep-a</artifactId>
<version>1.0</version> <version>${project.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,4 +1,4 @@
invoker.goals.1 = clean install invoker.goals.1 = clean install -DskipTests
invoker.profiles.1 = setup invoker.profiles.1 = setup
invoker.goals.2 = clean process-classes invoker.goals.2 = clean process-classes

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr</artifactId> <artifactId>ipcr</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Aggregator</name> <name>Aggregator</name>

View File

@ -25,7 +25,7 @@ under the License.
<parent> <parent>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr</artifactId> <artifactId>ipcr</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>ipcr-plugin</artifactId> <artifactId>ipcr-plugin</artifactId>
@ -45,7 +45,7 @@ under the License.
<dependency> <dependency>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr-dep-b</artifactId> <artifactId>ipcr-dep-b</artifactId>
<version>1.0</version> <version>${project.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
@ -58,7 +58,7 @@ under the License.
<dependency> <dependency>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>ipcr-dep-b</artifactId> <artifactId>ipcr-dep-b</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<exclusions> <exclusions>
<exclusion> <exclusion>
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>

View File

@ -0,0 +1,3 @@
invoker.goals.1 = clean install -DskipTests
invoker.goals.2 = org.apache.maven.its.basic-java-annotations:maven-it-basic-java-annotations:1.0-SNAPSHOT:it0014
invoker.goals.3 = org.apache.maven.its.basic-java-annotations:maven-it-basic-java-annotations:1.0-SNAPSHOT:help

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you 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.
-->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.maven.its.basic-java-annotations</groupId>
<artifactId>maven-it-basic-java-annotations</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>Maven Integration Test :: basic-java-annotations</name>
<description>
Test plugin-plugin, which tests maven-plugin-tools-api and
maven-plugin-tools-java. This will generate a plugin descriptor from
java-based mojo sources, install the plugin, and then use it.
</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>@project.version@</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>@project.version@</version>
<configuration>
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<phase>process-classes</phase>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
<execution>
<id>help-goal</id>
<goals>
<goal>helpmojo</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,66 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.io.File;
import java.io.IOException;
/**
* Touches a test file.
*
*/
@Mojo( name = "it0014")
public class CoreIt0014Mojo
extends AbstractMojo
{
@Parameter(expression ="${project.build.directory}", required = true)
private String outputDirectory;
public void execute()
throws MojoExecutionException
{
getLog().info( "outputDirectory = " + outputDirectory );
File f = new File( outputDirectory );
if ( !f.exists() )
{
f.mkdirs();
}
File touch = new File( f, "touch.txt" );
try
{
touch.createNewFile();
}
catch ( IOException e )
{
throw new MojoExecutionException( "Error writing verification file.", e );
}
}
}

View File

@ -0,0 +1,69 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import java.io.File;
/**
* Touches a test file.
*
* @since 1.2
* @deprecated Don't use!
*/
@Mojo( name = "first", requiresDependencyResolution = "test", defaultPhase = LifecyclePhase.INTEGRATION_TEST )
@Execute( phase = LifecyclePhase.GENERATE_SOURCES, lifecycle = "cobertura" )
public class FirstMojo
extends AbstractMojo
{
/**
* Project directory.
*/
@Parameter( defaultValue = "${basedir}", readonly = true )
private File basedir;
@Parameter( expression = "${first.touchFile}", defaultValue = "${project.build.directory}/touch.txt",
required = true )
private File touchFile;
/**
* @since 0.1
* @deprecated As of 0.2
*/
@Parameter( alias = "alias" )
private String aliasedParam;
@Component( role = "org.apache.maven.project.MavenProjectHelper", roleHint = "test" )
private Object projectHelper;
public void execute()
throws MojoExecutionException
{
}
}

View File

@ -0,0 +1,38 @@
package org.apache.maven.plugin.coreit;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Mojo;
/**
* Does nothing special.
*
*/
@Mojo( name = "second",requiresDependencyCollection = "compile", threadSafe = true)
public class SecondMojo
extends AbstractMojo
{
public void execute()
{
}
}

View File

@ -0,0 +1,78 @@
File touchFile = new File( basedir, "target/touch.txt" )
assert touchFile.isFile()
File descriptorFile = new File( basedir, "target/classes/META-INF/maven/plugin.xml" );
assert descriptorFile.isFile()
def pluginDescriptor = new XmlParser().parse( descriptorFile );
def mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "first"}[0]
assert mojo.goal.text() == 'first'
assert mojo.implementation.text() == 'org.apache.maven.plugin.coreit.FirstMojo'
assert mojo.language.text() == 'java'
assert mojo.description.text() == 'Touches a test file.'
assert mojo.deprecated.text() == "Don't use!"
assert mojo.requiresDependencyResolution.text() == 'test'
assert mojo.requiresDependencyCollection.text() == ''
assert mojo.requiresProject.text() == 'true'
assert mojo.requiresOnline.text() == 'false'
assert mojo.requiresDirectInvocation.text() == 'false'
assert mojo.aggregator.text() == 'false'
assert mojo.threadSafe.text() == 'false'
assert mojo.phase.text() == 'integration-test'
assert mojo.executePhase.text() == 'generate-sources'
assert mojo.executeLifecycle.text() == 'cobertura'
assert mojo.configuration.basedir[0].text() == ''
assert mojo.configuration.basedir[0].'@implementation' == 'java.io.File'
assert mojo.configuration.basedir[0].'@default-value' == '${basedir}'
assert mojo.configuration.touchFile[0].text() == '${first.touchFile}'
assert mojo.configuration.touchFile[0].'@implementation' == 'java.io.File'
assert mojo.configuration.touchFile[0].'@default-value' == '${project.build.directory}/touch.txt'
assert mojo.requirements.requirement.size() == 1
assert mojo.requirements.requirement[0].role.text() == 'org.apache.maven.project.MavenProjectHelper'
assert mojo.requirements.requirement[0].'role-hint'.text() == 'test'
assert mojo.requirements.requirement[0].'field-name'.text() == 'projectHelper'
assert mojo.parameters.parameter.size() == 3
def parameter = mojo.parameters.parameter.findAll{ it.name.text() == "aliasedParam"}[0]
assert parameter.name.text() == 'aliasedParam'
assert parameter.alias.text() == 'alias'
assert parameter.type.text() == 'java.lang.String'
assert parameter.deprecated.text() == 'As of 0.2'
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "touchFile"}[0]
assert parameter.name.text() == 'touchFile'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'true'
assert parameter.editable.text() == 'true'
assert parameter.description.text() == ''
parameter = mojo.parameters.parameter.findAll{ it.name.text() == "basedir"}[0]
assert parameter.name.text() == 'basedir'
assert parameter.alias.isEmpty()
assert parameter.type.text() == 'java.io.File'
assert parameter.deprecated.isEmpty()
assert parameter.required.text() == 'false'
assert parameter.editable.text() == 'false'
assert parameter.description.text() == 'Project directory.'
mojo = pluginDescriptor.mojos.mojo.findAll{ it.goal.text() == "second"}[0]
assert mojo.requiresDependencyCollection.text() == 'compile'
assert mojo.threadSafe.text() == 'true'
return true;

View File

@ -1,2 +1,3 @@
invoker.goals.1 = install invoker.goals.1 = clean install -DskipTests
invoker.goals.2 = org.apache.maven.its.it0013:maven-it-it0013:1.0:it0013 invoker.goals.2 = org.apache.maven.its.it0013:maven-it-it0013:1.0-SNAPSHOT:it0013

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.it0013</groupId> <groupId>org.apache.maven.its.it0013</groupId>
<artifactId>maven-it-it0013</artifactId> <artifactId>maven-it-it0013</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>Maven Integration Test :: it0013</name> <name>Maven Integration Test :: it0013</name>

View File

@ -1 +1 @@
invoker.goals = clean plugin:report invoker.goals = clean plugin:report -DskipTests

View File

@ -1 +1 @@
invoker.goals = clean site invoker.goals = clean site -DskipTests

View File

@ -1,47 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<modelVersion>4.0.0</modelVersion> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<groupId>org.apache.maven.its</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>jdk-default-version</artifactId> <groupId>org.apache.maven.its</groupId>
<version>1.0-SNAPSHOT</version> <artifactId>jdk-default-version</artifactId>
<packaging>maven-plugin</packaging> <version>1.0-SNAPSHOT</version>
<properties> <packaging>maven-plugin</packaging>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <properties>
</properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<dependencies> </properties>
<dependency> <dependencies>
<groupId>org.apache.maven</groupId> <dependency>
<artifactId>maven-plugin-api</artifactId> <groupId>org.apache.maven</groupId>
<version>2.0</version> <artifactId>maven-plugin-api</artifactId>
</dependency> <version>2.0</version>
</dependencies> </dependency>
<build> </dependencies>
<pluginManagement> <build>
<plugins> <pluginManagement>
<plugin> <plugins>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-compiler-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>2.3.2</version> <artifactId>maven-compiler-plugin</artifactId>
<!-- <version>2.3.2</version>
<configuration> <!--
<source>1.5</source> <configuration>
<target>1.5</target> <source>1.5</source>
</configuration> <target>1.5</target>
--> </configuration>
</plugin> -->
<plugin> </plugin>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-plugin-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>@project.version@</version> <artifactId>maven-plugin-plugin</artifactId>
</plugin> <version>@project.version@</version>
<plugin> </plugin>
<groupId>org.apache.maven.plugins</groupId> <plugin>
<artifactId>maven-site-plugin</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>@sitePluginVersion@</version> <artifactId>maven-site-plugin</artifactId>
</plugin> <version>@sitePluginVersion@</version>
</plugins> </plugin>
</pluginManagement> </plugins>
</build> </pluginManagement>
</build>
<reporting> <reporting>
<plugins> <plugins>
<plugin> <plugin>

View File

@ -1 +1 @@
invoker.goals = clean site invoker.goals = clean site -DskipTests

View File

@ -30,7 +30,7 @@ under the License.
<groupId>org.apache.maven.its</groupId> <groupId>org.apache.maven.its</groupId>
<artifactId>plugin-report</artifactId> <artifactId>plugin-report</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>MPLUGIN-105</name> <name>MPLUGIN-105</name>

View File

@ -20,6 +20,13 @@ under the License.
--> -->
<settings> <settings>
<!--mirrors>
<mirror>
<id>local.mirror</id>
<url>@localRepositoryUrl@</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors-->
<profiles> <profiles>
<profile> <profile>
<id>it-repo</id> <id>it-repo</id>

View File

@ -1,2 +1,2 @@
invoker.goals = install invoker.goals = install -DskipTests
invoker.mavenOpts = -Dmaven.plugin.skip=true invoker.mavenOpts = -Dmaven.plugin.skip=true

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.it0013</groupId> <groupId>org.apache.maven.its.it0013</groupId>
<artifactId>mplugin-174</artifactId> <artifactId>mplugin-174</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>MPLUGIN-174</name> <name>MPLUGIN-174</name>

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>latin-1</artifactId> <artifactId>latin-1</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>Latin-1</name> <name>Latin-1</name>
@ -49,12 +49,12 @@ under the License.
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version> <version>2.4</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
<version>2.2</version> <version>2.5</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>aggregator</artifactId> <artifactId>aggregator</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Aggregator</name> <name>Aggregator</name>

View File

@ -24,7 +24,7 @@ under the License.
<groupId>org.apache.maven.its.plugin</groupId> <groupId>org.apache.maven.its.plugin</groupId>
<artifactId>utf-8</artifactId> <artifactId>utf-8</artifactId>
<version>1.0</version> <version>1.0-SNAPSHOT</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>UTF-8</name> <name>UTF-8</name>
@ -49,12 +49,12 @@ under the License.
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version> <version>2.4</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId> <artifactId>maven-resources-plugin</artifactId>
<version>2.2</version> <version>2.5</version>
</plugin> </plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>

View File

@ -19,6 +19,8 @@ package org.apache.maven.plugin.plugin;
* under the License. * under the License.
*/ */
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
@ -28,12 +30,15 @@ import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
import org.apache.maven.tools.plugin.PluginToolsRequest; import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.extractor.ExtractionException; import org.apache.maven.tools.plugin.extractor.ExtractionException;
import org.apache.maven.tools.plugin.generator.Generator; import org.apache.maven.tools.plugin.generator.Generator;
import org.apache.maven.tools.plugin.generator.GeneratorException;
import org.apache.maven.tools.plugin.scanner.MojoScanner; import org.apache.maven.tools.plugin.scanner.MojoScanner;
import org.apache.maven.tools.plugin.util.PluginUtils; import org.apache.maven.tools.plugin.util.PluginUtils;
import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.ReaderFactory;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.annotation.Documented;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@ -41,7 +46,6 @@ import java.util.Set;
* *
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a> * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @version $Id$ * @version $Id$
*
* @threadSafe * @threadSafe
*/ */
public abstract class AbstractGeneratorMojo public abstract class AbstractGeneratorMojo
@ -66,7 +70,7 @@ public abstract class AbstractGeneratorMojo
/** /**
* The file encoding of the source files. * The file encoding of the source files.
* *
* @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}" * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
* @since 2.5 * @since 2.5
*/ */
@ -79,6 +83,16 @@ public abstract class AbstractGeneratorMojo
*/ */
protected String goalPrefix; protected String goalPrefix;
/**
* By default an exception is throw if no mojo descriptor is found. As the maven-plugin is defined in core, the
* descriptor generator mojo is bound to generate-resources phase.
* But for annotations, the compiled classes are needed, so skip error
*
* @parameter expression="${maven.plugin.skipErrorNoDescriptorsFound}" default-value="false"
* @since 3.0
*/
protected boolean skipErrorNoDescriptorsFound;
/** /**
* The role names of mojo extractors to use. * The role names of mojo extractors to use.
* <p/> * <p/>
@ -90,12 +104,12 @@ public abstract class AbstractGeneratorMojo
* <pre> * <pre>
* &lt;!-- Use all mojo extractors --&gt; * &lt;!-- Use all mojo extractors --&gt;
* &lt;extractors/&gt; * &lt;extractors/&gt;
* *
* &lt;!-- Use no mojo extractors --&gt; * &lt;!-- Use no mojo extractors --&gt;
* &lt;extractors&gt; * &lt;extractors&gt;
* &lt;extractor/&gt; * &lt;extractor/&gt;
* &lt;/extractors&gt; * &lt;/extractors&gt;
* *
* &lt;!-- Use only bsh mojo extractor --&gt; * &lt;!-- Use only bsh mojo extractor --&gt;
* &lt;extractors&gt; * &lt;extractors&gt;
* &lt;extractor&gt;bsh&lt;/extractor&gt; * &lt;extractor&gt;bsh&lt;/extractor&gt;
@ -114,6 +128,36 @@ public abstract class AbstractGeneratorMojo
*/ */
protected boolean skip; protected boolean skip;
/**
* The set of dependencies for the current project
*
* @parameter default-value = "${project.artifacts}"
* @required
* @readonly
* @since 3.0
*/
protected Set<Artifact> dependencies;
/**
* List of Remote Repositories used by the resolver
*
* @parameter expression="${project.remoteArtifactRepositories}"
* @readonly
* @required
* @since 3.0
*/
protected List<ArtifactRepository> remoteRepos;
/**
* Location of the local repository.
*
* @parameter expression="${localRepository}"
* @readonly
* @required
* @since 3.0
*/
protected ArtifactRepository local;
/** /**
* @return the output directory where files will be generated. * @return the output directory where files will be generated.
*/ */
@ -124,7 +168,9 @@ public abstract class AbstractGeneratorMojo
*/ */
protected abstract Generator createGenerator(); protected abstract Generator createGenerator();
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public void execute() public void execute()
throws MojoExecutionException throws MojoExecutionException
{ {
@ -138,11 +184,11 @@ public abstract class AbstractGeneratorMojo
return; return;
} }
if ( project.getArtifactId().toLowerCase().startsWith( "maven-" ) if ( project.getArtifactId().toLowerCase().startsWith( "maven-" )
&& project.getArtifactId().toLowerCase().endsWith( "-plugin" ) && project.getArtifactId().toLowerCase().endsWith( "-plugin" ) && !"org.apache.maven.plugins".equals(
&& !"org.apache.maven.plugins".equals( project.getGroupId() ) ) project.getGroupId() ) )
{ {
getLog().error( "\n\nArtifact Ids of the format maven-___-plugin are reserved for \n" getLog().error( "\n\nArtifact Ids of the format maven-___-plugin are reserved for \n"
+ "plugins in the Group Id org.apache.maven.plugins\n" + "plugins in the Group Id org.apache.maven.plugins\n"
+ "Please change your artifactId to the format ___-maven-plugin\n" + "Please change your artifactId to the format ___-maven-plugin\n"
+ "In the future this error will break the build.\n\n" ); + "In the future this error will break the build.\n\n" );
@ -156,8 +202,8 @@ public abstract class AbstractGeneratorMojo
else if ( !goalPrefix.equals( defaultGoalPrefix ) ) else if ( !goalPrefix.equals( defaultGoalPrefix ) )
{ {
getLog().warn( getLog().warn(
"\n\nGoal prefix is specified as: '" + goalPrefix + "'. " "\n\nGoal prefix is specified as: '" + goalPrefix + "'. " + "Maven currently expects it to be '"
+ "Maven currently expects it to be '" + defaultGoalPrefix + "'.\n" ); + defaultGoalPrefix + "'.\n" );
} }
mojoScanner.setActiveExtractors( extractors ); mojoScanner.setActiveExtractors( extractors );
@ -180,19 +226,23 @@ public abstract class AbstractGeneratorMojo
if ( encoding == null || encoding.length() < 1 ) if ( encoding == null || encoding.length() < 1 )
{ {
getLog().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING getLog().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING
+ " actually) to read mojo metadata, i.e. build is platform dependent!" ); + " actually) to read mojo metadata, i.e. build is platform dependent!" );
} }
else else
{ {
getLog().info( "Using '" + encoding + "' encoding to read mojo metadata." ); getLog().info( "Using '" + encoding + "' encoding to read mojo metadata." );
} }
try try
{ {
pluginDescriptor.setDependencies( PluginUtils.toComponentDependencies( project.getRuntimeDependencies() ) ); pluginDescriptor.setDependencies( PluginUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor ); PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
request.setEncoding( encoding ); request.setEncoding( encoding );
request.setSkipErrorNoDescriptorsFound( skipErrorNoDescriptorsFound );
request.setDependencies( dependencies );
request.setLocal( this.local );
request.setRemoteRepos( this.remoteRepos );
mojoScanner.populatePluginDescriptor( request ); mojoScanner.populatePluginDescriptor( request );
@ -200,7 +250,7 @@ public abstract class AbstractGeneratorMojo
createGenerator().execute( getOutputDirectory(), request ); createGenerator().execute( getOutputDirectory(), request );
} }
catch ( IOException e ) catch ( GeneratorException e )
{ {
throw new MojoExecutionException( "Error writing plugin descriptor", e ); throw new MojoExecutionException( "Error writing plugin descriptor", e );
} }
@ -217,7 +267,8 @@ public abstract class AbstractGeneratorMojo
catch ( LinkageError e ) catch ( LinkageError e )
{ {
throw new MojoExecutionException( "The API of the mojo scanner is not compatible with this plugin version." throw new MojoExecutionException( "The API of the mojo scanner is not compatible with this plugin version."
+ " Please check the plugin dependencies configured in the POM and ensure the versions match.", e ); + " Please check the plugin dependencies configured in the POM and ensure the versions match.",
e );
} }
} }

View File

@ -19,20 +19,21 @@ package org.apache.maven.plugin.plugin;
* under the License. * under the License.
*/ */
import java.io.File;
import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.tools.plugin.generator.Generator; import org.apache.maven.tools.plugin.generator.Generator;
import org.apache.maven.tools.plugin.generator.PluginHelpGenerator; import org.apache.maven.tools.plugin.generator.PluginHelpGenerator;
import org.codehaus.plexus.velocity.VelocityComponent;
import java.io.File;
/** /**
* Generates a <code>HelpMojo</code> class. * Generates a <code>HelpMojo</code> class.
* *
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @version $Id$ * @version $Id$
* @since 2.4
* @goal helpmojo * @goal helpmojo
* @phase generate-sources * @phase generate-sources
* @since 2.4
*/ */
public class HelpGeneratorMojo public class HelpGeneratorMojo
extends AbstractGeneratorMojo extends AbstractGeneratorMojo
@ -47,7 +48,7 @@ public class HelpGeneratorMojo
/** /**
* The name of the package for the generated <code>HelpMojo</code>. By default, the package will be calculated based * The name of the package for the generated <code>HelpMojo</code>. By default, the package will be calculated based
* on the packages of the other plugin goals. * on the packages of the other plugin goals.
* *
* @parameter * @parameter
* @since 2.6 * @since 2.6
*/ */
@ -61,19 +62,35 @@ public class HelpGeneratorMojo
*/ */
private boolean useJava5; private boolean useJava5;
/** {@inheritDoc} */ /**
* Velocity component.
*
* @component
* @readonly
* @required
*/
private VelocityComponent velocity;
/**
* {@inheritDoc}
*/
protected File getOutputDirectory() protected File getOutputDirectory()
{ {
return outputDirectory; return outputDirectory;
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
protected Generator createGenerator() protected Generator createGenerator()
{ {
return new PluginHelpGenerator().setHelpPackageName( helpPackageName ).setUseJava5( useJava5 ); return new PluginHelpGenerator().setHelpPackageName( helpPackageName ).setUseJava5(
useJava5 ).setVelocityComponent( this.velocity );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public void execute() public void execute()
throws MojoExecutionException throws MojoExecutionException
{ {
@ -83,5 +100,7 @@ public class HelpGeneratorMojo
{ {
project.addCompileSourceRoot( outputDirectory.getAbsolutePath() ); project.addCompileSourceRoot( outputDirectory.getAbsolutePath() );
} }
} }
} }

View File

@ -19,15 +19,6 @@ package org.apache.maven.plugin.plugin;
* under the License. * under the License.
*/ */
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import org.apache.maven.doxia.sink.Sink; import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.siterenderer.Renderer; import org.apache.maven.doxia.siterenderer.Renderer;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
@ -42,21 +33,30 @@ import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
import org.apache.maven.tools.plugin.PluginToolsRequest; import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.extractor.ExtractionException; import org.apache.maven.tools.plugin.extractor.ExtractionException;
import org.apache.maven.tools.plugin.generator.GeneratorException;
import org.apache.maven.tools.plugin.generator.PluginXdocGenerator; import org.apache.maven.tools.plugin.generator.PluginXdocGenerator;
import org.apache.maven.tools.plugin.scanner.MojoScanner; import org.apache.maven.tools.plugin.scanner.MojoScanner;
import org.apache.maven.tools.plugin.util.PluginUtils; import org.apache.maven.tools.plugin.util.PluginUtils;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3Dom;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
/** /**
* Generates the Plugin's documentation report. * Generates the Plugin's documentation report.
* *
* @author <a href="snicoll@apache.org">Stephane Nicoll</a> * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @version $Id$ * @version $Id$
* @since 2.0
* @goal report * @goal report
* @execute phase="compile" * @execute phase="compile"
* @since 2.0
*/ */
public class PluginReport public class PluginReport
extends AbstractMavenReport extends AbstractMavenReport
@ -91,13 +91,12 @@ public class PluginReport
*/ */
protected MojoScanner mojoScanner; protected MojoScanner mojoScanner;
/** /**
* The file encoding of the source files. * The file encoding of the source files.
* *
* @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}" * @parameter expression="${encoding}" default-value="${project.build.sourceEncoding}"
* * @since 2.7
* @since 2.7 */
*/
private String encoding; private String encoding;
@ -124,10 +123,10 @@ public class PluginReport
private Requirements requirements; private Requirements requirements;
/** /**
* The goal prefix that will appear before the ":". * The goal prefix that will appear before the ":".
* By default, this plugin applies a heuristic to derive a heuristic from * By default, this plugin applies a heuristic to derive a heuristic from
* the plugin's artifactId. * the plugin's artifactId.
* * <p/>
* It removes any occurrences of the regular expression <strong>-?maven-?</strong>, * It removes any occurrences of the regular expression <strong>-?maven-?</strong>,
* and then removes any occurrences of <strong>-?plugin-?</strong>. * and then removes any occurrences of <strong>-?plugin-?</strong>.
* <p> * <p>
@ -158,31 +157,41 @@ public class PluginReport
*/ */
private boolean skipReport; private boolean skipReport;
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
protected Renderer getSiteRenderer() protected Renderer getSiteRenderer()
{ {
return siteRenderer; return siteRenderer;
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
protected String getOutputDirectory() protected String getOutputDirectory()
{ {
return outputDirectory.getPath(); return outputDirectory.getPath();
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
protected MavenProject getProject() protected MavenProject getProject()
{ {
return project; return project;
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public boolean canGenerateReport() public boolean canGenerateReport()
{ {
return "maven-plugin".equals( project.getPackaging() ); return "maven-plugin".equals( project.getPackaging() );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
protected void executeReport( Locale locale ) protected void executeReport( Locale locale )
throws MavenReportException throws MavenReportException
@ -205,8 +214,7 @@ public class PluginReport
} }
else else
{ {
getLog().warn( getLog().warn( "\n\nGoal prefix is specified as: '" + goalPrefix + "'. Maven currently expects it to be '"
"\n\nGoal prefix is specified as: '" + goalPrefix + "'. Maven currently expects it to be '"
+ defaultGoalPrefix + "'.\n" ); + defaultGoalPrefix + "'.\n" );
} }
@ -224,11 +232,11 @@ public class PluginReport
try try
{ {
pluginDescriptor.setDependencies( PluginUtils.toComponentDependencies( project.getRuntimeDependencies() ) ); pluginDescriptor.setDependencies( PluginUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor ); PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
request.setEncoding( encoding ); request.setEncoding( encoding );
try try
{ {
mojoScanner.populatePluginDescriptor( request ); mojoScanner.populatePluginDescriptor( request );
} }
@ -243,11 +251,11 @@ public class PluginReport
generatePluginDocumentation( pluginDescriptor, locale ); generatePluginDocumentation( pluginDescriptor, locale );
// Write the overview // Write the overview
PluginOverviewRenderer r = new PluginOverviewRenderer( project, requirements, getSink(), pluginDescriptor, PluginOverviewRenderer r =
locale ); new PluginOverviewRenderer( project, requirements, getSink(), pluginDescriptor, locale );
r.render(); r.render();
} }
catch ( ExtractionException e ) catch ( ExtractionException e )
{ {
throw new MavenReportException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'", throw new MavenReportException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
@ -255,19 +263,25 @@ public class PluginReport
} }
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public String getDescription( Locale locale ) public String getDescription( Locale locale )
{ {
return getBundle( locale ).getString( "report.plugin.description" ); return getBundle( locale ).getString( "report.plugin.description" );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public String getName( Locale locale ) public String getName( Locale locale )
{ {
return getBundle( locale ).getString( "report.plugin.name" ); return getBundle( locale ).getString( "report.plugin.name" );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public String getOutputName() public String getOutputName()
{ {
return "plugin-info"; return "plugin-info";
@ -275,7 +289,7 @@ public class PluginReport
/** /**
* @param pluginDescriptor not null * @param pluginDescriptor not null
* @param locale not null * @param locale not null
* @throws MavenReportException if any * @throws MavenReportException if any
*/ */
private void generatePluginDocumentation( PluginDescriptor pluginDescriptor, Locale locale ) private void generatePluginDocumentation( PluginDescriptor pluginDescriptor, Locale locale )
@ -287,9 +301,10 @@ public class PluginReport
outputDir.mkdirs(); outputDir.mkdirs();
PluginXdocGenerator generator = new PluginXdocGenerator( project, locale ); PluginXdocGenerator generator = new PluginXdocGenerator( project, locale );
generator.execute( outputDir, pluginDescriptor ); PluginToolsRequest pluginToolsRequest = new DefaultPluginToolsRequest( project, pluginDescriptor );
generator.execute( outputDir, pluginToolsRequest );
} }
catch ( IOException e ) catch ( GeneratorException e )
{ {
throw new MavenReportException( "Error writing plugin documentation", e ); throw new MavenReportException( "Error writing plugin documentation", e );
} }
@ -321,11 +336,11 @@ public class PluginReport
private final Locale locale; private final Locale locale;
/** /**
* @param project not null * @param project not null
* @param requirements not null * @param requirements not null
* @param sink not null * @param sink not null
* @param pluginDescriptor not null * @param pluginDescriptor not null
* @param locale not null * @param locale not null
*/ */
public PluginOverviewRenderer( MavenProject project, Requirements requirements, Sink sink, public PluginOverviewRenderer( MavenProject project, Requirements requirements, Sink sink,
PluginDescriptor pluginDescriptor, Locale locale ) PluginDescriptor pluginDescriptor, Locale locale )
@ -341,13 +356,17 @@ public class PluginReport
this.locale = locale; this.locale = locale;
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public String getTitle() public String getTitle()
{ {
return getBundle( locale ).getString( "report.plugin.title" ); return getBundle( locale ).getString( "report.plugin.title" );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
@SuppressWarnings( { "unchecked", "rawtypes" } ) @SuppressWarnings( { "unchecked", "rawtypes" } )
public void renderBody() public void renderBody()
{ {
@ -362,7 +381,6 @@ public class PluginReport
paragraph( getBundle( locale ).getString( "report.plugin.goals.intro" ) ); paragraph( getBundle( locale ).getString( "report.plugin.goals.intro" ) );
boolean hasMavenReport = false; boolean hasMavenReport = false;
for ( Iterator<MojoDescriptor> i = pluginDescriptor.getMojos().iterator(); i.hasNext(); ) for ( Iterator<MojoDescriptor> i = pluginDescriptor.getMojos().iterator(); i.hasNext(); )
{ {
@ -381,11 +399,11 @@ public class PluginReport
String descriptionColumnName = getBundle( locale ).getString( "report.plugin.goals.column.description" ); String descriptionColumnName = getBundle( locale ).getString( "report.plugin.goals.column.description" );
if ( hasMavenReport ) if ( hasMavenReport )
{ {
tableHeader( new String[] { goalColumnName, isMavenReport, descriptionColumnName } ); tableHeader( new String[]{ goalColumnName, isMavenReport, descriptionColumnName } );
} }
else else
{ {
tableHeader( new String[] { goalColumnName, descriptionColumnName } ); tableHeader( new String[]{ goalColumnName, descriptionColumnName } );
} }
List<MojoDescriptor> mojos = new ArrayList<MojoDescriptor>(); List<MojoDescriptor> mojos = new ArrayList<MojoDescriptor>();
@ -449,15 +467,16 @@ public class PluginReport
String maven = discoverMavenRequirement( project, requirements ); String maven = discoverMavenRequirement( project, requirements );
sink.tableRow(); sink.tableRow();
tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.maven" ) ); tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.maven" ) );
tableCell( ( maven != null ? maven : getBundle( locale ) tableCell( ( maven != null
.getString( "report.plugin.systemrequirements.nominimum" ) ) ); ? maven
: getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
sink.tableRow_(); sink.tableRow_();
String jdk = discoverJdkRequirement( project, requirements ); String jdk = discoverJdkRequirement( project, requirements );
sink.tableRow(); sink.tableRow();
tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.jdk" ) ); tableCell( getBundle( locale ).getString( "report.plugin.systemrequirements.jdk" ) );
tableCell( ( jdk != null ? jdk : getBundle( locale ) tableCell(
.getString( "report.plugin.systemrequirements.nominimum" ) ) ); ( jdk != null ? jdk : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
sink.tableRow_(); sink.tableRow_();
sink.tableRow(); sink.tableRow();
@ -482,9 +501,9 @@ public class PluginReport
sink.tableRow(); sink.tableRow();
tableCell( key ); tableCell( key );
tableCell( ( StringUtils.isNotEmpty( requirements.getOthers().getProperty( key ) ) ? requirements tableCell( ( StringUtils.isNotEmpty( requirements.getOthers().getProperty( key ) )
.getOthers().getProperty( key ) : getBundle( locale ) ? requirements.getOthers().getProperty( key )
.getString( "report.plugin.systemrequirements.nominimum" ) ) ); : getBundle( locale ).getString( "report.plugin.systemrequirements.nominimum" ) ) );
sink.tableRow_(); sink.tableRow_();
} }
} }
@ -515,31 +534,32 @@ public class PluginReport
sb.append( "<project>" ).append( '\n' ); sb.append( "<project>" ).append( '\n' );
sb.append( " ..." ).append( '\n' ); sb.append( " ..." ).append( '\n' );
sb.append( " <build>" ).append( '\n' ); sb.append( " <build>" ).append( '\n' );
sb.append( " <!-- " + getBundle( locale ).getString( "report.plugin.usage.pluginManagement" ) + " -->" ) sb.append(
.append( '\n' ); " <!-- " + getBundle( locale ).getString( "report.plugin.usage.pluginManagement" ) + " -->" ).append(
'\n' );
sb.append( " <pluginManagement>" ).append( '\n' ); sb.append( " <pluginManagement>" ).append( '\n' );
sb.append( " <plugins>" ).append( '\n' ); sb.append( " <plugins>" ).append( '\n' );
sb.append( " <plugin>" ).append( '\n' ); sb.append( " <plugin>" ).append( '\n' );
sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ) sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
.append( '\n' ); '\n' );
sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append( "</artifactId>" ) sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
.append( '\n' ); "</artifactId>" ).append( '\n' );
sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ) sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
.append( '\n' ); '\n' );
sb.append( " </plugin>" ).append( '\n' ); sb.append( " </plugin>" ).append( '\n' );
sb.append( " ..." ).append( '\n' ); sb.append( " ..." ).append( '\n' );
sb.append( " </plugins>" ).append( '\n' ); sb.append( " </plugins>" ).append( '\n' );
sb.append( " </pluginManagement>" ).append( '\n' ); sb.append( " </pluginManagement>" ).append( '\n' );
sb.append( " <!-- " + getBundle( locale ).getString( "report.plugin.usage.plugins" ) + " -->" ) sb.append( " <!-- " + getBundle( locale ).getString( "report.plugin.usage.plugins" ) + " -->" ).append(
.append( '\n' ); '\n' );
sb.append( " <plugins>" ).append( '\n' ); sb.append( " <plugins>" ).append( '\n' );
sb.append( " <plugin>" ).append( '\n' ); sb.append( " <plugin>" ).append( '\n' );
sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ) sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
.append( '\n' ); '\n' );
sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append( "</artifactId>" ) sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
.append( '\n' ); "</artifactId>" ).append( '\n' );
sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ) sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
.append( '\n' ); '\n' );
sb.append( " </plugin>" ).append( '\n' ); sb.append( " </plugin>" ).append( '\n' );
sb.append( " ..." ).append( '\n' ); sb.append( " ..." ).append( '\n' );
sb.append( " </plugins>" ).append( '\n' ); sb.append( " </plugins>" ).append( '\n' );
@ -548,17 +568,18 @@ public class PluginReport
if ( hasMavenReport ) if ( hasMavenReport )
{ {
sb.append( " ..." ).append( '\n' ); sb.append( " ..." ).append( '\n' );
sb.append( " <!-- " + getBundle( locale ).getString( "report.plugin.usage.reporting" ) + " -->" ) sb.append(
.append( '\n' ); " <!-- " + getBundle( locale ).getString( "report.plugin.usage.reporting" ) + " -->" ).append(
'\n' );
sb.append( " <reporting>" ).append( '\n' ); sb.append( " <reporting>" ).append( '\n' );
sb.append( " <plugins>" ).append( '\n' ); sb.append( " <plugins>" ).append( '\n' );
sb.append( " <plugin>" ).append( '\n' ); sb.append( " <plugin>" ).append( '\n' );
sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ) sb.append( " <groupId>" ).append( pluginDescriptor.getGroupId() ).append( "</groupId>" ).append(
.append( '\n' ); '\n' );
sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append( "</artifactId>" ) sb.append( " <artifactId>" ).append( pluginDescriptor.getArtifactId() ).append(
.append( '\n' ); "</artifactId>" ).append( '\n' );
sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ) sb.append( " <version>" ).append( pluginDescriptor.getVersion() ).append( "</version>" ).append(
.append( '\n' ); '\n' );
sb.append( " </plugin>" ).append( '\n' ); sb.append( " </plugin>" ).append( '\n' );
sb.append( " ..." ).append( '\n' ); sb.append( " ..." ).append( '\n' );
sb.append( " </plugins>" ).append( '\n' ); sb.append( " </plugins>" ).append( '\n' );
@ -581,7 +602,7 @@ public class PluginReport
* Try to lookup on the Maven prerequisites property. * Try to lookup on the Maven prerequisites property.
* If not specified, uses the value defined by the user. * If not specified, uses the value defined by the user.
* *
* @param project not null * @param project not null
* @param requirements not null * @param requirements not null
* @return the Maven version * @return the Maven version
*/ */
@ -606,7 +627,7 @@ public class PluginReport
* If not specified, uses the value defined by the user. * If not specified, uses the value defined by the user.
* If not specified, uses the value of the system property <code>java.specification.version</code>. * If not specified, uses the value of the system property <code>java.specification.version</code>.
* *
* @param project not null * @param project not null
* @param requirements not null * @param requirements not null
* @return the JDK version * @return the JDK version
*/ */
@ -686,11 +707,11 @@ public class PluginReport
jdk = pluginConf.getChild( "target" ).getValue(); jdk = pluginConf.getChild( "target" ).getValue();
} }
if ( jdk == null ) if ( jdk == null )
{ {
return backupJdk; return backupJdk;
} }
else else
{ {
return jdk; return jdk;
} }

View File

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId>
<version>3.0-SNAPSHOT</version>
</parent>
<artifactId>maven-plugin-tools-annotations</artifactId>
<name>Maven Plugin Tools Annotations</name>
<dependencies>
<!-- maven -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-project</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-descriptor</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
</dependency>
<dependency>
<groupId>com.thoughtworks.qdox</groupId>
<artifactId>qdox</artifactId>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-compiler-manager</artifactId>
<version>1.8.6</version>
<exclusions>
<exclusion>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-api</artifactId>
</exclusion>
</exclusions>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>test-jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,647 @@
package org.apache.maven.tools.plugin.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.DocletTag;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.plugin.descriptor.DuplicateParameterException;
import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.Requirement;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScannerRequest;
import org.apache.maven.tools.plugin.extractor.ExtractionException;
import org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor;
import org.codehaus.plexus.archiver.UnArchiver;
import org.codehaus.plexus.archiver.manager.ArchiverManager;
import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.StringUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class JavaAnnotationsMojoDescriptorExtractor
extends AbstractLogEnabled
implements MojoDescriptorExtractor
{
/**
* @requirement
*/
private MojoAnnotationsScanner mojoAnnotationsScanner;
/**
* @requirement
*/
private ArtifactResolver artifactResolver;
/**
* @requirement
*/
private ArtifactFactory artifactFactory;
/**
* @requirement
*/
private ArchiverManager archiverManager;
public List<MojoDescriptor> execute( MavenProject project, PluginDescriptor pluginDescriptor )
throws ExtractionException, InvalidPluginDescriptorException
{
return execute( new DefaultPluginToolsRequest( project, pluginDescriptor ) );
}
public List<MojoDescriptor> execute( PluginToolsRequest request )
throws ExtractionException, InvalidPluginDescriptorException
{
MojoAnnotationsScannerRequest mojoAnnotationsScannerRequest = new MojoAnnotationsScannerRequest();
mojoAnnotationsScannerRequest.setClassesDirectories(
Arrays.asList( new File( request.getProject().getBuild().getOutputDirectory() ) ) );
mojoAnnotationsScannerRequest.setDependencies( request.getDependencies() );
mojoAnnotationsScannerRequest.setProject( request.getProject() );
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses =
mojoAnnotationsScanner.scan( mojoAnnotationsScannerRequest );
// found artifact from reactors to scan sources
// we currently only scan sources from reactors
List<MavenProject> mavenProjects = new ArrayList<MavenProject>();
// if we need to scan sources from external artifacts
Set<Artifact> externalArtifacts = new HashSet<Artifact>();
for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses.values() )
{
if ( !StringUtils.equals( mojoAnnotatedClass.getArtifact().getArtifactId(),
request.getProject().getArtifact().getArtifactId() ) )
{
MavenProject mavenProject =
getFromProjectReferences( mojoAnnotatedClass.getArtifact(), request.getProject() );
if ( mavenProject != null )
{
mavenProjects.add( mavenProject );
}
else
{
externalArtifacts.add( mojoAnnotatedClass.getArtifact() );
}
}
}
Map<String, JavaClass> javaClassesMap = new HashMap<String, JavaClass>();
// try to get artifact with classifier sources
// extract somewhere then scan doclet for @since, @deprecated
for ( Artifact artifact : externalArtifacts )
{
// parameter for test-sources too ?? olamy I need that for it test only
if ( StringUtils.equalsIgnoreCase( "tests", artifact.getClassifier() ) )
{
javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "test-sources" ) );
}
else
{
javaClassesMap.putAll( discoverClassesFromSourcesJar( artifact, request, "sources" ) );
}
}
for ( MavenProject mavenProject : mavenProjects )
{
javaClassesMap.putAll( discoverClasses( request.getEncoding(), mavenProject ) );
}
javaClassesMap.putAll( discoverClasses( request ) );
populateDataFromJavadoc( mojoAnnotatedClasses, javaClassesMap );
return toMojoDescriptors( mojoAnnotatedClasses, request, javaClassesMap );
}
protected Map<String, JavaClass> discoverClassesFromSourcesJar( Artifact artifact, PluginToolsRequest request,
String classifier )
throws ExtractionException
{
try
{
Artifact sourcesArtifact =
artifactFactory.createArtifactWithClassifier( artifact.getGroupId(), artifact.getArtifactId(),
artifact.getVersion(), artifact.getType(), classifier );
artifactResolver.resolve( sourcesArtifact, request.getRemoteRepos(), request.getLocal() );
if ( sourcesArtifact.getFile() != null && sourcesArtifact.getFile().exists() )
{
File extractDirectory = new File( request.getProject().getBuild().getDirectory(),
"maven-plugin-plugin-sources/" + sourcesArtifact.getGroupId() + "/"
+ sourcesArtifact.getArtifactId() + "/"
+ sourcesArtifact.getVersion() + "/"
+ sourcesArtifact.getClassifier() );
if ( !extractDirectory.exists() )
{
extractDirectory.mkdirs();
}
// extract sources in a directory
//target/maven-plugin-plugin/${groupId}/${artifact}/sources
UnArchiver unArchiver = archiverManager.getUnArchiver( "jar" );
unArchiver.setSourceFile( sourcesArtifact.getFile() );
unArchiver.setDestDirectory( extractDirectory );
unArchiver.extract();
return discoverClasses( request.getEncoding(), Arrays.asList( extractDirectory ) );
}
}
catch ( ArtifactResolutionException e )
{
throw new ExtractionException( e.getMessage(), e );
}
catch ( ArtifactNotFoundException e )
{
//throw new ExtractionException( e.getMessage(), e );
getLogger().debug( "skip ArtifactNotFoundException:" + e.getMessage() );
getLogger().warn(
"Impossible to get sources artifact for " + artifact.getGroupId() + ":" + artifact.getArtifactId() + ":"
+ artifact.getVersion() + ". Some javadoc tags (@since, @deprecated and comments) won't be used" );
}
catch ( NoSuchArchiverException e )
{
throw new ExtractionException( e.getMessage(), e );
}
return Collections.emptyMap();
}
/**
* from sources scan to get @since and @deprecated and description of classes and fields.
*
* @param mojoAnnotatedClasses
* @param javaClassesMap
*/
protected void populateDataFromJavadoc( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
Map<String, JavaClass> javaClassesMap )
{
for ( Map.Entry<String, MojoAnnotatedClass> entry : mojoAnnotatedClasses.entrySet() )
{
JavaClass javaClass = javaClassesMap.get( entry.getKey() );
if ( javaClass != null )
{
MojoAnnotationContent mojoAnnotationContent = entry.getValue().getMojo();
if ( mojoAnnotationContent != null )
{
mojoAnnotationContent.setDescription( javaClass.getComment() );
DocletTag since = findInClassHierarchy( javaClass, "since" );
if ( since != null )
{
mojoAnnotationContent.setSince( since.getValue() );
}
DocletTag deprecated = findInClassHierarchy( javaClass, "deprecated" );
if ( deprecated != null )
{
mojoAnnotationContent.setDeprecated( deprecated.getValue() );
}
}
Map<String, JavaField> fieldsMap =
extractFieldParameterTags( javaClass, javaClassesMap, mojoAnnotatedClasses );
Map<String, ParameterAnnotationContent> parameters =
getParametersParentHierarchy( entry.getValue(), new HashMap<String, ParameterAnnotationContent>(),
mojoAnnotatedClasses );
for ( Map.Entry<String, ParameterAnnotationContent> parameter : new TreeMap<String, ParameterAnnotationContent>(
parameters ).entrySet() )
{
JavaField javaField = fieldsMap.get( parameter.getKey() );
if ( javaField != null )
{
ParameterAnnotationContent parameterAnnotationContent = parameter.getValue();
DocletTag deprecated = javaField.getTagByName( "deprecated" );
if ( deprecated != null )
{
parameterAnnotationContent.setDeprecated( deprecated.getValue() );
}
DocletTag since = javaField.getTagByName( "since" );
if ( since != null )
{
parameterAnnotationContent.setSince( since.getValue() );
}
parameterAnnotationContent.setDescription( javaField.getComment() );
}
}
for ( Map.Entry<String, ComponentAnnotationContent> component : entry.getValue().getComponents().entrySet() )
{
JavaField javaField = fieldsMap.get( component.getKey() );
if ( javaField != null )
{
ComponentAnnotationContent componentAnnotationContent = component.getValue();
DocletTag deprecated = javaField.getTagByName( "deprecated" );
if ( deprecated != null )
{
componentAnnotationContent.setDeprecated( deprecated.getValue() );
}
DocletTag since = javaField.getTagByName( "since" );
if ( since != null )
{
componentAnnotationContent.setSince( since.getValue() );
}
componentAnnotationContent.setDescription( javaField.getComment() );
}
}
}
}
}
/**
* @param javaClass not null
* @param tagName not null
* @return docletTag instance
*/
private DocletTag findInClassHierarchy( JavaClass javaClass, String tagName )
{
DocletTag tag = javaClass.getTagByName( tagName );
if ( tag == null )
{
JavaClass superClass = javaClass.getSuperJavaClass();
if ( superClass != null )
{
tag = findInClassHierarchy( superClass, tagName );
}
}
return tag;
}
/**
* extract fields that are either parameters or components.
*
* @param javaClass not null
* @return map with Mojo parameters names as keys
*/
private Map<String, JavaField> extractFieldParameterTags( JavaClass javaClass,
Map<String, JavaClass> javaClassesMap,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
Map<String, JavaField> rawParams = new TreeMap<String, com.thoughtworks.qdox.model.JavaField>();
// we have to add the parent fields first, so that they will be overwritten by the local fields if
// that actually happens...
JavaClass superClass = javaClass.getSuperJavaClass();
if ( superClass != null )
{
if ( superClass.getFields().length > 0 )
{
rawParams = extractFieldParameterTags( superClass, javaClassesMap, mojoAnnotatedClasses );
}
// maybe sources comes from scan of sources artifact
superClass = javaClassesMap.get( superClass.getFullyQualifiedName() );
if ( superClass != null )
{
rawParams = extractFieldParameterTags( superClass, javaClassesMap, mojoAnnotatedClasses );
}
}
else
{
rawParams = new TreeMap<String, JavaField>();
}
JavaField[] classFields = javaClass.getFields();
if ( classFields != null )
{
for ( JavaField field : classFields )
{
rawParams.put( field.getName(), field );
}
}
return rawParams;
}
protected Map<String, JavaClass> discoverClasses( final PluginToolsRequest request )
{
return discoverClasses( request.getEncoding(), request.getProject() );
}
protected Map<String, JavaClass> discoverClasses( final String encoding, final MavenProject project )
{
List<File> sources = new ArrayList<File>();
for ( String source : (List<String>) project.getCompileSourceRoots() )
{
sources.add( new File( source ) );
}
// TODO be more dynamic
File generatedPlugin = new File( project.getBasedir(), "target/generated-sources/plugin" );
if ( !project.getCompileSourceRoots().contains( generatedPlugin.getAbsolutePath() )
&& generatedPlugin.exists() )
{
sources.add( generatedPlugin );
}
return discoverClasses( encoding, sources );
}
protected Map<String, JavaClass> discoverClasses( final String encoding, List<File> sourceDirectories )
{
JavaDocBuilder builder = new JavaDocBuilder();
builder.setEncoding( encoding );
for ( File source : sourceDirectories )
{
builder.addSourceTree( source );
}
JavaClass[] javaClasses = builder.getClasses();
if ( javaClasses == null || javaClasses.length < 1 )
{
return Collections.emptyMap();
}
Map<String, JavaClass> javaClassMap = new HashMap<String, JavaClass>( javaClasses.length );
for ( JavaClass javaClass : javaClasses )
{
javaClassMap.put( javaClass.getFullyQualifiedName(), javaClass );
}
return javaClassMap;
}
private List<MojoDescriptor> toMojoDescriptors( Map<String, MojoAnnotatedClass> mojoAnnotatedClasses,
PluginToolsRequest request, Map<String, JavaClass> javaClassesMap )
throws DuplicateParameterException
{
List<MojoDescriptor> mojoDescriptors = new ArrayList<MojoDescriptor>( mojoAnnotatedClasses.size() );
for ( MojoAnnotatedClass mojoAnnotatedClass : mojoAnnotatedClasses.values() )
{
// no mojo so skip it
if ( mojoAnnotatedClass.getMojo() == null )
{
continue;
}
ExtendedMojoDescriptor mojoDescriptor = new ExtendedMojoDescriptor();
//mojoDescriptor.setRole( mojoAnnotatedClass.getClassName() );
//mojoDescriptor.setRoleHint( "default" );
mojoDescriptor.setImplementation( mojoAnnotatedClass.getClassName() );
mojoDescriptor.setLanguage( "java" );
MojoAnnotationContent mojo = mojoAnnotatedClass.getMojo();
mojoDescriptor.setDescription( mojo.getDescription() );
mojoDescriptor.setSince( mojo.getSince() );
mojo.setDeprecated( mojo.getDeprecated() );
mojoDescriptor.setAggregator( mojo.aggregator() );
mojoDescriptor.setDependencyResolutionRequired( mojo.requiresDependencyResolution() );
mojoDescriptor.setDependencyCollectionRequired( mojo.requiresDependencyCollection() );
mojoDescriptor.setDirectInvocationOnly( mojo.requiresDirectInvocation() );
mojoDescriptor.setDeprecated( mojo.getDeprecated() );
mojoDescriptor.setThreadSafe( mojo.threadSafe() );
ExecuteAnnotationContent execute = findExecuteInParentHierarchy( mojoAnnotatedClass, mojoAnnotatedClasses );
if ( execute != null )
{
mojoDescriptor.setExecuteGoal( execute.goal() );
mojoDescriptor.setExecuteLifecycle( execute.lifecycle() );
mojoDescriptor.setExecutePhase( execute.phase().id() );
}
mojoDescriptor.setExecutionStrategy( mojo.executionStrategy() );
// ???
//mojoDescriptor.alwaysExecute(mojo.a)
mojoDescriptor.setGoal( mojo.name() );
mojoDescriptor.setOnlineRequired( mojo.requiresOnline() );
mojoDescriptor.setPhase( mojo.defaultPhase().id() );
Map<String, ParameterAnnotationContent> parameters =
getParametersParentHierarchy( mojoAnnotatedClass, new HashMap<String, ParameterAnnotationContent>(),
mojoAnnotatedClasses );
for ( ParameterAnnotationContent parameterAnnotationContent : new TreeSet<ParameterAnnotationContent>(
parameters.values() ) )
{
org.apache.maven.plugin.descriptor.Parameter parameter =
new org.apache.maven.plugin.descriptor.Parameter();
parameter.setName( parameterAnnotationContent.getFieldName() );
parameter.setAlias( parameterAnnotationContent.alias() );
parameter.setDefaultValue( parameterAnnotationContent.defaultValue() );
parameter.setDeprecated( parameterAnnotationContent.getDeprecated() );
parameter.setDescription( parameterAnnotationContent.getDescription() );
parameter.setEditable( !parameterAnnotationContent.readonly() );
parameter.setExpression( parameterAnnotationContent.expression() );
parameter.setType( parameterAnnotationContent.getClassName() );
parameter.setSince( parameterAnnotationContent.getSince() );
parameter.setRequired( parameterAnnotationContent.required() );
mojoDescriptor.addParameter( parameter );
}
Map<String, ComponentAnnotationContent> components =
getComponentsParentHierarchy( mojoAnnotatedClass, new HashMap<String, ComponentAnnotationContent>(),
mojoAnnotatedClasses );
for ( ComponentAnnotationContent componentAnnotationContent : new TreeSet<ComponentAnnotationContent>(
components.values() ) )
{
org.apache.maven.plugin.descriptor.Parameter parameter =
new org.apache.maven.plugin.descriptor.Parameter();
parameter.setName( componentAnnotationContent.getFieldName() );
parameter.setRequirement(
new Requirement( componentAnnotationContent.role(), componentAnnotationContent.roleHint() ) );
parameter.setEditable( false );
parameter.setDeprecated( componentAnnotationContent.getDeprecated() );
parameter.setSince( componentAnnotationContent.getSince() );
mojoDescriptor.addParameter( parameter );
}
mojoDescriptor.setPluginDescriptor( request.getPluginDescriptor() );
mojoDescriptors.add( mojoDescriptor );
}
return mojoDescriptors;
}
protected ExecuteAnnotationContent findExecuteInParentHierarchy( MojoAnnotatedClass mojoAnnotatedClass,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
if ( mojoAnnotatedClass.getExecute() != null )
{
return mojoAnnotatedClass.getExecute();
}
String parentClassName = mojoAnnotatedClass.getParentClassName();
if ( StringUtils.isEmpty( parentClassName ) )
{
return null;
}
MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
if ( parent == null )
{
return null;
}
return findExecuteInParentHierarchy( parent, mojoAnnotatedClasses );
}
protected Map<String, ParameterAnnotationContent> getParametersParentHierarchy(
MojoAnnotatedClass mojoAnnotatedClass, Map<String, ParameterAnnotationContent> parameters,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
List<ParameterAnnotationContent> parameterAnnotationContents = new ArrayList<ParameterAnnotationContent>();
parameterAnnotationContents =
getParametersParent( mojoAnnotatedClass, parameterAnnotationContents, mojoAnnotatedClasses );
// move to parent first to build the Map
Collections.reverse( parameterAnnotationContents );
Map<String, ParameterAnnotationContent> map =
new HashMap<String, ParameterAnnotationContent>( parameterAnnotationContents.size() );
for ( ParameterAnnotationContent parameterAnnotationContent : parameterAnnotationContents )
{
map.put( parameterAnnotationContent.getFieldName(), parameterAnnotationContent );
}
return map;
}
protected List<ParameterAnnotationContent> getParametersParent( MojoAnnotatedClass mojoAnnotatedClass,
List<ParameterAnnotationContent> parameterAnnotationContents,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
parameterAnnotationContents.addAll( mojoAnnotatedClass.getParameters().values() );
String parentClassName = mojoAnnotatedClass.getParentClassName();
if ( parentClassName != null )
{
MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
if ( parent != null )
{
return getParametersParent( parent, parameterAnnotationContents, mojoAnnotatedClasses );
}
}
return parameterAnnotationContents;
}
protected Map<String, ComponentAnnotationContent> getComponentsParentHierarchy(
MojoAnnotatedClass mojoAnnotatedClass, Map<String, ComponentAnnotationContent> components,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
List<ComponentAnnotationContent> componentAnnotationContents = new ArrayList<ComponentAnnotationContent>();
componentAnnotationContents =
getComponentParent( mojoAnnotatedClass, componentAnnotationContents, mojoAnnotatedClasses );
// move to parent first to build the Map
Collections.reverse( componentAnnotationContents );
Map<String, ComponentAnnotationContent> map =
new HashMap<String, ComponentAnnotationContent>( componentAnnotationContents.size() );
for ( ComponentAnnotationContent componentAnnotationContent : componentAnnotationContents )
{
map.put( componentAnnotationContent.getFieldName(), componentAnnotationContent );
}
return map;
}
protected List<ComponentAnnotationContent> getComponentParent( MojoAnnotatedClass mojoAnnotatedClass,
List<ComponentAnnotationContent> componentAnnotationContents,
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses )
{
componentAnnotationContents.addAll( mojoAnnotatedClass.getComponents().values() );
String parentClassName = mojoAnnotatedClass.getParentClassName();
if ( parentClassName != null )
{
MojoAnnotatedClass parent = mojoAnnotatedClasses.get( parentClassName );
if ( parent != null )
{
return getComponentParent( parent, componentAnnotationContents, mojoAnnotatedClasses );
}
}
return componentAnnotationContents;
}
protected MavenProject getFromProjectReferences( Artifact artifact, MavenProject project )
{
if ( project.getProjectReferences() == null || project.getProjectReferences().isEmpty() )
{
return null;
}
Collection<MavenProject> mavenProjects = project.getProjectReferences().values();
for ( MavenProject mavenProject : mavenProjects )
{
if ( StringUtils.equals( mavenProject.getId(), artifact.getId() ) )
{
return mavenProject;
}
}
return null;
}
}

View File

@ -0,0 +1,66 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.artifact.Artifact;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class AnnotatedContent
{
private String description;
private String since;
private String deprecated;
public String getDescription()
{
return description;
}
public void setDescription( String description )
{
this.description = description;
}
public String getSince()
{
return since;
}
public void setSince( String since )
{
this.since = since;
}
public String getDeprecated()
{
return deprecated;
}
public void setDeprecated( String deprecated )
{
this.deprecated = deprecated;
}
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Olivier Lamy
* @since 3.0
*/
public class AnnotatedField
extends AnnotatedContent
implements Comparable<AnnotatedField>
{
private String fieldName;
public AnnotatedField( String fieldName )
{
this.fieldName = fieldName;
}
public String getFieldName()
{
return fieldName;
}
public void setFieldName( String name )
{
this.fieldName = name;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "AnnotatedField" );
sb.append( "{fieldName='" ).append( fieldName ).append( '\'' );
sb.append( '}' );
return sb.toString();
}
public int compareTo( AnnotatedField annotatedField )
{
return getFieldName().compareTo( annotatedField.getFieldName() );
}
}

View File

@ -0,0 +1,86 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Component;
import java.lang.annotation.Annotation;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class ComponentAnnotationContent
extends AnnotatedField
implements Component
{
private String role;
private String roleHint;
public ComponentAnnotationContent( String fieldName )
{
super( fieldName );
}
public ComponentAnnotationContent( String fieldName, String role, String roleHint )
{
this( fieldName );
this.role = role;
this.roleHint = roleHint;
}
public String role()
{
return role == null ? "" : role;
}
public void role( String role )
{
this.role = role;
}
public String roleHint()
{
return roleHint == null ? "" : roleHint;
}
public void roleHint( String roleHint )
{
this.roleHint = roleHint;
}
public Class<? extends Annotation> annotationType()
{
return null;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( super.toString() );
sb.append( "ComponentAnnotationContent" );
sb.append( "{role='" ).append( role ).append( '\'' );
sb.append( ", roleHint='" ).append( roleHint ).append( '\'' );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -0,0 +1,87 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import java.lang.annotation.Annotation;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class ExecuteAnnotationContent
implements Execute
{
private String goal;
private String lifecycle;
private LifecyclePhase phase;
public LifecyclePhase phase()
{
return this.phase;
}
public String goal()
{
return this.goal;
}
public String lifecycle()
{
return this.lifecycle;
}
public void phase( String phase )
{
this.phase = LifecyclePhase.valueOf( phase );
}
public void goal( String goal )
{
this.goal = goal;
}
public void lifecycle( String lifecycle )
{
this.lifecycle = lifecycle;
}
public Class<? extends Annotation> annotationType()
{
return null;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "ExecuteAnnotationContent" );
sb.append( "{goal='" ).append( goal ).append( '\'' );
sb.append( ", lifecycle='" ).append( lifecycle ).append( '\'' );
sb.append( ", phase=" ).append( phase );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -0,0 +1,229 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import java.lang.annotation.Annotation;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoAnnotationContent
extends AnnotatedContent
implements Mojo
{
private String name;
private LifecyclePhase defaultPhase = LifecyclePhase.NONE;
private String requiresDependencyResolution = "runtime";
private String requiresDependencyCollection;
private String instantiationStrategy = "per-lookup";
private String executionStrategy = "once-per-session";
private boolean requiresProject = true;
private boolean requiresReports = false;
private boolean aggregator = false;
private boolean requiresDirectInvocation = false;
private boolean requiresOnline = false;
private boolean inheritByDefault = true;
private String configurator;
private boolean threadSafe = false;
public Class<? extends Annotation> annotationType()
{
return null;
}
public LifecyclePhase defaultPhase()
{
return defaultPhase;
}
public void defaultPhase( String phase )
{
this.defaultPhase = LifecyclePhase.valueOf( phase );
}
public String requiresDependencyResolution()
{
return requiresDependencyResolution;
}
public void requiresDependencyResolution( String requiresDependencyResolution )
{
this.requiresDependencyResolution = requiresDependencyResolution;
}
public String requiresDependencyCollection()
{
return requiresDependencyCollection == null ? "" : requiresDependencyCollection;
}
public void requiresDependencyCollection( String requiresDependencyCollection )
{
this.requiresDependencyCollection = requiresDependencyCollection;
}
public String instantiationStrategy()
{
return instantiationStrategy;
}
public void instantiationStrategy( String instantiationStrategy )
{
this.instantiationStrategy = instantiationStrategy;
}
public String executionStrategy()
{
return executionStrategy;
}
public void executionStrategy( String executionStrategy )
{
this.executionStrategy = executionStrategy;
}
public boolean requiresProject()
{
return requiresProject;
}
public void requiresProject( boolean requiresProject )
{
this.requiresProject = requiresProject;
}
public boolean requiresReports()
{
return requiresReports;
}
public void requiresReports( boolean requiresReports )
{
this.requiresReports = requiresReports;
}
public boolean aggregator()
{
return aggregator;
}
public void aggregator( boolean aggregator )
{
this.aggregator = aggregator;
}
public boolean requiresDirectInvocation()
{
return requiresDirectInvocation;
}
public void requiresDirectInvocation( boolean requiresDirectInvocation )
{
this.requiresDirectInvocation = requiresDirectInvocation;
}
public boolean requiresOnline()
{
return requiresOnline;
}
public void requiresOnline( boolean requiresOnline )
{
this.requiresOnline = requiresOnline;
}
public boolean inheritByDefault()
{
return inheritByDefault;
}
public void inheritByDefault( boolean inheritByDefault )
{
this.inheritByDefault = inheritByDefault;
}
public String configurator()
{
return configurator;
}
public void configurator( String configurator )
{
this.configurator = configurator;
}
public boolean threadSafe()
{
return threadSafe;
}
public void threadSafe( boolean threadSafe )
{
this.threadSafe = threadSafe;
}
public String name()
{
return this.name;
}
public void name( String name )
{
this.name = name;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "MojoAnnotationContent" );
sb.append( "{name='" ).append( name ).append( '\'' );
sb.append( ", defaultPhase=" ).append( defaultPhase );
sb.append( ", requiresDependencyResolution='" ).append( requiresDependencyResolution ).append( '\'' );
sb.append( ", requiresDependencyCollection='" ).append( requiresDependencyCollection ).append( '\'' );
sb.append( ", instantiationStrategy='" ).append( instantiationStrategy ).append( '\'' );
sb.append( ", executionStrategy='" ).append( executionStrategy ).append( '\'' );
sb.append( ", requiresProject=" ).append( requiresProject );
sb.append( ", requiresReports=" ).append( requiresReports );
sb.append( ", aggregator=" ).append( aggregator );
sb.append( ", requiresDirectInvocation=" ).append( requiresDirectInvocation );
sb.append( ", requiresOnline=" ).append( requiresOnline );
sb.append( ", inheritByDefault=" ).append( inheritByDefault );
sb.append( ", configurator='" ).append( configurator ).append( '\'' );
sb.append( ", threadSafe=" ).append( threadSafe );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -0,0 +1,198 @@
package org.apache.maven.tools.plugin.annotations.datamodel;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Parameter;
import java.lang.annotation.Annotation;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class ParameterAnnotationContent
extends AnnotatedField
implements Parameter
{
private String alias;
private String expression;
private String defaultValue;
private boolean required = false;
private boolean readonly = false;
private String className;
public ParameterAnnotationContent( String fieldName, String className )
{
super( fieldName );
this.className = className;
}
public ParameterAnnotationContent( String fieldName, String alias, String expression, String defaultValue,
boolean required, boolean readonly, String className )
{
this( fieldName, className );
this.alias = alias;
this.expression = expression;
this.defaultValue = defaultValue;
this.required = required;
this.readonly = readonly;
}
public String alias()
{
return alias;
}
public void alias( String alias )
{
this.alias = alias;
}
public String expression()
{
return expression;
}
public void expression( String expression )
{
this.expression = expression;
}
public String defaultValue()
{
return defaultValue;
}
public void defaultValue( String defaultValue )
{
this.defaultValue = defaultValue;
}
public boolean required()
{
return required;
}
public void required( boolean required )
{
this.required = required;
}
public boolean readonly()
{
return readonly;
}
public void readonly( boolean readonly )
{
this.readonly = readonly;
}
public Class<? extends Annotation> annotationType()
{
return null;
}
public String getClassName()
{
return className;
}
public void setClassName( String className )
{
this.className = className;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( super.toString() );
sb.append( "ParameterAnnotationContent" );
sb.append( "{alias='" ).append( alias ).append( '\'' );
sb.append( ", expression='" ).append( expression ).append( '\'' );
sb.append( ", defaultValue='" ).append( defaultValue ).append( '\'' );
sb.append( ", required=" ).append( required );
sb.append( ", readonly=" ).append( readonly );
sb.append( '}' );
return sb.toString();
}
@Override
public boolean equals( Object o )
{
if ( this == o )
{
return true;
}
if ( !( o instanceof ParameterAnnotationContent ) )
{
return false;
}
ParameterAnnotationContent that = (ParameterAnnotationContent) o;
if ( readonly != that.readonly )
{
return false;
}
if ( required != that.required )
{
return false;
}
if ( getFieldName() != null ? !getFieldName().equals( that.getFieldName() ) : that.getFieldName() != null )
{
return false;
}
if ( alias != null ? !alias.equals( that.alias ) : that.alias != null )
{
return false;
}
if ( defaultValue != null ? !defaultValue.equals( that.defaultValue ) : that.defaultValue != null )
{
return false;
}
if ( expression != null ? !expression.equals( that.expression ) : that.expression != null )
{
return false;
}
return true;
}
@Override
public int hashCode()
{
int result = alias != null ? alias.hashCode() : 0;
result = 31 * result + ( getFieldName() != null ? getFieldName().hashCode() : 0 );
result = 31 * result + ( expression != null ? expression.hashCode() : 0 );
result = 31 * result + ( defaultValue != null ? defaultValue.hashCode() : 0 );
result = 31 * result + ( required ? 1 : 0 );
result = 31 * result + ( readonly ? 1 : 0 );
return result;
}
}

View File

@ -0,0 +1,321 @@
package org.apache.maven.tools.plugin.annotations.scanner;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.artifact.Artifact;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoAnnotationVisitor;
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoClassVisitor;
import org.apache.maven.tools.plugin.annotations.scanner.visitors.MojoFieldVisitor;
import org.apache.maven.tools.plugin.extractor.ExtractionException;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.reflection.Reflector;
import org.objectweb.asm.ClassReader;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class DefaultMojoAnnotationsScanner
extends AbstractLogEnabled
implements MojoAnnotationsScanner
{
private Reflector reflector = new Reflector();
public Map<String, MojoAnnotatedClass> scan( MojoAnnotationsScannerRequest request )
throws ExtractionException
{
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>();
try
{
for ( Artifact dependency : request.getDependencies() )
{
File dependencyFile = dependency.getFile();
if ( dependencyFile != null && dependencyFile.exists() )
{
if ( dependencyFile.isDirectory() )
{
mojoAnnotatedClasses.putAll(
scanDirectory( dependencyFile, request.getIncludePatterns(), dependency, true ) );
}
else
{
mojoAnnotatedClasses.putAll(
scanFile( dependencyFile, request.getIncludePatterns(), dependency, true ) );
}
}
}
for ( File classDirectory : request.getClassesDirectories() )
{
if ( classDirectory.exists() && classDirectory.isDirectory() )
{
mojoAnnotatedClasses.putAll(
scanDirectory( classDirectory, request.getIncludePatterns(), request.getProject().getArtifact(),
false ) );
}
}
return mojoAnnotatedClasses;
}
catch ( IOException e )
{
throw new ExtractionException( e.getMessage(), e );
}
}
/**
* @param archiveFile
* @param includePatterns
* @param artifact
* @param excludeMojo for dependencies we exclude Mojo annotations found
* @return
* @throws IOException
* @throws ExtractionException
*/
protected Map<String, MojoAnnotatedClass> scanFile( File archiveFile, List<String> includePatterns,
Artifact artifact, boolean excludeMojo )
throws IOException, ExtractionException
{
if ( !archiveFile.exists() )
{
return Collections.emptyMap();
}
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>();
ZipInputStream archiveStream = new ZipInputStream( new FileInputStream( archiveFile ) );
try
{
for ( ZipEntry zipEntry = archiveStream.getNextEntry(); zipEntry != null;
zipEntry = archiveStream.getNextEntry() )
{
if ( zipEntry.getName().endsWith( ".class" ) )
{
MojoClassVisitor mojoClassVisitor = new MojoClassVisitor( getLogger() );
ClassReader rdr = new ClassReader( archiveStream );
rdr.accept( mojoClassVisitor,
ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG );
analyzeVisitors( mojoClassVisitor );
if ( excludeMojo )
{
mojoClassVisitor.getMojoAnnotatedClass().setMojo( null );
}
if ( isMojoAnnnotatedClassCandidate( mojoClassVisitor.getMojoAnnotatedClass() ) != null )
{
getLogger().debug(
"found MojoAnnotatedClass:" + mojoClassVisitor.getMojoAnnotatedClass().getClassName() + ":"
+ mojoClassVisitor.getMojoAnnotatedClass() );
mojoClassVisitor.getMojoAnnotatedClass().setArtifact( artifact );
mojoAnnotatedClasses.put( mojoClassVisitor.getMojoAnnotatedClass().getClassName(),
mojoClassVisitor.getMojoAnnotatedClass() );
}
}
}
}
finally
{
IOUtil.close( archiveStream );
}
return mojoAnnotatedClasses;
}
/**
* @param classDirectory
* @param includePatterns
* @param artifact
* @param excludeMojo for dependencies we exclude Mojo annotations found
* @return
* @throws IOException
* @throws ExtractionException
*/
protected Map<String, MojoAnnotatedClass> scanDirectory( File classDirectory, List<String> includePatterns,
Artifact artifact, boolean excludeMojo )
throws IOException, ExtractionException
{
if ( !classDirectory.exists() )
{
return Collections.emptyMap();
}
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = new HashMap<String, MojoAnnotatedClass>();
DirectoryScanner scanner = new DirectoryScanner();
scanner.setBasedir( classDirectory );
scanner.addDefaultExcludes();
if ( includePatterns != null )
{
scanner.setIncludes( includePatterns.toArray( new String[includePatterns.size()] ) );
}
scanner.scan();
String[] classFiles = scanner.getIncludedFiles();
for ( String classFile : classFiles )
{
InputStream is = new BufferedInputStream( new FileInputStream( new File( classDirectory, classFile ) ) );
try
{
if ( classFile.endsWith( ".class" ) )
{
MojoClassVisitor mojoClassVisitor = new MojoClassVisitor( getLogger() );
ClassReader rdr = new ClassReader( is );
rdr.accept( mojoClassVisitor,
ClassReader.SKIP_FRAMES | ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG );
analyzeVisitors( mojoClassVisitor );
if ( excludeMojo )
{
mojoClassVisitor.getMojoAnnotatedClass().setMojo( null );
}
if ( isMojoAnnnotatedClassCandidate( mojoClassVisitor.getMojoAnnotatedClass() ) != null )
{
getLogger().debug(
"found MojoAnnotatedClass:" + mojoClassVisitor.getMojoAnnotatedClass().getClassName() + ":"
+ mojoClassVisitor.getMojoAnnotatedClass() );
mojoClassVisitor.getMojoAnnotatedClass().setArtifact( artifact );
mojoAnnotatedClasses.put( mojoClassVisitor.getMojoAnnotatedClass().getClassName(),
mojoClassVisitor.getMojoAnnotatedClass() );
}
}
}
finally
{
IOUtil.close( is );
}
}
return mojoAnnotatedClasses;
}
private MojoAnnotatedClass isMojoAnnnotatedClassCandidate( MojoAnnotatedClass mojoAnnotatedClass )
{
if ( mojoAnnotatedClass == null )
{
return null;
}
if ( !mojoAnnotatedClass.getComponents().isEmpty() || !mojoAnnotatedClass.getParameters().isEmpty()
|| mojoAnnotatedClass.getExecute() != null || mojoAnnotatedClass.getMojo() != null )
{
return mojoAnnotatedClass;
}
return null;
}
protected void analyzeVisitors( MojoClassVisitor mojoClassVisitor )
throws ExtractionException
{
try
{
MojoAnnotationVisitor mojoAnnotationVisitor =
mojoClassVisitor.getAnnotationVisitorMap().get( Mojo.class.getName() );
if ( mojoAnnotationVisitor != null )
{
MojoAnnotationContent mojoAnnotationContent = new MojoAnnotationContent();
for ( Map.Entry<String, Object> entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() )
{
reflector.invoke( mojoAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } );
}
mojoClassVisitor.getMojoAnnotatedClass().setMojo( mojoAnnotationContent );
}
mojoAnnotationVisitor = mojoClassVisitor.getAnnotationVisitorMap().get( Execute.class.getName() );
if ( mojoAnnotationVisitor != null )
{
ExecuteAnnotationContent executeAnnotationContent = new ExecuteAnnotationContent();
for ( Map.Entry<String, Object> entry : mojoAnnotationVisitor.getAnnotationValues().entrySet() )
{
reflector.invoke( executeAnnotationContent, entry.getKey(), new Object[]{ entry.getValue() } );
}
mojoClassVisitor.getMojoAnnotatedClass().setExecute( executeAnnotationContent );
}
List<MojoFieldVisitor> mojoFieldVisitors =
mojoClassVisitor.findFieldWithAnnotationClass( Parameter.class.getName() );
for ( MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors )
{
ParameterAnnotationContent parameterAnnotationContent =
new ParameterAnnotationContent( mojoFieldVisitor.getFieldName(), mojoFieldVisitor.getClassName() );
if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null )
{
for ( Map.Entry<String, Object> entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() )
{
reflector.invoke( parameterAnnotationContent, entry.getKey(),
new Object[]{ entry.getValue() } );
}
}
mojoClassVisitor.getMojoAnnotatedClass().getParameters().put( parameterAnnotationContent.getFieldName(),
parameterAnnotationContent );
}
mojoFieldVisitors = mojoClassVisitor.findFieldWithAnnotationClass( Component.class.getName() );
for ( MojoFieldVisitor mojoFieldVisitor : mojoFieldVisitors )
{
ComponentAnnotationContent componentAnnotationContent =
new ComponentAnnotationContent( mojoFieldVisitor.getFieldName() );
if ( mojoFieldVisitor.getMojoAnnotationVisitor() != null )
{
for ( Map.Entry<String, Object> entry : mojoFieldVisitor.getMojoAnnotationVisitor().getAnnotationValues().entrySet() )
{
reflector.invoke( componentAnnotationContent, entry.getKey(),
new Object[]{ entry.getValue() } );
}
if ( StringUtils.isEmpty( componentAnnotationContent.role() ) )
{
componentAnnotationContent.role( mojoFieldVisitor.getClassName() );
}
}
mojoClassVisitor.getMojoAnnotatedClass().getComponents().put( componentAnnotationContent.getFieldName(),
componentAnnotationContent );
}
}
catch ( Exception e )
{
throw new ExtractionException( e.getMessage(), e );
}
}
}

View File

@ -0,0 +1,162 @@
package org.apache.maven.tools.plugin.annotations.scanner;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.artifact.Artifact;
import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ExecuteAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.MojoAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
import java.util.HashMap;
import java.util.Map;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoAnnotatedClass
{
private String className;
private String parentClassName;
private MojoAnnotationContent mojo;
private ExecuteAnnotationContent execute;
/**
* key is field name
*/
private Map<String, ParameterAnnotationContent> parameters;
/**
* key is field name
*/
private Map<String, ComponentAnnotationContent> components;
/**
* artifact which contains this annotation
*/
private Artifact artifact;
public MojoAnnotatedClass()
{
// no op
}
public String getClassName()
{
return className;
}
public MojoAnnotatedClass setClassName( String className )
{
this.className = className;
return this;
}
public MojoAnnotationContent getMojo()
{
return mojo;
}
public MojoAnnotatedClass setMojo( MojoAnnotationContent mojo )
{
this.mojo = mojo;
return this;
}
public ExecuteAnnotationContent getExecute()
{
return execute;
}
public MojoAnnotatedClass setExecute( ExecuteAnnotationContent execute )
{
this.execute = execute;
return this;
}
public Map<String, ParameterAnnotationContent> getParameters()
{
if ( this.parameters == null )
{
this.parameters = new HashMap<String, ParameterAnnotationContent>();
}
return parameters;
}
public MojoAnnotatedClass setParameters( Map<String, ParameterAnnotationContent> parameters )
{
this.parameters = parameters;
return this;
}
public Map<String, ComponentAnnotationContent> getComponents()
{
if ( this.components == null )
{
this.components = new HashMap<String, ComponentAnnotationContent>();
}
return components;
}
public MojoAnnotatedClass setComponents( Map<String, ComponentAnnotationContent> components )
{
this.components = components;
return this;
}
public String getParentClassName()
{
return parentClassName;
}
public MojoAnnotatedClass setParentClassName( String parentClassName )
{
this.parentClassName = parentClassName;
return this;
}
public Artifact getArtifact()
{
return artifact;
}
public void setArtifact( Artifact artifact )
{
this.artifact = artifact;
}
@Override
public String toString()
{
final StringBuilder sb = new StringBuilder();
sb.append( "MojoAnnotatedClass" );
sb.append( "{className='" ).append( className ).append( '\'' );
sb.append( ", parentClassName='" ).append( parentClassName ).append( '\'' );
sb.append( ", mojo=" ).append( mojo );
sb.append( ", execute=" ).append( execute );
sb.append( ", parameters=" ).append( parameters );
sb.append( ", components=" ).append( components );
sb.append( '}' );
return sb.toString();
}
}

View File

@ -0,0 +1,47 @@
package org.apache.maven.tools.plugin.annotations.scanner;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.tools.plugin.extractor.ExtractionException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @author Olivier Lamy
* @since 3.0
*/
public interface MojoAnnotationsScanner
{
String ROLE = MojoAnnotationsScanner.class.getName();
static final List<String> acceptedClassLevelAnnotationClasses =
Arrays.asList( Mojo.class.getName(), Execute.class.getName() );
static final List<String> acceptedFieldLevelAnnotationClasses =
Arrays.asList( Parameter.class.getName(), Component.class.getName() );
Map<String, MojoAnnotatedClass> scan( MojoAnnotationsScannerRequest request )
throws ExtractionException;
}

View File

@ -0,0 +1,102 @@
package org.apache.maven.tools.plugin.annotations.scanner;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.artifact.Artifact;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.ProjectArtifactMetadata;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoAnnotationsScannerRequest
{
private List<File> classesDirectories = new ArrayList<File>();
private Set<Artifact> dependencies = new HashSet<Artifact>();
private List<String> includePatterns = Arrays.asList( "**/*.class" );
private List<File> sourceDirectories = new ArrayList<File>();
private MavenProject project;
public MojoAnnotationsScannerRequest()
{
// no o
}
public List<File> getClassesDirectories()
{
return classesDirectories;
}
public void setClassesDirectories( List<File> classesDirectories )
{
this.classesDirectories = classesDirectories;
}
public Set<Artifact> getDependencies()
{
return dependencies;
}
public void setDependencies( Set<Artifact> dependencies )
{
this.dependencies = dependencies;
}
public List<String> getIncludePatterns()
{
return includePatterns;
}
public void setIncludePatterns( List<String> includePatterns )
{
this.includePatterns = includePatterns;
}
public List<File> getSourceDirectories()
{
return sourceDirectories;
}
public void setSourceDirectories( List<File> sourceDirectories )
{
this.sourceDirectories = sourceDirectories;
}
public MavenProject getProject()
{
return project;
}
public void setProject( MavenProject project )
{
this.project = project;
}
}

View File

@ -0,0 +1,84 @@
package org.apache.maven.tools.plugin.annotations.scanner.visitors;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plexus.logging.Logger;
import org.objectweb.asm.AnnotationVisitor;
import java.util.HashMap;
import java.util.Map;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoAnnotationVisitor
implements AnnotationVisitor
{
private Logger logger;
private String annotationClassName;
private Map<String, Object> annotationValues = new HashMap<String, Object>();
MojoAnnotationVisitor( Logger logger, String annotationClassName )
{
this.logger = logger;
this.annotationClassName = annotationClassName;
}
public Map<String, Object> getAnnotationValues()
{
return annotationValues;
}
public void visit( String name, Object value )
{
annotationValues.put( name, value );
logger.debug( "MojoAnnotationVisitor#visit:" + name + ":" + value );
}
public void visitEnum( String name, String desc, String value )
{
annotationValues.put( name, value );
logger.debug( "MojoAnnotationVisitor#visitEnum:" + name + ":" + desc + ":" + value );
}
public AnnotationVisitor visitAnnotation( String name, String desc )
{
logger.debug( "MojoAnnotationVisitor#visitAnnotation:" + name + ":" + desc );
return new MojoAnnotationVisitor( logger, this.annotationClassName );
}
public AnnotationVisitor visitArray( String s )
{
logger.debug( "MojoAnnotationVisitor#visitArray" );
return new MojoAnnotationVisitor( logger, this.annotationClassName );
}
public void visitEnd()
{
logger.debug( "MojoAnnotationVisitor#visitEnd" );
}
public String getAnnotationClassName()
{
return annotationClassName;
}
}

View File

@ -0,0 +1,160 @@
package org.apache.maven.tools.plugin.annotations.scanner.visitors;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.tools.plugin.annotations.scanner.MojoAnnotatedClass;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.util.StringUtils;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoClassVisitor
implements ClassVisitor
{
private Logger logger;
private MojoAnnotatedClass mojoAnnotatedClass;
private Map<String, MojoAnnotationVisitor> annotationVisitorMap = new HashMap<String, MojoAnnotationVisitor>();
private List<MojoFieldVisitor> fieldVisitors = new ArrayList<MojoFieldVisitor>();
public MojoClassVisitor( Logger logger )
{
this.logger = logger;
}
public MojoAnnotatedClass getMojoAnnotatedClass()
{
return mojoAnnotatedClass;
}
public void setMojoAnnotatedClass( MojoAnnotatedClass mojoAnnotatedClass )
{
this.mojoAnnotatedClass = mojoAnnotatedClass;
}
public Map<String, MojoAnnotationVisitor> getAnnotationVisitorMap()
{
return annotationVisitorMap;
}
public void setAnnotationVisitorMap( Map<String, MojoAnnotationVisitor> annotationVisitorMap )
{
this.annotationVisitorMap = annotationVisitorMap;
}
public List<MojoFieldVisitor> getFieldVisitors()
{
return fieldVisitors;
}
public void setFieldVisitors( List<MojoFieldVisitor> fieldVisitors )
{
this.fieldVisitors = fieldVisitors;
}
public List<MojoFieldVisitor> findFieldWithAnnotationClass( String annotationClassName )
{
List<MojoFieldVisitor> mojoFieldVisitors = new ArrayList<MojoFieldVisitor>();
for ( MojoFieldVisitor mojoFieldVisitor : this.fieldVisitors )
{
MojoAnnotationVisitor mojoAnnotationVisitor = mojoFieldVisitor.getMojoAnnotationVisitor();
if ( mojoAnnotationVisitor != null && StringUtils.equals( annotationClassName,
mojoAnnotationVisitor.getAnnotationClassName() ) )
{
mojoFieldVisitors.add( mojoFieldVisitor );
}
}
return mojoFieldVisitors;
}
public void visit( int version, int access, String name, String signature, String superName, String[] interfaces )
{
mojoAnnotatedClass = new MojoAnnotatedClass();
mojoAnnotatedClass.setClassName( Type.getObjectType( name ).getClassName() ).setParentClassName(
Type.getObjectType( superName ).getClassName() );
logger.debug( "MojoClassVisitor#visit" );
}
public AnnotationVisitor visitAnnotation( String desc, boolean visible )
{
logger.debug( "MojoClassVisitor#visitAnnotation" );
String annotationClassName = Type.getType( desc ).getClassName();
if ( !MojoAnnotationsScanner.acceptedClassLevelAnnotationClasses.contains( annotationClassName ) )
{
return null;
}
MojoAnnotationVisitor mojoAnnotationVisitor = new MojoAnnotationVisitor( logger, annotationClassName );
annotationVisitorMap.put( annotationClassName, mojoAnnotationVisitor );
return mojoAnnotationVisitor;
}
public FieldVisitor visitField( int access, String name, String desc, String signature, Object value )
{
logger.debug( "MojoClassVisitor#visitField" );
MojoFieldVisitor mojoFieldVisitor = new MojoFieldVisitor( logger, name, Type.getType( desc ).getClassName() );
fieldVisitors.add( mojoFieldVisitor );
return mojoFieldVisitor;
}
public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions )
{
// we don't need methods informations
return null;
}
public void visitAttribute( Attribute attr )
{
}
public void visitSource( String source, String debug )
{
}
public void visitOuterClass( String owner, String name, String desc )
{
}
public void visitInnerClass( String name, String outerName, String innerName, int access )
{
}
public void visitEnd()
{
logger.debug( "MojoClassVisitor#visitEnd" );
}
}

View File

@ -0,0 +1,91 @@
package org.apache.maven.tools.plugin.annotations.scanner.visitors;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
import org.codehaus.plexus.logging.Logger;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Type;
/**
* @author Olivier Lamy
* @since 3.0
*/
public class MojoFieldVisitor
implements FieldVisitor
{
private Logger logger;
private String fieldName;
private MojoAnnotationVisitor mojoAnnotationVisitor;
private String className;
MojoFieldVisitor( Logger logger, String fieldName, String className )
{
this.logger = logger;
this.fieldName = fieldName;
this.className = className;
}
public MojoAnnotationVisitor getMojoAnnotationVisitor()
{
return mojoAnnotationVisitor;
}
public String getFieldName()
{
return fieldName;
}
public AnnotationVisitor visitAnnotation( String desc, boolean visible )
{
logger.debug( "MojoFieldVisitor#visitAnnotation:" + desc );
String annotationClassName = Type.getType( desc ).getClassName();
if ( !MojoAnnotationsScanner.acceptedFieldLevelAnnotationClasses.contains( annotationClassName ) )
{
return null;
}
mojoAnnotationVisitor = new MojoAnnotationVisitor( logger, annotationClassName );
return mojoAnnotationVisitor;
}
public void visitAttribute( Attribute attribute )
{
logger.debug( "MojoFieldVisitor#visitAttribute" );
}
public void visitEnd()
{
logger.debug( "MojoFieldVisitor#visitEnd" );
}
public String getClassName()
{
return className;
}
public void setClassName( String className )
{
this.className = className;
}
}

View File

@ -0,0 +1,56 @@
<!--
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you 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.
-->
<component-set>
<components>
<!--
|
| JavaMojoDescriptorExtractor, a MojoDescriptor extractor to read
| descriptors from java classes with annotations.
|
-->
<component>
<role>org.apache.maven.tools.plugin.extractor.MojoDescriptorExtractor</role>
<role-hint>java-annotations</role-hint>
<implementation>org.apache.maven.tools.plugin.annotations.JavaAnnotationsMojoDescriptorExtractor</implementation>
<requirements>
<requirement>
<role>org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.resolver.ArtifactResolver</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.factory.ArtifactFactory</role>
</requirement>
<requirement>
<role>org.codehaus.plexus.archiver.manager.ArchiverManager</role>
</requirement>
</requirements>
</component>
<component>
<role>org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner</role>
<role-hint>default</role-hint>
<implementation>org.apache.maven.tools.plugin.annotations.scanner.DefaultMojoAnnotationsScanner</implementation>
</component>
</components>
</component-set>

View File

@ -0,0 +1,71 @@
package org.apache.maven.tools.plugin.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.codehaus.plexus.compiler.manager.CompilerManager;
/**
* @author Olivier Lamy
*/
@Mojo( name = "foo", defaultPhase = LifecyclePhase.COMPILE, threadSafe = true )
@Execute( goal = "compiler", lifecycle = "my-lifecycle", phase = LifecyclePhase.PACKAGE )
public class FooMojo
extends AbstractMojo
{
/**
* the cool bar to go
* @since 1.0
*/
@Parameter( expression = "${thebar}", required = true, defaultValue = "coolbar" )
protected String bar;
/**
* beer for non french folks
* @deprecated wine is better
*/
@Parameter( expression = "${thebeer}", defaultValue = "coolbeer" )
protected String beer;
/**
* Plexus compiler manager.
*/
@Component
protected CompilerManager compilerManager;
/**
*
*/
@Component( role = "org.apache.maven.artifact.metadata.ArtifactMetadataSource", roleHint = "maven" )
protected ArtifactMetadataSource artifactMetadataSource;
public void execute()
throws MojoExecutionException, MojoFailureException
{
// nothing
}
}

View File

@ -0,0 +1,89 @@
package org.apache.maven.tools.plugin.annotations;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.plugins.annotations.Execute;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.annotations.datamodel.ComponentAnnotationContent;
import org.apache.maven.tools.plugin.annotations.datamodel.ParameterAnnotationContent;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotatedClass;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScanner;
import org.apache.maven.tools.plugin.annotations.scanner.MojoAnnotationsScannerRequest;
import org.codehaus.plexus.PlexusTestCase;
import org.fest.assertions.Assertions;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* @author Olivier Lamy
*/
public class TestAnnotationsReader
extends PlexusTestCase
{
public void testReadMojoClass()
throws Exception
{
MojoAnnotationsScanner mojoAnnotationsScanner = (MojoAnnotationsScanner) lookup( MojoAnnotationsScanner.ROLE );
MojoAnnotationsScannerRequest request = new MojoAnnotationsScannerRequest();
request.setClassesDirectories( Collections.singletonList( new File( "target/test-classes" ) ) );
request.setIncludePatterns( Arrays.asList( "**/FooMojo.class" ) );
request.setProject( new MavenProject() );
Map<String, MojoAnnotatedClass> mojoAnnotatedClasses = mojoAnnotationsScanner.scan( request );
System.out.println( "mojoAnnotatedClasses:" + mojoAnnotatedClasses );
Assertions.assertThat( mojoAnnotatedClasses ).isNotNull().isNotEmpty().hasSize( 1 );
MojoAnnotatedClass mojoAnnotatedClass = mojoAnnotatedClasses.values().iterator().next();
assertEquals( FooMojo.class.getName(), mojoAnnotatedClass.getClassName() );
assertEquals( AbstractMojo.class.getName(), mojoAnnotatedClass.getParentClassName() );
Mojo mojo = mojoAnnotatedClass.getMojo();
assertEquals( "foo", mojo.name() );
assertEquals( true, mojo.threadSafe() );
assertEquals( false, mojo.aggregator() );
assertEquals( LifecyclePhase.COMPILE, mojo.defaultPhase() );
Execute execute = mojoAnnotatedClass.getExecute();
assertEquals( "compiler", execute.goal() );
assertEquals( "my-lifecycle", execute.lifecycle() );
assertEquals( LifecyclePhase.PACKAGE, execute.phase() );
Collection<ComponentAnnotationContent> components = mojoAnnotatedClass.getComponents().values();
Assertions.assertThat( components ).isNotNull().isNotEmpty().hasSize( 2 );
Collection<ParameterAnnotationContent> parameters = mojoAnnotatedClass.getParameters().values();
Assertions.assertThat( parameters ).isNotNull().isNotEmpty().hasSize( 2 ).contains(
new ParameterAnnotationContent( "bar", null, "${thebar}", "coolbar", true, false, String.class.getName() ),
new ParameterAnnotationContent( "beer", null, "${thebeer}", "coolbeer", false, false,
String.class.getName() ) );
}
}

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-ant</artifactId> <artifactId>maven-plugin-tools-ant</artifactId>

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-api</artifactId> <artifactId>maven-plugin-tools-api</artifactId>
@ -71,6 +71,31 @@
<groupId>org.codehaus.plexus</groupId> <groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId> <artifactId>plexus-container-default</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-velocity</artifactId>
<exclusions>
<exclusion>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- other -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
</dependency>
<!-- misc --> <!-- misc -->
<dependency> <dependency>
@ -93,6 +118,20 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<java.io.tmpdir>${project.build.outputDirectory}</java.io.tmpdir>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
<profiles> <profiles>
<profile> <profile>
<id>reporting</id> <id>reporting</id>

View File

@ -19,23 +19,29 @@ package org.apache.maven.tools.plugin;
* under the License. * under the License.
*/ */
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.ReaderFactory;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/** /**
* Default implementation of {@link PluginToolsRequest}, which is used to pass parameters to components used to extract * Default implementation of {@link PluginToolsRequest}, which is used to pass parameters to components used to extract
* {@link MojoDescriptor} instances from different types of metadata for a given plugin. * {@link MojoDescriptor} instances from different types of metadata for a given plugin.
* *
* @author jdcasey * @author jdcasey
* @since 2.5 * @since 2.5
*/ */
public class DefaultPluginToolsRequest public class DefaultPluginToolsRequest
implements PluginToolsRequest implements PluginToolsRequest
{ {
private static final String DEFAULT_ENCODING = ReaderFactory.FILE_ENCODING; private static final String DEFAULT_ENCODING = ReaderFactory.FILE_ENCODING;
private PluginDescriptor pluginDescriptor; private PluginDescriptor pluginDescriptor;
@ -44,6 +50,14 @@ public class DefaultPluginToolsRequest
private String encoding = DEFAULT_ENCODING; private String encoding = DEFAULT_ENCODING;
private boolean skipErrorNoDescriptorsFound;
private Set<Artifact> dependencies;
private List<ArtifactRepository> remoteRepos;
private ArtifactRepository local;
public DefaultPluginToolsRequest( MavenProject project, PluginDescriptor pluginDescriptor ) public DefaultPluginToolsRequest( MavenProject project, PluginDescriptor pluginDescriptor )
{ {
this.project = project; this.project = project;
@ -57,7 +71,7 @@ public class DefaultPluginToolsRequest
{ {
return pluginDescriptor; return pluginDescriptor;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -74,7 +88,7 @@ public class DefaultPluginToolsRequest
{ {
return project; return project;
} }
/** /**
* {@inheritDoc} * {@inheritDoc}
*/ */
@ -109,4 +123,57 @@ public class DefaultPluginToolsRequest
return this; return this;
} }
/**
* {@inheritDoc}
*/
public boolean isSkipErrorNoDescriptorsFound()
{
return skipErrorNoDescriptorsFound;
}
/**
* {@inheritDoc}
*/
public PluginToolsRequest setSkipErrorNoDescriptorsFound( boolean skipErrorNoDescriptorsFound )
{
this.skipErrorNoDescriptorsFound = skipErrorNoDescriptorsFound;
return this;
}
public Set<Artifact> getDependencies()
{
if ( this.dependencies == null )
{
this.dependencies = new HashSet<Artifact>();
}
return dependencies;
}
public PluginToolsRequest setDependencies( Set<Artifact> dependencies )
{
this.dependencies = dependencies;
return this;
}
public List<ArtifactRepository> getRemoteRepos()
{
return remoteRepos;
}
public PluginToolsRequest setRemoteRepos( List<ArtifactRepository> remoteRepos )
{
this.remoteRepos = remoteRepos;
return this;
}
public ArtifactRepository getLocal()
{
return local;
}
public PluginToolsRequest setLocal( ArtifactRepository local )
{
this.local = local;
return this;
}
} }

View File

@ -19,30 +19,35 @@ package org.apache.maven.tools.plugin;
* under the License. * under the License.
*/ */
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import java.util.List;
import java.util.Set;
/** /**
* Request that encapsulates all information relevant to the process of extracting {@link MojoDescriptor} * Request that encapsulates all information relevant to the process of extracting {@link MojoDescriptor}
* instances from metadata for a certain type of mojo. * instances from metadata for a certain type of mojo.
* *
* @author jdcasey * @author jdcasey
* @since 2.5 * @since 2.5
*/ */
public interface PluginToolsRequest public interface PluginToolsRequest
{ {
/** /**
* Return the current {@link MavenProject} instance in use. * Return the current {@link MavenProject} instance in use.
*/ */
MavenProject getProject(); MavenProject getProject();
/** /**
* @see PluginToolsRequest#getProject() * @see PluginToolsRequest#getProject()
*/ */
PluginToolsRequest setProject( MavenProject project ); PluginToolsRequest setProject( MavenProject project );
/** /**
* Return the {@link PluginDescriptor} currently being populated as part of the build of the * Return the {@link PluginDescriptor} currently being populated as part of the build of the
* current plugin project. * current plugin project.
@ -53,21 +58,81 @@ public interface PluginToolsRequest
* @see PluginToolsRequest#getPluginDescriptor() * @see PluginToolsRequest#getPluginDescriptor()
*/ */
PluginToolsRequest setPluginDescriptor( PluginDescriptor pluginDescriptor ); PluginToolsRequest setPluginDescriptor( PluginDescriptor pluginDescriptor );
/** /**
* Gets the file encoding of the source files. * Gets the file encoding of the source files.
* *
* @return The file encoding of the source files, never <code>null</code>. * @return The file encoding of the source files, never <code>null</code>.
*/ */
String getEncoding(); String getEncoding();
/** /**
* Sets the file encoding of the source files. * Sets the file encoding of the source files.
* *
* @param encoding The file encoding of the source files, may be empty or <code>null</code> to use the platform's * @param encoding The file encoding of the source files, may be empty or <code>null</code> to use the platform's
* default encoding. * default encoding.
* @return This request. * @return This request.
*/ */
PluginToolsRequest setEncoding( String encoding ); PluginToolsRequest setEncoding( String encoding );
/**
* By default an exception is throw if no mojo descriptor is found. As the maven-plugin is defined in core, the
* descriptor generator mojo is bound to generate-resources phase.
* But for annotations, the compiled classes are needed, so skip error
*
* @since 3.0
*/
PluginToolsRequest setSkipErrorNoDescriptorsFound( boolean skipErrorNoDescriptorsFound );
/**
* @return
* @since 3.0
*/
boolean isSkipErrorNoDescriptorsFound();
/**
* Returns the list of {@link Artifact} used in class path scanning for annotations
*
* @return
* @since 3.0
*/
Set<Artifact> getDependencies();
/**
* @param dependencies
* @return
* @since 3.0
*/
PluginToolsRequest setDependencies( Set<Artifact> dependencies );
/**
*
* @return
* @since 3.0
*/
List<ArtifactRepository> getRemoteRepos();
/**
*
* @param remoteRepos
* @return
* @since 3.0
*/
PluginToolsRequest setRemoteRepos( List<ArtifactRepository> remoteRepos );
/**
*
* @return
* @since 3.0
*/
ArtifactRepository getLocal();
/**
*
* @param local
* @return
* @since 3.0
*/
PluginToolsRequest setLocal( ArtifactRepository local );
} }

View File

@ -33,18 +33,7 @@ import java.io.IOException;
*/ */
public interface Generator public interface Generator
{ {
/**
* Execute the generation for a given plugin descriptor.
*
* @param destinationDirectory required
* @param pluginDescriptor required
* @throws IOException if any
*
* @deprecated Use {@link Generator#execute(File, PluginToolsRequest)} instead.
*/
void execute( File destinationDirectory, PluginDescriptor pluginDescriptor )
throws IOException;
/** /**
* Execute the generation for a given plugin descriptor. * Execute the generation for a given plugin descriptor.
* *
@ -55,5 +44,5 @@ public interface Generator
* @since 2.5 * @since 2.5
*/ */
void execute( File destinationDirectory, PluginToolsRequest request ) void execute( File destinationDirectory, PluginToolsRequest request )
throws IOException; throws GeneratorException;
} }

View File

@ -0,0 +1,32 @@
package org.apache.maven.tools.plugin.generator;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* @author Olivier Lamy
* @since 3.0
*/
public class GeneratorException
extends Exception
{
public GeneratorException( String s, Throwable throwable )
{
super( s, throwable );
}
}

View File

@ -19,11 +19,12 @@ package org.apache.maven.tools.plugin.generator;
* under the License. * under the License.
*/ */
import org.apache.maven.plugin.descriptor.DuplicateMojoDescriptorException;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.plugin.descriptor.Requirement; import org.apache.maven.plugin.descriptor.Requirement;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.ExtendedMojoDescriptor; import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
import org.apache.maven.tools.plugin.PluginToolsRequest; import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.util.PluginUtils; import org.apache.maven.tools.plugin.util.PluginUtils;
@ -31,63 +32,130 @@ import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
import org.codehaus.plexus.util.xml.XMLWriter; import org.codehaus.plexus.util.xml.XMLWriter;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.commons.RemappingClassAdapter;
import org.objectweb.asm.commons.SimpleRemapper;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties;
import java.util.Set; import java.util.Set;
/** /**
* @version $Id$
* @todo add example usage tag that can be shown in the doco * @todo add example usage tag that can be shown in the doco
* @todo need to add validation directives so that systems embedding maven2 can * @todo need to add validation directives so that systems embedding maven2 can
* get validation directives to help users in IDEs. * get validation directives to help users in IDEs.
*
* @version $Id$
*/ */
public class PluginDescriptorGenerator public class PluginDescriptorGenerator
implements Generator implements Generator
{ {
/** {@inheritDoc} */
public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) /**
throws IOException * {@inheritDoc}
{ */
execute( destinationDirectory, new DefaultPluginToolsRequest( null, pluginDescriptor ) );
}
/** {@inheritDoc} */
public void execute( File destinationDirectory, PluginToolsRequest request ) public void execute( File destinationDirectory, PluginToolsRequest request )
throws IOException throws GeneratorException
{
File tmpPropertiesFile =
new File( request.getProject().getBuild().getDirectory(), "maven-plugin-help.properties" );
if ( tmpPropertiesFile.exists() )
{
Properties properties = new Properties();
try
{
properties.load( new FileInputStream( tmpPropertiesFile ) );
}
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
String helpPackageName = properties.getProperty( "helpPackageName" );
// if helpPackageName property is empty we have to rewrite the class with a better package name than empty
if ( StringUtils.isEmpty( helpPackageName ) )
{
String helpMojoImplementation = rewriteHelpClassToMojoPackage( request );
if ( helpMojoImplementation != null )
{
// rewrite plugin descriptor with new HelpMojo implementation class
rewriteDescriptor( request.getPluginDescriptor(), helpMojoImplementation );
}
}
}
try
{
File f = new File( destinationDirectory, "plugin.xml" );
writeDescriptor( f, request, false );
MavenProject mavenProject = request.getProject();
String pluginDescriptionFilePath =
"META-INF/maven/" + mavenProject.getGroupId() + "/" + mavenProject.getArtifactId()
+ "/plugin-description.xml";
f = new File( request.getProject().getBuild().getOutputDirectory(), pluginDescriptionFilePath );
writeDescriptor( f, request, true );
}
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
catch ( DuplicateMojoDescriptorException e )
{
throw new GeneratorException( e.getMessage(), e );
}
}
public void writeDescriptor( File destinationFile, PluginToolsRequest request, boolean cleanDescription )
throws IOException, DuplicateMojoDescriptorException
{ {
PluginDescriptor pluginDescriptor = request.getPluginDescriptor(); PluginDescriptor pluginDescriptor = request.getPluginDescriptor();
String encoding = "UTF-8";
File f = new File( destinationDirectory, "plugin.xml" ); if ( destinationFile.exists() )
if ( !f.getParentFile().exists() )
{ {
f.getParentFile().mkdirs(); destinationFile.delete();
} }
else
{
if ( !destinationFile.getParentFile().exists() )
{
destinationFile.getParentFile().mkdirs();
}
}
String encoding = "UTF-8";
Writer writer = null; Writer writer = null;
try try
{ {
writer = new OutputStreamWriter( new FileOutputStream( f ), encoding ); writer = new OutputStreamWriter( new FileOutputStream( destinationFile ), encoding );
XMLWriter w = new PrettyPrintXMLWriter( writer, encoding, null ); XMLWriter w = new PrettyPrintXMLWriter( writer, encoding, null );
w.startElement( "plugin" ); w.startElement( "plugin" );
PluginUtils.element( w, "name", pluginDescriptor.getName() ); PluginUtils.element( w, "name", pluginDescriptor.getName() );
if ( cleanDescription )
PluginUtils.element( w, "description", pluginDescriptor.getDescription() ); {
PluginUtils.element( w, "description", PluginUtils.toText( pluginDescriptor.getDescription() ) );
}
else
{
PluginUtils.element( w, "description", pluginDescriptor.getDescription() );
}
PluginUtils.element( w, "groupId", pluginDescriptor.getGroupId() ); PluginUtils.element( w, "groupId", pluginDescriptor.getGroupId() );
@ -105,11 +173,11 @@ public class PluginDescriptorGenerator
if ( pluginDescriptor.getMojos() != null ) if ( pluginDescriptor.getMojos() != null )
{ {
for ( @SuppressWarnings( "unchecked" ) for ( @SuppressWarnings( "unchecked" ) Iterator<MojoDescriptor> it =
Iterator<MojoDescriptor> it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) pluginDescriptor.getMojos().iterator(); it.hasNext(); )
{ {
MojoDescriptor descriptor = it.next(); MojoDescriptor descriptor = it.next();
processMojoDescriptor( descriptor, w ); processMojoDescriptor( descriptor, w, cleanDescription );
} }
} }
@ -120,6 +188,7 @@ public class PluginDescriptorGenerator
w.endElement(); w.endElement();
writer.flush(); writer.flush();
} }
finally finally
{ {
@ -128,10 +197,142 @@ public class PluginDescriptorGenerator
} }
/** /**
* @param mojoDescriptor not null * Creates a minimalistic mojo descriptor for the generated help goal.
* @param w not null *
* @param pluginDescriptor The descriptor of the plugin for which to generate a help goal, must not be
* <code>null</code>.
* @return The mojo descriptor for the generated help goal, never <code>null</code>.
*/ */
private MojoDescriptor makeHelpDescriptor( PluginDescriptor pluginDescriptor, String packageName )
{
MojoDescriptor descriptor = new MojoDescriptor();
descriptor.setPluginDescriptor( pluginDescriptor );
descriptor.setLanguage( "java" );
descriptor.setGoal( "help" );
if ( StringUtils.isEmpty( packageName ) )
{
packageName = discoverPackageName( pluginDescriptor );
}
if ( StringUtils.isNotEmpty( packageName ) )
{
descriptor.setImplementation( packageName + '.' + "HelpMojo" );
}
else
{
descriptor.setImplementation( "HelpMojo" );
}
descriptor.setDescription(
"Display help information on " + pluginDescriptor.getArtifactId() + ".<br/> Call <pre> mvn "
+ descriptor.getFullGoalName()
+ " -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details." );
try
{
Parameter param = new Parameter();
param.setName( "detail" );
param.setType( "boolean" );
param.setDescription( "If <code>true</code>, display all settable properties for each goal." );
param.setDefaultValue( "false" );
param.setExpression( "${detail}" );
descriptor.addParameter( param );
param = new Parameter();
param.setName( "goal" );
param.setType( "java.lang.String" );
param.setDescription(
"The name of the goal for which to show help." + " If unspecified, all goals will be displayed." );
param.setExpression( "${goal}" );
descriptor.addParameter( param );
param = new Parameter();
param.setName( "lineLength" );
param.setType( "int" );
param.setDescription( "The maximum length of a display line, should be positive." );
param.setDefaultValue( "80" );
param.setExpression( "${lineLength}" );
descriptor.addParameter( param );
param = new Parameter();
param.setName( "indentSize" );
param.setType( "int" );
param.setDescription( "The number of spaces per indentation level, should be positive." );
param.setDefaultValue( "2" );
param.setExpression( "${indentSize}" );
descriptor.addParameter( param );
}
catch ( Exception e )
{
throw new RuntimeException( "Failed to setup parameters for help goal", e );
}
return descriptor;
}
/**
* Find the best package name, based on the number of hits of actual Mojo classes.
*
* @param pluginDescriptor not null
* @return the best name of the package for the generated mojo
*/
private static String discoverPackageName( PluginDescriptor pluginDescriptor )
{
Map packageNames = new HashMap();
for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); )
{
MojoDescriptor descriptor = (MojoDescriptor) it.next();
String impl = descriptor.getImplementation();
if ( impl.lastIndexOf( '.' ) != -1 )
{
String name = impl.substring( 0, impl.lastIndexOf( '.' ) );
if ( packageNames.get( name ) != null )
{
int next = ( (Integer) packageNames.get( name ) ).intValue() + 1;
packageNames.put( name, new Integer( next ) );
}
else
{
packageNames.put( name, new Integer( 1 ) );
}
}
else
{
packageNames.put( "", new Integer( 1 ) );
}
}
String packageName = "";
int max = 0;
for ( Iterator it = packageNames.keySet().iterator(); it.hasNext(); )
{
String key = it.next().toString();
int value = ( (Integer) packageNames.get( key ) ).intValue();
if ( value > max )
{
max = value;
packageName = key;
}
}
return packageName;
}
protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w ) protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w )
{
processMojoDescriptor( mojoDescriptor, w, false );
}
/**
* @param mojoDescriptor not null
* @param w not null
* @param cleanDescription will clean html content from description fields
*/
protected void processMojoDescriptor( MojoDescriptor mojoDescriptor, XMLWriter w, boolean cleanDescription )
{ {
w.startElement( "mojo" ); w.startElement( "mojo" );
@ -152,7 +353,14 @@ public class PluginDescriptorGenerator
if ( description != null ) if ( description != null )
{ {
w.startElement( "description" ); w.startElement( "description" );
w.writeText( mojoDescriptor.getDescription() ); if ( cleanDescription )
{
w.writeText( PluginUtils.toText( mojoDescriptor.getDescription() ) );
}
else
{
w.writeText( mojoDescriptor.getDescription() );
}
w.endElement(); w.endElement();
} }
@ -323,8 +531,7 @@ public class PluginDescriptorGenerator
// Parameters // Parameters
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" ) List<Parameter> parameters = mojoDescriptor.getParameters();
List<Parameter> parameters = mojoDescriptor.getParameters();
w.startElement( "parameters" ); w.startElement( "parameters" );
@ -397,11 +604,17 @@ public class PluginDescriptorGenerator
PluginUtils.element( w, "required", Boolean.toString( parameter.isRequired() ) ); PluginUtils.element( w, "required", Boolean.toString( parameter.isRequired() ) );
PluginUtils.element( w, "editable", Boolean.toString( parameter.isEditable() ) ); PluginUtils.element( w, "editable", Boolean.toString( parameter.isEditable() ) );
if ( cleanDescription )
{
PluginUtils.element( w, "description", PluginUtils.toText( parameter.getDescription() ) );
}
else
{
PluginUtils.element( w, "description", parameter.getDescription() );
}
PluginUtils.element( w, "description", parameter.getDescription() ); if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) || StringUtils.isNotEmpty(
parameter.getExpression() ) )
if ( StringUtils.isNotEmpty( parameter.getDefaultValue() )
|| StringUtils.isNotEmpty( parameter.getExpression() ) )
{ {
configuration.add( parameter ); configuration.add( parameter );
} }
@ -480,4 +693,80 @@ public class PluginDescriptorGenerator
w.endElement(); w.endElement();
} }
protected String rewriteHelpClassToMojoPackage( PluginToolsRequest request )
throws GeneratorException
{
String destinationPackage = PluginHelpGenerator.discoverPackageName( request.getPluginDescriptor() );
if ( StringUtils.isEmpty( destinationPackage ) )
{
return null;
}
File helpClassFile = new File( request.getProject().getBuild().getOutputDirectory(), "HelpMojo.class" );
if ( !helpClassFile.exists() )
{
return null;
}
File rewriteHelpClassFile = new File(
request.getProject().getBuild().getOutputDirectory() + "/" + StringUtils.replace( destinationPackage, ".",
"/" ), "HelpMojo.class" );
if ( !rewriteHelpClassFile.getParentFile().exists() )
{
rewriteHelpClassFile.getParentFile().mkdirs();
}
ClassReader cr = null;
try
{
cr = new ClassReader( new FileInputStream( helpClassFile ) );
}
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
ClassWriter cw = new ClassWriter( 0 );
ClassVisitor cv = new RemappingClassAdapter( cw, new SimpleRemapper( "HelpMojo",
StringUtils.replace( destinationPackage,
".", "/" )
+ "/HelpMojo" ) );
try
{
cr.accept( cv, ClassReader.EXPAND_FRAMES );
}
catch ( Throwable e )
{
throw new GeneratorException( "ASM issue processing classFile " + helpClassFile.getPath(), e );
}
byte[] renamedClass = cw.toByteArray();
FileOutputStream fos = null;
try
{
fos = new FileOutputStream( rewriteHelpClassFile );
fos.write( renamedClass );
}
catch ( IOException e )
{
throw new GeneratorException( "Error rewriting help class: " + e.getMessage(), e );
}
finally
{
IOUtil.close( fos );
}
helpClassFile.delete();
return destinationPackage + ".HelpMojo";
}
private void rewriteDescriptor( PluginDescriptor pluginDescriptor, String helpMojoImplementation )
{
MojoDescriptor mojoDescriptor = pluginDescriptor.getMojo( "help" );
if ( mojoDescriptor != null )
{
mojoDescriptor.setImplementation( helpMojoImplementation );
}
}
} }

View File

@ -19,31 +19,32 @@ package org.apache.maven.tools.plugin.generator;
* under the License. * under the License.
*/ */
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.PluginToolsRequest; import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.util.PluginUtils; import org.apache.velocity.VelocityContext;
import org.codehaus.plexus.logging.AbstractLogEnabled; import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger; import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.velocity.VelocityComponent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/** /**
* Generates an <code>HelpMojo</code> class. * Generates an <code>HelpMojo</code> class.
@ -56,20 +57,30 @@ public class PluginHelpGenerator
extends AbstractLogEnabled extends AbstractLogEnabled
implements Generator implements Generator
{ {
/** Line separator */ /**
* Line separator
*/
private static final String LS = System.getProperty( "line.separator" ); private static final String LS = System.getProperty( "line.separator" );
/** Default generated class name */ /**
* Default generated class name
*/
private static final String HELP_MOJO_CLASS_NAME = "HelpMojo"; private static final String HELP_MOJO_CLASS_NAME = "HelpMojo";
/** Default goal */ /**
* Default goal
*/
private static final String HELP_GOAL = "help"; private static final String HELP_GOAL = "help";
private String helpPackageName; private String helpPackageName;
/** Flag to indicate if the generated help mojo should use Java 5 features */ /**
* Flag to indicate if the generated help mojo should use Java 5 features
*/
private boolean useJava5; private boolean useJava5;
private VelocityComponent velocityComponent;
/** /**
* Default constructor * Default constructor
*/ */
@ -82,46 +93,67 @@ public class PluginHelpGenerator
// Public methods // Public methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
/** {@inheritDoc} */
public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) /**
throws IOException * {@inheritDoc}
{ */
execute( destinationDirectory, new DefaultPluginToolsRequest( null, pluginDescriptor ) );
}
/** {@inheritDoc} */
public void execute( File destinationDirectory, PluginToolsRequest request ) public void execute( File destinationDirectory, PluginToolsRequest request )
throws IOException throws GeneratorException
{ {
PluginDescriptor pluginDescriptor = request.getPluginDescriptor(); PluginDescriptor pluginDescriptor = request.getPluginDescriptor();
if ( pluginDescriptor.getMojos() == null || pluginDescriptor.getMojos().size() < 1 )
{
return;
}
MojoDescriptor helpDescriptor = makeHelpDescriptor( pluginDescriptor ); MojoDescriptor helpDescriptor = makeHelpDescriptor( pluginDescriptor );
// Verify that no help goal already exists List<MojoDescriptor> mojoDescriptors = pluginDescriptor.getMojos();
for ( @SuppressWarnings( "unchecked" )
Iterator<MojoDescriptor> it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) if ( mojoDescriptors != null )
{ {
MojoDescriptor descriptor = it.next(); // Verify that no help goal already exists
for ( MojoDescriptor descriptor : mojoDescriptors )
if ( descriptor.getGoal().equals( helpDescriptor.getGoal() )
&& !descriptor.getImplementation().equals( helpDescriptor.getImplementation() ) )
{ {
if ( getLogger().isWarnEnabled() ) if ( descriptor.getGoal().equals( helpDescriptor.getGoal() ) && !descriptor.getImplementation().equals(
helpDescriptor.getImplementation() ) )
{ {
getLogger().warn( if ( getLogger().isWarnEnabled() )
"\n\nA help goal (" + descriptor.getImplementation() {
+ ") already exists in this plugin. SKIPPED THE " getLogger().warn( "\n\nA help goal (" + descriptor.getImplementation()
+ helpDescriptor.getImplementation() + " GENERATION.\n" ); + ") already exists in this plugin. SKIPPED THE "
} + helpDescriptor.getImplementation() + " GENERATION.\n" );
}
return; return;
}
} }
} }
Properties properties = new Properties();
properties.put( "helpPackageName", helpPackageName == null ? "" : helpPackageName );
MavenProject mavenProject = request.getProject();
String propertiesFilePath = "META-INF/maven/" + mavenProject.getGroupId() + "/" + mavenProject.getArtifactId();
File tmpPropertiesFile =
new File( request.getProject().getBuild().getDirectory(), "maven-plugin-help.properties" );
if ( tmpPropertiesFile.exists() )
{
tmpPropertiesFile.delete();
}
else
{
if ( !tmpPropertiesFile.getParentFile().exists() )
{
tmpPropertiesFile.getParentFile().mkdirs();
}
}
try
{
properties.store( new FileOutputStream( tmpPropertiesFile ), "maven plugin help generation informations" );
}
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
String sourcePath = helpDescriptor.getImplementation().replace( '.', File.separatorChar ) + ".java"; String sourcePath = helpDescriptor.getImplementation().replace( '.', File.separatorChar ) + ".java";
File helpClass = new File( destinationDirectory, sourcePath ); File helpClass = new File( destinationDirectory, sourcePath );
@ -131,13 +163,19 @@ public class PluginHelpGenerator
try try
{ {
writer = new OutputStreamWriter( new FileOutputStream( helpClass ), request.getEncoding() ); writer = new OutputStreamWriter( new FileOutputStream( helpClass ), request.getEncoding() );
writeClass( writer, pluginDescriptor, helpDescriptor, useJava5 ); writer.write( getHelpClassSources( propertiesFilePath ) );
writer.flush(); writer.flush();
} }
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
finally finally
{ {
IOUtil.close( writer ); IOUtil.close( writer );
} }
} }
public PluginHelpGenerator setHelpPackageName( String helpPackageName ) public PluginHelpGenerator setHelpPackageName( String helpPackageName )
@ -152,15 +190,52 @@ public class PluginHelpGenerator
return this; return this;
} }
public VelocityComponent getVelocityComponent()
{
return velocityComponent;
}
public PluginHelpGenerator setVelocityComponent( VelocityComponent velocityComponent )
{
this.velocityComponent = velocityComponent;
return this;
}
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// Private methods // Private methods
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
protected String getHelpClassSources( String propertiesFilePath )
{
Properties properties = new Properties();
VelocityContext context = new VelocityContext( properties );
if ( this.helpPackageName != null )
{
properties.put( "helpPackageName", this.helpPackageName );
}
else
{
properties.put( "helpPackageName", "" );
}
properties.put( "propertiesFilePath", propertiesFilePath + "/plugin-description.xml" );
// FIXME encoding !
StringWriter stringWriter = new StringWriter();
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream( "help-class-source.vm" );
InputStreamReader isReader = new InputStreamReader( is );
velocityComponent.getEngine().evaluate( context, stringWriter, "", isReader );
return stringWriter.toString();
}
/** /**
* Creates a minimalistic mojo descriptor for the generated help goal. * Creates a minimalistic mojo descriptor for the generated help goal.
* *
* @param pluginDescriptor The descriptor of the plugin for which to generate a help goal, must not be * @param pluginDescriptor The descriptor of the plugin for which to generate a help goal, must not be
* <code>null</code>. * <code>null</code>.
* @return The mojo descriptor for the generated help goal, never <code>null</code>. * @return The mojo descriptor for the generated help goal, never <code>null</code>.
*/ */
private MojoDescriptor makeHelpDescriptor( PluginDescriptor pluginDescriptor ) private MojoDescriptor makeHelpDescriptor( PluginDescriptor pluginDescriptor )
@ -187,9 +262,10 @@ public class PluginHelpGenerator
descriptor.setImplementation( HELP_MOJO_CLASS_NAME ); descriptor.setImplementation( HELP_MOJO_CLASS_NAME );
} }
descriptor.setDescription( "Display help information on " + pluginDescriptor.getArtifactId() descriptor.setDescription(
+ ".<br/> Call <pre> mvn " + descriptor.getFullGoalName() "Display help information on " + pluginDescriptor.getArtifactId() + ".<br/> Call <pre> mvn "
+ " -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details." ); + descriptor.getFullGoalName()
+ " -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details." );
try try
{ {
@ -204,8 +280,8 @@ public class PluginHelpGenerator
param = new Parameter(); param = new Parameter();
param.setName( "goal" ); param.setName( "goal" );
param.setType( "java.lang.String" ); param.setType( "java.lang.String" );
param.setDescription( "The name of the goal for which to show help." param.setDescription(
+ " If unspecified, all goals will be displayed." ); "The name of the goal for which to show help." + " If unspecified, all goals will be displayed." );
param.setExpression( "${goal}" ); param.setExpression( "${goal}" );
descriptor.addParameter( param ); descriptor.addParameter( param );
@ -239,597 +315,55 @@ public class PluginHelpGenerator
* @param pluginDescriptor not null * @param pluginDescriptor not null
* @return the best name of the package for the generated mojo * @return the best name of the package for the generated mojo
*/ */
private static String discoverPackageName( PluginDescriptor pluginDescriptor ) protected static String discoverPackageName( PluginDescriptor pluginDescriptor )
{ {
Map<String, Integer> packageNames = new HashMap<String, Integer>(); Map<String, Integer> packageNames = new HashMap<String, Integer>();
for ( @SuppressWarnings( "unchecked" ) List<MojoDescriptor> mojoDescriptors = pluginDescriptor.getMojos();
Iterator<MojoDescriptor> it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) if ( mojoDescriptors == null )
{
return "";
}
for ( MojoDescriptor descriptor : mojoDescriptors )
{ {
MojoDescriptor descriptor = it.next();
String name = "";
int next = 1;
String impl = descriptor.getImplementation(); String impl = descriptor.getImplementation();
if ( StringUtils.equals( descriptor.getGoal(), "help" ) && StringUtils.equals( "HelpMojo", impl ) )
{
continue;
}
if ( impl.lastIndexOf( '.' ) != -1 ) if ( impl.lastIndexOf( '.' ) != -1 )
{ {
name = impl.substring( 0, impl.lastIndexOf( '.' ) ); String name = impl.substring( 0, impl.lastIndexOf( '.' ) );
Integer count = packageNames.get( name ); if ( packageNames.get( name ) != null )
if ( count != null )
{ {
next = count.intValue() + 1; int next = ( packageNames.get( name ) ).intValue() + 1;
packageNames.put( name, new Integer( next ) );
}
else
{
packageNames.put( name, new Integer( 1 ) );
} }
} }
else
packageNames.put( name, next ); {
packageNames.put( "", new Integer( 1 ) );
}
} }
String packageName = ""; String packageName = "";
int max = 0; int max = 0;
for ( Map.Entry<String, Integer> entry : packageNames.entrySet() ) for ( Iterator it = packageNames.keySet().iterator(); it.hasNext(); )
{ {
int value = entry.getValue().intValue(); String key = it.next().toString();
int value = ( packageNames.get( key ) ).intValue();
if ( value > max ) if ( value > max )
{ {
max = value; max = value;
packageName = entry.getKey(); packageName = key;
} }
} }
return packageName; return packageName;
} }
/**
* Generates the <code>HelpMojo</code> class.
*
* @param writer not null
* @param pluginDescriptor not null
* @param helpDescriptor not null
* @param useJava5 If the generated code should use Java5 features
* @throws IOException if any
*/
private static void writeClass( Writer writer, PluginDescriptor pluginDescriptor, MojoDescriptor helpDescriptor,
boolean useJava5 )
throws IOException
{
String packageName = "";
String simpleName = helpDescriptor.getImplementation();
int dot = simpleName.lastIndexOf( '.' );
if ( dot >= 0 )
{
packageName = simpleName.substring( 0, dot );
simpleName = simpleName.substring( dot + 1 );
}
if ( packageName.length() > 0 )
{
writer.write( "package " + packageName + ";" + LS );
writer.write( LS );
}
writeImports( writer );
writer.write( LS );
writeMojoJavadoc( writer, pluginDescriptor, helpDescriptor );
if ( useJava5 )
{
writer.write( "@SuppressWarnings( \"all\" )" + LS );
}
writer.write( "public class " + simpleName + LS );
writer.write( " extends AbstractMojo" + LS );
writer.write( "{" + LS );
writeVariables( writer, helpDescriptor );
writer.write( LS );
writeExecute( writer, pluginDescriptor, helpDescriptor );
writer.write( LS );
writeUtilities( writer, useJava5 );
writer.write( "}" + LS );
}
/**
* @param writer not null
* @throws IOException if any
*/
private static void writeImports( Writer writer )
throws IOException
{
writer.write( "import java.util.ArrayList;" + LS );
writer.write( "import java.util.Iterator;" + LS );
writer.write( "import java.util.List;" + LS );
writer.write( LS );
writer.write( "import org.apache.maven.plugin.AbstractMojo;" + LS );
writer.write( "import org.apache.maven.plugin.MojoExecutionException;" + LS );
}
/**
* @param writer not null
* @param pluginDescriptor not null
* @param helpDescriptor not null
* @throws IOException if any
*/
private static void writeMojoJavadoc( Writer writer, PluginDescriptor pluginDescriptor,
MojoDescriptor helpDescriptor )
throws IOException
{
StringBuffer author = new StringBuffer();
author.append( PluginHelpGenerator.class.getName() );
String resource = "META-INF/maven/org.apache.maven.plugin-tools/maven-plugin-tools-api/pom.properties";
InputStream resourceAsStream = PluginHelpGenerator.class.getClassLoader().getResourceAsStream( resource );
if ( resourceAsStream != null )
{
try
{
Properties properties = new Properties();
properties.load( resourceAsStream );
author.append( " (version " ).append( properties.getProperty( "version", "unknown" ) ).append( ")" );
}
catch ( IOException e )
{
// nope
}
finally
{
IOUtil.close( resourceAsStream );
}
}
writer.write( "/**" + LS );
writer.write( " * " + helpDescriptor.getDescription() + LS );
writer.write( " *" + LS );
writer.write( " * @version generated on " + new Date() + LS );
writer.write( " * @author " + author.toString() + LS );
writer.write( " * @goal " + helpDescriptor.getGoal() + LS );
writer.write( " * @requiresProject false" + LS );
writer.write( " * @threadSafe" + LS );
writer.write( " */" + LS );
}
/**
* @param writer not null
* @param helpDescriptor not null
* @throws IOException if any
*/
private static void writeVariables( Writer writer, MojoDescriptor helpDescriptor )
throws IOException
{
for ( @SuppressWarnings( "unchecked" )
Iterator<Parameter> it = helpDescriptor.getParameters().iterator(); it.hasNext(); )
{
Parameter param = it.next();
writer.write( " /**" + LS );
writer.write( " * " + StringUtils.escape( param.getDescription() ) + LS );
writer.write( " * " + LS );
writer.write( " * @parameter" );
if ( StringUtils.isNotEmpty( param.getExpression() ) )
{
writer.write( " expression=\"" );
writer.write( StringUtils.escape( param.getExpression() ) );
writer.write( "\"" );
}
if ( StringUtils.isNotEmpty( param.getDefaultValue() ) )
{
writer.write( " default-value=\"" );
writer.write( StringUtils.escape( param.getDefaultValue() ) );
writer.write( "\"" );
}
writer.write( LS );
writer.write( " */" + LS );
writer.write( " private " + param.getType() + " " + param.getName() + ";" + LS );
writer.write( LS );
}
}
/**
* @param writer not null
* @param pluginDescriptor not null
* @param helpDescriptor not null
* @throws IOException if any
*/
private static void writeExecute( Writer writer, PluginDescriptor pluginDescriptor, MojoDescriptor helpDescriptor )
throws IOException
{
List<MojoDescriptor> mojoDescriptors = new ArrayList<MojoDescriptor>();
mojoDescriptors.add( helpDescriptor );
for ( @SuppressWarnings( "unchecked" )
Iterator<MojoDescriptor> it = pluginDescriptor.getMojos().iterator(); it.hasNext(); )
{
MojoDescriptor mojoDescriptor = it.next();
if ( !helpDescriptor.getGoal().equals( mojoDescriptor.getGoal() ) )
{
mojoDescriptors.add( mojoDescriptor );
}
}
PluginUtils.sortMojos( mojoDescriptors );
writer.write( " /** {@inheritDoc} */" + LS );
writer.write( " public void execute()" + LS );
writer.write( " throws MojoExecutionException" + LS );
writer.write( " {" + LS );
writer.write( " if ( lineLength <= 0 )" + LS );
writer.write( " {" + LS );
writer.write( " getLog().warn( \"The parameter 'lineLength' should be positive, using '80' as "
+ "default.\" );" + LS );
writer.write( " lineLength = 80;" + LS );
writer.write( " }" + LS );
writer.write( " if ( indentSize <= 0 )" + LS );
writer.write( " {" + LS );
writer.write( " getLog().warn( \"The parameter 'indentSize' should be positive, using '2' as "
+ "default.\" );" + LS );
writer.write( " indentSize = 2;" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " StringBuffer sb = new StringBuffer();" + LS );
writer.write( LS );
writer.write( " append( sb, \"" + StringUtils.escape( pluginDescriptor.getId() ) + "\", 0 );" + LS );
writer.write( " append( sb, \"\", 0 );" + LS );
writer.write( LS );
if ( StringUtils.isNotEmpty( pluginDescriptor.getName() )
&& ( pluginDescriptor.getName().indexOf( pluginDescriptor.getId() ) != -1 ) )
{
writer.write( " append( sb, \""
+ StringUtils.escape( pluginDescriptor.getName() + " " + pluginDescriptor.getVersion() )
+ "\", 0 );" + LS );
}
else
{
if ( StringUtils.isNotEmpty( pluginDescriptor.getName() ) )
{
writer.write( " append( sb, \"" + StringUtils.escape( pluginDescriptor.getName() )
+ "\", 0 );" + LS );
}
else
{
writer.write( " append( sb, \"" + StringUtils.escape( pluginDescriptor.getId() )
+ "\", 0 );" + LS );
}
}
writer.write( " append( sb, \"" + toDescription( pluginDescriptor.getDescription() ) + "\", 1 );"
+ LS );
writer.write( " append( sb, \"\", 0 );" + LS );
writer.write( LS );
writer.write( " if ( goal == null || goal.length() <= 0 )" + LS );
writer.write( " {" + LS );
writer.write( " append( sb, \"This plugin has " + mojoDescriptors.size() + " "
+ ( mojoDescriptors.size() > 1 ? "goals" : "goal" ) + ":\", 0 );" + LS );
writer.write( " append( sb, \"\", 0 );" + LS );
writer.write( " }" + LS );
writer.write( LS );
for ( MojoDescriptor descriptor : mojoDescriptors )
{
writeGoal( writer, descriptor );
}
writer.write( " if ( getLog().isInfoEnabled() )" + LS );
writer.write( " {" + LS );
writer.write( " getLog().info( sb.toString() );" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
}
/**
* @param writer not null
* @param descriptor not null
* @throws IOException if any
*/
private static void writeGoal( Writer writer, MojoDescriptor descriptor )
throws IOException
{
String goalDescription = toDescription( descriptor.getDescription() );
writer.write( " if ( goal == null || goal.length() <= 0 || \""
+ StringUtils.escape( descriptor.getGoal() ) + "\".equals( goal ) )" + LS );
writer.write( " {" + LS );
writer.write( " append( sb, \"" + StringUtils.escape( descriptor.getFullGoalName() ) + "\", 0 );"
+ LS );
if ( StringUtils.isNotEmpty( descriptor.getDeprecated() ) )
{
writer.write( " append( sb, \"Deprecated. " + toDescription( descriptor.getDeprecated() )
+ "\", 1 );" + LS );
writer.write( " if ( detail )" + LS );
writer.write( " {" + LS );
writer.write( " append( sb, \"\", 0 );" + LS );
writer.write( " append( sb, \"" + goalDescription + "\", 1 );" + LS );
writer.write( " }" + LS );
}
else
{
writer.write( " append( sb, \"" + goalDescription + "\", 1 );" + LS );
}
writer.write( " append( sb, \"\", 0 );" + LS );
if ( descriptor.getParameters() != null && descriptor.getParameters().size() > 0 )
{
@SuppressWarnings( "unchecked" )
List<Parameter> params = descriptor.getParameters();
PluginUtils.sortMojoParameters( params );
writer.write( " if ( detail )" + LS );
writer.write( " {" + LS );
writer.write( " append( sb, \"Available parameters:\", 1 );" + LS );
writer.write( " append( sb, \"\", 0 );" + LS );
for ( Parameter parameter : params )
{
if ( parameter.isEditable() )
{
writer.write( LS );
writeParameter( writer, parameter );
}
}
writer.write( " }" + LS );
}
writer.write( " }" + LS );
writer.write( LS );
}
/**
* @param writer not null
* @param parameter not null
* @throws IOException if any
*/
private static void writeParameter( Writer writer, Parameter parameter )
throws IOException
{
String expression = parameter.getExpression();
if ( expression == null || !expression.startsWith( "${component." ) )
{
String parameterName = StringUtils.escape( parameter.getName() );
String parameterDescription = toDescription( parameter.getDescription() );
String parameterDefaultValue = "";
if ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) )
{
parameterDefaultValue = " (Default: " + StringUtils.escape( parameter.getDefaultValue() ) + ")";
}
writer.write( " append( sb, \"" + parameterName + parameterDefaultValue + "\", 2 );" + LS );
if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) )
{
writer.write( " append( sb, \"Deprecated. " + toDescription( parameter.getDeprecated() )
+ "\", 3 );" + LS );
writer.write( " append( sb, \"\", 0 );" + LS );
}
writer.write( " append( sb, \"" + parameterDescription + "\", 3 );" + LS );
if ( parameter.isRequired() )
{
writer.write( " append( sb, \"Required: Yes\", 3 );" + LS );
}
if ( StringUtils.isNotEmpty( parameter.getExpression() ) )
{
writer.write( " append( sb, \"Expression: "
+ StringUtils.escape( parameter.getExpression() ) + "\", 3 );" + LS );
}
writer.write( " append( sb, \"\", 0 );" + LS );
}
}
/**
* @param writer not null
* @param useJava5 If the generated code should use Java5 features
* @throws IOException if any
*/
private static void writeUtilities( Writer writer, boolean useJava5 )
throws IOException
{
writer.write( " /**" + LS );
writer.write( " * <p>Repeat a String <code>n</code> times to form a new string.</p>" + LS );
writer.write( " *" + LS );
writer.write( " * @param str String to repeat" + LS );
writer.write( " * @param repeat number of times to repeat str" + LS );
writer.write( " * @return String with repeated String" + LS );
writer.write( " * @throws NegativeArraySizeException if <code>repeat < 0</code>" + LS );
writer.write( " * @throws NullPointerException if str is <code>null</code>" + LS );
writer.write( " */" + LS );
writer.write( " private static String repeat( String str, int repeat )" + LS );
writer.write( " {" + LS );
writer.write( " StringBuffer buffer = new StringBuffer( repeat * str.length() );" + LS );
writer.write( LS );
writer.write( " for ( int i = 0; i < repeat; i++ )" + LS );
writer.write( " {" + LS );
writer.write( " buffer.append( str );" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " return buffer.toString();" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " /** " + LS );
writer.write( " * Append a description to the buffer by respecting the indentSize and lineLength "
+ "parameters." + LS );
writer.write( " * <b>Note</b>: The last character is always a new line." + LS );
writer.write( " * " + LS );
writer.write( " * @param sb The buffer to append the description, not <code>null</code>." + LS );
writer.write( " * @param description The description, not <code>null</code>." + LS );
writer.write( " * @param indent The base indentation level of each line, must not be negative." + LS );
writer.write( " */" + LS );
writer.write( " private void append( StringBuffer sb, String description, int indent )" + LS );
writer.write( " {" + LS );
writer.write( " for ( Iterator it = toLines( description, indent, indentSize, lineLength )"
+ ".iterator(); it.hasNext(); )" + LS );
writer.write( " {" + LS );
writer.write( " sb.append( it.next().toString() ).append( '\\n' );" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " /** " + LS );
writer.write( " * Splits the specified text into lines of convenient display length." + LS );
writer.write( " * " + LS );
writer.write( " * @param text The text to split into lines, must not be <code>null</code>." + LS );
writer.write( " * @param indent The base indentation level of each line, must not be negative." + LS );
writer.write( " * @param indentSize The size of each indentation, must not be negative." + LS );
writer.write( " * @param lineLength The length of the line, must not be negative." + LS );
writer.write( " * @return The sequence of display lines, never <code>null</code>." + LS );
writer.write( " * @throws NegativeArraySizeException if <code>indent < 0</code>" + LS );
writer.write( " */" + LS );
writer.write( " private static List toLines( String text, int indent, int indentSize, int lineLength )"
+ LS );
writer.write( " {" + LS );
if ( useJava5 )
{
writer.write( " List<String> lines = new ArrayList<String>();" + LS );
}
else
{
writer.write( " List lines = new ArrayList();" + LS );
}
writer.write( LS );
writer.write( " String ind = repeat( \"\\t\", indent );" + LS );
writer.write( " String[] plainLines = text.split( \"(\\r\\n)|(\\r)|(\\n)\" );" + LS );
writer.write( " for ( int i = 0; i < plainLines.length; i++ )" + LS );
writer.write( " {" + LS );
writer.write( " toLines( lines, ind + plainLines[i], indentSize, lineLength );" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " return lines;" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " /** " + LS );
writer.write( " * Adds the specified line to the output sequence, performing line wrapping if necessary."
+ LS );
writer.write( " * " + LS );
writer.write( " * @param lines The sequence of display lines, must not be <code>null</code>." + LS );
writer.write( " * @param line The line to add, must not be <code>null</code>." + LS );
writer.write( " * @param indentSize The size of each indentation, must not be negative." + LS );
writer.write( " * @param lineLength The length of the line, must not be negative." + LS );
writer.write( " */" + LS );
if ( useJava5 )
{
writer.write( " private static void toLines( List<String> lines, String line, int indentSize, int lineLength )"
+ LS );
}
else
{
writer.write( " private static void toLines( List lines, String line, int indentSize, int lineLength )"
+ LS );
}
writer.write( " {" + LS );
writer.write( " int lineIndent = getIndentLevel( line );" + LS );
writer.write( " StringBuffer buf = new StringBuffer( 256 );" + LS );
writer.write( " String[] tokens = line.split( \" +\" );" + LS );
writer.write( " for ( int i = 0; i < tokens.length; i++ )" + LS );
writer.write( " {" + LS );
writer.write( " String token = tokens[i];" + LS );
writer.write( " if ( i > 0 )" + LS );
writer.write( " {" + LS );
writer.write( " if ( buf.length() + token.length() >= lineLength )" + LS );
writer.write( " {" + LS );
writer.write( " lines.add( buf.toString() );" + LS );
writer.write( " buf.setLength( 0 );" + LS );
writer.write( " buf.append( repeat( \" \", lineIndent * indentSize ) );" + LS );
writer.write( " }" + LS );
writer.write( " else" + LS );
writer.write( " {" + LS );
writer.write( " buf.append( ' ' );" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
writer.write( " for ( int j = 0; j < token.length(); j++ )" + LS );
writer.write( " {" + LS );
writer.write( " char c = token.charAt( j );" + LS );
writer.write( " if ( c == '\\t' )" + LS );
writer.write( " {" + LS );
writer.write( " buf.append( repeat( \" \", indentSize - buf.length() % indentSize ) );"
+ LS );
writer.write( " }" + LS );
writer.write( " else if ( c == '\\u00A0' )" + LS );
writer.write( " {" + LS );
writer.write( " buf.append( ' ' );" + LS );
writer.write( " }" + LS );
writer.write( " else" + LS );
writer.write( " {" + LS );
writer.write( " buf.append( c );" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
writer.write( " lines.add( buf.toString() );" + LS );
writer.write( " }" + LS );
writer.write( LS );
writer.write( " /** " + LS );
writer.write( " * Gets the indentation level of the specified line." + LS );
writer.write( " * " + LS );
writer.write( " * @param line The line whose indentation level should be retrieved, must not be "
+ "<code>null</code>." + LS );
writer.write( " * @return The indentation level of the line." + LS );
writer.write( " */" + LS );
writer.write( " private static int getIndentLevel( String line )" + LS );
writer.write( " {" + LS );
writer.write( " int level = 0;" + LS );
writer.write( " for ( int i = 0; i < line.length() && line.charAt( i ) == '\\t'; i++ )" + LS );
writer.write( " {" + LS );
writer.write( " level++;" + LS );
writer.write( " }" + LS );
writer.write( " for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )" + LS );
writer.write( " {" + LS );
writer.write( " if ( line.charAt( i ) == '\\t' )" + LS );
writer.write( " {" + LS );
writer.write( " level++;" + LS );
writer.write( " break;" + LS );
writer.write( " }" + LS );
writer.write( " }" + LS );
writer.write( " return level;" + LS );
writer.write( " }" + LS );
}
/**
* Gets the effective string to use for the plugin/mojo/parameter description.
*
* @param description The description of the element, may be <code>null</code>.
* @return The effective description string, never <code>null</code>.
*/
private static String toDescription( String description )
{
if ( StringUtils.isNotEmpty( description ) )
{
return StringUtils.escape( PluginUtils.toText( description ) );
}
return "(no description available)";
}
/**
* Converts a HTML fragment as extracted from a javadoc comment to a plain text string. This method tries to retain
* as much of the text formatting as possible by means of the following transformations:
* <ul>
* <li>List items are converted to leading tabs (U+0009), followed by the item number/bullet, another tab and
* finally the item contents. Each tab denotes an increase of indentation.</li>
* <li>Flow breaking elements as well as literal line terminators in preformatted text are converted to a newline
* (U+000A) to denote a mandatory line break.</li>
* <li>Consecutive spaces and line terminators from character data outside of preformatted text will be normalized
* to a single space. The resulting space denotes a possible point for line wrapping.</li>
* <li>Each space in preformatted text will be converted to a non-breaking space (U+00A0).</li>
* </ul>
*
* @param html The HTML fragment to convert to plain text, may be <code>null</code>.
* @return A string with HTML tags converted into pure text, never <code>null</code>.
* @deprecated since 2.4.3, using {@link PluginUtils#toText(String)} instead of.
*/
protected static String toText( String html )
{
return PluginUtils.toText( html );
}
} }

View File

@ -19,6 +19,17 @@ package org.apache.maven.tools.plugin.generator;
* under the License. * under the License.
*/ */
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.util.PluginUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
import org.codehaus.plexus.util.xml.XMLWriter;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
@ -32,30 +43,21 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
import org.apache.maven.tools.plugin.ExtendedMojoDescriptor;
import org.apache.maven.tools.plugin.PluginToolsRequest;
import org.apache.maven.tools.plugin.util.PluginUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter;
import org.codehaus.plexus.util.xml.XMLWriter;
/** /**
* @todo add example usage tag that can be shown in the doco
* @version $Id$ * @version $Id$
* @todo add example usage tag that can be shown in the doco
*/ */
public class PluginXdocGenerator public class PluginXdocGenerator
implements Generator implements Generator
{ {
/** locale */ /**
* locale
*/
private final Locale locale; private final Locale locale;
/** project */ /**
* project
*/
private final MavenProject project; private final MavenProject project;
/** /**
@ -81,7 +83,7 @@ public class PluginXdocGenerator
/** /**
* @param project not null. * @param project not null.
* @param locale not null wanted locale. * @param locale not null wanted locale.
*/ */
public PluginXdocGenerator( MavenProject project, Locale locale ) public PluginXdocGenerator( MavenProject project, Locale locale )
{ {
@ -96,31 +98,35 @@ public class PluginXdocGenerator
} }
} }
/** {@inheritDoc} */
public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor )
throws IOException
{
execute( destinationDirectory, new DefaultPluginToolsRequest( project, pluginDescriptor ) );
}
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public void execute( File destinationDirectory, PluginToolsRequest request ) public void execute( File destinationDirectory, PluginToolsRequest request )
throws IOException throws GeneratorException
{ {
if ( request.getPluginDescriptor().getMojos() != null ) try
{ {
for ( @SuppressWarnings( "unchecked" ) if ( request.getPluginDescriptor().getMojos() != null )
Iterator<MojoDescriptor> it = request.getPluginDescriptor().getMojos().iterator(); it.hasNext(); )
{ {
MojoDescriptor descriptor = it.next(); for ( @SuppressWarnings( "unchecked" ) Iterator<MojoDescriptor> it =
request.getPluginDescriptor().getMojos().iterator(); it.hasNext(); )
{
MojoDescriptor descriptor = it.next();
processMojoDescriptor( descriptor, destinationDirectory ); processMojoDescriptor( descriptor, destinationDirectory );
}
} }
} }
catch ( IOException e )
{
throw new GeneratorException( e.getMessage(), e );
}
} }
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param destinationDirectory not null * @param destinationDirectory not null
* @throws IOException if any * @throws IOException if any
*/ */
@ -147,7 +153,7 @@ public class PluginXdocGenerator
/** /**
* @param mojo not null * @param mojo not null
* @param ext not null * @param ext not null
* @return the output file name * @return the output file name
*/ */
private String getMojoFilename( MojoDescriptor mojo, String ext ) private String getMojoFilename( MojoDescriptor mojo, String ext )
@ -157,7 +163,7 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param w not null * @param w not null
*/ */
private void writeBody( MojoDescriptor mojoDescriptor, XMLWriter w ) private void writeBody( MojoDescriptor mojoDescriptor, XMLWriter w )
{ {
@ -196,8 +202,8 @@ public class PluginXdocGenerator
w.endElement(); //p w.endElement(); //p
w.startElement( "p" ); w.startElement( "p" );
w.writeMarkup( mojoDescriptor.getPluginDescriptor().getGroupId() + ":" w.writeMarkup( mojoDescriptor.getPluginDescriptor().getGroupId() + ":"
+ mojoDescriptor.getPluginDescriptor().getArtifactId() + ":" + mojoDescriptor.getPluginDescriptor().getArtifactId() + ":"
+ mojoDescriptor.getPluginDescriptor().getVersion() + ":" + mojoDescriptor.getGoal() ); + mojoDescriptor.getPluginDescriptor().getVersion() + ":" + mojoDescriptor.getGoal() );
w.endElement(); //p w.endElement(); //p
if ( StringUtils.isNotEmpty( mojoDescriptor.getDeprecated() ) ) if ( StringUtils.isNotEmpty( mojoDescriptor.getDeprecated() ) )
@ -237,7 +243,7 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param w not null * @param w not null
*/ */
private void writeReportNotice( MojoDescriptor mojoDescriptor, XMLWriter w ) private void writeReportNotice( MojoDescriptor mojoDescriptor, XMLWriter w )
{ {
@ -252,7 +258,7 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param w not null * @param w not null
*/ */
private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w ) private void writeGoalAttributes( MojoDescriptor mojoDescriptor, XMLWriter w )
{ {
@ -273,12 +279,12 @@ public class PluginXdocGenerator
w.writeMarkup( getString( "pluginxdoc.mojodescriptor.projectRequired" ) ); w.writeMarkup( getString( "pluginxdoc.mojodescriptor.projectRequired" ) );
w.endElement(); //li w.endElement(); //li
} }
if ( mojoDescriptor.isRequiresReports() ) if ( mojoDescriptor.isRequiresReports() )
{ {
if ( !addedUl ) if ( !addedUl )
{ {
w.startElement( "ul" ); w.startElement( "ul" );
addedUl = true; addedUl = true;
} }
w.startElement( "li" ); w.startElement( "li" );
@ -451,12 +457,11 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param w not null * @param w not null
*/ */
private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w ) private void writeGoalParameterTable( MojoDescriptor mojoDescriptor, XMLWriter w )
{ {
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" ) List<Parameter> parameterList = mojoDescriptor.getParameters();
List<Parameter> parameterList = mojoDescriptor.getParameters();
//remove components and read-only parameters //remove components and read-only parameters
List<Parameter> list = filterParameters( parameterList ); List<Parameter> list = filterParameters( parameterList );
@ -490,7 +495,7 @@ public class PluginXdocGenerator
if ( parameterList != null ) if ( parameterList != null )
{ {
for ( Parameter parameter : parameterList ) for ( Parameter parameter : parameterList )
{ {
if ( parameter.isEditable() ) if ( parameter.isEditable() )
{ {
@ -509,8 +514,8 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param parameterList not null * @param parameterList not null
* @param w not null * @param w not null
*/ */
private void writeParameterDetails( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) private void writeParameterDetails( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w )
{ {
@ -570,8 +575,8 @@ public class PluginXdocGenerator
w.startElement( "ul" ); w.startElement( "ul" );
addedUl = true; addedUl = true;
} }
writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.since" ), mojoDescriptor.getSince(),
mojoDescriptor.getSince(), w ); w );
} }
} }
@ -582,8 +587,8 @@ public class PluginXdocGenerator
w.startElement( "ul" ); w.startElement( "ul" );
addedUl = true; addedUl = true;
} }
writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.yes" ),
getString( "pluginxdoc.yes" ), w ); w );
} }
else else
{ {
@ -592,8 +597,8 @@ public class PluginXdocGenerator
w.startElement( "ul" ); w.startElement( "ul" );
addedUl = true; addedUl = true;
} }
writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), writeDetail( getString( "pluginxdoc.mojodescriptor.parameter.required" ), getString( "pluginxdoc.no" ),
getString( "pluginxdoc.no" ), w ); w );
} }
if ( !addedUl && StringUtils.isNotEmpty( parameter.getExpression() ) ) if ( !addedUl && StringUtils.isNotEmpty( parameter.getExpression() ) )
@ -628,7 +633,7 @@ public class PluginXdocGenerator
/** /**
* @param param not null * @param param not null
* @param value could be null * @param value could be null
* @param w not null * @param w not null
*/ */
private void writeDetail( String param, String value, XMLWriter w ) private void writeDetail( String param, String value, XMLWriter w )
{ {
@ -642,8 +647,8 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param parameterList not null * @param parameterList not null
* @param w not null * @param w not null
*/ */
private void writeParameterSummary( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w ) private void writeParameterSummary( MojoDescriptor mojoDescriptor, List<Parameter> parameterList, XMLWriter w )
{ {
@ -664,11 +669,12 @@ public class PluginXdocGenerator
/** /**
* @param mojoDescriptor not null * @param mojoDescriptor not null
* @param title not null * @param title not null
* @param parameterList not null * @param parameterList not null
* @param w not null * @param w not null
*/ */
private void writeParameterList( MojoDescriptor mojoDescriptor, String title, List<Parameter> parameterList, XMLWriter w ) private void writeParameterList( MojoDescriptor mojoDescriptor, String title, List<Parameter> parameterList,
XMLWriter w )
{ {
w.startElement( "subsection" ); w.startElement( "subsection" );
w.addAttribute( "name", title ); w.addAttribute( "name", title );
@ -722,9 +728,8 @@ public class PluginXdocGenerator
String description; String description;
if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) ) if ( StringUtils.isNotEmpty( parameter.getDeprecated() ) )
{ {
description = description = format( "pluginxdoc.mojodescriptor.parameter.deprecated",
format( "pluginxdoc.mojodescriptor.parameter.deprecated", PluginUtils.makeHtmlValid( parameter.getDeprecated() ) );
PluginUtils.makeHtmlValid( parameter.getDeprecated() ) );
} }
else if ( StringUtils.isNotEmpty( parameter.getDescription() ) ) else if ( StringUtils.isNotEmpty( parameter.getDescription() ) )
{ {
@ -750,7 +755,7 @@ public class PluginXdocGenerator
} }
/** /**
* @param required <code>true</code> for required parameters, <code>false</code> otherwise. * @param required <code>true</code> for required parameters, <code>false</code> otherwise.
* @param parameterList not null * @param parameterList not null
* @return list of parameters depending the value of <code>required</code> * @return list of parameters depending the value of <code>required</code>
*/ */
@ -792,21 +797,21 @@ public class PluginXdocGenerator
/** /**
* Convenience method. * Convenience method.
* *
* @param key not null * @param key not null
* @param arg1 not null * @param arg1 not null
* @return Localized, formatted text identified by <code>key</code>. * @return Localized, formatted text identified by <code>key</code>.
* @see #format(String, Object[]) * @see #format(String, Object[])
*/ */
private String format( String key, Object arg1 ) private String format( String key, Object arg1 )
{ {
return format( key, new Object[] { arg1 } ); return format( key, new Object[]{ arg1 } );
} }
/** /**
* Looks up the value for <code>key</code> in the <code>ResourceBundle</code>, * Looks up the value for <code>key</code> in the <code>ResourceBundle</code>,
* then formats that value for the specified <code>Locale</code> using <code>args</code>. * then formats that value for the specified <code>Locale</code> using <code>args</code>.
* *
* @param key not null * @param key not null
* @param args not null * @param args not null
* @return Localized, formatted text identified by <code>key</code>. * @return Localized, formatted text identified by <code>key</code>.
*/ */

View File

@ -19,11 +19,6 @@ package org.apache.maven.tools.plugin.scanner;
* under the License. * under the License.
*/ */
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException; import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
@ -36,6 +31,11 @@ import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger; import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger; import org.codehaus.plexus.logging.console.ConsoleLogger;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/** /**
* @author jdcasey * @author jdcasey
*/ */
@ -71,14 +71,18 @@ public class DefaultMojoScanner
// nop // nop
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public void populatePluginDescriptor( MavenProject project, PluginDescriptor pluginDescriptor ) public void populatePluginDescriptor( MavenProject project, PluginDescriptor pluginDescriptor )
throws ExtractionException, InvalidPluginDescriptorException throws ExtractionException, InvalidPluginDescriptorException
{ {
populatePluginDescriptor( new DefaultPluginToolsRequest( project, pluginDescriptor ) ); populatePluginDescriptor( new DefaultPluginToolsRequest( project, pluginDescriptor ) );
} }
/** {@inheritDoc} */ /**
* {@inheritDoc}
*/
public void populatePluginDescriptor( PluginToolsRequest request ) public void populatePluginDescriptor( PluginToolsRequest request )
throws ExtractionException, InvalidPluginDescriptorException throws ExtractionException, InvalidPluginDescriptorException
{ {
@ -103,7 +107,7 @@ public class DefaultMojoScanner
List<MojoDescriptor> extractorDescriptors = extractor.execute( request ); List<MojoDescriptor> extractorDescriptors = extractor.execute( request );
logger.info( "Mojo extractor for language: " + language + " found " + extractorDescriptors.size() logger.info( "Mojo extractor for language: " + language + " found " + extractorDescriptors.size()
+ " mojo descriptors." ); + " mojo descriptors." );
numMojoDescriptors += extractorDescriptors.size(); numMojoDescriptors += extractorDescriptors.size();
for ( MojoDescriptor descriptor : extractorDescriptors ) for ( MojoDescriptor descriptor : extractorDescriptors )
@ -116,10 +120,11 @@ public class DefaultMojoScanner
} }
} }
if ( numMojoDescriptors == 0 ) if ( numMojoDescriptors == 0 && !request.isSkipErrorNoDescriptorsFound() )
{ {
throw new InvalidPluginDescriptorException( "No mojo definitions were found for plugin: " throw new InvalidPluginDescriptorException(
+ request.getPluginDescriptor().getPluginLookupKey() + "." ); "No mojo definitions were found for plugin: " + request.getPluginDescriptor().getPluginLookupKey()
+ "." );
} }
} }

View File

@ -715,7 +715,7 @@ public final class PluginUtils
String text; String text;
if ( preformatted > 0 ) if ( preformatted > 0 )
{ {
text = data.replace( ' ', '\u00A0' ); text = data;
} }
else else
{ {

View File

@ -0,0 +1,340 @@
#if ($helpPackageName.length()>0)
package ${helpPackageName};
#end
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Display help information on maven-plugin-plugin.<br/> Call <pre> mvn plugin:help -Ddetail=true -Dgoal=&lt;goal-name&gt;</pre> to display parameter details.
* @author
* @version
* @goal help
* @requiresProject false
* @threadSafe
*/
public class HelpMojo
extends AbstractMojo
{
/**
* If <code>true</code>, display all settable properties for each goal.
*
*/
//@Parameter( expression = "${detail}", defaultValue = "false" )
//private boolean detail;
/**
* The name of the goal for which to show help. If unspecified, all goals will be displayed.
*
*/
//@Parameter( expression = "${goal}" )
//private java.lang.String goal;
/**
* The maximum length of a display line, should be positive.
*
*/
//@Parameter( expression = "${lineLength}", defaultValue = "80" )
//private int lineLength;
/**
* The number of spaces per indentation level, should be positive.
*
*/
//@Parameter( expression = "${indentSize}", defaultValue = "2" )
//private int indentSize;
/**
* If <code>true</code>, display all settable properties for each goal.
*
* @parameter expression="${detail}" default-value="false"
*/
private boolean detail;
/**
* The name of the goal for which to show help. If unspecified, all goals will be displayed.
*
* @parameter expression="${goal}"
*/
private java.lang.String goal;
/**
* The maximum length of a display line, should be positive.
*
* @parameter expression="${lineLength}" default-value="80"
*/
private int lineLength;
/**
* The number of spaces per indentation level, should be positive.
*
* @parameter expression="${indentSize}" default-value="2"
*/
private int indentSize;
// groupId/artifactId/version
private String pluginDescriptorPath = "/${propertiesFilePath}";
private Xpp3Dom build()
throws MojoExecutionException
{
// olamy more than one pluginDescriptor in the classloader possible ?
getLog().debug("load pluginDescriptorPath: " + pluginDescriptorPath);
InputStream is = getClass().getResourceAsStream( pluginDescriptorPath );
try
{
return Xpp3DomBuilder.build( is, "ISO-8859-1" );
}
catch ( XmlPullParserException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
catch ( IOException e )
{
throw new MojoExecutionException( e.getMessage(), e );
}
}
/**
* {@inheritDoc}
*/
public void execute()
throws MojoExecutionException
{
if ( lineLength <= 0 )
{
getLog().warn( "The parameter 'lineLength' should be positive, using '80' as default." );
lineLength = 80;
}
if ( indentSize <= 0 )
{
getLog().warn( "The parameter 'indentSize' should be positive, using '2' as default." );
indentSize = 2;
}
// FIXME encoding as parameter
Xpp3Dom pluginElement = build();
StringBuffer sb = new StringBuffer();
/**
* <groupId>org.apache.maven.plugins</groupId>
* <artifactId>maven-plugin-plugin</artifactId>
* <version>3.0-SNAPSHOT</version>
*/
//append( sb, "org.apache.maven.plugins:maven-plugin-plugin:3.0-SNAPSHOT", 0 );
append( sb,
pluginElement.getChild( "groupId" ).getValue() + ":" + pluginElement.getChild( "artifactId" ).getValue()
+ ":" + pluginElement.getChild( "version" ).getValue(), 0 );
append( sb, "", 0 );
//append( sb, "Maven Plugin Plugin", 0 );
append( sb, pluginElement.getChild( "name" ).getValue(), 0 );
//append( sb,
// "The Plugin Plugin is used to create a Maven plugin descriptor for any Mojo\'s found in the source tree, to include in the JAR. It is also used to generate Xdoc files for the Mojos as well as for updating the plugin registry, the artifact metadata and a generic help goal.",
// 1 );
append( sb, pluginElement.getChild( "description" ).getValue(), 1 );
append( sb, "", 0 );
//<goalPrefix>plugin</goalPrefix>
String goalPrefix = pluginElement.getChild( "goalPrefix" ).getValue();
Xpp3Dom[] mojos = pluginElement.getChild( "mojos" ).getChildren( "mojo" );
if ( goal == null || goal.length() <= 0 )
{
append( sb, "This plugin has " + mojos.length + " goals:", 0 );
append( sb, "", 0 );
}
for ( Xpp3Dom mojo : mojos )
{
String mojoGoal = mojo.getChild( "goal" ).getValue();
Xpp3Dom configurationElement = mojo.getChild( "configuration" );
if ( goal == null || goal.length() <= 0 || mojoGoal.equals( goal ) )
{
append( sb, goalPrefix + ":" + mojoGoal, 0 );
append( sb, mojo.getChild( "description" ).getValue(), 1 );
append( sb, "", 0 );
if ( detail )
{
Xpp3Dom[] parameters = mojo.getChild( "parameters" ).getChildren( "parameter" );
append( sb, "Available parameters:", 1 );
append( sb, "", 0 );
append( sb, "goalPrefix", 2 );
append( sb, "The prefix for the plugin goal.", 3 );
append( sb, "", 0 );
for ( Xpp3Dom parameter : parameters )
{
Xpp3Dom name = parameter.getChild( "name" );
Xpp3Dom fieldConfigurationElement = configurationElement.getChild( name.getValue() );
if ( fieldConfigurationElement != null && fieldConfigurationElement.getValue() != null )
{
append( sb, name.getValue() + "(Default: " + configurationElement.getChild(
name.getValue() ).getAttribute( "default-value" ) + ")", 2 );
}
append( sb, parameter.getChild( "description" ).getValue(), 3 );
if ( fieldConfigurationElement != null && fieldConfigurationElement.getValue() != null )
{
append( sb, fieldConfigurationElement.getValue(), 3 );
}
append( sb, "", 0 );
}
}
}
}
if ( getLog().isInfoEnabled() )
{
getLog().info( sb.toString() );
}
}
/**
* <p>Repeat a String <code>n</code> times to form a new string.</p>
*
* @param str String to repeat
* @param repeat number of times to repeat str
* @return String with repeated String
* @throws NegativeArraySizeException if <code>repeat < 0</code>
* @throws NullPointerException if str is <code>null</code>
*/
private static String repeat( String str, int repeat )
{
StringBuffer buffer = new StringBuffer( repeat * str.length() );
for ( int i = 0; i < repeat; i++ )
{
buffer.append( str );
}
return buffer.toString();
}
/**
* Append a description to the buffer by respecting the indentSize and lineLength parameters.
* <b>Note</b>: The last character is always a new line.
*
* @param sb The buffer to append the description, not <code>null</code>.
* @param description The description, not <code>null</code>.
* @param indent The base indentation level of each line, must not be negative.
*/
private void append( StringBuffer sb, String description, int indent )
{
for ( Iterator it = toLines( description, indent, indentSize, lineLength ).iterator(); it.hasNext(); )
{
sb.append( it.next().toString() ).append( '\n' );
}
}
/**
* Splits the specified text into lines of convenient display length.
*
* @param text The text to split into lines, must not be <code>null</code>.
* @param indent The base indentation level of each line, must not be negative.
* @param indentSize The size of each indentation, must not be negative.
* @param lineLength The length of the line, must not be negative.
* @return The sequence of display lines, never <code>null</code>.
* @throws NegativeArraySizeException if <code>indent < 0</code>
*/
private static List toLines( String text, int indent, int indentSize, int lineLength )
{
List<String> lines = new ArrayList<String>();
String ind = repeat( "\t", indent );
String[] plainLines = text.split( "(\r\n)|(\r)|(\n)" );
for ( int i = 0; i < plainLines.length; i++ )
{
toLines( lines, ind + plainLines[i], indentSize, lineLength );
}
return lines;
}
/**
* Adds the specified line to the output sequence, performing line wrapping if necessary.
*
* @param lines The sequence of display lines, must not be <code>null</code>.
* @param line The line to add, must not be <code>null</code>.
* @param indentSize The size of each indentation, must not be negative.
* @param lineLength The length of the line, must not be negative.
*/
private static void toLines( List<String> lines, String line, int indentSize, int lineLength )
{
int lineIndent = getIndentLevel( line );
StringBuffer buf = new StringBuffer( 256 );
String[] tokens = line.split( " +" );
for ( int i = 0; i < tokens.length; i++ )
{
String token = tokens[i];
if ( i > 0 )
{
if ( buf.length() + token.length() >= lineLength )
{
lines.add( buf.toString() );
buf.setLength( 0 );
buf.append( repeat( " ", lineIndent * indentSize ) );
}
else
{
buf.append( ' ' );
}
}
for ( int j = 0; j < token.length(); j++ )
{
char c = token.charAt( j );
if ( c == '\t' )
{
buf.append( repeat( " ", indentSize - buf.length() % indentSize ) );
}
else if ( c == '\u00A0' )
{
buf.append( ' ' );
}
else
{
buf.append( c );
}
}
}
lines.add( buf.toString() );
}
/**
* Gets the indentation level of the specified line.
*
* @param line The line whose indentation level should be retrieved, must not be <code>null</code>.
* @return The indentation level of the line.
*/
private static int getIndentLevel( String line )
{
int level = 0;
for ( int i = 0; i < line.length() && line.charAt( i ) == '\t'; i++ )
{
level++;
}
for ( int i = level + 1; i <= level + 4 && i < line.length(); i++ )
{
if ( line.charAt( i ) == '\t' )
{
level++;
break;
}
}
return level;
}
}

View File

@ -19,11 +19,13 @@ package org.apache.maven.tools.plugin.generator;
* under the License. * under the License.
*/ */
import junit.framework.TestCase; import org.apache.maven.model.Build;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.PluginDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.tools.plugin.DefaultPluginToolsRequest; import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
import org.codehaus.plexus.PlexusTestCase;
import org.codehaus.plexus.component.repository.ComponentDependency; import org.codehaus.plexus.component.repository.ComponentDependency;
import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.FileUtils;
@ -38,7 +40,7 @@ import java.util.List;
* jdcasey Exp $ * jdcasey Exp $
*/ */
public abstract class AbstractGeneratorTestCase public abstract class AbstractGeneratorTestCase
extends TestCase extends PlexusTestCase
{ {
protected Generator generator; protected Generator generator;
@ -47,6 +49,7 @@ public abstract class AbstractGeneratorTestCase
protected void setUp() protected void setUp()
throws Exception throws Exception
{ {
super.setUp();
basedir = System.getProperty( "basedir" ); basedir = System.getProperty( "basedir" );
} }
@ -93,7 +96,25 @@ public abstract class AbstractGeneratorTestCase
FileUtils.deleteDirectory( destinationDirectory ); FileUtils.deleteDirectory( destinationDirectory );
destinationDirectory.mkdir(); destinationDirectory.mkdir();
generator.execute( destinationDirectory, new DefaultPluginToolsRequest( null, pluginDescriptor ) ); MavenProject mavenProject = new MavenProject();
mavenProject.setGroupId( "foo" );
mavenProject.setArtifactId( "bar" );
mavenProject.setBuild( new Build()
{
@Override
public String getDirectory()
{
return basedir + "/target";
}
@Override
public String getOutputDirectory()
{
return basedir + "/target";
}
} );
generator.execute( destinationDirectory, new DefaultPluginToolsRequest( mavenProject, pluginDescriptor ) );
validate( destinationDirectory ); validate( destinationDirectory );
@ -120,8 +141,8 @@ public abstract class AbstractGeneratorTestCase
catch ( Exception e ) catch ( Exception e )
{ {
throw new Exception( "Cannot find " + generatorClassName + throw new Exception( "Cannot find " + generatorClassName +
"! Make sure your test case is named in the form ${generatorClassName}Test " + "! Make sure your test case is named in the form ${generatorClassName}Test " +
"or override the setupPlugin() method to instantiate the mojo yourself." ); "or override the setupPlugin() method to instantiate the mojo yourself." );
} }
} }

View File

@ -19,6 +19,8 @@ package org.apache.maven.tools.plugin.generator;
* under the License. * under the License.
*/ */
import org.codehaus.plexus.velocity.VelocityComponent;
/** /**
* @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a> * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
* @version $Id$ * @version $Id$
@ -27,4 +29,12 @@ public class PluginHelpGeneratorTest
extends AbstractGeneratorTestCase extends AbstractGeneratorTestCase
{ {
// inherits tests from base class // inherits tests from base class
protected void setupGenerator()
throws Exception
{
generator =
new PluginHelpGenerator().setVelocityComponent( (VelocityComponent) lookup( VelocityComponent.ROLE ) );
}
} }

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-beanshell</artifactId> <artifactId>maven-plugin-tools-beanshell</artifactId>

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-java</artifactId> <artifactId>maven-plugin-tools-java</artifactId>
@ -66,7 +66,6 @@
<dependency> <dependency>
<groupId>com.thoughtworks.qdox</groupId> <groupId>com.thoughtworks.qdox</groupId>
<artifactId>qdox</artifactId> <artifactId>qdox</artifactId>
<version>1.11</version>
</dependency> </dependency>
<dependency> <dependency>
@ -77,4 +76,18 @@
</dependency> </dependency>
</dependencies> </dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<filePath>${project.build.directory}</filePath>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project> </project>

View File

@ -20,6 +20,7 @@ package org.apache.maven.tools.plugin.extractor.java;
*/ */
import junit.framework.TestCase; import junit.framework.TestCase;
import org.apache.maven.model.Build;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.apache.maven.plugin.descriptor.MojoDescriptor; import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.Parameter;
@ -77,6 +78,13 @@ public class JavaMojoDescriptorExtractorTest
model.setArtifactId( "maven-unitTesting-plugin" ); model.setArtifactId( "maven-unitTesting-plugin" );
MavenProject project = new MavenProject( model ); MavenProject project = new MavenProject( model );
project.setBuild( new Build(){
@Override
public String getOutputDirectory()
{
return System.getProperty( "filePath" );
}
});
project.setFile( new File( root, "pom.xml" ) ); project.setFile( new File( root, "pom.xml" ) );
project.addCompileSourceRoot( new File( root, directory ).getPath() ); project.addCompileSourceRoot( new File( root, directory ).getPath() );

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-javadoc</artifactId> <artifactId>maven-plugin-tools-javadoc</artifactId>

View File

@ -25,7 +25,7 @@
<parent> <parent>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
</parent> </parent>
<artifactId>maven-plugin-tools-model</artifactId> <artifactId>maven-plugin-tools-model</artifactId>

77
pom.xml
View File

@ -1,5 +1,4 @@
<?xml version='1.0' encoding='UTF-8'?> <?xml version="1.0" encoding="UTF-8"?>
<!-- <!--
~ Licensed to the Apache Software Foundation (ASF) under one ~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file ~ or more contributor license agreements. See the NOTICE file
@ -18,7 +17,6 @@
~ specific language governing permissions and limitations ~ specific language governing permissions and limitations
~ under the License. ~ under the License.
--> -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -31,7 +29,7 @@
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools</artifactId> <artifactId>maven-plugin-tools</artifactId>
<version>2.10-SNAPSHOT</version> <version>3.0-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>Maven Plugin Tools</name> <name>Maven Plugin Tools</name>
@ -132,6 +130,8 @@
<module>maven-plugin-plugin</module> <module>maven-plugin-plugin</module>
<module>maven-plugin-tools-model</module> <module>maven-plugin-tools-model</module>
<module>maven-plugin-tools-javadoc</module> <module>maven-plugin-tools-javadoc</module>
<module>maven-plugin-tools-annotations</module>
<module>maven-plugin-annotations</module>
</modules> </modules>
<scm> <scm>
@ -145,7 +145,7 @@
</issueManagement> </issueManagement>
<ciManagement> <ciManagement>
<system>Jenkins</system> <system>Jenkins</system>
<url>https://builds.apache.org/hudson/job/maven-plugin-tools/</url> <url>https://builds.apache.org/job/maven-plugin-tools/</url>
</ciManagement> </ciManagement>
<distributionManagement> <distributionManagement>
<site> <site>
@ -155,7 +155,6 @@
</distributionManagement> </distributionManagement>
<properties> <properties>
<pluginToolsVersion>2.10-SNAPSHOT</pluginToolsVersion>
<pluginTestingHarnessVersion>1.2</pluginTestingHarnessVersion> <pluginTestingHarnessVersion>1.2</pluginTestingHarnessVersion>
</properties> </properties>
@ -165,22 +164,32 @@
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-api</artifactId> <artifactId>maven-plugin-tools-api</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-model</artifactId> <artifactId>maven-plugin-tools-model</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-java</artifactId> <artifactId>maven-plugin-tools-java</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-tools</groupId> <groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-tools-beanshell</artifactId> <artifactId>maven-plugin-tools-beanshell</artifactId>
<version>${pluginToolsVersion}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.maven</groupId> <groupId>org.apache.maven</groupId>
@ -212,13 +221,53 @@
<dependency> <dependency>
<groupId>org.codehaus.plexus</groupId> <groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-utils</artifactId> <artifactId>plexus-utils</artifactId>
<version>2.0.5</version> <version>3.0</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.codehaus.plexus</groupId> <groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-container-default</artifactId> <artifactId>plexus-container-default</artifactId>
<version>1.0-alpha-9-stable-1</version> <version>1.0-alpha-9-stable-1</version>
</dependency> </dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-archiver</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-velocity</artifactId>
<version>1.1.8</version>
<exclusions>
<exclusion>
<groupId>velocity</groupId>
<artifactId>velocity</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- other -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<dependency>
<groupId>com.thoughtworks.qdox</groupId>
<artifactId>qdox</artifactId>
<version>1.11</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm-commons</artifactId>
<version>3.3.1</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.maven.plugin-testing</groupId> <groupId>org.apache.maven.plugin-testing</groupId>
@ -236,6 +285,12 @@
<version>3.8.2</version> <version>3.8.2</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>