001 package org.apache.maven.plugin.plugin;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.maven.artifact.Artifact;
023 import org.apache.maven.artifact.repository.ArtifactRepository;
024 import org.apache.maven.plugin.AbstractMojo;
025 import org.apache.maven.plugin.MojoExecutionException;
026 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
027 import org.apache.maven.plugin.descriptor.PluginDescriptor;
028 import org.apache.maven.plugins.annotations.Component;
029 import org.apache.maven.plugins.annotations.Parameter;
030 import org.apache.maven.project.MavenProject;
031 import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
032 import org.apache.maven.tools.plugin.PluginToolsRequest;
033 import org.apache.maven.tools.plugin.extractor.ExtractionException;
034 import org.apache.maven.tools.plugin.generator.Generator;
035 import org.apache.maven.tools.plugin.generator.GeneratorException;
036 import org.apache.maven.tools.plugin.generator.GeneratorUtils;
037 import org.apache.maven.tools.plugin.scanner.MojoScanner;
038 import org.codehaus.plexus.util.ReaderFactory;
039
040 import java.io.File;
041 import java.util.List;
042 import java.util.Set;
043
044 /**
045 * Abstract class for this Plugin.
046 *
047 * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
048 * @version $Id: AbstractGeneratorMojo.java 1345787 2012-06-03 21:58:22Z hboutemy $
049 */
050 public abstract class AbstractGeneratorMojo
051 extends AbstractMojo
052 {
053 /**
054 * The project currently being built.
055 */
056 @Component
057 protected MavenProject project;
058
059 /**
060 * The component used for scanning the source tree for mojos.
061 */
062 @Component
063 protected MojoScanner mojoScanner;
064
065 /**
066 * The file encoding of the source files.
067 *
068 * @since 2.5
069 */
070 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
071 protected String encoding;
072
073 /**
074 * The goal prefix that will appear before the ":".
075 */
076 @Parameter
077 protected String goalPrefix;
078
079 /**
080 * By default an exception is throw if no mojo descriptor is found. As the maven-plugin is defined in core, the
081 * descriptor generator mojo is bound to generate-resources phase.
082 * But for annotations, the compiled classes are needed, so skip error
083 *
084 * @since 3.0
085 */
086 @Parameter( property = "maven.plugin.skipErrorNoDescriptorsFound", defaultValue = "false" )
087 protected boolean skipErrorNoDescriptorsFound;
088
089 /**
090 * The role names of mojo extractors to use.
091 * <p/>
092 * If not set, all mojo extractors will be used. If set to an empty extractor name, no mojo extractors
093 * will be used.
094 * <p/>
095 * Example:
096 * <p/>
097 * <pre>
098 * <!-- Use all mojo extractors -->
099 * <extractors/>
100 *
101 * <!-- Use no mojo extractors -->
102 * <extractors>
103 * <extractor/>
104 * </extractors>
105 *
106 * <!-- Use only bsh mojo extractor -->
107 * <extractors>
108 * <extractor>bsh</extractor>
109 * </extractors>
110 * </pre>
111 */
112 @Parameter
113 protected Set<String> extractors;
114
115 /**
116 * Set this to "true" to skip invoking any goals or reports of the plugin.
117 *
118 * @since 2.8
119 */
120 @Parameter( defaultValue = "false", property = "maven.plugin.skip" )
121 protected boolean skip;
122
123 /**
124 * The set of dependencies for the current project
125 *
126 * @since 3.0
127 */
128 @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
129 protected Set<Artifact> dependencies;
130
131 /**
132 * List of Remote Repositories used by the resolver
133 *
134 * @since 3.0
135 */
136 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
137 protected List<ArtifactRepository> remoteRepos;
138
139 /**
140 * Location of the local repository.
141 *
142 * @since 3.0
143 */
144 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
145 protected ArtifactRepository local;
146
147 /**
148 * @return the output directory where files will be generated.
149 */
150 protected abstract File getOutputDirectory();
151
152 /**
153 * @return the wanted <code>Generator</code> implementation.
154 */
155 protected abstract Generator createGenerator();
156
157 /**
158 * {@inheritDoc}
159 */
160 public void execute()
161 throws MojoExecutionException
162 {
163 if ( !"maven-plugin".equals( project.getPackaging() ) )
164 {
165 return;
166 }
167 if ( skip )
168 {
169 getLog().warn( "Execution skipped" );
170 return;
171 }
172
173 if ( project.getArtifactId().toLowerCase().startsWith( "maven-" )
174 && project.getArtifactId().toLowerCase().endsWith( "-plugin" ) && !"org.apache.maven.plugins".equals(
175 project.getGroupId() ) )
176 {
177 getLog().error( "\n\nArtifact Ids of the format maven-___-plugin are reserved for \n"
178 + "plugins in the Group Id org.apache.maven.plugins\n"
179 + "Please change your artifactId to the format ___-maven-plugin\n"
180 + "In the future this error will break the build.\n\n" );
181 }
182
183 String defaultGoalPrefix = PluginDescriptor.getGoalPrefixFromArtifactId( project.getArtifactId() );
184 if ( goalPrefix == null )
185 {
186 goalPrefix = defaultGoalPrefix;
187 }
188 else if ( !goalPrefix.equals( defaultGoalPrefix ) )
189 {
190 getLog().warn(
191 "\n\nGoal prefix is specified as: '" + goalPrefix + "'. " + "Maven currently expects it to be '"
192 + defaultGoalPrefix + "'.\n" );
193 }
194
195 mojoScanner.setActiveExtractors( extractors );
196
197 // TODO: could use this more, eg in the writing of the plugin descriptor!
198 PluginDescriptor pluginDescriptor = new PluginDescriptor();
199
200 pluginDescriptor.setGroupId( project.getGroupId() );
201
202 pluginDescriptor.setArtifactId( project.getArtifactId() );
203
204 pluginDescriptor.setVersion( project.getVersion() );
205
206 pluginDescriptor.setGoalPrefix( goalPrefix );
207
208 pluginDescriptor.setName( project.getName() );
209
210 pluginDescriptor.setDescription( project.getDescription() );
211
212 if ( encoding == null || encoding.length() < 1 )
213 {
214 getLog().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING
215 + " actually) to read mojo metadata, i.e. build is platform dependent!" );
216 }
217 else
218 {
219 getLog().info( "Using '" + encoding + "' encoding to read mojo metadata." );
220 }
221
222 try
223 {
224 pluginDescriptor.setDependencies( GeneratorUtils.toComponentDependencies( project.getRuntimeDependencies() ) );
225
226 PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
227 request.setEncoding( encoding );
228 request.setSkipErrorNoDescriptorsFound( skipErrorNoDescriptorsFound );
229 request.setDependencies( dependencies );
230 request.setLocal( this.local );
231 request.setRemoteRepos( this.remoteRepos );
232
233 mojoScanner.populatePluginDescriptor( request );
234
235 getOutputDirectory().mkdirs();
236
237 createGenerator().execute( getOutputDirectory(), request );
238 }
239 catch ( GeneratorException e )
240 {
241 throw new MojoExecutionException( "Error writing plugin descriptor", e );
242 }
243 catch ( InvalidPluginDescriptorException e )
244 {
245 throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
246 e );
247 }
248 catch ( ExtractionException e )
249 {
250 throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
251 e );
252 }
253 catch ( LinkageError e )
254 {
255 throw new MojoExecutionException( "The API of the mojo scanner is not compatible with this plugin version."
256 + " Please check the plugin dependencies configured in the POM and ensure the versions match.",
257 e );
258 }
259 }
260
261 }