1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.descriptor;
20
21 import javax.xml.stream.XMLStreamException;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.MalformedURLException;
27 import java.net.URL;
28 import java.nio.file.Files;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Set;
35 import java.util.regex.Pattern;
36 import java.util.stream.Collectors;
37
38 import org.apache.maven.api.plugin.descriptor.lifecycle.Lifecycle;
39 import org.apache.maven.api.plugin.descriptor.lifecycle.LifecycleConfiguration;
40 import org.apache.maven.artifact.Artifact;
41 import org.apache.maven.artifact.ArtifactUtils;
42 import org.apache.maven.model.Plugin;
43 import org.apache.maven.plugin.lifecycle.io.LifecycleStaxReader;
44 import org.codehaus.plexus.classworlds.realm.ClassRealm;
45 import org.codehaus.plexus.component.repository.ComponentDescriptor;
46 import org.codehaus.plexus.component.repository.ComponentSetDescriptor;
47 import org.eclipse.aether.graph.DependencyNode;
48
49
50
51 public class PluginDescriptor extends ComponentSetDescriptor implements Cloneable {
52
53 private static final String LIFECYCLE_DESCRIPTOR = "META-INF/maven/lifecycle.xml";
54
55 private static final Pattern PATTERN_FILTER_1 = Pattern.compile("-?(maven|plugin)-?");
56
57 private String groupId;
58
59 private String artifactId;
60
61 private String version;
62
63 private String goalPrefix;
64
65 private String source;
66
67 private boolean inheritedByDefault = true;
68
69 private List<Artifact> artifacts;
70
71 private DependencyNode dependencyNode;
72
73 private ClassRealm classRealm;
74
75
76 private Map<String, Artifact> artifactMap;
77
78 private Set<Artifact> introducedDependencyArtifacts;
79
80 private String name;
81
82 private String description;
83
84 private String requiredMavenVersion;
85
86 private String requiredJavaVersion;
87
88 private Plugin plugin;
89
90 private Artifact pluginArtifact;
91
92 private Map<String, Lifecycle> lifecycleMappings;
93
94
95
96
97
98 public PluginDescriptor() {}
99
100 public PluginDescriptor(PluginDescriptor original) {
101 this.setGroupId(original.getGroupId());
102 this.setArtifactId(original.getArtifactId());
103 this.setVersion(original.getVersion());
104 this.setGoalPrefix(original.getGoalPrefix());
105 this.setInheritedByDefault(original.isInheritedByDefault());
106 this.setName(original.getName());
107 this.setDescription(original.getDescription());
108 this.setRequiredMavenVersion(original.getRequiredMavenVersion());
109 this.setRequiredJavaVersion(original.getRequiredJavaVersion());
110 this.setPluginArtifact(ArtifactUtils.copyArtifactSafe(original.getPluginArtifact()));
111 this.setComponents(clone(original.getMojos(), this));
112 this.setId(original.getId());
113 this.setIsolatedRealm(original.isIsolatedRealm());
114 this.setSource(original.getSource());
115 this.setDependencies(original.getDependencies());
116 this.setDependencyNode(original.getDependencyNode());
117 }
118
119 private static List<ComponentDescriptor<?>> clone(List<MojoDescriptor> mojos, PluginDescriptor pluginDescriptor) {
120 List<ComponentDescriptor<?>> clones = null;
121 if (mojos != null) {
122 clones = new ArrayList<>(mojos.size());
123 for (MojoDescriptor mojo : mojos) {
124 MojoDescriptor clone = mojo.clone();
125 clone.setPluginDescriptor(pluginDescriptor);
126 clones.add(clone);
127 }
128 }
129 return clones;
130 }
131
132 public PluginDescriptor(org.apache.maven.api.plugin.descriptor.PluginDescriptor original) {
133 this.setGroupId(original.getGroupId());
134 this.setArtifactId(original.getArtifactId());
135 this.setVersion(original.getVersion());
136 this.setGoalPrefix(original.getGoalPrefix());
137 this.setInheritedByDefault(original.isInheritedByDefault());
138 this.setName(original.getName());
139 this.setDescription(original.getDescription());
140 this.setRequiredMavenVersion(original.getRequiredMavenVersion());
141 this.setRequiredJavaVersion(original.getRequiredJavaVersion());
142 this.setPluginArtifact(null);
143 this.setComponents(original.getMojos().stream()
144 .map(m -> new MojoDescriptor(this, m))
145 .collect(Collectors.toList()));
146 this.setId(original.getId());
147 this.setIsolatedRealm(original.isIsolatedRealm());
148 this.setSource(null);
149 this.setDependencies(Collections.emptyList());
150 this.setDependencyNode(null);
151 this.pluginDescriptorV4 = original;
152 }
153
154
155
156
157
158 @SuppressWarnings({"unchecked", "rawtypes"})
159 public List<MojoDescriptor> getMojos() {
160 return (List) getComponents();
161 }
162
163 public void addMojo(MojoDescriptor mojoDescriptor) throws DuplicateMojoDescriptorException {
164 MojoDescriptor existing = null;
165
166
167
168 List<MojoDescriptor> mojos = getMojos();
169
170 if (mojos != null && mojos.contains(mojoDescriptor)) {
171 int indexOf = mojos.indexOf(mojoDescriptor);
172
173 existing = mojos.get(indexOf);
174 }
175
176 if (existing != null) {
177 throw new DuplicateMojoDescriptorException(
178 getGoalPrefix(),
179 mojoDescriptor.getGoal(),
180 existing.getImplementation(),
181 mojoDescriptor.getImplementation());
182 } else {
183 addComponentDescriptor(mojoDescriptor);
184 }
185 }
186
187 public String getGroupId() {
188 return groupId;
189 }
190
191 public void setGroupId(String groupId) {
192 this.groupId = groupId;
193 }
194
195 public String getArtifactId() {
196 return artifactId;
197 }
198
199 public void setArtifactId(String artifactId) {
200 this.artifactId = artifactId;
201 }
202
203
204
205
206
207 public static String constructPluginKey(String groupId, String artifactId, String version) {
208 return groupId + ":" + artifactId + ":" + version;
209 }
210
211 public String getPluginLookupKey() {
212 return groupId + ":" + artifactId;
213 }
214
215 public String getId() {
216 return constructPluginKey(groupId, artifactId, version);
217 }
218
219 public static String getDefaultPluginArtifactId(String id) {
220 return "maven-" + id + "-plugin";
221 }
222
223 public static String getDefaultPluginGroupId() {
224 return "org.apache.maven.plugins";
225 }
226
227
228
229
230
231
232 public static String getGoalPrefixFromArtifactId(String artifactId) {
233 if ("maven-plugin-plugin".equals(artifactId)) {
234 return "plugin";
235 } else {
236 return PATTERN_FILTER_1.matcher(artifactId).replaceAll("");
237 }
238 }
239
240 public String getGoalPrefix() {
241 return goalPrefix;
242 }
243
244 public void setGoalPrefix(String goalPrefix) {
245 this.goalPrefix = goalPrefix;
246 }
247
248 public void setVersion(String version) {
249 this.version = version;
250 }
251
252 public String getVersion() {
253 return version;
254 }
255
256 public void setSource(String source) {
257 this.source = source;
258 }
259
260 public String getSource() {
261 return source;
262 }
263
264 public boolean isInheritedByDefault() {
265 return inheritedByDefault;
266 }
267
268 public void setInheritedByDefault(boolean inheritedByDefault) {
269 this.inheritedByDefault = inheritedByDefault;
270 }
271
272
273
274
275
276
277
278 public List<Artifact> getArtifacts() {
279 return artifacts;
280 }
281
282 public void setArtifacts(List<Artifact> artifacts) {
283 this.artifacts = artifacts;
284
285
286 artifactMap = null;
287 }
288
289 public DependencyNode getDependencyNode() {
290 return dependencyNode;
291 }
292
293 public void setDependencyNode(DependencyNode dependencyNode) {
294 this.dependencyNode = dependencyNode;
295 }
296
297
298
299
300
301
302
303 public Map<String, Artifact> getArtifactMap() {
304 if (artifactMap == null) {
305 artifactMap = ArtifactUtils.artifactMapByVersionlessId(getArtifacts());
306 }
307
308 return artifactMap;
309 }
310
311 public boolean equals(Object object) {
312 if (this == object) {
313 return true;
314 }
315
316 return object instanceof PluginDescriptor && getId().equals(((PluginDescriptor) object).getId());
317 }
318
319 public int hashCode() {
320 return 10 + getId().hashCode();
321 }
322
323 public MojoDescriptor getMojo(String goal) {
324 if (getMojos() == null) {
325 return null;
326 }
327
328
329
330 for (MojoDescriptor desc : getMojos()) {
331 if (goal.equals(desc.getGoal())) {
332 return desc;
333 }
334 }
335 return null;
336 }
337
338 public void setClassRealm(ClassRealm classRealm) {
339 this.classRealm = classRealm;
340 }
341
342 public ClassRealm getClassRealm() {
343 return classRealm;
344 }
345
346 public void setIntroducedDependencyArtifacts(Set<Artifact> introducedDependencyArtifacts) {
347 this.introducedDependencyArtifacts = introducedDependencyArtifacts;
348 }
349
350 public Set<Artifact> getIntroducedDependencyArtifacts() {
351 return (introducedDependencyArtifacts != null) ? introducedDependencyArtifacts : Collections.emptySet();
352 }
353
354 public void setName(String name) {
355 this.name = name;
356 }
357
358 public String getName() {
359 return name;
360 }
361
362 public void setDescription(String description) {
363 this.description = description;
364 }
365
366 public String getDescription() {
367 return description;
368 }
369
370
371
372
373
374
375
376
377
378
379 public void setRequiredMavenVersion(String requiredMavenVersion) {
380 this.requiredMavenVersion = requiredMavenVersion;
381 }
382
383
384
385
386
387
388
389
390 public String getRequiredMavenVersion() {
391 return requiredMavenVersion;
392 }
393
394 public void setRequiredJavaVersion(String requiredJavaVersion) {
395 this.requiredJavaVersion = requiredJavaVersion;
396 }
397
398 public String getRequiredJavaVersion() {
399 return requiredJavaVersion;
400 }
401
402 public void setPlugin(Plugin plugin) {
403 this.plugin = plugin;
404 }
405
406 public Plugin getPlugin() {
407 return plugin;
408 }
409
410 public Artifact getPluginArtifact() {
411 return pluginArtifact;
412 }
413
414 public void setPluginArtifact(Artifact pluginArtifact) {
415 this.pluginArtifact = pluginArtifact;
416 }
417
418 public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XMLStreamException {
419 return getLifecycleMappings().get(lifecycleId);
420 }
421
422 public Map<String, Lifecycle> getLifecycleMappings() throws IOException, XMLStreamException {
423 if (lifecycleMappings == null) {
424 LifecycleConfiguration lifecycleConfiguration;
425
426 try (InputStream input = getDescriptorStream(LIFECYCLE_DESCRIPTOR)) {
427 lifecycleConfiguration = new LifecycleStaxReader().read(input);
428 }
429
430 lifecycleMappings = new HashMap<>();
431
432 for (Lifecycle lifecycle : lifecycleConfiguration.getLifecycles()) {
433 lifecycleMappings.put(lifecycle.getId(), lifecycle);
434 }
435 }
436 return lifecycleMappings;
437 }
438
439 private InputStream getDescriptorStream(String descriptor) throws IOException {
440 File pluginFile = (pluginArtifact != null) ? pluginArtifact.getFile() : null;
441 if (pluginFile == null) {
442 throw new IllegalStateException("plugin main artifact has not been resolved for " + getId());
443 }
444
445 if (pluginFile.isFile()) {
446 try {
447 return new URL("jar:" + pluginFile.toURI() + "!/" + descriptor).openStream();
448 } catch (MalformedURLException e) {
449 throw new IllegalStateException(e);
450 }
451 } else {
452 return Files.newInputStream(new File(pluginFile, descriptor).toPath());
453 }
454 }
455
456
457
458
459 @Override
460 public PluginDescriptor clone() {
461 try {
462 return (PluginDescriptor) super.clone();
463 } catch (CloneNotSupportedException e) {
464 throw new UnsupportedOperationException(e);
465 }
466 }
467
468 public void addMojos(List<MojoDescriptor> mojos) throws DuplicateMojoDescriptorException {
469 for (MojoDescriptor mojoDescriptor : mojos) {
470 addMojo(mojoDescriptor);
471 }
472 }
473
474 private volatile org.apache.maven.api.plugin.descriptor.PluginDescriptor pluginDescriptorV4;
475
476 public org.apache.maven.api.plugin.descriptor.PluginDescriptor getPluginDescriptorV4() {
477 if (pluginDescriptorV4 == null) {
478 synchronized (this) {
479 if (pluginDescriptorV4 == null) {
480 pluginDescriptorV4 = org.apache.maven.api.plugin.descriptor.PluginDescriptor.newBuilder()
481 .namespaceUri(null)
482 .modelEncoding(null)
483 .name(name)
484 .description(description)
485 .groupId(groupId)
486 .artifactId(artifactId)
487 .version(version)
488 .goalPrefix(goalPrefix)
489 .isolatedRealm(isIsolatedRealm())
490 .inheritedByDefault(inheritedByDefault)
491 .requiredJavaVersion(requiredJavaVersion)
492 .requiredMavenVersion(requiredMavenVersion)
493 .mojos(getMojos().stream()
494 .map(MojoDescriptor::getMojoDescriptorV4)
495 .collect(Collectors.toList()))
496 .build();
497 }
498 }
499 }
500 return pluginDescriptorV4;
501 }
502 }