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