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.ArrayList;
22 import java.util.Collections;
23 import java.util.HashSet;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27 import java.util.concurrent.atomic.AtomicReference;
28
29 import org.apache.maven.api.model.Dependency;
30 import org.apache.maven.api.model.Parent;
31 import org.apache.maven.api.model.Repository;
32 import org.apache.maven.model.building.ArtifactModelSource;
33 import org.apache.maven.model.building.ModelSource;
34 import org.apache.maven.model.resolution.InvalidRepositoryException;
35 import org.apache.maven.model.resolution.ModelResolver;
36 import org.apache.maven.model.resolution.UnresolvableModelException;
37 import org.eclipse.aether.RepositorySystemSession;
38 import org.eclipse.aether.RequestTrace;
39 import org.eclipse.aether.artifact.Artifact;
40 import org.eclipse.aether.artifact.DefaultArtifact;
41 import org.eclipse.aether.impl.ArtifactResolver;
42 import org.eclipse.aether.impl.RemoteRepositoryManager;
43 import org.eclipse.aether.impl.VersionRangeResolver;
44 import org.eclipse.aether.repository.RemoteRepository;
45 import org.eclipse.aether.resolution.ArtifactRequest;
46 import org.eclipse.aether.resolution.ArtifactResolutionException;
47 import org.eclipse.aether.resolution.VersionRangeRequest;
48 import org.eclipse.aether.resolution.VersionRangeResolutionException;
49 import org.eclipse.aether.resolution.VersionRangeResult;
50
51
52
53
54
55
56
57
58 class DefaultModelResolver implements ModelResolver {
59
60 private final RepositorySystemSession session;
61
62 private final RequestTrace trace;
63
64 private final String context;
65
66 private List<RemoteRepository> repositories;
67
68 private final List<RemoteRepository> externalRepositories;
69
70 private final ArtifactResolver resolver;
71
72 private final VersionRangeResolver versionRangeResolver;
73
74 private final RemoteRepositoryManager remoteRepositoryManager;
75
76 private final Set<String> repositoryIds;
77
78 DefaultModelResolver(
79 RepositorySystemSession session,
80 RequestTrace trace,
81 String context,
82 ArtifactResolver resolver,
83 VersionRangeResolver versionRangeResolver,
84 RemoteRepositoryManager remoteRepositoryManager,
85 List<RemoteRepository> repositories) {
86 this.session = session;
87 this.trace = trace;
88 this.context = context;
89 this.resolver = resolver;
90 this.versionRangeResolver = versionRangeResolver;
91 this.remoteRepositoryManager = remoteRepositoryManager;
92 this.repositories = repositories;
93 this.externalRepositories = Collections.unmodifiableList(new ArrayList<>(repositories));
94
95 this.repositoryIds = new HashSet<>();
96 }
97
98 private DefaultModelResolver(DefaultModelResolver original) {
99 this.session = original.session;
100 this.trace = original.trace;
101 this.context = original.context;
102 this.resolver = original.resolver;
103 this.versionRangeResolver = original.versionRangeResolver;
104 this.remoteRepositoryManager = original.remoteRepositoryManager;
105 this.repositories = new ArrayList<>(original.repositories);
106 this.externalRepositories = original.externalRepositories;
107 this.repositoryIds = new HashSet<>(original.repositoryIds);
108 }
109
110 @Override
111 public void addRepository(Repository repository) throws InvalidRepositoryException {
112 addRepository(repository, false);
113 }
114
115 @Override
116 public void addRepository(final Repository repository, boolean replace) throws InvalidRepositoryException {
117 if (session.isIgnoreArtifactDescriptorRepositories()) {
118 return;
119 }
120
121 if (!repositoryIds.add(repository.getId())) {
122 if (!replace) {
123 return;
124 }
125
126 removeMatchingRepository(repositories, repository.getId());
127 }
128
129 List<RemoteRepository> newRepositories = Collections.singletonList(
130 ArtifactDescriptorUtils.toRemoteRepository(new org.apache.maven.model.Repository(repository)));
131
132 this.repositories = remoteRepositoryManager.aggregateRepositories(session, repositories, newRepositories, true);
133 }
134
135 private static void removeMatchingRepository(Iterable<RemoteRepository> repositories, final String id) {
136 Iterator<RemoteRepository> iterator = repositories.iterator();
137 while (iterator.hasNext()) {
138 RemoteRepository remoteRepository = iterator.next();
139 if (remoteRepository.getId().equals(id)) {
140 iterator.remove();
141 }
142 }
143 }
144
145 @Override
146 public ModelResolver newCopy() {
147 return new DefaultModelResolver(this);
148 }
149
150 @Override
151 public ModelSource resolveModel(String groupId, String artifactId, String version)
152 throws UnresolvableModelException {
153 Artifact pomArtifact = new DefaultArtifact(groupId, artifactId, "", "pom", version);
154
155 try {
156 ArtifactRequest request = new ArtifactRequest(pomArtifact, repositories, context);
157 request.setTrace(trace);
158 pomArtifact = resolver.resolveArtifact(session, request).getArtifact();
159 } catch (ArtifactResolutionException e) {
160 throw new UnresolvableModelException(e.getMessage(), groupId, artifactId, version, e);
161 }
162
163 return new ArtifactModelSource(pomArtifact.getFile(), groupId, artifactId, version);
164 }
165
166 @Override
167 public ModelSource resolveModel(final Parent parent, final AtomicReference<Parent> modified)
168 throws UnresolvableModelException {
169 try {
170 final Artifact artifact =
171 new DefaultArtifact(parent.getGroupId(), parent.getArtifactId(), "", "pom", parent.getVersion());
172
173 final VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, repositories, context);
174 versionRangeRequest.setTrace(trace);
175
176 final VersionRangeResult versionRangeResult =
177 versionRangeResolver.resolveVersionRange(session, versionRangeRequest);
178
179 if (versionRangeResult.getHighestVersion() == null) {
180 throw new UnresolvableModelException(
181 String.format(
182 "No versions matched the requested parent version range '%s'", parent.getVersion()),
183 parent.getGroupId(),
184 parent.getArtifactId(),
185 parent.getVersion());
186 }
187
188 if (versionRangeResult.getVersionConstraint() != null
189 && versionRangeResult.getVersionConstraint().getRange() != null
190 && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) {
191
192 throw new UnresolvableModelException(
193 String.format(
194 "The requested parent version range '%s' does not specify an upper bound",
195 parent.getVersion()),
196 parent.getGroupId(),
197 parent.getArtifactId(),
198 parent.getVersion());
199 }
200
201 String newVersion = versionRangeResult.getHighestVersion().toString();
202 if (!parent.getVersion().equals(newVersion)) {
203 modified.set(parent.withVersion(newVersion));
204 }
205
206 return resolveModel(parent.getGroupId(), parent.getArtifactId(), newVersion);
207 } catch (final VersionRangeResolutionException e) {
208 throw new UnresolvableModelException(
209 e.getMessage(), parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), e);
210 }
211 }
212
213 @Override
214 public ModelSource resolveModel(final Dependency dependency, AtomicReference<Dependency> modified)
215 throws UnresolvableModelException {
216 try {
217 final Artifact artifact = new DefaultArtifact(
218 dependency.getGroupId(), dependency.getArtifactId(), "", "pom", dependency.getVersion());
219
220 final VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, repositories, context);
221 versionRangeRequest.setTrace(trace);
222
223 final VersionRangeResult versionRangeResult =
224 versionRangeResolver.resolveVersionRange(session, versionRangeRequest);
225
226 if (versionRangeResult.getHighestVersion() == null) {
227 throw new UnresolvableModelException(
228 String.format(
229 "No versions matched the requested dependency version range '%s'",
230 dependency.getVersion()),
231 dependency.getGroupId(),
232 dependency.getArtifactId(),
233 dependency.getVersion());
234 }
235
236 if (versionRangeResult.getVersionConstraint() != null
237 && versionRangeResult.getVersionConstraint().getRange() != null
238 && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null) {
239
240 throw new UnresolvableModelException(
241 String.format(
242 "The requested dependency version range '%s' does not specify an upper bound",
243 dependency.getVersion()),
244 dependency.getGroupId(),
245 dependency.getArtifactId(),
246 dependency.getVersion());
247 }
248
249 String newVersion = versionRangeResult.getHighestVersion().toString();
250 if (!dependency.getVersion().equals(newVersion)) {
251 modified.set(dependency.withVersion(newVersion));
252 }
253
254 return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), newVersion);
255 } catch (VersionRangeResolutionException e) {
256 throw new UnresolvableModelException(
257 e.getMessage(), dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion(), e);
258 }
259 }
260
261 @Override
262 public ModelSource resolveModel(org.apache.maven.model.Parent parent) throws UnresolvableModelException {
263 AtomicReference<org.apache.maven.api.model.Parent> resolvedParent = new AtomicReference<>();
264 ModelSource result = resolveModel(parent.getDelegate(), resolvedParent);
265 if (resolvedParent.get() != null) {
266 parent.setVersion(resolvedParent.get().getVersion());
267 }
268 return result;
269 }
270
271 @Override
272 public ModelSource resolveModel(org.apache.maven.model.Dependency dependency) throws UnresolvableModelException {
273 AtomicReference<org.apache.maven.api.model.Dependency> resolvedDependency = new AtomicReference<>();
274 ModelSource result = resolveModel(dependency.getDelegate(), resolvedDependency);
275 if (resolvedDependency.get() != null) {
276 dependency.setVersion(resolvedDependency.get().getVersion());
277 }
278 return result;
279 }
280
281 @Override
282 public void addRepository(org.apache.maven.model.Repository repository) throws InvalidRepositoryException {
283 addRepository(repository.getDelegate());
284 }
285
286 @Override
287 public void addRepository(org.apache.maven.model.Repository repository, boolean replace)
288 throws InvalidRepositoryException {
289 addRepository(repository.getDelegate(), replace);
290 }
291 }