Author: brett Date: Tue Jul 19 22:53:57 2005 New Revision: 219844 URL: http://svn.apache.org/viewcvs?rev=219844&view=rev Log: PR: MNG-505 enable version ranges in resolution (only default conflict resolution - nearest suggested version, fail if over-constrained)
Added: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java (with props) Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java (original) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/Artifact.java Tue Jul 19 22:53:57 2005 @@ -20,6 +20,7 @@ import org.apache.maven.artifact.metadata.ArtifactMetadata; import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.versioning.VersionRange; import java.io.File; import java.util.List; @@ -107,4 +108,10 @@ void setDependencyTrail( List dependencyTrail ); void setScope( String scope ); + + VersionRange getVersionRange(); + + void setVersionRange( VersionRange newRange ); + + void selectVersion( String version ); } Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java (original) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/DefaultArtifact.java Tue Jul 19 22:53:57 2005 @@ -78,9 +78,7 @@ this.artifactId = artifactId; - this.versionRange = versionRange; - - this.version = versionRange == null ? null : versionRange.getRecommendedVersion().toString(); + setVersionRange( versionRange ); this.artifactHandler = artifactHandler; @@ -113,7 +111,7 @@ "The type cannot be empty." ); } - if ( getVersion() == null ) + if ( version == null && versionRange == null ) { throw new InvalidArtifactRTException( groupId, artifactId, getVersion(), type, "The version cannot be empty." ); @@ -229,7 +227,10 @@ result = 37 * result + groupId.hashCode(); result = 37 * result + artifactId.hashCode(); result = 37 * result + type.hashCode(); - result = 37 * result + version.hashCode(); + if ( version != null ) + { + result = 37 * result + version.hashCode(); + } result = 37 * result + ( classifier != null ? classifier.hashCode() : 0 ); return result; } @@ -380,4 +381,29 @@ { this.scope = scope; } + + public VersionRange getVersionRange() + { + return versionRange; + } + + public final void setVersionRange( VersionRange versionRange ) + { + this.versionRange = versionRange; + + if ( versionRange != null && versionRange.getRecommendedVersion() != null ) + { + this.version = versionRange.getRecommendedVersion().toString(); + } + else + { + this.version = null; + } + } + + public void selectVersion( String version ) + { + this.version = version; + } + } Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java (original) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/DefaultArtifactCollector.java Tue Jul 19 22:53:57 2005 @@ -23,6 +23,8 @@ 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.OverConstrainedVersionException; +import org.apache.maven.artifact.versioning.VersionRange; import java.util.Collections; import java.util.HashMap; @@ -60,41 +62,47 @@ Map resolvedArtifacts = new HashMap(); ResolutionNode root = new ResolutionNode( originatingArtifact, remoteRepositories ); - root.addDependencies( artifacts, remoteRepositories, filter ); - recurse( root, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, - artifactFactory, listeners ); + try + { + root.addDependencies( artifacts, remoteRepositories, filter ); - Set set = new HashSet(); + recurse( root, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, + artifactFactory, listeners ); - for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); ) - { - ResolutionNode node = (ResolutionNode) i.next(); - if ( !node.equals( root ) ) + Set set = new HashSet(); + + for ( Iterator i = resolvedArtifacts.values().iterator(); i.hasNext(); ) { - Artifact artifact = node.getArtifact(); + ResolutionNode node = (ResolutionNode) i.next(); + if ( !node.equals( root ) ) + { + Artifact artifact = node.getArtifact(); - artifact.setDependencyTrail( node.getDependencyTrail() ); + artifact.setDependencyTrail( node.getDependencyTrail() ); - set.add( node ); + set.add( node ); + } } - } - - ArtifactResolutionResult result = new ArtifactResolutionResult(); - - result.setArtifactResolutionNodes( set ); - return result; + ArtifactResolutionResult result = new ArtifactResolutionResult(); + result.setArtifactResolutionNodes( set ); + return result; + } + catch ( OverConstrainedVersionException e ) + { + throw new ArtifactResolutionException( "Unable to mediate dependency", e ); + } } private void recurse( ResolutionNode node, Map resolvedArtifacts, Map managedVersions, ArtifactRepository localRepository, List remoteRepositories, ArtifactMetadataSource source, ArtifactFilter filter, ArtifactFactory artifactFactory, List listeners ) - throws CyclicDependencyException, TransitiveArtifactResolutionException + throws CyclicDependencyException, TransitiveArtifactResolutionException, OverConstrainedVersionException { fireEvent( ResolutionListener.TEST_ARTIFACT, listeners, node ); - // TODO: conflict resolvers, shouldn't be munging original artifact perhaps? + // TODO: use as a conflict resolver Object key = node.getKey(); if ( managedVersions.containsKey( key ) ) { @@ -116,6 +124,25 @@ if ( previous != null ) { // TODO: use as conflict resolver(s), chain and introduce version mediation + VersionRange previousRange = previous.getArtifact().getVersionRange(); + VersionRange currentRange = node.getArtifact().getVersionRange(); + + if ( previousRange == null ) + { + // version was already resolved + node.getArtifact().setVersion( previous.getArtifact().getVersion() ); + } + else if ( currentRange == null ) + { + // version was already resolved + previous.getArtifact().setVersion( node.getArtifact().getVersion() ); + } + else + { + VersionRange newRange = previousRange.restrict( currentRange ); + previous.getArtifact().setVersionRange( newRange ); + node.getArtifact().setVersionRange( newRange ); + } // previous one is more dominant if ( previous.getDepth() <= node.getDepth() ) @@ -145,10 +172,18 @@ ResolutionNode child = (ResolutionNode) i.next(); if ( !child.isResolved() ) { + Artifact artifact = child.getArtifact(); try { - ResolutionGroup rGroup = source.retrieve( child.getArtifact(), localRepository, - remoteRepositories ); + if ( artifact.getVersion() == null ) + { + // set the recommended version + VersionRange versionRange = artifact.getVersionRange(); + String version = versionRange.getSelectedVersion().toString(); + artifact.selectVersion( version ); + } + + ResolutionGroup rGroup = source.retrieve( artifact, localRepository, remoteRepositories ); child.addDependencies( rGroup.getArtifacts(), rGroup.getResolutionRepositories(), filter ); } catch ( CyclicDependencyException e ) @@ -162,9 +197,8 @@ } catch ( ArtifactMetadataRetrievalException e ) { - child.getArtifact().setDependencyTrail( node.getDependencyTrail() ); - throw new TransitiveArtifactResolutionException( e.getMessage(), child.getArtifact(), - remoteRepositories, e ); + artifact.setDependencyTrail( node.getDependencyTrail() ); + throw new TransitiveArtifactResolutionException( e.getMessage(), artifact, remoteRepositories, e ); } recurse( child, resolvedArtifacts, managedVersions, localRepository, remoteRepositories, source, filter, Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java (original) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/resolver/ResolutionNode.java Tue Jul 19 22:53:57 2005 @@ -1,7 +1,25 @@ package org.apache.maven.artifact.resolver; +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.resolver.filter.ArtifactFilter; +import org.apache.maven.artifact.versioning.OverConstrainedVersionException; +import org.apache.maven.artifact.versioning.VersionRange; import java.util.ArrayList; import java.util.Collections; @@ -14,7 +32,7 @@ { private Artifact artifact; - private List children = null; + private List children; private final List parents; @@ -55,7 +73,7 @@ } public void addDependencies( Set artifacts, List remoteRepositories, ArtifactFilter filter ) - throws CyclicDependencyException + throws CyclicDependencyException, OverConstrainedVersionException { children = new ArrayList( artifacts.size() ); @@ -78,12 +96,22 @@ } public List getDependencyTrail() + throws OverConstrainedVersionException { List path = new LinkedList(); ResolutionNode node = this; while ( node != null ) { - path.add( 0, node.getArtifact().getId() ); + Artifact artifact = node.getArtifact(); + if ( artifact.getVersion() == null ) + { + // set the recommended version + VersionRange versionRange = artifact.getVersionRange(); + String version = versionRange.getSelectedVersion().toString(); + artifact.selectVersion( version ); + } + + path.add( 0, artifact.getId() ); node = node.parent; } return path; @@ -108,7 +136,7 @@ { this.artifact = artifact; } - + public List getRemoteRepositories() { return remoteRepositories; Added: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java?rev=219844&view=auto ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java (added) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java Tue Jul 19 22:53:57 2005 @@ -0,0 +1,32 @@ +package org.apache.maven.artifact.versioning; + +/* + * Copyright 2001-2005 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Occurs when ranges exclude each other and no valid value remains. + * + * @author <a href="mailto:[EMAIL PROTECTED]">Brett Porter</a> + * @version $Id$ + */ +public class OverConstrainedVersionException + extends Exception +{ + public OverConstrainedVersionException( String msg ) + { + super( msg ); + } +} Propchange: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/OverConstrainedVersionException.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Modified: maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java (original) +++ maven/components/trunk/maven-artifact/src/main/java/org/apache/maven/artifact/versioning/VersionRange.java Tue Jul 19 22:53:57 2005 @@ -29,6 +29,8 @@ */ public class VersionRange { + private final ArtifactVersion RELEASE = new DefaultArtifactVersion( "RELEASE" ); + private final ArtifactVersion recommendedVersion; private final List restrictions; @@ -380,6 +382,68 @@ else { return v2; + } + } + + public ArtifactVersion getSelectedVersion() + throws OverConstrainedVersionException + { + ArtifactVersion version; + if ( recommendedVersion != null ) + { + version = recommendedVersion; + } + else + { + if ( restrictions.size() == 0 ) + { + throw new OverConstrainedVersionException( "The artifact has no valid ranges" ); + } + else + { + Restriction restriction = (Restriction) restrictions.get( restrictions.size() - 1 ); + // TODO: how can we find the latest release before something to facilitate ) at the end? + version = restriction.getUpperBound(); + if ( version == null ) + { + version = RELEASE; + } + } + } + return version; + } + + public String toString() + { + if ( recommendedVersion != null ) + { + return recommendedVersion.toString(); + } + else + { + StringBuffer buf = new StringBuffer(); + for ( Iterator i = restrictions.iterator(); i.hasNext(); ) + { + Restriction r = (Restriction) i.next(); + + buf.append( r.isLowerBoundInclusive() ? "[" : "(" ); + if ( r.getLowerBound() != null ) + { + buf.append( r.getLowerBound().toString() ); + } + buf.append( "," ); + if ( r.getUpperBound() != null ) + { + buf.append( r.getUpperBound().toString() ); + } + buf.append( r.isUpperBoundInclusive() ? "]" : ")" ); + + if ( i.hasNext() ) + { + buf.append( "," ); + } + } + return buf.toString(); } } } Modified: maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java URL: http://svn.apache.org/viewcvs/maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java?rev=219844&r1=219843&r2=219844&view=diff ============================================================================== --- maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java (original) +++ maven/components/trunk/maven-artifact/src/test/java/org/apache/maven/artifact/resolver/DefaultArtifactCollectorTest.java Tue Jul 19 22:53:57 2005 @@ -135,6 +135,73 @@ ArtifactResolutionResult res = collect( a ); assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ), res.getArtifacts() ); + assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); + } + + public void testResolveNearestWithRanges() + throws ArtifactResolutionException + { + ArtifactSpec a = createArtifact( "a", "1.0" ); + ArtifactSpec b = a.addDependency( "b", "1.0" ); + ArtifactSpec c = a.addDependency( "c", "2.0" ); + + b.addDependency( "c", "[1.0,3.0]" ); + + ArtifactResolutionResult res = collect( a ); + assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ), + res.getArtifacts() ); + assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); + } + + public void testCompatibleRanges() + throws ArtifactResolutionException + { + ArtifactSpec a = createArtifact( "a", "1.0" ); + ArtifactSpec b = a.addDependency( "b", "1.0" ); + a.addDependency( "c", "[2.0,2.5]" ); + b.addDependency( "c", "[1.0,3.0]" ); + + ArtifactResolutionResult res = collect( a ); + + ArtifactSpec c = createArtifact( "c", "2.5" ); + assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ), + res.getArtifacts() ); + assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() ); + } + + public void testIncompatibleRanges() + throws ArtifactResolutionException + { + ArtifactSpec a = createArtifact( "a", "1.0" ); + ArtifactSpec b = a.addDependency( "b", "1.0" ); + a.addDependency( "c", "[2.4,3.0]" ); + + b.addDependency( "c", "[1.0,2.0]" ); + + try + { + ArtifactResolutionResult res = collect( a ); + fail( "Should not succeed collecting, got: " + res.getArtifacts() ); + } + catch ( ArtifactResolutionException expected ) + { + } + } + + public void testUnboundedRange() + throws ArtifactResolutionException + { + ArtifactSpec a = createArtifact( "a", "1.0" ); + ArtifactSpec b = a.addDependency( "b", "1.0" ); + a.addDependency( "c", "[2.0,]" ); + b.addDependency( "c", "[1.0,]" ); + + ArtifactResolutionResult res = collect( a ); + + ArtifactSpec c = createArtifact( "c", "RELEASE" ); + assertEquals( "Check artifact list", createSet( new Object[]{a.artifact, b.artifact, c.artifact} ), + res.getArtifacts() ); + assertEquals( "Check version", "RELEASE", getArtifact( "c", res.getArtifacts() ).getVersion() ); } public void testResolveManagedVersion() @@ -303,8 +370,9 @@ private ArtifactSpec createArtifact( String id, String version, String scope ) { ArtifactSpec spec = new ArtifactSpec(); - spec.artifact = artifactFactory.createArtifact( GROUP_ID, id, version, scope, "jar" ); - source.artifacts.put( spec.artifact.getId(), spec ); + Artifact artifact = artifactFactory.createArtifact( GROUP_ID, id, version, scope, "jar" ); + spec.artifact = artifact; + source.artifacts.put( source.getKey( artifact ), spec ); return spec; } @@ -346,7 +414,9 @@ List remoteRepositories ) throws ArtifactMetadataRetrievalException { - ArtifactSpec a = (ArtifactSpec) artifacts.get( artifact.getId() ); + String key = getKey( artifact ); + + ArtifactSpec a = (ArtifactSpec) artifacts.get( key ); try { return new ResolutionGroup( createArtifacts( artifactFactory, a.dependencies, artifact.getScope(), @@ -356,6 +426,11 @@ { throw new ArtifactMetadataRetrievalException( e ); } + } + + private String getKey( Artifact artifact ) + { + return artifact.getDependencyConflictId() + ":" + artifact.getVersionRange(); } private Set createArtifacts( ArtifactFactory artifactFactory, Set dependencies, String inheritedScope, --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]