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