1 package org.apache.maven.project;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.io.File;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.List;
27 import java.util.Set;
28
29 import com.google.common.base.Predicate;
30 import com.google.common.collect.Iterables;
31 import org.apache.maven.model.Parent;
32 import org.apache.maven.model.Repository;
33 import org.apache.maven.model.building.FileModelSource;
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.apache.maven.repository.internal.ArtifactDescriptorUtils;
39 import org.eclipse.aether.RepositorySystem;
40 import org.eclipse.aether.RepositorySystemSession;
41 import org.eclipse.aether.RequestTrace;
42 import org.eclipse.aether.artifact.Artifact;
43 import org.eclipse.aether.artifact.DefaultArtifact;
44 import org.eclipse.aether.impl.RemoteRepositoryManager;
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 class ProjectModelResolver
59 implements ModelResolver
60 {
61
62 private final RepositorySystemSession session;
63
64 private final RequestTrace trace;
65
66 private final String context = "project";
67
68 private List<RemoteRepository> repositories;
69
70 private List<RemoteRepository> pomRepositories;
71
72 private final List<RemoteRepository> externalRepositories;
73
74 private final RepositorySystem resolver;
75
76 private final RemoteRepositoryManager remoteRepositoryManager;
77
78 private final Set<String> repositoryIds;
79
80 private final ReactorModelPool modelPool;
81
82 private final ProjectBuildingRequest.RepositoryMerging repositoryMerging;
83
84 public ProjectModelResolver( RepositorySystemSession session, RequestTrace trace, RepositorySystem resolver,
85 RemoteRepositoryManager remoteRepositoryManager, List<RemoteRepository> repositories,
86 ProjectBuildingRequest.RepositoryMerging repositoryMerging, ReactorModelPool modelPool )
87 {
88 this.session = session;
89 this.trace = trace;
90 this.resolver = resolver;
91 this.remoteRepositoryManager = remoteRepositoryManager;
92 this.pomRepositories = new ArrayList<RemoteRepository>();
93 List<RemoteRepository> externalRepositories = new ArrayList<RemoteRepository>();
94 externalRepositories.addAll(repositories);
95 this.externalRepositories = Collections.unmodifiableList(externalRepositories);
96 this.repositories = new ArrayList<RemoteRepository>();
97 this.repositories.addAll(externalRepositories);
98 this.repositoryMerging = repositoryMerging;
99 this.repositoryIds = new HashSet<String>();
100 this.modelPool = modelPool;
101 }
102
103 private ProjectModelResolver( ProjectModelResolver original )
104 {
105 this.session = original.session;
106 this.trace = original.trace;
107 this.resolver = original.resolver;
108 this.remoteRepositoryManager = original.remoteRepositoryManager;
109 this.pomRepositories = new ArrayList<RemoteRepository>(original.pomRepositories);
110 this.externalRepositories = original.externalRepositories;
111 this.repositories = new ArrayList<RemoteRepository>(original.repositories);
112 this.repositoryMerging = original.repositoryMerging;
113 this.repositoryIds = new HashSet<String>( original.repositoryIds );
114 this.modelPool = original.modelPool;
115 }
116
117 public void addRepository( Repository repository )
118 throws InvalidRepositoryException
119 {
120 addRepository( repository, false );
121 }
122
123 @Override
124 public void addRepository(final Repository repository, boolean replace) throws InvalidRepositoryException {
125 if ( !repositoryIds.add( repository.getId() ) ) {
126 if ( !replace ) {
127 return;
128 }
129
130
131 removeMatchingRepository(repositories, repository.getId());
132 removeMatchingRepository(pomRepositories, repository.getId());
133 }
134
135 List<RemoteRepository> newRepositories =
136 Collections.singletonList( ArtifactDescriptorUtils.toRemoteRepository( repository ) );
137
138 if ( ProjectBuildingRequest.RepositoryMerging.REQUEST_DOMINANT.equals( repositoryMerging ) )
139 {
140 repositories = remoteRepositoryManager.aggregateRepositories( session, repositories, newRepositories, true );
141 }
142 else
143 {
144 pomRepositories =
145 remoteRepositoryManager.aggregateRepositories( session, pomRepositories, newRepositories, true );
146 repositories =
147 remoteRepositoryManager.aggregateRepositories( session, pomRepositories, externalRepositories, false );
148 }
149 }
150
151 private static void removeMatchingRepository(Iterable<RemoteRepository> repositories, final String id) {
152 Iterables.removeIf(repositories, new Predicate<RemoteRepository>() {
153 @Override
154 public boolean apply(RemoteRepository remoteRepository) {
155 return remoteRepository.getId().equals(id);
156 }
157 });
158 }
159
160 public ModelResolver newCopy()
161 {
162 return new ProjectModelResolver( this );
163 }
164
165 public ModelSource resolveModel( String groupId, String artifactId, String version )
166 throws UnresolvableModelException
167 {
168 File pomFile = null;
169
170 if ( modelPool != null )
171 {
172 pomFile = modelPool.get( groupId, artifactId, version );
173 }
174
175 if ( pomFile == null )
176 {
177 Artifact pomArtifact = new DefaultArtifact( groupId, artifactId, "", "pom", version );
178
179 try
180 {
181 ArtifactRequest request = new ArtifactRequest( pomArtifact, repositories, context );
182 request.setTrace( trace );
183 pomArtifact = resolver.resolveArtifact( session, request ).getArtifact();
184 }
185 catch ( ArtifactResolutionException e )
186 {
187 throw new UnresolvableModelException( e.getMessage(), groupId, artifactId, version, e );
188 }
189
190 pomFile = pomArtifact.getFile();
191 }
192
193 return new FileModelSource( pomFile );
194 }
195
196 public ModelSource resolveModel( Parent parent )
197 throws UnresolvableModelException
198 {
199 Artifact artifact = new DefaultArtifact( parent.getGroupId(), parent.getArtifactId(), "", "pom",
200 parent.getVersion() );
201
202 VersionRangeRequest versionRangeRequest = new VersionRangeRequest( artifact, repositories, context );
203 versionRangeRequest.setTrace( trace );
204
205 try
206 {
207 VersionRangeResult versionRangeResult = resolver.resolveVersionRange( session, versionRangeRequest );
208
209 if ( versionRangeResult.getHighestVersion() == null )
210 {
211 throw new UnresolvableModelException( "No versions matched the requested range '" + parent.getVersion()
212 + "'", parent.getGroupId(), parent.getArtifactId(),
213 parent.getVersion() );
214
215 }
216
217 if ( versionRangeResult.getVersionConstraint() != null
218 && versionRangeResult.getVersionConstraint().getRange() != null
219 && versionRangeResult.getVersionConstraint().getRange().getUpperBound() == null )
220 {
221 throw new UnresolvableModelException( "The requested version range '" + parent.getVersion()
222 + "' does not specify an upper bound", parent.getGroupId(),
223 parent.getArtifactId(), parent.getVersion() );
224
225 }
226
227 parent.setVersion( versionRangeResult.getHighestVersion().toString() );
228 }
229 catch ( VersionRangeResolutionException e )
230 {
231 throw new UnresolvableModelException( e.getMessage(), parent.getGroupId(), parent.getArtifactId(),
232 parent.getVersion(), e );
233
234 }
235
236 return resolveModel( parent.getGroupId(), parent.getArtifactId(), parent.getVersion() );
237 }
238 }