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