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.io.FileInputStream;
23 import java.io.FileNotFoundException;
24 import java.util.ArrayList;
25 import java.util.Collections;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.apache.maven.artifact.repository.metadata.Versioning;
31 import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
32 import org.codehaus.plexus.component.annotations.Component;
33 import org.codehaus.plexus.component.annotations.Requirement;
34 import org.codehaus.plexus.util.IOUtil;
35 import org.sonatype.aether.RepositoryListener;
36 import org.sonatype.aether.RepositorySystemSession;
37 import org.sonatype.aether.util.listener.DefaultRepositoryEvent;
38 import org.sonatype.aether.util.metadata.DefaultMetadata;
39 import org.sonatype.aether.util.version.GenericVersionScheme;
40 import org.sonatype.aether.version.InvalidVersionSpecificationException;
41 import org.sonatype.aether.version.Version;
42 import org.sonatype.aether.version.VersionConstraint;
43 import org.sonatype.aether.version.VersionScheme;
44 import org.sonatype.aether.impl.MetadataResolver;
45 import org.sonatype.aether.impl.VersionRangeResolver;
46 import org.sonatype.aether.metadata.Metadata;
47 import org.sonatype.aether.repository.ArtifactRepository;
48 import org.sonatype.aether.repository.RemoteRepository;
49 import org.sonatype.aether.repository.WorkspaceReader;
50 import org.sonatype.aether.resolution.MetadataRequest;
51 import org.sonatype.aether.resolution.MetadataResult;
52 import org.sonatype.aether.resolution.VersionRangeRequest;
53 import org.sonatype.aether.resolution.VersionRangeResolutionException;
54 import org.sonatype.aether.resolution.VersionRangeResult;
55 import org.sonatype.aether.spi.locator.Service;
56 import org.sonatype.aether.spi.locator.ServiceLocator;
57 import org.sonatype.aether.spi.log.Logger;
58 import org.sonatype.aether.spi.log.NullLogger;
59
60
61
62
63 @Component( role = VersionRangeResolver.class )
64 public class DefaultVersionRangeResolver
65 implements VersionRangeResolver, Service
66 {
67
68 private static final String MAVEN_METADATA_XML = "maven-metadata.xml";
69
70 @Requirement
71 private Logger logger = NullLogger.INSTANCE;
72
73 @Requirement
74 private MetadataResolver metadataResolver;
75
76 public void initService( ServiceLocator locator )
77 {
78 setLogger( locator.getService( Logger.class ) );
79 setMetadataResolver( locator.getService( MetadataResolver.class ) );
80 }
81
82 public DefaultVersionRangeResolver setLogger( Logger logger )
83 {
84 this.logger = ( logger != null ) ? logger : NullLogger.INSTANCE;
85 return this;
86 }
87
88 public DefaultVersionRangeResolver setMetadataResolver( MetadataResolver metadataResolver )
89 {
90 if ( metadataResolver == null )
91 {
92 throw new IllegalArgumentException( "metadata resolver has not been specified" );
93 }
94 this.metadataResolver = metadataResolver;
95 return this;
96 }
97
98 public VersionRangeResult resolveVersionRange( RepositorySystemSession session, VersionRangeRequest request )
99 throws VersionRangeResolutionException
100 {
101 VersionRangeResult result = new VersionRangeResult( request );
102
103 VersionScheme versionScheme = new GenericVersionScheme();
104
105 VersionConstraint versionConstraint;
106 try
107 {
108 versionConstraint = versionScheme.parseVersionConstraint( request.getArtifact().getVersion() );
109 }
110 catch ( InvalidVersionSpecificationException e )
111 {
112 result.addException( e );
113 throw new VersionRangeResolutionException( result );
114 }
115
116 result.setVersionConstraint( versionConstraint );
117
118 if ( versionConstraint.getRanges().isEmpty() )
119 {
120 result.addVersion( versionConstraint.getVersion() );
121 }
122 else
123 {
124 Map<String, ArtifactRepository> versionIndex = getVersions( session, result, request );
125
126 List<Version> versions = new ArrayList<Version>();
127 for ( Map.Entry<String, ArtifactRepository> v : versionIndex.entrySet() )
128 {
129 try
130 {
131 Version ver = versionScheme.parseVersion( v.getKey() );
132 if ( versionConstraint.containsVersion( ver ) )
133 {
134 versions.add( ver );
135 result.setRepository( ver, v.getValue() );
136 }
137 }
138 catch ( InvalidVersionSpecificationException e )
139 {
140 result.addException( e );
141 }
142 }
143
144 Collections.sort( versions );
145 result.setVersions( versions );
146 }
147
148 return result;
149 }
150
151 private Map<String, ArtifactRepository> getVersions( RepositorySystemSession session, VersionRangeResult result,
152 VersionRangeRequest request )
153 {
154 Map<String, ArtifactRepository> versionIndex = new HashMap<String, ArtifactRepository>();
155
156 Metadata metadata =
157 new DefaultMetadata( request.getArtifact().getGroupId(), request.getArtifact().getArtifactId(),
158 MAVEN_METADATA_XML, Metadata.Nature.RELEASE_OR_SNAPSHOT );
159
160 List<MetadataRequest> metadataRequests = new ArrayList<MetadataRequest>( request.getRepositories().size() );
161
162 metadataRequests.add( new MetadataRequest( metadata, null, request.getRequestContext() ) );
163
164 for ( RemoteRepository repository : request.getRepositories() )
165 {
166 MetadataRequest metadataRequest = new MetadataRequest( metadata, repository, request.getRequestContext() );
167 metadataRequest.setDeleteLocalCopyIfMissing( true );
168 metadataRequests.add( metadataRequest );
169 }
170
171 List<MetadataResult> metadataResults = metadataResolver.resolveMetadata( session, metadataRequests );
172
173 WorkspaceReader workspace = session.getWorkspaceReader();
174 if ( workspace != null )
175 {
176 List<String> versions = workspace.findVersions( request.getArtifact() );
177 for ( String version : versions )
178 {
179 versionIndex.put( version, workspace.getRepository() );
180 }
181 }
182
183 for ( MetadataResult metadataResult : metadataResults )
184 {
185 result.addException( metadataResult.getException() );
186
187 ArtifactRepository repository = metadataResult.getRequest().getRepository();
188 if ( repository == null )
189 {
190 repository = session.getLocalRepository();
191 }
192
193 Versioning versioning = readVersions( session, metadataResult.getMetadata(), repository, result );
194 for ( String version : versioning.getVersions() )
195 {
196 if ( !versionIndex.containsKey( version ) )
197 {
198 versionIndex.put( version, repository );
199 }
200 }
201 }
202
203 return versionIndex;
204 }
205
206 private Versioning readVersions( RepositorySystemSession session, Metadata metadata, ArtifactRepository repository,
207 VersionRangeResult result )
208 {
209 Versioning versioning = null;
210
211 FileInputStream fis = null;
212 try
213 {
214 if ( metadata != null && metadata.getFile() != null )
215 {
216 fis = new FileInputStream( metadata.getFile() );
217 org.apache.maven.artifact.repository.metadata.Metadata m = new MetadataXpp3Reader().read( fis, false );
218 versioning = m.getVersioning();
219 }
220 }
221 catch ( FileNotFoundException e )
222 {
223
224 }
225 catch ( Exception e )
226 {
227 invalidMetadata( session, metadata, repository, e );
228 result.addException( e );
229 }
230 finally
231 {
232 IOUtil.close( fis );
233 }
234
235 return ( versioning != null ) ? versioning : new Versioning();
236 }
237
238 private void invalidMetadata( RepositorySystemSession session, Metadata metadata, ArtifactRepository repository,
239 Exception exception )
240 {
241 RepositoryListener listener = session.getRepositoryListener();
242 if ( listener != null )
243 {
244 DefaultRepositoryEvent event = new DefaultRepositoryEvent( session, metadata );
245 event.setException( exception );
246 event.setRepository( repository );
247 listener.metadataInvalid( event );
248 }
249 }
250
251 }