1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugin.prefix.internal;
20
21 import javax.inject.Inject;
22 import javax.inject.Named;
23 import javax.inject.Singleton;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.List;
29 import java.util.Map;
30
31 import org.apache.maven.artifact.repository.metadata.Metadata;
32 import org.apache.maven.artifact.repository.metadata.io.MetadataReader;
33 import org.apache.maven.model.Build;
34 import org.apache.maven.model.Plugin;
35 import org.apache.maven.plugin.BuildPluginManager;
36 import org.apache.maven.plugin.descriptor.PluginDescriptor;
37 import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException;
38 import org.apache.maven.plugin.prefix.PluginPrefixRequest;
39 import org.apache.maven.plugin.prefix.PluginPrefixResolver;
40 import org.apache.maven.plugin.prefix.PluginPrefixResult;
41 import org.eclipse.aether.DefaultRepositorySystemSession;
42 import org.eclipse.aether.RepositoryEvent;
43 import org.eclipse.aether.RepositoryEvent.EventType;
44 import org.eclipse.aether.RepositoryListener;
45 import org.eclipse.aether.RepositorySystem;
46 import org.eclipse.aether.RepositorySystemSession;
47 import org.eclipse.aether.RequestTrace;
48 import org.eclipse.aether.metadata.DefaultMetadata;
49 import org.eclipse.aether.repository.ArtifactRepository;
50 import org.eclipse.aether.repository.RemoteRepository;
51 import org.eclipse.aether.repository.RepositoryPolicy;
52 import org.eclipse.aether.resolution.MetadataRequest;
53 import org.eclipse.aether.resolution.MetadataResult;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56
57
58
59
60
61
62
63 @Named
64 @Singleton
65 public class DefaultPluginPrefixResolver implements PluginPrefixResolver {
66 private static final String REPOSITORY_CONTEXT = "plugin";
67
68 private final Logger logger = LoggerFactory.getLogger(getClass());
69 private final BuildPluginManager pluginManager;
70 private final RepositorySystem repositorySystem;
71 private final MetadataReader metadataReader;
72
73 @Inject
74 public DefaultPluginPrefixResolver(
75 BuildPluginManager pluginManager, RepositorySystem repositorySystem, MetadataReader metadataReader) {
76 this.pluginManager = pluginManager;
77 this.repositorySystem = repositorySystem;
78 this.metadataReader = metadataReader;
79 }
80
81 public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFoundForPrefixException {
82 logger.debug("Resolving plugin prefix " + request.getPrefix() + " from " + request.getPluginGroups());
83
84 PluginPrefixResult result = resolveFromProject(request);
85
86 if (result == null) {
87 result = resolveFromRepository(request);
88
89 if (result == null) {
90 throw new NoPluginFoundForPrefixException(
91 request.getPrefix(),
92 request.getPluginGroups(),
93 request.getRepositorySession().getLocalRepository(),
94 request.getRepositories());
95 } else if (logger.isDebugEnabled()) {
96 logger.debug("Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
97 + result.getArtifactId() + " from repository "
98 + (result.getRepository() != null
99 ? result.getRepository().getId()
100 : "null"));
101 }
102 } else if (logger.isDebugEnabled()) {
103 logger.debug("Resolved plugin prefix " + request.getPrefix() + " to " + result.getGroupId() + ":"
104 + result.getArtifactId() + " from POM " + request.getPom());
105 }
106
107 return result;
108 }
109
110 private PluginPrefixResult resolveFromProject(PluginPrefixRequest request) {
111 PluginPrefixResult result = null;
112
113 if (request.getPom() != null && request.getPom().getBuild() != null) {
114 Build build = request.getPom().getBuild();
115
116 result = resolveFromProject(request, build.getPlugins());
117
118 if (result == null && build.getPluginManagement() != null) {
119 result = resolveFromProject(request, build.getPluginManagement().getPlugins());
120 }
121 }
122
123 return result;
124 }
125
126 private PluginPrefixResult resolveFromProject(PluginPrefixRequest request, List<Plugin> plugins) {
127 for (Plugin plugin : plugins) {
128 try {
129 PluginDescriptor pluginDescriptor =
130 pluginManager.loadPlugin(plugin, request.getRepositories(), request.getRepositorySession());
131
132 if (request.getPrefix().equals(pluginDescriptor.getGoalPrefix())) {
133 return new DefaultPluginPrefixResult(plugin);
134 }
135 } catch (Exception e) {
136 if (logger.isDebugEnabled()) {
137 logger.warn(
138 "Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage(), e);
139 } else {
140 logger.warn("Failed to retrieve plugin descriptor for " + plugin.getId() + ": " + e.getMessage());
141 }
142 }
143 }
144
145 return null;
146 }
147
148 private PluginPrefixResult resolveFromRepository(PluginPrefixRequest request) {
149 RequestTrace trace = RequestTrace.newChild(null, request);
150
151 List<MetadataRequest> requests = new ArrayList<>();
152
153 for (String pluginGroup : request.getPluginGroups()) {
154 org.eclipse.aether.metadata.Metadata metadata =
155 new DefaultMetadata(pluginGroup, "maven-metadata.xml", DefaultMetadata.Nature.RELEASE_OR_SNAPSHOT);
156
157 requests.add(new MetadataRequest(metadata, null, REPOSITORY_CONTEXT).setTrace(trace));
158
159 for (RemoteRepository repository : request.getRepositories()) {
160 requests.add(new MetadataRequest(metadata, repository, REPOSITORY_CONTEXT).setTrace(trace));
161 }
162 }
163
164
165
166 List<MetadataResult> results = repositorySystem.resolveMetadata(request.getRepositorySession(), requests);
167 requests.clear();
168
169 PluginPrefixResult result = processResults(request, trace, results, requests);
170
171 if (result != null) {
172 return result;
173 }
174
175
176
177 if (!request.getRepositorySession().isOffline() && !requests.isEmpty()) {
178 DefaultRepositorySystemSession session = new DefaultRepositorySystemSession(request.getRepositorySession());
179 session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS);
180
181 results = repositorySystem.resolveMetadata(session, requests);
182
183 return processResults(request, trace, results, null);
184 }
185
186 return null;
187 }
188
189 private PluginPrefixResult processResults(
190 PluginPrefixRequest request,
191 RequestTrace trace,
192 List<MetadataResult> results,
193 List<MetadataRequest> requests) {
194 for (MetadataResult res : results) {
195 org.eclipse.aether.metadata.Metadata metadata = res.getMetadata();
196
197 if (metadata != null) {
198 ArtifactRepository repository = res.getRequest().getRepository();
199 if (repository == null) {
200 repository = request.getRepositorySession().getLocalRepository();
201 }
202
203 PluginPrefixResult result =
204 resolveFromRepository(request, trace, metadata.getGroupId(), metadata, repository);
205
206 if (result != null) {
207 return result;
208 }
209 }
210
211 if (requests != null && !res.isUpdated()) {
212 requests.add(res.getRequest());
213 }
214 }
215
216 return null;
217 }
218
219 private PluginPrefixResult resolveFromRepository(
220 PluginPrefixRequest request,
221 RequestTrace trace,
222 String pluginGroup,
223 org.eclipse.aether.metadata.Metadata metadata,
224 ArtifactRepository repository) {
225 if (metadata != null && metadata.getFile() != null && metadata.getFile().isFile()) {
226 try {
227 Map<String, ?> options = Collections.singletonMap(MetadataReader.IS_STRICT, Boolean.FALSE);
228
229 Metadata pluginGroupMetadata = metadataReader.read(metadata.getFile(), options);
230
231 List<org.apache.maven.artifact.repository.metadata.Plugin> plugins = pluginGroupMetadata.getPlugins();
232
233 if (plugins != null) {
234 for (org.apache.maven.artifact.repository.metadata.Plugin plugin : plugins) {
235 if (request.getPrefix().equals(plugin.getPrefix())) {
236 return new DefaultPluginPrefixResult(pluginGroup, plugin.getArtifactId(), repository);
237 }
238 }
239 }
240 } catch (IOException e) {
241 invalidMetadata(request.getRepositorySession(), trace, metadata, repository, e);
242 }
243 }
244
245 return null;
246 }
247
248 private void invalidMetadata(
249 RepositorySystemSession session,
250 RequestTrace trace,
251 org.eclipse.aether.metadata.Metadata metadata,
252 ArtifactRepository repository,
253 Exception exception) {
254 RepositoryListener listener = session.getRepositoryListener();
255 if (listener != null) {
256 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.METADATA_INVALID);
257 event.setTrace(trace);
258 event.setMetadata(metadata);
259 event.setException(exception);
260 event.setRepository(repository);
261 listener.metadataInvalid(event.build());
262 }
263 }
264 }