diff --git a/maven-artifact-ant/src/main/java/org/apache/maven/artifact/ant/AntResolutionListener.java b/maven-artifact-ant/src/main/java/org/apache/maven/artifact/ant/AntResolutionListener.java index 679fdcc94c..40eca46836 100644 --- a/maven-artifact-ant/src/main/java/org/apache/maven/artifact/ant/AntResolutionListener.java +++ b/maven-artifact-ant/src/main/java/org/apache/maven/artifact/ant/AntResolutionListener.java @@ -69,12 +69,18 @@ public class AntResolutionListener public void updateScope( Artifact artifact, String scope ) { - project.log( indent + artifact.getId() + " (settings scope to: " + scope + ")" ); + project.log( indent + artifact.getId() + " (setting scope to: " + scope + ")" ); } public void updateScopeCurrentPom( Artifact artifact, String scope ) { - updateScope( artifact, scope ); + updateScope( artifact, scope ); + } + + public void selectVersionFromRange( Artifact artifact ) + { + project.log( indent + artifact.getId() + " (setting version to: " + artifact.getVersion() + " from range: " + + artifact.getVersionRange() + ")" ); } public void manageArtifact( Artifact artifact, Artifact replacement ) diff --git a/maven-artifact-ant/src/main/resources/META-INF/plexus/components.xml b/maven-artifact-ant/src/main/resources/META-INF/plexus/components.xml index 956c425faa..e7e3aad5b8 100644 --- a/maven-artifact-ant/src/main/resources/META-INF/plexus/components.xml +++ b/maven-artifact-ant/src/main/resources/META-INF/plexus/components.xml @@ -441,6 +441,9 @@ org.apache.maven.artifact.factory.ArtifactFactory + + org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager + diff --git a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java index 0fcf7592a7..ad87a59e64 100644 --- a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java +++ b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DebugResolutionListener.java @@ -76,6 +76,12 @@ public class DebugResolutionListener logger.debug( indent + artifact.getId() + " (setting scope to: " + scope + ")" ); } + public void selectVersionFromRange( Artifact artifact ) + { + logger.debug( indent + artifact.getId() + " (setting version to: " + artifact.getVersion() + " from range: " + + artifact.getVersionRange() + ")" ); + } + public void manageArtifact( Artifact artifact, Artifact replacement ) { String msg = indent + artifact.getId(); diff --git a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java index 9b21695e8a..315c86846a 100644 --- a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java +++ b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactResolver.java @@ -198,7 +198,7 @@ public class DefaultArtifactResolver ArtifactResolutionResult artifactResolutionResult; artifactResolutionResult = artifactCollector.collect( artifacts, originatingArtifact, managedVersions, localRepository, remoteRepositories, source, filter, - artifactFactory, listeners ); + listeners ); for ( Iterator i = artifactResolutionResult.getArtifactResolutionNodes().iterator(); i.hasNext(); ) { diff --git a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java index e58d0d2028..f587eb9684 100644 --- a/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java +++ b/maven-artifact-manager/src/main/java/org/apache/maven/artifact/resolver/WarningResolutionListener.java @@ -84,4 +84,8 @@ public class WarningResolutionListener public void manageArtifact( Artifact artifact, Artifact replacement ) { } + + public void selectVersionFromRange( Artifact artifact ) + { + } } diff --git a/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java b/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java index 2343351533..6e980bd5b3 100644 --- a/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java +++ b/maven-artifact-manager/src/test/java/org/apache/maven/artifact/resolver/ArtifactResolverTest.java @@ -104,7 +104,7 @@ public class ArtifactResolverTest { Set dependencies = new HashSet(); - if ( artifact.getArtifactId().equals( "g" ) ) + if ( "g".equals( artifact.getArtifactId() ) ) { try { @@ -118,6 +118,12 @@ public class ArtifactResolverTest return new ResolutionGroup( artifact, dependencies, remoteRepositories ); } + + public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, + List remoteRepositories ) + { + throw new UnsupportedOperationException( "Cannot get available versions in this test case" ); + } }; ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( g ), @@ -152,7 +158,7 @@ public class ArtifactResolverTest { Set dependencies = new HashSet(); - if ( artifact.getArtifactId().equals( "i" ) ) + if ( "i".equals( artifact.getArtifactId() ) ) { try { @@ -166,6 +172,12 @@ public class ArtifactResolverTest return new ResolutionGroup( artifact, dependencies, remoteRepositories ); } + + public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, + List remoteRepositories ) + { + throw new UnsupportedOperationException( "Cannot get available versions in this test case" ); + } }; ArtifactResolutionResult result = artifactResolver.resolveTransitively( Collections.singleton( i ), diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java index 7bbb03d128..32e0ad180f 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java @@ -145,4 +145,8 @@ public interface Artifact boolean isRelease(); void setRelease( boolean release ); + + List getAvailableVersions(); + + void setAvailableVersions( List versions ); } \ No newline at end of file diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java index 795271415e..115a2d3410 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java @@ -76,6 +76,8 @@ public class DefaultArtifact private boolean release = false; + private List availableVersions; + public DefaultArtifact( String groupId, String artifactId, VersionRange versionRange, String scope, String type, String classifier, ArtifactHandler artifactHandler ) { @@ -229,7 +231,8 @@ public class DefaultArtifact public String toString() { - return getId(); + return getDependencyConflictId() + ( hasClassifier() ? ":" + getClassifier() : "" ) + ":" + + ( version != null || baseVersion != null ? getBaseVersion() : versionRange.toString() ); } public int hashCode() @@ -431,15 +434,22 @@ public class DefaultArtifact public boolean isSnapshot() { - Matcher m = VERSION_FILE_PATTERN.matcher( getBaseVersion() ); - if ( m.matches() ) + if ( version != null || baseVersion != null ) { - setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION ); - return true; + Matcher m = VERSION_FILE_PATTERN.matcher( getBaseVersion() ); + if ( m.matches() ) + { + setBaseVersion( m.group( 1 ) + "-" + SNAPSHOT_VERSION ); + return true; + } + else + { + return getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ); + } } else { - return getBaseVersion().endsWith( SNAPSHOT_VERSION ) || getBaseVersion().equals( LATEST_VERSION ); + return false; } } @@ -473,4 +483,14 @@ public class DefaultArtifact { return release; } + + public List getAvailableVersions() + { + return availableVersions; + } + + public void setAvailableVersions( List availableVersions ) + { + this.availableVersions = availableVersions; + } } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java b/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java index de37124fa3..44aef5d916 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/metadata/ArtifactMetadataSource.java @@ -31,4 +31,7 @@ public interface ArtifactMetadataSource ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, List remoteRepositories ) throws ArtifactMetadataRetrievalException; + + List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, List remoteRepositories ) + throws ArtifactMetadataRetrievalException; } \ No newline at end of file diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java index f7c0866e8f..035b5b4791 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ArtifactCollector.java @@ -17,7 +17,6 @@ package org.apache.maven.artifact.resolver; */ import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; @@ -37,12 +36,11 @@ public interface ArtifactCollector { ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter, - ArtifactFactory artifactFactory, List listeners ) + List listeners ) throws ArtifactResolutionException; ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter, - ArtifactFactory artifactFactory, List listeners ) + ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) throws ArtifactResolutionException; } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java index 13d092eb0a..142caaaa31 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java @@ -17,12 +17,12 @@ package org.apache.maven.artifact.resolver; */ import org.apache.maven.artifact.Artifact; -import org.apache.maven.artifact.factory.ArtifactFactory; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.metadata.ResolutionGroup; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.artifact.versioning.OverConstrainedVersionException; import org.apache.maven.artifact.versioning.VersionRange; @@ -45,18 +45,16 @@ public class DefaultArtifactCollector { public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, ArtifactRepository localRepository, List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter, - ArtifactFactory artifactFactory, List listeners ) + ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) throws ArtifactResolutionException { return collect( artifacts, originatingArtifact, Collections.EMPTY_MAP, localRepository, remoteRepositories, - source, filter, artifactFactory, listeners ); + source, filter, listeners ); } public ArtifactResolutionResult collect( Set artifacts, Artifact originatingArtifact, Map managedVersions, ArtifactRepository localRepository, List remoteRepositories, - ArtifactMetadataSource source, ArtifactFilter filter, - ArtifactFactory artifactFactory, List listeners ) + ArtifactMetadataSource source, ArtifactFilter filter, List listeners ) throws ArtifactResolutionException { Map resolvedArtifacts = new HashMap(); @@ -68,7 +66,7 @@ public class DefaultArtifactCollector root.addDependencies( artifacts, remoteRepositories, filter ); recurse( root, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, - artifactFactory, listeners ); + listeners ); Set set = new HashSet(); @@ -97,7 +95,7 @@ public class DefaultArtifactCollector private void recurse( ResolutionNode node, Map resolvedArtifacts, Map managedVersions, ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source, - ArtifactFilter filter, ArtifactFactory artifactFactory, List listeners ) + ArtifactFilter filter, List listeners ) throws CyclicDependencyException, TransitiveArtifactResolutionException, OverConstrainedVersionException { fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node ); @@ -179,8 +177,43 @@ public class DefaultArtifactCollector { // set the recommended version VersionRange versionRange = artifact.getVersionRange(); - String version = versionRange.getSelectedVersion().toString(); - artifact.selectVersion( version ); + + // TODO: maybe its better to just pass the range through to retrieval and use a transformation? + ArtifactVersion version; + if ( !versionRange.isSelectedVersionKnown() ) + { + List versions = artifact.getAvailableVersions(); + if ( versions == null ) + { + versions = source.retrieveAvailableVersions( artifact, localRepository, + remoteRepositories ); + artifact.setAvailableVersions( versions ); + } + + version = versionRange.matchVersion( versions ); + + if ( version == null ) + { + if ( versions.isEmpty() ) + { + throw new OverConstrainedVersionException( + "No versions are present in the repository for the artifact with a range " + + versionRange ); + } + else + { + throw new OverConstrainedVersionException( + "Couldn't find a version in " + versions + " to match range " + versionRange ); + } + } + } + else + { + version = versionRange.getSelectedVersion(); + } + + artifact.selectVersion( version.toString() ); + fireEvent( ResolutionListener.SELECT_VERSION_FROM_RANGE, listeners, child ); } ResolutionGroup rGroup = source.retrieve( artifact, localRepository, remoteRepositories ); @@ -202,7 +235,7 @@ public class DefaultArtifactCollector } recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, - artifactFactory, listeners ); + listeners ); } } @@ -289,6 +322,9 @@ public class DefaultArtifactCollector case ResolutionListener.MANAGE_ARTIFACT: listener.manageArtifact( node.getArtifact(), replacement ); break; + case ResolutionListener.SELECT_VERSION_FROM_RANGE: + listener.selectVersionFromRange( node.getArtifact() ); + break; default: throw new IllegalStateException( "Unknown event: " + event ); } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java index f85002d8c8..b4e0294b71 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionListener.java @@ -46,6 +46,8 @@ public interface ResolutionListener int UPDATE_SCOPE_CURRENT_POM = 9; + int SELECT_VERSION_FROM_RANGE = 10; + void testArtifact( Artifact node ); void startProcessChildren( Artifact artifact ); @@ -63,4 +65,6 @@ public interface ResolutionListener void omitForCycle( Artifact artifact ); void updateScopeCurrentPom( Artifact artifact, String scope ); + + void selectVersionFromRange( Artifact artifact ); } diff --git a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java index 945f988cb0..9b2351c590 100644 --- a/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java +++ b/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java @@ -407,9 +407,7 @@ public class VersionRange else { Restriction restriction = (Restriction) restrictions.get( restrictions.size() - 1 ); - // TODO: how can we find the latest release before something to facilitate ) at the end? - // Also, how can we find the latest release when there no RELEASE metadata? We need to be maintaining - // a version list in the repository + version = restriction.getUpperBound(); if ( version == null ) { @@ -420,6 +418,38 @@ public class VersionRange return version; } + public boolean isSelectedVersionKnown() + throws OverConstrainedVersionException + { + boolean value; + if ( recommendedVersion != null ) + { + value = true; + } + else + { + if ( restrictions.size() == 0 ) + { + throw new OverConstrainedVersionException( "The artifact has no valid ranges" ); + } + else + { + Restriction restriction = (Restriction) restrictions.get( restrictions.size() - 1 ); + + if ( restriction.getUpperBound() == null ) + { + // RELEASE version, considered known + value = true; + } + else + { + value = restriction.isUpperBoundInclusive(); + } + } + } + return value; + } + public String toString() { if ( recommendedVersion != null ) @@ -453,4 +483,38 @@ public class VersionRange return buf.toString(); } } + + public ArtifactVersion matchVersion( List versions ) + { + // TODO: could be more efficient by sorting the list and then moving along the restrictions in order? + + ArtifactVersion matched = null; + for ( Iterator i = versions.iterator(); i.hasNext(); ) + { + ArtifactVersion version = (ArtifactVersion) i.next(); + if ( containsVersion( version ) ) + { + // valid - check if it is greater than the currently matched version + if ( matched == null || version.compareTo( matched ) > 0 ) + { + matched = version; + } + } + } + return matched; + } + + private boolean containsVersion( ArtifactVersion version ) + { + boolean matched = false; + for ( Iterator i = restrictions.iterator(); i.hasNext() && !matched; ) + { + Restriction restriction = (Restriction) i.next(); + if ( restriction.containsVersion( version ) ) + { + matched = true; + } + } + return matched; + } } diff --git a/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java b/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java index 422a104105..dc6b8f4032 100644 --- a/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java +++ b/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java @@ -336,21 +336,21 @@ public class DefaultArtifactCollectorTest throws ArtifactResolutionException { return artifactCollector.collect( artifacts, projectArtifact.artifact, null, null, source, null, - artifactFactory, Collections.EMPTY_LIST ); + Collections.EMPTY_LIST ); } private ArtifactResolutionResult collect( ArtifactSpec a ) throws ArtifactResolutionException { return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null, - source, null, artifactFactory, Collections.EMPTY_LIST ); + source, null, Collections.EMPTY_LIST ); } private ArtifactResolutionResult collect( ArtifactSpec a, ArtifactFilter filter ) throws ArtifactResolutionException { return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null, - source, filter, artifactFactory, Collections.EMPTY_LIST ); + source, filter, Collections.EMPTY_LIST ); } private ArtifactResolutionResult collect( ArtifactSpec a, Artifact managedVersion ) @@ -358,8 +358,7 @@ public class DefaultArtifactCollectorTest { Map managedVersions = Collections.singletonMap( managedVersion.getDependencyConflictId(), managedVersion ); return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, - managedVersions, null, null, source, null, artifactFactory, - Collections.EMPTY_LIST ); + managedVersions, null, null, source, null, Collections.EMPTY_LIST ); } private ArtifactSpec createArtifact( String id, String version ) @@ -461,5 +460,12 @@ public class DefaultArtifactCollectorTest return projectArtifacts; } + + public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, + List remoteRepositories ) + throws ArtifactMetadataRetrievalException + { + throw new UnsupportedOperationException( "Cannot get available versions in this test case" ); + } } } diff --git a/maven-core-it/it0034/expected-results.txt b/maven-core-it/it0034/expected-results.txt index 64f948ec6c..d2fed33a5a 100644 --- a/maven-core-it/it0034/expected-results.txt +++ b/maven-core-it/it0034/expected-results.txt @@ -1 +1,2 @@ +${artifact:junit:junit:3.7:jar} ${artifact:org.apache.maven:maven-core-it-support:1.1:jar} diff --git a/maven-core-it/it0034/pom.xml b/maven-core-it/it0034/pom.xml index 755a9f0997..a1223ea94f 100644 --- a/maven-core-it/it0034/pom.xml +++ b/maven-core-it/it0034/pom.xml @@ -7,8 +7,8 @@ junit junit - 3.8.1 - jar + + (,3.8) test diff --git a/maven-core-it/it0034/prebuild-hook.txt b/maven-core-it/it0034/prebuild-hook.txt index 58e13fba23..245966da96 100644 --- a/maven-core-it/it0034/prebuild-hook.txt +++ b/maven-core-it/it0034/prebuild-hook.txt @@ -1 +1,2 @@ rm ${artifact:org.apache.maven:maven-core-it-support:1.1:jar} +rm ${artifact:junit:junit:3.7:jar} diff --git a/maven-project/pom.xml b/maven-project/pom.xml index 4601fc40f5..d748943a30 100755 --- a/maven-project/pom.xml +++ b/maven-project/pom.xml @@ -18,6 +18,12 @@ maven-model 2.0-beta-1-SNAPSHOT + + + org.apache.maven + maven-artifact-manager + 2.0-beta-1-SNAPSHOT + org.apache.maven maven-profile diff --git a/maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java b/maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java index fe77a66ca5..0d41e28a8d 100644 --- a/maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java +++ b/maven-project/src/main/java/org/apache/maven/project/artifact/ActiveProjectArtifact.java @@ -260,4 +260,14 @@ public class ActiveProjectArtifact { artifact.setResolved( release ); } + + public List getAvailableVersions() + { + return artifact.getAvailableVersions(); + } + + public void setAvailableVersions( List versions ) + { + artifact.setAvailableVersions( versions ); + } } diff --git a/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java b/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java index 9977ead375..cf51960af9 100644 --- a/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java +++ b/maven-project/src/main/java/org/apache/maven/project/artifact/MavenMetadataSource.java @@ -18,13 +18,20 @@ package org.apache.maven.project.artifact; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.metadata.ArtifactMetadataSource; import org.apache.maven.artifact.metadata.ResolutionGroup; import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.metadata.ArtifactRepositoryMetadata; +import org.apache.maven.artifact.repository.metadata.Metadata; +import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager; +import org.apache.maven.artifact.repository.metadata.Versioning; +import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader; import org.apache.maven.artifact.resolver.filter.AndArtifactFilter; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.model.Dependency; @@ -36,9 +43,15 @@ import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectBuilder; import org.apache.maven.project.ProjectBuildingException; import org.codehaus.plexus.logging.AbstractLogEnabled; +import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -48,20 +61,22 @@ import java.util.Map; import java.util.Set; /** - * @author Jason van Zyl + * @author Jason van Zyl + * @author Brett Porter * @version $Id$ */ public class MavenMetadataSource extends AbstractLogEnabled implements ArtifactMetadataSource { - public static final String ROLE_HINT = "maven"; private MavenProjectBuilder mavenProjectBuilder; private ArtifactFactory artifactFactory; + private RepositoryMetadataManager repositoryMetadataManager; + /** * Retrieve the metadata for the project from the repository. * Uses the ProjectBuilder, to enable post-processing and inheritance calculation before retrieving the @@ -88,8 +103,8 @@ public class MavenMetadataSource { try { - project = mavenProjectBuilder - .buildFromRepository( pomArtifact, remoteRepositories, localRepository ); + project = mavenProjectBuilder.buildFromRepository( pomArtifact, remoteRepositories, + localRepository ); } catch ( InvalidModelException e ) { @@ -256,4 +271,107 @@ public class MavenMetadataSource return projectArtifacts; } + + public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, + List remoteRepositories ) + throws ArtifactMetadataRetrievalException + { + ArtifactMetadata metadata = new ArtifactRepositoryMetadata( artifact ); + repositoryMetadataManager.resolve( metadata, remoteRepositories, localRepository ); + + // TODO: this has been ripped from AbstractVersionTransformation - stop duplication + Versioning versioning = null; + for ( Iterator i = remoteRepositories.iterator(); i.hasNext(); ) + { + ArtifactRepository repository = (ArtifactRepository) i.next(); + + versioning = loadVersioningInformation( metadata, repository, localRepository, artifact ); + if ( versioning != null ) + { + artifact.setRepository( repository ); + // TODO: merge instead (see above) + break; + } + } + Versioning v = loadVersioningInformation( metadata, localRepository, localRepository, artifact ); + if ( v != null ) + { + versioning = v; + // TODO: figure out way to avoid duplicated message + if ( getLogger().isDebugEnabled() /*&& !alreadyResolved*/ ) + { + // Locally installed file is newer, don't use the resolved version + getLogger().debug( artifact.getArtifactId() + ": using locally installed snapshot" ); + } + } + + List versions; + if ( versioning != null ) + { + versions = new ArrayList( versioning.getVersions().size() ); + for ( Iterator i = versioning.getVersions().iterator(); i.hasNext(); ) + { + String version = (String) i.next(); + versions.add( new DefaultArtifactVersion( version ) ); + } + } + else + { + versions = Collections.EMPTY_LIST; + } + + return versions; + } + + private Versioning loadVersioningInformation( ArtifactMetadata repoMetadata, ArtifactRepository remoteRepository, + ArtifactRepository localRepository, Artifact artifact ) + throws ArtifactMetadataRetrievalException + { + File metadataFile = new File( localRepository.getBasedir(), + localRepository.pathOfLocalRepositoryMetadata( repoMetadata, remoteRepository ) ); + + Versioning versioning = null; + if ( metadataFile.exists() ) + { + Metadata metadata = readMetadata( metadataFile ); + versioning = metadata.getVersioning(); + } + return versioning; + } + + /** + * @todo share with DefaultPluginMappingManager. + */ + private static Metadata readMetadata( File mappingFile ) + throws ArtifactMetadataRetrievalException + { + Metadata result; + + Reader fileReader = null; + try + { + fileReader = new FileReader( mappingFile ); + + MetadataXpp3Reader mappingReader = new MetadataXpp3Reader(); + + result = mappingReader.read( fileReader ); + } + catch ( FileNotFoundException e ) + { + throw new ArtifactMetadataRetrievalException( "Cannot read version information from: " + mappingFile, e ); + } + catch ( IOException e ) + { + throw new ArtifactMetadataRetrievalException( "Cannot read version information from: " + mappingFile, e ); + } + catch ( XmlPullParserException e ) + { + throw new ArtifactMetadataRetrievalException( "Cannot parse version information from: " + mappingFile, e ); + } + finally + { + IOUtil.close( fileReader ); + } + return result; + } } diff --git a/maven-project/src/main/resources/META-INF/plexus/components.xml b/maven-project/src/main/resources/META-INF/plexus/components.xml index eb6c2eeaee..6fd727eb1f 100644 --- a/maven-project/src/main/resources/META-INF/plexus/components.xml +++ b/maven-project/src/main/resources/META-INF/plexus/components.xml @@ -175,6 +175,9 @@ org.apache.maven.artifact.factory.ArtifactFactory + + org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager + diff --git a/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java b/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java index d3b4f4f0a8..c0f3bb22e0 100644 --- a/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java +++ b/maven-project/src/test/java/org/apache/maven/project/TestArtifactResolver.java @@ -136,6 +136,12 @@ public class TestArtifactResolver return new ResolutionGroup( artifact, artifacts, artifactRepositories ); } + public List retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, + List remoteRepositories ) + { + throw new UnsupportedOperationException( "Cannot get available versions in this test case" ); + } + protected Set createArtifacts( List dependencies, String inheritedScope ) throws InvalidVersionSpecificationException { @@ -146,11 +152,11 @@ public class TestArtifactResolver Dependency d = (Dependency) i.next(); String scope = d.getScope(); - + if ( StringUtils.isEmpty( scope ) ) { scope = Artifact.SCOPE_COMPILE; - + d.setScope( scope ); }