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 @Override
312 public boolean equals(Object object) {
313 if (this == object) {
314 return true;
315 }
316
317 return object instanceof PluginDescriptor pluginDescriptor && getId().equals(pluginDescriptor.getId());
318 }
319
320 @Override
321 public int hashCode() {
322 return 10 + getId().hashCode();
323 }
324
325 public MojoDescriptor getMojo(String goal) {
326 if (getMojos() == null) {
327 return null;
328 }
329
330
331
332 for (MojoDescriptor desc : getMojos()) {
333 if (goal.equals(desc.getGoal())) {
334 return desc;
335 }
336 }
337 return null;
338 }
339
340 public void setClassRealm(ClassRealm classRealm) {
341 this.classRealm = classRealm;
342 }
343
344 public ClassRealm getClassRealm() {
345 return classRealm;
346 }
347
348 public void setIntroducedDependencyArtifacts(Set<Artifact> introducedDependencyArtifacts) {
349 this.introducedDependencyArtifacts = introducedDependencyArtifacts;
350 }
351
352 public Set<Artifact> getIntroducedDependencyArtifacts() {
353 return (introducedDependencyArtifacts != null) ? introducedDependencyArtifacts : Collections.emptySet();
354 }
355
356 public void setName(String name) {
357 this.name = name;
358 }
359
360 public String getName() {
361 return name;
362 }
363
364 public void setDescription(String description) {
365 this.description = description;
366 }
367
368 public String getDescription() {
369 return description;
370 }
371
372
373
374
375
376
377
378
379
380
381 public void setRequiredMavenVersion(String requiredMavenVersion) {
382 this.requiredMavenVersion = requiredMavenVersion;
383 }
384
385
386
387
388
389
390
391
392 public String getRequiredMavenVersion() {
393 return requiredMavenVersion;
394 }
395
396 public void setRequiredJavaVersion(String requiredJavaVersion) {
397 this.requiredJavaVersion = requiredJavaVersion;
398 }
399
400 public String getRequiredJavaVersion() {
401 return requiredJavaVersion;
402 }
403
404 public void setPlugin(Plugin plugin) {
405 this.plugin = plugin;
406 }
407
408 public Plugin getPlugin() {
409 return plugin;
410 }
411
412 public Artifact getPluginArtifact() {
413 return pluginArtifact;
414 }
415
416 public void setPluginArtifact(Artifact pluginArtifact) {
417 this.pluginArtifact = pluginArtifact;
418 }
419
420 public Lifecycle getLifecycleMapping(String lifecycleId) throws IOException, XMLStreamException {
421 return getLifecycleMappings().get(lifecycleId);
422 }
423
424 public Map<String, Lifecycle> getLifecycleMappings() throws IOException, XMLStreamException {
425 if (lifecycleMappings == null) {
426 LifecycleConfiguration lifecycleConfiguration;
427
428 try (InputStream input = getDescriptorStream(LIFECYCLE_DESCRIPTOR)) {
429 lifecycleConfiguration = new LifecycleStaxReader().read(input);
430 }
431
432 lifecycleMappings = new HashMap<>();
433
434 for (Lifecycle lifecycle : lifecycleConfiguration.getLifecycles()) {
435 lifecycleMappings.put(lifecycle.getId(), lifecycle);
436 }
437 }
438 return lifecycleMappings;
439 }
440
441 private InputStream getDescriptorStream(String descriptor) throws IOException {
442 File pluginFile = (pluginArtifact != null) ? pluginArtifact.getFile() : null;
443 if (pluginFile == null) {
444 throw new IllegalStateException("plugin main artifact has not been resolved for " + getId());
445 }
446
447 if (pluginFile.isFile()) {
448 try {
449 return new URL("jar:" + pluginFile.toURI() + "!/" + descriptor).openStream();
450 } catch (MalformedURLException e) {
451 throw new IllegalStateException(e);
452 }
453 } else {
454 return Files.newInputStream(new File(pluginFile, descriptor).toPath());
455 }
456 }
457
458
459
460
461 @Override
462 public PluginDescriptor clone() {
463 try {
464 return (PluginDescriptor) super.clone();
465 } catch (CloneNotSupportedException e) {
466 throw new UnsupportedOperationException(e);
467 }
468 }
469
470 public void addMojos(List<MojoDescriptor> mojos) throws DuplicateMojoDescriptorException {
471 for (MojoDescriptor mojoDescriptor : mojos) {
472 addMojo(mojoDescriptor);
473 }
474 }
475
476 private volatile org.apache.maven.api.plugin.descriptor.PluginDescriptor pluginDescriptorV4;
477
478 public org.apache.maven.api.plugin.descriptor.PluginDescriptor getPluginDescriptorV4() {
479 if (pluginDescriptorV4 == null) {
480 synchronized (this) {
481 if (pluginDescriptorV4 == null) {
482 pluginDescriptorV4 = org.apache.maven.api.plugin.descriptor.PluginDescriptor.newBuilder()
483 .namespaceUri(null)
484 .modelEncoding(null)
485 .name(name)
486 .description(description)
487 .groupId(groupId)
488 .artifactId(artifactId)
489 .version(version)
490 .goalPrefix(goalPrefix)
491 .isolatedRealm(isIsolatedRealm())
492 .inheritedByDefault(inheritedByDefault)
493 .requiredJavaVersion(requiredJavaVersion)
494 .requiredMavenVersion(requiredMavenVersion)
495 .mojos(getMojos().stream()
496 .map(MojoDescriptor::getMojoDescriptorV4)
497 .collect(Collectors.toList()))
498 .build();
499 }
500 }
501 }
502 return pluginDescriptorV4;
503 }
504 }