1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.repository.internal;
20
21 import java.io.Reader;
22 import java.nio.file.Files;
23 import java.nio.file.Path;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.LinkedHashMap;
29 import java.util.Map;
30 import java.util.Objects;
31 import java.util.jar.JarFile;
32 import java.util.zip.ZipEntry;
33
34 import org.apache.maven.repository.internal.PluginsMetadata.PluginInfo;
35 import org.codehaus.plexus.util.ReaderFactory;
36 import org.codehaus.plexus.util.xml.Xpp3Dom;
37 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
38 import org.eclipse.aether.RepositorySystemSession;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.deployment.DeployRequest;
41 import org.eclipse.aether.impl.MetadataGenerator;
42 import org.eclipse.aether.installation.InstallRequest;
43 import org.eclipse.aether.metadata.Metadata;
44 import org.eclipse.aether.util.ConfigUtils;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48
49
50
51
52
53 class PluginsMetadataGenerator implements MetadataGenerator {
54 private static final String PLUGIN_DESCRIPTOR_LOCATION = "META-INF/maven/plugin.xml";
55
56 private final Logger logger = LoggerFactory.getLogger(getClass());
57
58 private final Map<Object, PluginsMetadata> processedPlugins;
59
60 private final Date timestamp;
61
62 PluginsMetadataGenerator(RepositorySystemSession session, InstallRequest request) {
63 this(session, request.getMetadata());
64 }
65
66 PluginsMetadataGenerator(RepositorySystemSession session, DeployRequest request) {
67 this(session, request.getMetadata());
68 }
69
70 private PluginsMetadataGenerator(RepositorySystemSession session, Collection<? extends Metadata> metadatas) {
71 this.processedPlugins = new LinkedHashMap<>();
72 this.timestamp = (Date) ConfigUtils.getObject(session, new Date(), "maven.startTime");
73
74
75
76
77
78
79
80 for (Iterator<? extends Metadata> it = metadatas.iterator(); it.hasNext(); ) {
81 Metadata metadata = it.next();
82 if (metadata instanceof PluginsMetadata) {
83 it.remove();
84 PluginsMetadata pluginMetadata = (PluginsMetadata) metadata;
85 processedPlugins.put(pluginMetadata.getGroupId(), pluginMetadata);
86 }
87 }
88 }
89
90 @Override
91 public Collection<? extends Metadata> prepare(Collection<? extends Artifact> artifacts) {
92 return Collections.emptyList();
93 }
94
95 @Override
96 public Artifact transformArtifact(Artifact artifact) {
97 return artifact;
98 }
99
100 @Override
101 public Collection<? extends Metadata> finish(Collection<? extends Artifact> artifacts) {
102 LinkedHashMap<String, PluginsMetadata> plugins = new LinkedHashMap<>();
103 for (Artifact artifact : artifacts) {
104 PluginInfo pluginInfo = extractPluginInfo(artifact);
105 if (pluginInfo != null) {
106 String key = pluginInfo.groupId;
107 if (processedPlugins.get(key) == null) {
108 PluginsMetadata pluginMetadata = plugins.get(key);
109 if (pluginMetadata == null) {
110 pluginMetadata = new PluginsMetadata(pluginInfo, timestamp);
111 plugins.put(key, pluginMetadata);
112 }
113 }
114 }
115 }
116 return plugins.values();
117 }
118
119 private PluginInfo extractPluginInfo(Artifact artifact) {
120
121 if (artifact != null
122 && "jar".equals(artifact.getExtension())
123 && "".equals(artifact.getClassifier())
124 && artifact.getFile() != null) {
125 Path artifactPath = artifact.getFile().toPath();
126 if (Files.isRegularFile(artifactPath)) {
127 try (JarFile artifactJar = new JarFile(artifactPath.toFile(), false)) {
128 ZipEntry pluginDescriptorEntry = artifactJar.getEntry(PLUGIN_DESCRIPTOR_LOCATION);
129
130 if (pluginDescriptorEntry != null) {
131 try (Reader reader =
132 ReaderFactory.newXmlReader(artifactJar.getInputStream(pluginDescriptorEntry))) {
133
134
135
136
137
138 Xpp3Dom root = Xpp3DomBuilder.build(reader);
139 String groupId = mayGetChild(root, "groupId");
140 String artifactId = mayGetChild(root, "artifactId");
141 String goalPrefix = mayGetChild(root, "goalPrefix");
142 String name = mayGetChild(root, "name");
143
144 if (Objects.equals(artifact.getGroupId(), groupId)
145 && Objects.equals(artifact.getArtifactId(), artifactId)) {
146
147 return new PluginInfo(groupId, artifactId, goalPrefix, name);
148 } else {
149 logger.warn(
150 "Artifact {}:{}"
151 + " JAR (about to be installed/deployed) contains Maven Plugin metadata for"
152 + " conflicting coordinates: {}:{}."
153 + " Your JAR contains rogue Maven Plugin metadata."
154 + " Possible causes may be: shaded into this JAR some Maven Plugin or some rogue resource.",
155 artifact.getGroupId(),
156 artifact.getArtifactId(),
157 groupId,
158 artifactId);
159 }
160 }
161 }
162 } catch (Exception e) {
163
164 }
165 }
166 }
167 return null;
168 }
169
170 private static String mayGetChild(Xpp3Dom node, String child) {
171 Xpp3Dom c = node.getChild(child);
172 if (c != null) {
173 return c.getValue();
174 }
175 return null;
176 }
177 }