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