PR: MNG-613

Completion of the version selection from a range.



git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@279720 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-09-09 06:49:59 +00:00
parent f11def89c1
commit 9c060b192a
22 changed files with 353 additions and 42 deletions

View File

@ -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 )

View File

@ -441,6 +441,9 @@
<requirement>
<role>org.apache.maven.artifact.factory.ArtifactFactory</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager</role>
</requirement>
</requirements>
</component>

View File

@ -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();

View File

@ -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(); )
{

View File

@ -84,4 +84,8 @@ public class WarningResolutionListener
public void manageArtifact( Artifact artifact, Artifact replacement )
{
}
public void selectVersionFromRange( Artifact artifact )
{
}
}

View File

@ -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 ),

View File

@ -145,4 +145,8 @@ public interface Artifact
boolean isRelease();
void setRelease( boolean release );
List getAvailableVersions();
void setAvailableVersions( List versions );
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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;
}
}

View File

@ -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" );
}
}
}

View File

@ -1 +1,2 @@
${artifact:junit:junit:3.7:jar}
${artifact:org.apache.maven:maven-core-it-support:1.1:jar}

View File

@ -7,8 +7,8 @@
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<!-- Select 3.7 -->
<version>(,3.8)</version>
<scope>test</scope>
</dependency>
<dependency>

View File

@ -1 +1,2 @@
rm ${artifact:org.apache.maven:maven-core-it-support:1.1:jar}
rm ${artifact:junit:junit:3.7:jar}

View File

@ -18,6 +18,12 @@
<artifactId>maven-model</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<!-- TODO: temporary - refactor code to avoid this. It is for metadata retrieval in MavenMetadataSource -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-artifact-manager</artifactId>
<version>2.0-beta-1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-profile</artifactId>

View File

@ -260,4 +260,14 @@ public class ActiveProjectArtifact
{
artifact.setResolved( release );
}
public List getAvailableVersions()
{
return artifact.getAvailableVersions();
}
public void setAvailableVersions( List versions )
{
artifact.setAvailableVersions( versions );
}
}

View File

@ -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 <a href="mailto:jason@maven.org">Jason van Zyl </a>
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @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;
}
}

View File

@ -175,6 +175,9 @@
<requirement>
<role>org.apache.maven.artifact.factory.ArtifactFactory</role>
</requirement>
<requirement>
<role>org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager</role>
</requirement>
</requirements>
</component>
</components>

View File

@ -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 );
}