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