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.util.LinkedHashSet;
22 import java.util.Map;
23 import java.util.Objects;
24 import java.util.Properties;
25 import java.util.Set;
26 import javax.inject.Inject;
27 import javax.inject.Named;
28 import javax.inject.Singleton;
29 import org.apache.maven.model.DistributionManagement;
30 import org.apache.maven.model.Model;
31 import org.apache.maven.model.Relocation;
32 import org.apache.maven.model.building.ArtifactModelSource;
33 import org.apache.maven.model.building.DefaultModelBuildingRequest;
34 import org.apache.maven.model.building.ModelBuilder;
35 import org.apache.maven.model.building.ModelBuildingException;
36 import org.apache.maven.model.building.ModelBuildingRequest;
37 import org.apache.maven.model.building.ModelProblem;
38 import org.apache.maven.model.resolution.UnresolvableModelException;
39 import org.eclipse.aether.RepositoryEvent;
40 import org.eclipse.aether.RepositoryEvent.EventType;
41 import org.eclipse.aether.RepositoryException;
42 import org.eclipse.aether.RepositorySystemSession;
43 import org.eclipse.aether.RequestTrace;
44 import org.eclipse.aether.artifact.Artifact;
45 import org.eclipse.aether.impl.ArtifactDescriptorReader;
46 import org.eclipse.aether.impl.ArtifactResolver;
47 import org.eclipse.aether.impl.RemoteRepositoryManager;
48 import org.eclipse.aether.impl.RepositoryEventDispatcher;
49 import org.eclipse.aether.impl.VersionRangeResolver;
50 import org.eclipse.aether.impl.VersionResolver;
51 import org.eclipse.aether.repository.WorkspaceReader;
52 import org.eclipse.aether.repository.WorkspaceRepository;
53 import org.eclipse.aether.resolution.ArtifactDescriptorException;
54 import org.eclipse.aether.resolution.ArtifactDescriptorPolicy;
55 import org.eclipse.aether.resolution.ArtifactDescriptorPolicyRequest;
56 import org.eclipse.aether.resolution.ArtifactDescriptorRequest;
57 import org.eclipse.aether.resolution.ArtifactDescriptorResult;
58 import org.eclipse.aether.resolution.ArtifactRequest;
59 import org.eclipse.aether.resolution.ArtifactResolutionException;
60 import org.eclipse.aether.resolution.ArtifactResult;
61 import org.eclipse.aether.resolution.VersionRequest;
62 import org.eclipse.aether.resolution.VersionResolutionException;
63 import org.eclipse.aether.resolution.VersionResult;
64 import org.eclipse.aether.transfer.ArtifactNotFoundException;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68
69
70
71 @Named
72 @Singleton
73 public class DefaultArtifactDescriptorReader implements ArtifactDescriptorReader {
74 private static final Logger LOGGER = LoggerFactory.getLogger(DefaultArtifactDescriptorReader.class);
75
76 private final RemoteRepositoryManager remoteRepositoryManager;
77 private final VersionResolver versionResolver;
78 private final VersionRangeResolver versionRangeResolver;
79 private final ArtifactResolver artifactResolver;
80 private final RepositoryEventDispatcher repositoryEventDispatcher;
81 private final ModelBuilder modelBuilder;
82 private final ModelCacheFactory modelCacheFactory;
83
84 @Inject
85 public DefaultArtifactDescriptorReader(
86 RemoteRepositoryManager remoteRepositoryManager,
87 VersionResolver versionResolver,
88 VersionRangeResolver versionRangeResolver,
89 ArtifactResolver artifactResolver,
90 ModelBuilder modelBuilder,
91 RepositoryEventDispatcher repositoryEventDispatcher,
92 ModelCacheFactory modelCacheFactory) {
93 this.remoteRepositoryManager =
94 Objects.requireNonNull(remoteRepositoryManager, "remoteRepositoryManager cannot be null");
95 this.versionResolver = Objects.requireNonNull(versionResolver, "versionResolver cannot be null");
96 this.versionRangeResolver = Objects.requireNonNull(versionRangeResolver, "versionRangeResolver cannot be null");
97 this.artifactResolver = Objects.requireNonNull(artifactResolver, "artifactResolver cannot be null");
98 this.modelBuilder = Objects.requireNonNull(modelBuilder, "modelBuilder cannot be null");
99 this.repositoryEventDispatcher =
100 Objects.requireNonNull(repositoryEventDispatcher, "repositoryEventDispatcher cannot be null");
101 this.modelCacheFactory = Objects.requireNonNull(modelCacheFactory, "modelCacheFactory cannot be null");
102 }
103
104 public ArtifactDescriptorResult readArtifactDescriptor(
105 RepositorySystemSession session, ArtifactDescriptorRequest request) throws ArtifactDescriptorException {
106 ArtifactDescriptorResult result = new ArtifactDescriptorResult(request);
107
108 Model model = loadPom(session, request, result);
109 if (model != null) {
110 Map<String, Object> config = session.getConfigProperties();
111 ArtifactDescriptorReaderDelegate delegate =
112 (ArtifactDescriptorReaderDelegate) config.get(ArtifactDescriptorReaderDelegate.class.getName());
113
114 if (delegate == null) {
115 delegate = new ArtifactDescriptorReaderDelegate();
116 }
117
118 delegate.populateResult(session, result, model);
119 }
120
121 return result;
122 }
123
124 private Model loadPom(
125 RepositorySystemSession session, ArtifactDescriptorRequest request, ArtifactDescriptorResult result)
126 throws ArtifactDescriptorException {
127 RequestTrace trace = RequestTrace.newChild(request.getTrace(), request);
128
129 Set<String> visited = new LinkedHashSet<>();
130 for (Artifact a = request.getArtifact(); ; ) {
131 Artifact pomArtifact = ArtifactDescriptorUtils.toPomArtifact(a);
132 try {
133 VersionRequest versionRequest =
134 new VersionRequest(a, request.getRepositories(), request.getRequestContext());
135 versionRequest.setTrace(trace);
136 VersionResult versionResult = versionResolver.resolveVersion(session, versionRequest);
137
138 a = a.setVersion(versionResult.getVersion());
139
140 versionRequest =
141 new VersionRequest(pomArtifact, request.getRepositories(), request.getRequestContext());
142 versionRequest.setTrace(trace);
143 versionResult = versionResolver.resolveVersion(session, versionRequest);
144
145 pomArtifact = pomArtifact.setVersion(versionResult.getVersion());
146 } catch (VersionResolutionException e) {
147 result.addException(e);
148 throw new ArtifactDescriptorException(result);
149 }
150
151 if (!visited.add(a.getGroupId() + ':' + a.getArtifactId() + ':' + a.getBaseVersion())) {
152 RepositoryException exception =
153 new RepositoryException("Artifact relocations form a cycle: " + visited);
154 invalidDescriptor(session, trace, a, exception);
155 if ((getPolicy(session, a, request) & ArtifactDescriptorPolicy.IGNORE_INVALID) != 0) {
156 return null;
157 }
158 result.addException(exception);
159 throw new ArtifactDescriptorException(result);
160 }
161
162 ArtifactResult resolveResult;
163 try {
164 ArtifactRequest resolveRequest =
165 new ArtifactRequest(pomArtifact, request.getRepositories(), request.getRequestContext());
166 resolveRequest.setTrace(trace);
167 resolveResult = artifactResolver.resolveArtifact(session, resolveRequest);
168 pomArtifact = resolveResult.getArtifact();
169 result.setRepository(resolveResult.getRepository());
170 } catch (ArtifactResolutionException e) {
171 if (e.getCause() instanceof ArtifactNotFoundException) {
172 missingDescriptor(session, trace, a, (Exception) e.getCause());
173 if ((getPolicy(session, a, request) & ArtifactDescriptorPolicy.IGNORE_MISSING) != 0) {
174 return null;
175 }
176 }
177 result.addException(e);
178 throw new ArtifactDescriptorException(result);
179 }
180
181 Model model;
182
183
184 final WorkspaceReader workspace = session.getWorkspaceReader();
185 if (workspace instanceof MavenWorkspaceReader) {
186 model = ((MavenWorkspaceReader) workspace).findModel(pomArtifact);
187 if (model != null) {
188 return model;
189 }
190 }
191
192 try {
193 ModelBuildingRequest modelRequest = new DefaultModelBuildingRequest();
194 modelRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL);
195 modelRequest.setProcessPlugins(false);
196 modelRequest.setTwoPhaseBuilding(false);
197 modelRequest.setSystemProperties(toProperties(session.getSystemProperties()));
198 modelRequest.setUserProperties(toProperties(session.getUserProperties()));
199 modelRequest.setModelCache(modelCacheFactory.createCache(session));
200 modelRequest.setModelResolver(new DefaultModelResolver(
201 session,
202 trace.newChild(modelRequest),
203 request.getRequestContext(),
204 artifactResolver,
205 versionRangeResolver,
206 remoteRepositoryManager,
207 request.getRepositories()));
208 if (resolveResult.getRepository() instanceof WorkspaceRepository) {
209 modelRequest.setPomFile(pomArtifact.getFile());
210 } else {
211 modelRequest.setModelSource(new ArtifactModelSource(
212 pomArtifact.getFile(),
213 pomArtifact.getGroupId(),
214 pomArtifact.getArtifactId(),
215 pomArtifact.getVersion()));
216 }
217
218 model = modelBuilder.build(modelRequest).getEffectiveModel();
219 } catch (ModelBuildingException e) {
220 for (ModelProblem problem : e.getProblems()) {
221 if (problem.getException() instanceof UnresolvableModelException) {
222 result.addException(problem.getException());
223 throw new ArtifactDescriptorException(result);
224 }
225 }
226 invalidDescriptor(session, trace, a, e);
227 if ((getPolicy(session, a, request) & ArtifactDescriptorPolicy.IGNORE_INVALID) != 0) {
228 return null;
229 }
230 result.addException(e);
231 throw new ArtifactDescriptorException(result);
232 }
233
234 Relocation relocation = getRelocation(model);
235
236 if (relocation != null) {
237 result.addRelocation(a);
238 a = new RelocatedArtifact(
239 a,
240 relocation.getGroupId(),
241 relocation.getArtifactId(),
242 relocation.getVersion(),
243 relocation.getMessage());
244 result.setArtifact(a);
245 } else {
246 return model;
247 }
248 }
249 }
250
251 private Properties toProperties(Map<String, String> map) {
252 Properties props = new Properties();
253 props.putAll(map);
254 return props;
255 }
256
257 private Relocation getRelocation(Model model) {
258 Relocation relocation = null;
259 DistributionManagement distMgmt = model.getDistributionManagement();
260 if (distMgmt != null) {
261 relocation = distMgmt.getRelocation();
262 }
263 return relocation;
264 }
265
266 private void missingDescriptor(
267 RepositorySystemSession session, RequestTrace trace, Artifact artifact, Exception exception) {
268 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DESCRIPTOR_MISSING);
269 event.setTrace(trace);
270 event.setArtifact(artifact);
271 event.setException(exception);
272
273 repositoryEventDispatcher.dispatch(event.build());
274 }
275
276 private void invalidDescriptor(
277 RepositorySystemSession session, RequestTrace trace, Artifact artifact, Exception exception) {
278 RepositoryEvent.Builder event = new RepositoryEvent.Builder(session, EventType.ARTIFACT_DESCRIPTOR_INVALID);
279 event.setTrace(trace);
280 event.setArtifact(artifact);
281 event.setException(exception);
282
283 repositoryEventDispatcher.dispatch(event.build());
284 }
285
286 private int getPolicy(RepositorySystemSession session, Artifact a, ArtifactDescriptorRequest request) {
287 ArtifactDescriptorPolicy policy = session.getArtifactDescriptorPolicy();
288 if (policy == null) {
289 return ArtifactDescriptorPolicy.STRICT;
290 }
291 return policy.getPolicy(session, new ArtifactDescriptorPolicyRequest(a, request.getRequestContext()));
292 }
293 }