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