From 194c3a8ecacaa0bf9731eb37a8cb73377e9530c6 Mon Sep 17 00:00:00 2001 From: Vincent Siveton Date: Thu, 31 Jan 2008 23:23:02 +0000 Subject: [PATCH] MPLUGIN-40: All plugins should by default have an auto-generated goal 'help' o created a new Mojo which generates a generic HelpMojo class o added PluginHelpGenerator which does the generation o maven-plugin-plugin should extends maven-plugins for the look&feel o update the documentation git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/trunk@617289 13f79535-47bb-0310-9956-ffa450edef68 --- maven-plugin-plugin/pom.xml | 96 +++- .../plugin/plugin/HelpGeneratorMojo.java | 71 +++ .../src/site/apt/examples/generate-help.apt | 54 ++ .../src/site/apt/examples/generate-report.apt | 46 ++ maven-plugin-plugin/src/site/apt/index.apt | 14 +- maven-plugin-plugin/src/site/apt/usage.apt | 16 +- maven-plugin-plugin/src/site/site.xml | 6 +- .../plugin/generator/PluginHelpGenerator.java | 534 ++++++++++++++++++ .../java/JavaMojoDescriptorExtractor.java | 7 + 9 files changed, 812 insertions(+), 32 deletions(-) create mode 100644 maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/HelpGeneratorMojo.java create mode 100644 maven-plugin-plugin/src/site/apt/examples/generate-help.apt create mode 100644 maven-plugin-plugin/src/site/apt/examples/generate-report.apt create mode 100644 maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java diff --git a/maven-plugin-plugin/pom.xml b/maven-plugin-plugin/pom.xml index b8a830a..ea6567c 100644 --- a/maven-plugin-plugin/pom.xml +++ b/maven-plugin-plugin/pom.xml @@ -16,29 +16,34 @@ ~ KIND, either express or implied. See the License for the ~ specific language governing permissions and limitations ~ under the License. - --> - - org.apache.maven - maven-plugin-tools - 2.4-SNAPSHOT - 4.0.0 + + + org.apache.maven.plugins + maven-plugins + 8 + + org.apache.maven.plugins maven-plugin-plugin + 2.4-SNAPSHOT maven-plugin + Maven PLUGIN Plugin - 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 and the artifact metadata. + 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. - 2001 + 2.0.6 + + org.apache.maven maven-plugin-api @@ -130,14 +135,54 @@ org.codehaus.plexus plexus-utils - 1.4.5 org.codehaus.plexus plexus-container-default - 1.0-alpha-9 + + + + + + org.apache.maven + maven-plugin-tools-api + ${project.version} + + + org.apache.maven + maven-plugin-tools-model + ${project.version} + + + org.apache.maven + maven-plugin-tools-java + ${project.version} + + + org.apache.maven + maven-plugin-tools-beanshell + ${project.version} + + + org.apache.maven + maven-plugin-descriptor + 2.0.5 + + + org.codehaus.plexus + plexus-utils + 1.4.9 + + + org.codehaus.plexus + plexus-container-default + 1.0-alpha-9 + + + + @@ -149,24 +194,33 @@ + + 1.0-alpha-10-SNAPSHOT 1.0-alpha-10-SNAPSHOT + apache.website scp://people.apache.org/www/maven.apache.org/plugins/maven-plugin-plugin - - - - org.apache.maven.plugins - maven-plugin-plugin - - - - diff --git a/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/HelpGeneratorMojo.java b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/HelpGeneratorMojo.java new file mode 100644 index 0000000..92dcd21 --- /dev/null +++ b/maven-plugin-plugin/src/main/java/org/apache/maven/plugin/plugin/HelpGeneratorMojo.java @@ -0,0 +1,71 @@ +package org.apache.maven.plugin.plugin; + +/* + * 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.io.File; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.tools.plugin.generator.Generator; +import org.apache.maven.tools.plugin.generator.PluginHelpGenerator; + +/** + * Generates an HelpMojo class. + * + * @author Vincent Siveton + * @version $Id$ + * @since 2.4 + * @goal helpmojo + * @phase generate-sources + */ +public class HelpGeneratorMojo + extends AbstractGeneratorMojo +{ + /** + * The directory where the generated HelpMojo file will be put. + * + * @parameter expression="${project.build.directory}/generated-sources/plugin" + * @required + */ + protected File outputDirectory; + + /** {@inheritDoc} */ + protected File getOutputDirectory() + { + return outputDirectory; + } + + /** {@inheritDoc} */ + protected Generator createGenerator() + { + return new PluginHelpGenerator( getLog() ); + } + + /** {@inheritDoc} */ + public void execute() + throws MojoExecutionException + { + super.execute(); + + if ( !project.getCompileSourceRoots().contains( outputDirectory.getAbsolutePath() ) ) + { + project.addCompileSourceRoot( outputDirectory.getAbsolutePath() ); + } + } +} diff --git a/maven-plugin-plugin/src/site/apt/examples/generate-help.apt b/maven-plugin-plugin/src/site/apt/examples/generate-help.apt new file mode 100644 index 0000000..dec2e29 --- /dev/null +++ b/maven-plugin-plugin/src/site/apt/examples/generate-help.apt @@ -0,0 +1,54 @@ + ------ + Configuring Generation of Help Mojo + ------ + Vincent Siveton + ------ + January 2008 + ------ + +~~ 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. + +Configuring Generation of Help Mojo + + To configure the generation of an <<>> Mojo, add the following to the project's pom: + ++-----+ + + ... + + + + org.apache.maven.plugins + maven-plugin-plugin + + + generated-helpmojo + + helpmojo + + + + + + ... + + ... + ++-----+ + + The mojo is generated by default in <<<$\{project.build.directory\}/generated-sources/plugin>>>. diff --git a/maven-plugin-plugin/src/site/apt/examples/generate-report.apt b/maven-plugin-plugin/src/site/apt/examples/generate-report.apt new file mode 100644 index 0000000..48ae355 --- /dev/null +++ b/maven-plugin-plugin/src/site/apt/examples/generate-report.apt @@ -0,0 +1,46 @@ + ------ + Configuring Generation of Documentation Reports + ------ + Vincent Siveton + ------ + January 2008 + ------ + +~~ 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. + +Configuring Generation of Documentation Reports + + To configure the generation of the documentation reports, add the following to the project's pom: + ++-----+ + + ... + + + + org.apache.maven.plugins + maven-plugin-plugin + + + ... + + ... + ++-----+ + + The documentation is generated by default in <<<$\{project.build.directory\}/site>>>. diff --git a/maven-plugin-plugin/src/site/apt/index.apt b/maven-plugin-plugin/src/site/apt/index.apt index d665aee..e698d4c 100644 --- a/maven-plugin-plugin/src/site/apt/index.apt +++ b/maven-plugin-plugin/src/site/apt/index.apt @@ -3,7 +3,7 @@ ------ Maria Odea Ching ------ - 27 July 2006 + January 2008 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one @@ -26,11 +26,12 @@ Maven 2 Plugin Plugin 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 and the artifact metadata. + 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. * Goals Overview - The Plugin Plugin has five goals: + The Plugin Plugin has six goals: * {{{descriptor-mojo.html}plugin:descriptor}} generates a plugin descriptor. @@ -45,6 +46,8 @@ Maven 2 Plugin Plugin artifact, for subsequent installation and deployment. The first use-case for this is to add the LATEST metadata (which is plugin-specific) for shipping alongside the plugin's artifact. + * {{{helpmojo-mojo.html}helpmojo}} generates an help mojo with describes all project mojos. + * Usage Instructions on how to use the Plugin Plugin can be found {{{usage.html}here}}. @@ -55,7 +58,6 @@ Maven 2 Plugin Plugin * {{{examples/generate-descriptor.html}Configuring Generation of Plugin Descriptor}} + * {{{examples/generate-help.html}Configuring Generation of Help Mojo}} - - - + [] diff --git a/maven-plugin-plugin/src/site/apt/usage.apt b/maven-plugin-plugin/src/site/apt/usage.apt index f9d899d..0a28a3c 100644 --- a/maven-plugin-plugin/src/site/apt/usage.apt +++ b/maven-plugin-plugin/src/site/apt/usage.apt @@ -2,8 +2,9 @@ Usage ------ Maria Odea Ching + Vincent Siveton ------ - 27 July 2006 + January 2008 ------ ~~ Licensed to the Apache Software Foundation (ASF) under one @@ -40,7 +41,7 @@ Usage mvn package +-----+ - You will see that the plugin.xml file is generated in the target/classes/META-INF/maven directory of your project. The file is + You will see that the plugin.xml file is generated in the <<>> directory of your project. The file is also bundled in the generated jar file. To explicitly execute the <<>> goal, type the following in the command line: @@ -57,6 +58,8 @@ mvn plugin:descriptor mvn plugin:xdoc +-----+ + The xdoc file is generated by default in <<<$\{project.build.directory\}/generated-site/xdoc>>>. + * The <<>> Goal The <<>> goal is bound to the <<>> phase of the build life cycle. This goal updates the @@ -88,3 +91,12 @@ mvn plugin:updateRegistry mvn package +-----+ +* The <<>> Goal + + To generate an <<>> for the mojos of your plugin, execute the following on the command line: + ++-----+ +mvn plugin:helpmojo ++-----+ + + The mojo is generated by default in <<<$\{project.build.directory\}/generated-sources/plugin>>>. diff --git a/maven-plugin-plugin/src/site/site.xml b/maven-plugin-plugin/src/site/site.xml index 226ebeb..61167d0 100644 --- a/maven-plugin-plugin/src/site/site.xml +++ b/maven-plugin-plugin/src/site/site.xml @@ -21,7 +21,6 @@ - @@ -31,11 +30,12 @@ + + - + - diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java new file mode 100644 index 0000000..d8d1b13 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginHelpGenerator.java @@ -0,0 +1,534 @@ +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. + */ + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.StringReader; +import java.io.Writer; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.parser.ParserDelegator; + +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.plugin.logging.Log; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.StringUtils; + +/** + * Generates an HelpMojo class. + * + * @author Vincent Siveton + * @version $Id$ + * @since 2.4 + */ +public class PluginHelpGenerator + implements Generator +{ + private static final String LS = System.getProperty( "line.separator" ); + + private static final String HELP_MOJO_CLASS_NAME = "HelpMojo"; + + private static final String HELP_GOAL = "help"; + + private final Log log; + + /** + * Default constructor + * + * @param log + */ + public PluginHelpGenerator( Log log ) + { + this.log = log; + } + + // ---------------------------------------------------------------------- + // Public methods + // ---------------------------------------------------------------------- + + /** {@inheritDoc} */ + public void execute( File destinationDirectory, PluginDescriptor pluginDescriptor ) + throws IOException + { + if ( pluginDescriptor.getMojos() == null || pluginDescriptor.getMojos().size() < 1 ) + { + return; + } + + String packageName = discoverPackageName( pluginDescriptor ); + + File helpClass = new File( destinationDirectory, packageName.replace( '.', File.separatorChar ) + + File.separator + HELP_MOJO_CLASS_NAME + ".java" ); + + // Verify that no help goal already exists + for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) it.next(); + + if ( descriptor.getGoal().equals( HELP_GOAL ) + && !descriptor.getImplementation().equals( packageName + "." + HELP_MOJO_CLASS_NAME ) ) + { + if ( log.isWarnEnabled() ) + { + log.warn( "\n\nAn help goal (" + descriptor.getImplementation() + + ") already exists in this plugin. SKIPPED THE " + HELP_MOJO_CLASS_NAME + " GENERATION.\n" ); + } + + return; + } + } + + helpClass.getParentFile().mkdirs(); + + Writer writer = null; + try + { + writer = new FileWriter( helpClass ); + writeClass( writer, packageName, pluginDescriptor ); + writer.flush(); + } + finally + { + IOUtil.close( writer ); + } + } + + // ---------------------------------------------------------------------- + // Private methods + // ---------------------------------------------------------------------- + + /** + * @return the help goal for the generated mojo + */ + private static String getHelpGoalName() + { + return HELP_GOAL; + } + + /** + * @return the full help goal name for the generated mojo + */ + private static String getFullHelpGoalName( PluginDescriptor pluginDescriptor ) + { + return pluginDescriptor.getGoalPrefix() + ":" + getHelpGoalName(); + } + + /** + * @param pluginDescriptor + * @return the help description for the generated mojo + */ + private static String getHelpDescription( PluginDescriptor pluginDescriptor ) + { + return "Display help information on '" + pluginDescriptor.getPluginLookupKey() + "' plugin. Call 'mvn " + + getFullHelpGoalName( pluginDescriptor ) + " -Ddetail=true' to display all details."; + } + + /** + * Find the best package name, based on the number of hits of actual Mojo classes. + * + * @param pluginDescriptor + * @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, Integer.valueOf( "" + next ) ); + } + else + { + packageNames.put( name, Integer.valueOf( "" + 1 ) ); + } + } + else + { + packageNames.put( "", Integer.valueOf( "" + 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; + } + + /** + * Generated the HelpMojo class. + * + * @param writer + * @param packageName + * @param pluginDescriptor + * @throws IOException if any + */ + private static void writeClass( Writer writer, String packageName, PluginDescriptor pluginDescriptor ) + throws IOException + { + if ( packageName.length() > 0 ) + { + writer.write( "package " + packageName + ";" + LS ); + writer.write( LS ); + } + + writeImports( writer ); + writer.write( LS ); + + writeMojoJavadoc( writer, pluginDescriptor ); + + writer.write( "public class HelpMojo" + LS ); + writer.write( " extends AbstractMojo" + LS ); + writer.write( "{" + LS ); + + writeVariables( writer ); + + writer.write( LS ); + + writeExecute( writer, pluginDescriptor ); + + writer.write( LS ); + writeUtilities( writer ); + writer.write( "}" + LS ); + } + + 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( "import java.util.StringTokenizer;" + LS ); + writer.write( LS ); + writer.write( "import org.apache.maven.plugin.AbstractMojo;" + LS ); + writer.write( "import org.apache.maven.plugin.MojoExecutionException;" + LS ); + } + + private static void writeMojoJavadoc( Writer writer, PluginDescriptor pluginDescriptor ) + throws IOException + { + writer.write( "/**" + LS ); + writer.write( " * " + getHelpDescription( pluginDescriptor ) + LS ); + writer.write( " *" + LS ); + writer.write( " * @version generated on " + new Date() + LS ); + writer.write( " * @goal " + getHelpGoalName() + LS ); + writer.write( " */" + LS ); + } + + private static void writeVariables( Writer writer ) + throws IOException + { + writer.write( " /** 80-character display buffer */" + LS ); + writer.write( " private static final int DEFAULT_WIDTH = 80;" + LS ); + writer.write( LS ); + writer.write( " /** 4 indent spaces */" + LS ); + writer.write( " private static final String DEFAULT_INDENT = repeat( \" \", 4 );" + LS ); + writer.write( LS ); + writer.write( " /**" + LS ); + writer.write( " * If true, display all settable properies for each goal." + LS ); + writer.write( " *" + LS ); + writer.write( " * @parameter expression=\"${detail}\" default-value=\"false\"" + LS ); + writer.write( " */" + LS ); + writer.write( " private boolean detail;" + LS ); + } + + private static void writeExecute( Writer writer, PluginDescriptor pluginDescriptor ) + throws IOException + { + writer.write( " /** {@inheritDoc} */" + LS ); + writer.write( " public void execute()" + LS ); + writer.write( " throws MojoExecutionException" + LS ); + writer.write( " {" + LS ); + + writer.write( " StringBuffer sb = new StringBuffer();" + LS ); + writer.write( LS ); + writer.write( " sb.append( \"The '" + pluginDescriptor.getPluginLookupKey() + "' plugin has " + + ( pluginDescriptor.getMojos().size() + 1 ) + " " + + ( ( pluginDescriptor.getMojos().size() + 1 ) > 1 ? "goals" : "goal" ) + ":\" ).append( \"\\n\" );" + LS ); + writer.write( " sb.append( \"\\n\" );" + LS ); + + writer.write( LS ); + + for ( Iterator it = pluginDescriptor.getMojos().iterator(); it.hasNext(); ) + { + MojoDescriptor descriptor = (MojoDescriptor) it.next(); + + String goal = descriptor.getFullGoalName(); + String description = StringUtils.isNotEmpty( descriptor.getDescription() ) ? toText( descriptor + .getDescription() ) : "No description available."; + + writer.write( " sb.append( \"" + goal + "\" ).append( \"\\n\" );" + LS ); + writer.write( " for ( Iterator it = toLines( \"" + description + "\" ).iterator(); it.hasNext(); )" + + LS ); + writer.write( " {" + LS ); + writer.write( " sb.append( it.next().toString() ).append( \"\\n\" );" + LS ); + writer.write( " }" + LS ); + + if ( descriptor.getParameters() != null && descriptor.getParameters().size() > 0 ) + { + writer.write( " if ( detail )" + LS ); + writer.write( " {" + LS ); + + writer.write( " sb.append( \"\\n\" );" + LS ); + writer.write( LS ); + + writer.write( " sb.append( repeat( \" \", 4 ) );" + LS ); + writer.write( " sb.append( \"Available parameters:\" ).append( \"\\n\" );" + LS ); + writer.write( LS ); + writer.write( " sb.append( \"\\n\" );" + LS ); + writer.write( LS ); + + for ( Iterator it2 = descriptor.getParameters().iterator(); it2.hasNext(); ) + { + Parameter parameter = (Parameter) it2.next(); + + if ( parameter.isEditable() ) + { + String expression = parameter.getExpression(); + + if ( expression == null || !expression.startsWith( "${component." ) ) + { + String parameterName = parameter.getName(); + String parameterDescription = StringUtils.isNotEmpty( parameter.getDescription() ) + ? toText( parameter + .getDescription() ) + : "No description available."; + String parameterDefaultValue = parameterName + + ( StringUtils.isNotEmpty( parameter.getDefaultValue() ) ? " (Default: '" + + parameter.getDefaultValue() + "')" : "" ); + + writer.write( " for ( Iterator it = toLines( \"" + parameterDefaultValue + + "\", repeat( \" \", 4 ), DEFAULT_WIDTH ).iterator(); it.hasNext(); )" + LS ); + writer.write( " {" + LS ); + writer.write( " sb.append( it.next().toString() ).append( \"\\n\" );" + LS ); + writer.write( " }" + LS ); + + writer.write( " for ( Iterator it = toLines( \"" + parameterDescription + + "\", repeat( \" \", 8 ), DEFAULT_WIDTH ).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( " sb.append( \"\\n\" );" + LS ); + writer.write( LS ); + } + + // TODO Should be discovered + writer.write( " sb.append( \"" + getFullHelpGoalName( pluginDescriptor ) + "\" ).append( \"\\n\" );" + + LS ); + writer.write( " for ( Iterator it = toLines( \"" + getHelpDescription( pluginDescriptor ) + + "\" ).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( " if ( getLog().isInfoEnabled() )" + LS ); + writer.write( " {" + LS ); + writer.write( " getLog().info( sb.toString() );" + LS ); + writer.write( " }" + LS ); + writer.write( " }" + LS ); + } + + private static void writeUtilities( Writer writer ) + throws IOException + { + writer.write( " /**" + LS ); + writer.write( " *

Repeat a String n times to form a new string.

" + 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 repeat < 0" + LS ); + writer.write( " * @throws NullPointerException if str is null" + 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( " *

Give a list of lines for the str. " + "Each line is indented by 4 spaces" + + LS ); + writer.write( " * and has a maximum of 80 characters.

" + LS ); + writer.write( " *" + LS ); + writer.write( " * @param str String to split in lines" + LS ); + writer.write( " * @return List of lines" + LS ); + writer.write( " * @throws NullPointerException if str is null" + LS ); + writer.write( " */" + LS ); + writer.write( " private static List toLines( String str )" + LS ); + writer.write( " {" + LS ); + writer.write( " return toLines( str, DEFAULT_INDENT, DEFAULT_WIDTH );" + LS ); + writer.write( " }" + LS ); + writer.write( LS ); + writer.write( " /**" + LS ); + writer + .write( " *

Give a list of lines for the str. Each line is indented by indent" + + LS ); + writer.write( " * and has a maximum of size characters.

" + LS ); + writer.write( " *" + LS ); + writer.write( " * @param str String to split in lines" + LS ); + writer.write( " * @param indent the string to precede each line" + LS ); + writer.write( " * @param size the size of the character display buffer" + LS ); + writer.write( " * @return List of lines" + LS ); + writer.write( " * @throws IllegalArgumentException if size < 0" + LS ); + writer.write( " * @throws NullPointerException if str is null" + LS ); + writer.write( " */" + LS ); + writer.write( " private static List toLines( String str, String indent, int size )" + LS ); + writer.write( " {" + LS ); + writer.write( " List sentences = new ArrayList();" + LS ); + writer.write( LS ); + writer.write( " if ( indent == null )" + LS ); + writer.write( " {" + LS ); + writer.write( " indent = \"\";" + LS ); + writer.write( " }" + LS ); + writer.write( LS ); + writer.write( " if ( size < 0 )" + LS ); + writer.write( " {" + LS ); + writer.write( " throw new IllegalArgumentException( \"size should be positive\" );" + LS ); + writer.write( " }" + LS ); + writer.write( LS ); + writer.write( " StringBuffer tmp = new StringBuffer( indent );" + LS ); + writer.write( " StringTokenizer tokenizer = new StringTokenizer( str, \" \" );" + LS ); + writer.write( " while ( tokenizer.hasMoreTokens() )" + LS ); + writer.write( " {" + LS ); + writer.write( " String word = tokenizer.nextToken();" + LS ); + writer.write( LS ); + writer.write( " if ( tmp.length() + word.length() + 1 < size )" + LS ); + writer.write( " {" + LS ); + writer.write( " tmp.append( word ).append( \" \" );" + LS ); + writer.write( " }" + LS ); + writer.write( " else" + LS ); + writer.write( " {" + LS ); + writer.write( " sentences.add( tmp.toString() );" + LS ); + writer.write( " tmp = new StringBuffer( indent );" + LS ); + writer.write( " tmp.append( word ).append( \" \" );" + LS ); + writer.write( " }" + LS ); + writer.write( " }" + LS ); + writer.write( LS ); + writer.write( " if ( tmp.toString().length() > 0 )" + LS ); + writer.write( " {" + LS ); + writer.write( " sentences.add( tmp.toString() );" + LS ); + writer.write( " }" + LS ); + writer.write( LS ); + writer.write( " return sentences;" + LS ); + writer.write( " }" + LS ); + } + + /** + * Remove HTML tags from a string + * + * @param str + * @return a String with HTML tags into pure text + * @throws IOException if any + */ + private static String toText( String str ) + throws IOException + { + if ( StringUtils.isEmpty( str ) ) + { + return ""; + } + + final StringBuffer sb = new StringBuffer(); + + HTMLEditorKit.Parser parser = new ParserDelegator(); + HTMLEditorKit.ParserCallback htmlCallback = new HTMLEditorKit.ParserCallback() + { + /** {@inheritDoc} */ + public void handleText( char[] data, int pos ) + { + // the parser parses things like
as "\n>" + if ( data[0] == '>' ) + { + for ( int i = 1; i < data.length; i++ ) + { + if ( data[i] == '\n' ) + { + sb.append( ' ' ); + } + else + { + sb.append( data[i] ); + } + } + } + else + { + for ( int i = 0; i < data.length; i++ ) + { + if ( data[i] == '\n' ) + { + sb.append( ' ' ); + } + else + { + sb.append( data[i] ); + } + } + } + } + }; + + parser.parse( new StringReader( str ), htmlCallback, true ); + + return StringUtils.replace( sb.toString(), "\"", "'" ); // for CDATA + } +} diff --git a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java index a9591d5..096c111 100644 --- a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java +++ b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractor.java @@ -568,6 +568,13 @@ public class JavaMojoDescriptorExtractor builder.addSourceTree( new File( (String) i.next() ) ); } + // TODO be more dynamic + if ( !project.getCompileSourceRoots() + .contains( new File( project.getBasedir(), "target/generated-sources/plugin" ).getAbsolutePath() ) ) + { + builder.addSourceTree( new File( project.getBasedir(), "target/generated-sources/plugin" ) ); + } + return builder.getClasses(); }