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