1 package org.apache.maven.plugin.plugin;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.artifact.Artifact;
23 import org.apache.maven.artifact.repository.ArtifactRepository;
24 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
25 import org.apache.maven.artifact.resolver.filter.IncludesArtifactFilter;
26 import org.apache.maven.plugin.AbstractMojo;
27 import org.apache.maven.plugin.MojoExecutionException;
28 import org.apache.maven.plugin.descriptor.InvalidPluginDescriptorException;
29 import org.apache.maven.plugin.descriptor.PluginDescriptor;
30 import org.apache.maven.plugins.annotations.Component;
31 import org.apache.maven.plugins.annotations.Parameter;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.tools.plugin.DefaultPluginToolsRequest;
34 import org.apache.maven.tools.plugin.PluginToolsRequest;
35 import org.apache.maven.tools.plugin.extractor.ExtractionException;
36 import org.apache.maven.tools.plugin.generator.Generator;
37 import org.apache.maven.tools.plugin.generator.GeneratorException;
38 import org.apache.maven.tools.plugin.generator.GeneratorUtils;
39 import org.apache.maven.tools.plugin.scanner.MojoScanner;
40 import org.codehaus.plexus.component.repository.ComponentDependency;
41 import org.codehaus.plexus.util.ReaderFactory;
42
43 import java.io.File;
44 import java.util.Arrays;
45 import java.util.LinkedHashSet;
46 import java.util.List;
47 import java.util.Set;
48
49
50
51
52
53
54
55 public abstract class AbstractGeneratorMojo
56 extends AbstractMojo
57 {
58
59
60
61 @Parameter( defaultValue = "${project}", readonly = true )
62 protected MavenProject project;
63
64
65
66
67 @Component
68 protected MojoScanner mojoScanner;
69
70
71
72
73
74
75 @Parameter( property = "encoding", defaultValue = "${project.build.sourceEncoding}" )
76 protected String encoding;
77
78
79
80
81 @Parameter
82 protected String goalPrefix;
83
84
85
86
87
88
89
90
91 @Parameter( property = "maven.plugin.skipErrorNoDescriptorsFound", defaultValue = "false" )
92 protected boolean skipErrorNoDescriptorsFound;
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 @Parameter
118 protected Set<String> extractors;
119
120
121
122
123
124
125 @Parameter( defaultValue = "false", property = "maven.plugin.skip" )
126 protected boolean skip;
127
128
129
130
131
132
133 @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
134 protected Set<Artifact> dependencies;
135
136
137
138
139
140
141
142
143
144 @Parameter
145 private List<String> mojoDependencies;
146
147
148
149
150
151
152 @Parameter( defaultValue = "${project.remoteArtifactRepositories}", required = true, readonly = true )
153 protected List<ArtifactRepository> remoteRepos;
154
155
156
157
158
159
160 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
161 protected ArtifactRepository local;
162
163
164
165
166
167
168 @Parameter
169 protected List<String> packagingTypes = Arrays.asList( "maven-plugin" );
170
171
172
173
174 protected abstract File getOutputDirectory();
175
176
177
178
179 protected abstract Generator createGenerator();
180
181
182
183
184 public void execute()
185 throws MojoExecutionException
186 {
187 if ( !packagingTypes.contains( project.getPackaging() ) )
188 {
189 getLog().warn( "Unsupported packaging type " + project.getPackaging() + ", execution skipped" );
190 return;
191 }
192 if ( skip )
193 {
194 getLog().warn( "Execution skipped" );
195 return;
196 }
197
198 if ( project.getArtifactId().toLowerCase().startsWith( "maven-" )
199 && project.getArtifactId().toLowerCase().endsWith( "-plugin" ) && !"org.apache.maven.plugins".equals(
200 project.getGroupId() ) )
201 {
202 getLog().error( "\n\nArtifact Ids of the format maven-___-plugin are reserved for \n"
203 + "plugins in the Group Id org.apache.maven.plugins\n"
204 + "Please change your artifactId to the format ___-maven-plugin\n"
205 + "In the future this error will break the build.\n\n" );
206 }
207
208 String defaultGoalPrefix = PluginDescriptor.getGoalPrefixFromArtifactId( project.getArtifactId() );
209 if ( goalPrefix == null )
210 {
211 goalPrefix = defaultGoalPrefix;
212 }
213 else if ( !goalPrefix.equals( defaultGoalPrefix ) )
214 {
215 getLog().warn(
216 "\n\nGoal prefix is specified as: '" + goalPrefix + "'. " + "Maven currently expects it to be '"
217 + defaultGoalPrefix + "'.\n" );
218 }
219
220 mojoScanner.setActiveExtractors( extractors );
221
222
223 PluginDescriptor pluginDescriptor = new PluginDescriptor();
224
225 pluginDescriptor.setGroupId( project.getGroupId() );
226
227 pluginDescriptor.setArtifactId( project.getArtifactId() );
228
229 pluginDescriptor.setVersion( project.getVersion() );
230
231 pluginDescriptor.setGoalPrefix( goalPrefix );
232
233 pluginDescriptor.setName( project.getName() );
234
235 pluginDescriptor.setDescription( project.getDescription() );
236
237 if ( encoding == null || encoding.length() < 1 )
238 {
239 getLog().warn( "Using platform encoding (" + ReaderFactory.FILE_ENCODING
240 + " actually) to read mojo source files, i.e. build is platform dependent!" );
241 }
242 else
243 {
244 getLog().info( "Using '" + encoding + "' encoding to read mojo source files." );
245 }
246
247 try
248 {
249 List<ComponentDependency> deps = GeneratorUtils.toComponentDependencies( project.getRuntimeDependencies() );
250 pluginDescriptor.setDependencies( deps );
251
252 PluginToolsRequest request = new DefaultPluginToolsRequest( project, pluginDescriptor );
253 request.setEncoding( encoding );
254 request.setSkipErrorNoDescriptorsFound( skipErrorNoDescriptorsFound );
255 request.setDependencies( filterMojoDependencies() );
256 request.setLocal( this.local );
257 request.setRemoteRepos( this.remoteRepos );
258
259 mojoScanner.populatePluginDescriptor( request );
260
261 getOutputDirectory().mkdirs();
262
263 createGenerator().execute( getOutputDirectory(), request );
264 }
265 catch ( GeneratorException e )
266 {
267 throw new MojoExecutionException( "Error writing plugin descriptor", e );
268 }
269 catch ( InvalidPluginDescriptorException e )
270 {
271 throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
272 e );
273 }
274 catch ( ExtractionException e )
275 {
276 throw new MojoExecutionException( "Error extracting plugin descriptor: \'" + e.getLocalizedMessage() + "\'",
277 e );
278 }
279 catch ( LinkageError e )
280 {
281 throw new MojoExecutionException( "The API of the mojo scanner is not compatible with this plugin version."
282 + " Please check the plugin dependencies configured in the POM and ensure the versions match.", e );
283 }
284 }
285
286
287
288
289
290
291
292
293 private Set<Artifact> filterMojoDependencies()
294 {
295 Set<Artifact> filteredDependencies;
296 if ( mojoDependencies == null )
297 {
298 filteredDependencies = dependencies;
299 }
300 else if ( mojoDependencies.size() == 0 )
301 {
302 filteredDependencies = null;
303 }
304 else
305 {
306 filteredDependencies = new LinkedHashSet<Artifact>();
307
308 ArtifactFilter filter = new IncludesArtifactFilter( mojoDependencies );
309
310 for ( Artifact artifact : dependencies )
311 {
312 if ( filter.include( artifact ) )
313 {
314 filteredDependencies.add( artifact );
315 }
316 }
317 }
318
319 return filteredDependencies;
320 }
321 }