diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/ExtendedMojoDescriptor.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/ExtendedMojoDescriptor.java new file mode 100644 index 0000000..de5d2a7 --- /dev/null +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/ExtendedMojoDescriptor.java @@ -0,0 +1,53 @@ +package org.apache.maven.tools.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 org.apache.maven.plugin.descriptor.MojoDescriptor; + +/** + * @author Kristian Rosenvold + */ +public class ExtendedMojoDescriptor + extends MojoDescriptor +{ + private boolean threadSafe = false; + + private String requiresDependencyCollection = null; + + public boolean isThreadSafe() + { + return threadSafe; + } + + public void setThreadSafe( boolean threadSafe ) + { + this.threadSafe = threadSafe; + } + + public String getRequiresDependencyCollection() + { + return requiresDependencyCollection; + } + + public void setRequiresDependencyCollection( String requiresDependencyCollection ) + { + this.requiresDependencyCollection = requiresDependencyCollection; + } +} diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java index ac9da60..cec7ebf 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginDescriptorGenerator.java @@ -24,6 +24,7 @@ import org.apache.maven.plugin.descriptor.Parameter; import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.descriptor.Requirement; 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; @@ -301,6 +302,23 @@ public class PluginDescriptorGenerator w.endElement(); } + // ---------------------------------------------------------------------- + // Extended (3.0) descriptor + // ---------------------------------------------------------------------- + + if ( mojoDescriptor instanceof ExtendedMojoDescriptor ) + { + ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor; + if ( extendedMojoDescriptor.getRequiresDependencyCollection() != null ) + { + PluginUtils.element( w, "requiresDependencyCollection", + extendedMojoDescriptor.getRequiresDependencyCollection() ); + } + + PluginUtils.element( w, "threadSafe", "" + ( (ExtendedMojoDescriptor) mojoDescriptor ).isThreadSafe() ); + + } + // ---------------------------------------------------------------------- // Parameters // ---------------------------------------------------------------------- diff --git a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java index d98c1df..9c1821c 100644 --- a/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java +++ b/maven-plugin-tools-api/src/main/java/org/apache/maven/tools/plugin/generator/PluginXdocGenerator.java @@ -37,6 +37,7 @@ 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; @@ -308,6 +309,37 @@ public class PluginXdocGenerator w.endElement(); //li } + if ( mojoDescriptor instanceof ExtendedMojoDescriptor ) + { + ExtendedMojoDescriptor extendedMojoDescriptor = (ExtendedMojoDescriptor) mojoDescriptor; + + value = extendedMojoDescriptor.getRequiresDependencyCollection(); + if ( StringUtils.isNotEmpty( value ) ) + { + if ( !addedUl ) + { + w.startElement( "ul" ); + addedUl = true; + } + w.startElement( "li" ); + w.writeMarkup( format( "pluginxdoc.mojodescriptor.dependencyCollectionRequired", value ) ); + w.endElement(); //li + } + + if ( extendedMojoDescriptor.isThreadSafe() ) + { + if ( !addedUl ) + { + w.startElement( "ul" ); + addedUl = true; + } + w.startElement( "li" ); + w.writeMarkup( getString( "pluginxdoc.mojodescriptor.threadSafe" ) ); + w.endElement(); //li + } + + } + value = mojoDescriptor.getSince(); if ( StringUtils.isNotEmpty( value ) ) { diff --git a/maven-plugin-tools-api/src/main/resources/pluginxdoc.properties b/maven-plugin-tools-api/src/main/resources/pluginxdoc.properties index b4d4ba9..34a99b9 100644 --- a/maven-plugin-tools-api/src/main/resources/pluginxdoc.properties +++ b/maven-plugin-tools-api/src/main/resources/pluginxdoc.properties @@ -30,6 +30,7 @@ pluginxdoc.mojodescriptor.projectRequired=Requires a Maven 2.0 project to be exe pluginxdoc.mojodescriptor.aggregator=Executes as an aggregator plugin. pluginxdoc.mojodescriptor.directInvocationOnly=Executes by direct invocation only. pluginxdoc.mojodescriptor.dependencyResolutionRequired=Requires dependency resolution of artifacts in scope: {0}. +pluginxdoc.mojodescriptor.dependencyCollectionRequired=Requires dependency collection of artifacts in scope: {0}. pluginxdoc.mojodescriptor.since=Since version: {0}. pluginxdoc.mojodescriptor.phase=Binds by default to the lifecycle phase: {0}. pluginxdoc.mojodescriptor.executePhase=Invokes the execution of the lifecycle phase {0} prior to executing itself. @@ -53,3 +54,4 @@ pluginxdoc.mojodescriptor.requiredParameters=Required Parameters pluginxdoc.mojodescriptor.optionalParameters=Optional Parameters pluginxdoc.mojodescriptor.parameters=Parameters pluginxdoc.mojodescriptor.noParameter=(no parameters) +pluginxdoc.mojodescriptor.threadSafe=The mojo is threadsafe diff --git a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoAnnotation.java b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoAnnotation.java index d9c33db..ec5465b 100644 --- a/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoAnnotation.java +++ b/maven-plugin-tools-java/src/main/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoAnnotation.java @@ -181,6 +181,18 @@ public interface JavaMojoAnnotation */ String REQUIRES_DEPENDENCY_RESOLUTION = "requiresDependencyResolution"; + /** + * Flags this Mojo as requiring the dependencies in the specified scope (or an implied scope) to be collected + * before it can execute. Currently supports compile, runtime, and + * test scopes. + *
+ * Refer to @requiresDependencyCollection <requiredScope>. + *
+ * Note: Should be defined in a Mojo Type. + */ + String REQUIRES_DEPENDENCY_COLLECTION = "requiresDependencyCollection"; + + /** * Refer to @requiresDirectInvocation <true|false>. *
@@ -338,4 +350,12 @@ public interface JavaMojoAnnotation * Note: Could be defined in a Mojo Type or a Mojo Field. */ String DEPRECATED = "deprecated"; + + /** + * Indicates that this mojo is threadsafe and can be run in parallel + * + * Note: Should be defined in a Mojo Type. + */ + String THREADSAFE = "threadSafe"; + } 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 1837306..7074005 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 @@ -33,6 +33,7 @@ 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.extractor.MojoDescriptorExtractor; import org.apache.maven.tools.plugin.extractor.ExtractionException; @@ -198,7 +199,7 @@ public class JavaMojoDescriptorExtractor protected MojoDescriptor createMojoDescriptor( JavaClass javaClass ) throws InvalidPluginDescriptorException { - MojoDescriptor mojoDescriptor = new MojoDescriptor(); + ExtendedMojoDescriptor mojoDescriptor = new ExtendedMojoDescriptor(); mojoDescriptor.setLanguage( "java" ); mojoDescriptor.setImplementation( javaClass.getFullyQualifiedName() ); mojoDescriptor.setDescription( javaClass.getComment() ); @@ -303,6 +304,14 @@ public class JavaMojoDescriptorExtractor mojoDescriptor.setDependencyResolutionRequired( v ); } + // What version it was introduced in + DocletTag requiresDependencyCollection = + findInClassHierarchy( javaClass, JavaMojoAnnotation.REQUIRES_DEPENDENCY_COLLECTION ); + if ( requiresDependencyCollection != null ) + { + mojoDescriptor.setRequiresDependencyCollection( requiresDependencyCollection.getValue() ); + } + // requiresDirectInvocation flag value = getBooleanTagValue( javaClass, JavaMojoAnnotation.REQUIRES_DIRECT_INVOCATION, @@ -324,7 +333,7 @@ public class JavaMojoDescriptorExtractor getBooleanTagValue( javaClass, JavaMojoAnnotation.REQUIRES_REPORTS, mojoDescriptor.isRequiresReports() ); mojoDescriptor.setRequiresReports( value ); - // ---------------------------------------------------------------------- + // -------------------------------------------------------- -------------- // Javadoc annotations in alphabetical order // ---------------------------------------------------------------------- @@ -342,6 +351,11 @@ public class JavaMojoDescriptorExtractor mojoDescriptor.setSince( since.getValue() ); } + // Threadsafe mojo + + value = getBooleanTagValue( javaClass, JavaMojoAnnotation.THREADSAFE, true, mojoDescriptor.isThreadSafe() ); + mojoDescriptor.setThreadSafe( value ); + extractParameters( mojoDescriptor, javaClass ); return mojoDescriptor; @@ -370,6 +384,35 @@ public class JavaMojoDescriptorExtractor return defaultValue; } + /** + * @param javaClass not null + * @param tagName not null + * @param defaultForTag The wanted default value when only the tagname is present + * @param defaultValue the wanted default value when the tag is not specified + * @return the boolean value of the given tagName + * @see #findInClassHierarchy(JavaClass, String) + */ + private static boolean getBooleanTagValue( JavaClass javaClass, String tagName, boolean defaultForTag, + boolean defaultValue ) + { + DocletTag tag = findInClassHierarchy( javaClass, tagName ); + + if ( tag != null ) + { + String value = tag.getValue(); + + if ( StringUtils.isEmpty( value ) ) + { + return defaultForTag; + } + else if ( StringUtils.isNotEmpty( value ) ) + { + return Boolean.valueOf( value ).booleanValue(); + } + } + return defaultValue; + } + /** * @param javaClass not null * @param tagName not null diff --git a/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java b/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java index a7c8c6b..f4a571f 100644 --- a/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java +++ b/maven-plugin-tools-java/src/test/java/org/apache/maven/tools/plugin/extractor/java/JavaMojoDescriptorExtractorTest.java @@ -26,6 +26,7 @@ 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.codehaus.plexus.util.FileUtils; @@ -113,7 +114,20 @@ public class JavaMojoDescriptorExtractorTest assertEquals( "Implementation parameter", "source2.sub.MyBla", parameter.getImplementation() ); } - + + public void testMaven30Parameters() + throws Exception + { + List results = extract( "source2" ); + + assertEquals( 1, results.size() ); + + ExtendedMojoDescriptor mojoDescriptor = (ExtendedMojoDescriptor) results.get( 0 ); + assertTrue( mojoDescriptor.isThreadSafe()); + assertEquals( "test", mojoDescriptor.getRequiresDependencyCollection() ); + + } + /** * Check that the mojo descriptor extractor will ignore any annotations that are found. * diff --git a/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java b/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java index e0e6d89..fe5f60d 100644 --- a/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java +++ b/maven-plugin-tools-java/src/test/resources/source2/JavaExtractorTestThree.java @@ -26,6 +26,9 @@ import org.apache.maven.plugin.AbstractMojo; * * @goal ideaThree * @requiresDependencyResolution compile + * @requiresDependencyCollection test + * @threadSafe + * */ public class JavaExtractorTestThree extends AbstractMojo diff --git a/maven-plugin-tools-javadoc/src/it/basic/pom.xml b/maven-plugin-tools-javadoc/src/it/basic/pom.xml index 9ecbc8f..26b63a5 100644 --- a/maven-plugin-tools-javadoc/src/it/basic/pom.xml +++ b/maven-plugin-tools-javadoc/src/it/basic/pom.xml @@ -93,6 +93,9 @@ under the License. org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyResolutionTypeTaglet + + org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyCollectionTypeTaglet + org.apache.maven.tools.plugin.javadoc.MojoRequiresDirectInvocationTypeTaglet @@ -105,6 +108,9 @@ under the License. org.apache.maven.tools.plugin.javadoc.MojoRequiresReportsTypeTaglet + + org.apache.maven.tools.plugin.javadoc.MojoThreadSafeTypeTaglet + diff --git a/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoRequiresDependencyCollectionTypeTaglet.java b/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoRequiresDependencyCollectionTypeTaglet.java new file mode 100644 index 0000000..e2c250f --- /dev/null +++ b/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoRequiresDependencyCollectionTypeTaglet.java @@ -0,0 +1,117 @@ +package org.apache.maven.tools.plugin.javadoc; + +/* + * 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.sun.tools.doclets.Taglet; +import org.apache.maven.tools.plugin.extractor.java.JavaMojoAnnotation; + +import java.util.Map; + +/** + * The @requiresDependencyCollection tag is used to specify the required dependencies in the specified scope + * and has parameter. + *
+ * The following is a sample declaration: + *
+ * /**
+ *  * Dummy Mojo.
+ *  *
+ *  * @requiresDependencyCollection <requiredScope>
+ *  * ...
+ *  */
+ * public class MyMojo extends AbstractMojo{}
+ * 
+ * To use it, calling the Javadoc tool with the following: + *
+ * javadoc ... -taglet 'org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyCollectionTypeTaglet'
+ * 
+ * Note: This taglet is similar to call the Javadoc tool with the following: + *
+ * javadoc ... -tag 'requiresDependencyCollection:t:Requires the collection of the dependencies in this specified scope:'
+ * 
+ * + * @see package-summary.html + * + * @author Kristian Rosenvold + * @version $Id$ + */ +public class MojoRequiresDependencyCollectionTypeTaglet + extends AbstractMojoTypeTaglet +{ + /** The Javadoc annotation */ + private static final String NAME = JavaMojoAnnotation.REQUIRES_DEPENDENCY_COLLECTION; + + /** The Javadoc text which will be added to the generated page. */ + protected static final String HEADER = "Collects the dependencies in this specified scope"; + + /** + * @return By default, return the string defined in {@linkplain #HEADER}. + * @see AbstractMojoTaglet#getHeader() + * @see #HEADER + */ + public String getHeader() + { + return HEADER; + } + + /** + * @return "*" since @requiresDependencyCollection has value. + * @see AbstractMojoTaglet#getAllowedValue() + */ + public String getAllowedValue() + { + return "*"; + } + + /** + * @return null since @requiresDependencyCollection has no parameter. + * @see AbstractMojoTaglet#getAllowedParameterNames() + */ + public String[] getAllowedParameterNames() + { + return null; + } + + /** + * @return By default, return the name of this taglet. + * @see com.sun.tools.doclets.Taglet#getName() + * @see org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyCollectionTypeTaglet#NAME + */ + public String getName() + { + return NAME; + } + + /** + * Register this Taglet. + * + * @param tagletMap the map to register this tag to. + */ + public static void register( Map tagletMap ) + { + MojoRequiresDependencyCollectionTypeTaglet tag = new MojoRequiresDependencyCollectionTypeTaglet(); + Taglet t = (Taglet) tagletMap.get( tag.getName() ); + if ( t != null ) + { + tagletMap.remove( tag.getName() ); + } + tagletMap.put( tag.getName(), tag ); + } +} \ No newline at end of file diff --git a/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoThreadSafeTypeTaglet.java b/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoThreadSafeTypeTaglet.java new file mode 100644 index 0000000..2c8bd03 --- /dev/null +++ b/maven-plugin-tools-javadoc/src/main/java/org/apache/maven/tools/plugin/javadoc/MojoThreadSafeTypeTaglet.java @@ -0,0 +1,116 @@ +package org.apache.maven.tools.plugin.javadoc; + +/* + * 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.sun.tools.doclets.Taglet; +import org.apache.maven.tools.plugin.extractor.java.JavaMojoAnnotation; + +import java.util.Map; + +/** + * The @threadSafe tag is used to indicate that a mojo is threadsafe and can be run in parallel + *
+ * The following is a sample declaration: + *
+ * /**
+ *  * Dummy Mojo.
+ *  *
+ *  * @threadSafe <true|false>
+ *  * ...
+ *  */
+ * public class MyMojo extends AbstractMojo{}
+ * 
+ * To use it, calling the Javadoc tool with the following: + *
+ * javadoc ... -taglet 'org.apache.maven.tools.plugin.javadoc.MojoThreadSafeTypeTaglet'
+ * 
+ * Note: This taglet is similar to call the Javadoc tool with the following: + *
+ * javadoc ... -tag 'threadSafe:t:Indicates the mojo is threadsafe'
+ * 
+ * + * @see package-summary.html + * + * @author Kristian Rosenvold + * @version $Id$ + */ +public class MojoThreadSafeTypeTaglet + extends AbstractMojoTypeTaglet +{ + /** The Javadoc annotation */ + private static final String NAME = JavaMojoAnnotation.THREADSAFE; + + /** The Javadoc text which will be added to the generated page. */ + protected static final String HEADER = "Mojo is thread safe"; + + /** + * @return By default, return the string defined in {@linkplain #HEADER}. + * @see AbstractMojoTaglet#getHeader() + * @see #HEADER + */ + public String getHeader() + { + return HEADER; + } + + /** + * @return true|false since @requiresProject has value. + * @see AbstractMojoTaglet#getAllowedValue() + */ + public String getAllowedValue() + { + return "true|false"; + } + + /** + * @return null since @requiresProject has no parameter. + * @see AbstractMojoTaglet#getAllowedParameterNames() + */ + public String[] getAllowedParameterNames() + { + return null; + } + + /** + * @return By default, return the name of this taglet. + * @see com.sun.tools.doclets.Taglet#getName() + * @see MojoThreadSafeTypeTaglet#NAME + */ + public String getName() + { + return NAME; + } + + /** + * Register this Taglet. + * + * @param tagletMap the map to register this tag to. + */ + public static void register( Map tagletMap ) + { + MojoThreadSafeTypeTaglet tag = new MojoThreadSafeTypeTaglet(); + Taglet t = (Taglet) tagletMap.get( tag.getName() ); + if ( t != null ) + { + tagletMap.remove( tag.getName() ); + } + tagletMap.put( tag.getName(), tag ); + } +} \ No newline at end of file