[MPLUGIN-169][MPLUGIN-159] Added support for @threadSafe and @requiresDependencyCollection

git-svn-id: https://svn.apache.org/repos/asf/maven/plugin-tools/trunk@938248 13f79535-47bb-0310-9956-ffa450edef68
master
Kristian Rosenvold 2010-04-26 21:32:51 +00:00
parent 5b1e090544
commit ee79e019e3
11 changed files with 427 additions and 3 deletions

View File

@ -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;
}
}

View File

@ -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
// ----------------------------------------------------------------------

View File

@ -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 ) )
{

View File

@ -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: <code>{0}</code>.
pluginxdoc.mojodescriptor.dependencyCollectionRequired=Requires dependency collection of artifacts in scope: <code>{0}</code>.
pluginxdoc.mojodescriptor.since=Since version: <code>{0}</code>.
pluginxdoc.mojodescriptor.phase=Binds by default to the lifecycle phase: <code>{0}</code>.
pluginxdoc.mojodescriptor.executePhase=Invokes the execution of the lifecycle phase <code>{0}</code> 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

View File

@ -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 <code>compile</code>, <code>runtime</code>, and
* <code>test</code> scopes.
* <br/>
* Refer to <code>&#64;requiresDependencyCollection &lt;requiredScope&gt;</code>.
* <br/>
* <b>Note</b>: Should be defined in a Mojo Type.
*/
String REQUIRES_DEPENDENCY_COLLECTION = "requiresDependencyCollection";
/**
* Refer to <code>&#64;requiresDirectInvocation &lt;true|false&gt;</code>.
* <br/>
@ -338,4 +350,12 @@ public interface JavaMojoAnnotation
* <b>Note</b>: 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
*
* <b>Note</b>: Should be defined in a Mojo Type.
*/
String THREADSAFE = "threadSafe";
}

View File

@ -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

View File

@ -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.
*

View File

@ -26,6 +26,9 @@ import org.apache.maven.plugin.AbstractMojo;
*
* @goal ideaThree
* @requiresDependencyResolution compile
* @requiresDependencyCollection test
* @threadSafe
*
*/
public class JavaExtractorTestThree
extends AbstractMojo

View File

@ -93,6 +93,9 @@ under the License.
<taglet>
<tagletClass>org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyResolutionTypeTaglet</tagletClass>
</taglet>
<taglet>
<tagletClass>org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyCollectionTypeTaglet</tagletClass>
</taglet>
<taglet>
<tagletClass>org.apache.maven.tools.plugin.javadoc.MojoRequiresDirectInvocationTypeTaglet</tagletClass>
</taglet>
@ -105,6 +108,9 @@ under the License.
<taglet>
<tagletClass>org.apache.maven.tools.plugin.javadoc.MojoRequiresReportsTypeTaglet</tagletClass>
</taglet>
<taglet>
<tagletClass>org.apache.maven.tools.plugin.javadoc.MojoThreadSafeTypeTaglet</tagletClass>
</taglet>
</taglets>
<tagletArtifact>

View File

@ -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 <tt>@requiresDependencyCollection</tt> tag is used to specify the required dependencies in the specified scope
* and has parameter.
* <br/>
* The following is a sample declaration:
* <pre>
* &#x2f;&#x2a;&#x2a;
* &#x20;&#x2a; Dummy Mojo.
* &#x20;&#x2a;
* &#x20;&#x2a; &#64;requiresDependencyCollection &lt;requiredScope&gt;
* &#x20;&#x2a; ...
* &#x20;&#x2a;&#x2f;
* public class MyMojo extends AbstractMojo{}
* </pre>
* To use it, calling the <code>Javadoc</code> tool with the following:
* <pre>
* javadoc ... -taglet 'org.apache.maven.tools.plugin.javadoc.MojoRequiresDependencyCollectionTypeTaglet'
* </pre>
* <b>Note</b>: This taglet is similar to call the <code>Javadoc</code> tool with the following:
* <pre>
* javadoc ... -tag 'requiresDependencyCollection:t:Requires the collection of the dependencies in this specified scope:'
* </pre>
*
* @see <a href="package-summary.html#package_description">package-summary.html</a>
*
* @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 <code>"*"</code> since <code>@requiresDependencyCollection</code> has value.
* @see AbstractMojoTaglet#getAllowedValue()
*/
public String getAllowedValue()
{
return "*";
}
/**
* @return <code>null</code> since <code>@requiresDependencyCollection</code> 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 );
}
}

View File

@ -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 <tt>@threadSafe</tt> tag is used to indicate that a mojo is threadsafe and can be run in parallel
* <br/>
* The following is a sample declaration:
* <pre>
* &#x2f;&#x2a;&#x2a;
* &#x20;&#x2a; Dummy Mojo.
* &#x20;&#x2a;
* &#x20;&#x2a; &#64;threadSafe &lt;true|false&gt;
* &#x20;&#x2a; ...
* &#x20;&#x2a;&#x2f;
* public class MyMojo extends AbstractMojo{}
* </pre>
* To use it, calling the <code>Javadoc</code> tool with the following:
* <pre>
* javadoc ... -taglet 'org.apache.maven.tools.plugin.javadoc.MojoThreadSafeTypeTaglet'
* </pre>
* <b>Note</b>: This taglet is similar to call the <code>Javadoc</code> tool with the following:
* <pre>
* javadoc ... -tag 'threadSafe:t:Indicates the mojo is threadsafe'
* </pre>
*
* @see <a href="package-summary.html#package_description">package-summary.html</a>
*
* @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 <code>true|false</code> since <code>@requiresProject</code> has value.
* @see AbstractMojoTaglet#getAllowedValue()
*/
public String getAllowedValue()
{
return "true|false";
}
/**
* @return <code>null</code> since <code>@requiresProject</code> 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 );
}
}