View Javadoc
1   package org.apache.maven.plugin.plugin;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.Artifact;
23  import org.apache.maven.artifact.repository.ArtifactRepository;
24  import org.apache.maven.plugin.AbstractMojo;
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
27  import org.apache.maven.plugin.descriptor.PluginDescriptor;
28  import org.apache.maven.plugins.annotations.Component;
29  import org.apache.maven.plugins.annotations.Parameter;
30  import org.apache.maven.project.MavenProject;
31  import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
32  import org.apache.maven.tools.plugin.PluginToolsRequest;
33  import org.apache.maven.tools.plugin.extractor.ExtractionException;
34  import org.apache.maven.tools.plugin.generator.Generator;
35  import org.apache.maven.tools.plugin.generator.GeneratorException;
36  import org.apache.maven.tools.plugin.generator.GeneratorUtils;
37  import org.apache.maven.tools.plugin.scanner.MojoScanner;
38  import org.codehaus.plexus.util.ReaderFactory;
39  
40  import java.io.File;
41  import java.util.Arrays;
42  import java.util.List;
43  import java.util.Set;
44  
45  /**
46   * Abstract class for this Plugin.
47   *
48   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
49   * @version $Id: AbstractGeneratorMojo.html 907040 2014-04-27 09:50:12Z hboutemy $
50   */
51  public abstract class AbstractGeneratorMojo
52      extends AbstractMojo
53  {
54      /**
55       * The project currently being built.
56       */
57      @Component
58      protected MavenProject project;
59  
60      /**
61       * The component used for scanning the source tree for mojos.
62       */
63      @Component
64      protected MojoScanner mojoScanner;
65  
66      /**
67       * The file encoding of the source files.
68       *
69       * @since 2.5
70       */
71      @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
72      protected String encoding;
73  
74      /**
75       * The goal prefix that will appear before the ":".
76       */
77      @Parameter
78      protected String goalPrefix;
79  
80      /**
81       * By default an exception is throw if no mojo descriptor is found. As the maven-plugin is defined in core, the
82       * descriptor generator mojo is bound to generate-resources phase.
83       * But for annotations, the compiled classes are needed, so skip error
84       *
85       * @since 3.0
86       */
87      @Parameter( property = "maven.plugin.skipErrorNoDescriptorsFound", defaultValue = "false" )
88      protected boolean skipErrorNoDescriptorsFound;
89  
90      /**
91       * The role names of mojo extractors to use.
92       * <p/>
93       * If not set, all mojo extractors will be used. If set to an empty extractor name, no mojo extractors
94       * will be used.
95       * <p/>
96       * Example:
97       * <p/>
98       * <pre>
99       *  &lt;!-- Use all mojo extractors --&gt;
100      *  &lt;extractors/&gt;
101      *
102      *  &lt;!-- Use no mojo extractors --&gt;
103      *  &lt;extractors&gt;
104      *      &lt;extractor/&gt;
105      *  &lt;/extractors&gt;
106      *
107      *  &lt;!-- Use only bsh mojo extractor --&gt;
108      *  &lt;extractors&gt;
109      *      &lt;extractor&gt;bsh&lt;/extractor&gt;
110      *  &lt;/extractors&gt;
111      * </pre>
112      */
113     @Parameter
114     protected Set<String> extractors;
115 
116     /**
117      * Set this to "true" to skip invoking any goals or reports of the plugin.
118      *
119      * @since 2.8
120      */
121     @Parameter( defaultValue = "false", property = "maven.plugin.skip" )
122     protected boolean skip;
123 
124     /**
125      * The set of dependencies for the current project
126      *
127      * @since 3.0
128      */
129     @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
130     protected Set<Artifact> dependencies;
131 
132     /**
133      * List of Remote Repositories used by the resolver
134      *
135      * @since 3.0
136      */
137     @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
138     protected List<ArtifactRepository> remoteRepos;
139 
140     /**
141      * Location of the local repository.
142      *
143      * @since 3.0
144      */
145     @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
146     protected ArtifactRepository local;
147 
148     /**
149      * Maven plugin packaging types. Default is single "maven-plugin".
150      * 
151      * @since 3.3
152      */
153     @Parameter
154     protected List<String> packagingTypes = Arrays.asList( "maven-plugin" );
155 
156     /**
157      * @return the output directory where files will be generated.
158      */
159     protected abstract File getOutputDirectory();
160 
161     /**
162      * @return the wanted <code>Generator</code> implementation.
163      */
164     protected abstract Generator createGenerator();
165 
166     /**
167      * {@inheritDoc}
168      */
169     public void execute()
170         throws MojoExecutionException
171     {
172         if ( !packagingTypes.contains( project.getPackaging() ) )
173         {
174             getLog().warn( "Unsupported packaging type " + project.getPackaging() + ", execution skipped" );
175             return;
176         }
177         if ( skip )
178         {
179             getLog().warn( "Execution skipped" );
180             return;
181         }
182 
183         if ( project.getArtifactId().toLowerCase().startsWith( "maven-" )
184             && project.getArtifactId().toLowerCase().endsWith( "-plugin" ) && !"org.apache.maven.plugins".equals(
185             project.getGroupId() ) )
186         {
187             getLog().error( "\n\nArtifact Ids of the format maven-___-plugin are reserved for \n"
188                                 + "plugins in the Group Id org.apache.maven.plugins\n"
189                                 + "Please change your artifactId to the format ___-maven-plugin\n"
190                                 + "In the future this error will break the build.\n\n" );
191         }
192 
193         String defaultGoalPrefix = PluginDescriptor.getGoalPrefixFromArtifactId( project.getArtifactId() );
194         if ( goalPrefix == null )
195         {
196             goalPrefix = defaultGoalPrefix;
197         }
198         else if ( !goalPrefix.equals( defaultGoalPrefix ) )
199         {
200             getLog().warn(
201                 "\n\nGoal prefix is specified as: '" + goalPrefix + "'. " + "Maven currently expects it to be '"
202                     + defaultGoalPrefix + "'.\n" );
203         }
204 
205         mojoScanner.setActiveExtractors( extractors );
206 
207         // TODO: could use this more, eg in the writing of the plugin descriptor!
208         PluginDescriptor pluginDescriptor = new PluginDescriptor();
209 
210         pluginDescriptor.setGroupId( project.getGroupId() );
211 
212         pluginDescriptor.setArtifactId( project.getArtifactId() );
213 
214         pluginDescriptor.setVersion( project.getVersion() );
215 
216         pluginDescriptor.setGoalPrefix( goalPrefix );
217 
218         pluginDescriptor.setName( project.getName() );
219 
220         pluginDescriptor.setDescription( project.getDescription() );
221 
222         if ( encoding == null || encoding.length() < 1 )
223         {
224             getLog().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING
225                                + " actually) to read mojo metadata, i.e. build is platform dependent!" );
226         }
227         else
228         {
229             getLog().info( "Using '" + encoding + "' encoding to read mojo metadata." );
230         }
231 
232         try
233         {
234             pluginDescriptor.setDependencies( GeneratorUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
235 
236             PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
237             request.setEncoding( encoding );
238             request.setSkipErrorNoDescriptorsFound( skipErrorNoDescriptorsFound );
239             request.setDependencies( dependencies );
240             request.setLocal( this.local );
241             request.setRemoteRepos( this.remoteRepos );
242 
243             mojoScanner.populatePluginDescriptor( request );
244 
245             getOutputDirectory().mkdirs();
246 
247             createGenerator().execute( getOutputDirectory(), request );
248         }
249         catch ( GeneratorException e )
250         {
251             throw new MojoExecutionException( "Error writing plugin descriptor", e );
252         }
253         catch ( InvalidPluginDescriptorException e )
254         {
255             throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
256                                               e );
257         }
258         catch ( ExtractionException e )
259         {
260             throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
261                                               e );
262         }
263         catch ( LinkageError e )
264         {
265             throw new MojoExecutionException( "The API of the mojo scanner is not compatible with this plugin version."
266                 + " Please check the plugin dependencies configured in the POM and ensure the versions match.", e );
267         }
268     }
269 
270 }