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