PR: MNG-505

parse ranges

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@219625 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brett Leslie Porter 2005-07-19 06:43:09 +00:00
parent 810d4a3276
commit 4fcc1e1074
6 changed files with 360 additions and 21 deletions

View File

@ -80,7 +80,7 @@ public class DefaultArtifact
this.artifactId = artifactId;
// TODO: this would be where we might have a min/max instead
this.version = versionRange.getVersion();
this.version = versionRange != null ? versionRange.getRecommendedVersion() : null;
this.artifactHandler = artifactHandler;
@ -188,8 +188,7 @@ public class DefaultArtifact
public String getId()
{
return getDependencyConflictId() + ( hasClassifier() ? ( ":" + getClassifier() ) : "" ) + ":" +
getBaseVersion();
return getDependencyConflictId() + ( hasClassifier() ? ":" + getClassifier() : "" ) + ":" + getBaseVersion();
}
public String getDependencyConflictId()

View File

@ -101,14 +101,10 @@ public class DefaultArtifactFactory
String classifier, String inheritedScope )
{
// TODO: better constructor
VersionRange versionRange;
VersionRange versionRange = null;
if ( version != null )
{
versionRange = new VersionRange( "[" + version + "]" );
}
else
{
versionRange = new VersionRange( null );
versionRange = VersionRange.createFromVersion( version );
}
return createArtifact( groupId, artifactId, versionRange, scope, type, classifier, inheritedScope );
}
@ -127,13 +123,11 @@ public class DefaultArtifactFactory
{
return null;
}
// vvv added to retain compile scope. Remove if you want compile inherited as runtime
else if ( Artifact.SCOPE_COMPILE.equals( scope ) && Artifact.SCOPE_COMPILE.equals( inheritedScope ) )
{
// added to retain compile scope. Remove if you want compile inherited as runtime
desiredScope = Artifact.SCOPE_COMPILE;
}
// ^^^ added to retain compile scope. Remove if you want compile inherited as runtime
if ( Artifact.SCOPE_TEST.equals( inheritedScope ) )
{

View File

@ -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 a version is invalid.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class InvalidVersionSpecificationException
extends Exception
{
public InvalidVersionSpecificationException( String message )
{
super( message );
}
}

View File

@ -0,0 +1,62 @@
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.
*/
/**
* Describes a restriction in versioning.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class Restriction
{
private final String lowerBound;
private final boolean lowerBoundInclusive;
private final String upperBound;
private final boolean upperBoundInclusive;
public Restriction( String lowerBound, boolean lowerBoundInclusive, String upperBound, boolean upperBoundInclusive )
{
this.lowerBound = lowerBound;
this.lowerBoundInclusive = lowerBoundInclusive;
this.upperBound = upperBound;
this.upperBoundInclusive = upperBoundInclusive;
}
public String getLowerBound()
{
return lowerBound;
}
public boolean isLowerBoundInclusive()
{
return lowerBoundInclusive;
}
public String getUpperBound()
{
return upperBound;
}
public boolean isUpperBoundInclusive()
{
return upperBoundInclusive;
}
}

View File

@ -16,6 +16,10 @@ package org.apache.maven.artifact.versioning;
* limitations under the License.
*/
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Construct a version range from a specification.
*
@ -24,24 +28,124 @@ package org.apache.maven.artifact.versioning;
*/
public class VersionRange
{
private String version;
private final String recommendedVersion;
public VersionRange( String spec )
private final List restrictions;
private VersionRange( String recommendedVersion, List restrictions )
{
if ( spec != null )
this.recommendedVersion = recommendedVersion;
this.restrictions = restrictions;
}
public String getRecommendedVersion()
{
// temporary!
if ( spec.startsWith( "[" ) )
return recommendedVersion;
}
public List getRestrictions()
{
spec = spec.substring( 1, spec.length() - 1 );
return restrictions;
}
public static VersionRange createFromVersionSpec( String spec )
throws InvalidVersionSpecificationException
{
List exclusions = new ArrayList();
String process = spec;
String version = null;
while ( process.startsWith( "[" ) || process.startsWith( "(" ) )
{
int index1 = process.indexOf( ")" );
int index2 = process.indexOf( "]" );
int index = index2;
if ( index2 < 0 || index1 < index2 )
{
if ( index1 >= 0 )
{
index = index1;
}
}
this.version = spec;
if ( index < 0 )
{
throw new InvalidVersionSpecificationException( "Unbounded range: " + spec );
}
public String getVersion()
exclusions.add( parseRestriction( process.substring( 0, index + 1 ) ) );
process = process.substring( index + 1 ).trim();
if ( process.length() > 0 && process.startsWith( "," ) )
{
return version;
process = process.substring( 1 ).trim();
}
}
if ( process.length() > 0 )
{
if ( exclusions.size() > 0 )
{
throw new InvalidVersionSpecificationException(
"Only fully-qualified sets allowed in multiple set scenario: " + spec );
}
else
{
version = process;
}
}
return new VersionRange( version, exclusions );
}
private static Restriction parseRestriction( String spec )
throws InvalidVersionSpecificationException
{
boolean lowerBoundInclusive = spec.startsWith( "[" );
boolean upperBoundInclusive = spec.endsWith( "]" );
String process = spec.substring( 1, spec.length() - 1 ).trim();
Restriction restriction;
int index = process.indexOf( "," );
if ( index < 0 )
{
if ( !lowerBoundInclusive || !upperBoundInclusive )
{
throw new InvalidVersionSpecificationException( "Single version must be surrounded by []: " + spec );
}
restriction = new Restriction( process, lowerBoundInclusive, process, upperBoundInclusive );
}
else
{
String lowerBound = process.substring( 0, index ).trim();
String upperBound = process.substring( index + 1 ).trim();
if ( lowerBound.equals( upperBound ) )
{
throw new InvalidVersionSpecificationException( "Range cannot have identical boundaries: " + spec );
}
if ( lowerBound.length() == 0 )
{
lowerBound = null;
}
if ( upperBound.length() == 0 )
{
upperBound = null;
}
restriction = new Restriction( lowerBound, lowerBoundInclusive, upperBound, upperBoundInclusive );
}
return restriction;
}
public static VersionRange createFromVersion( String version )
{
return new VersionRange( version, Collections.EMPTY_LIST );
}
}

View File

@ -0,0 +1,148 @@
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.
*/
import junit.framework.TestCase;
import java.util.List;
/**
* Tests version range construction.
*
* @author <a href="mailto:brett@apache.org">Brett Porter</a>
* @version $Id$
*/
public class VersionRangeTest
extends TestCase
{
private static final String CHECK_NUM_RESTRICTIONS = "check number of restrictions";
private static final String CHECK_UPPER_BOUND = "check upper bound";
private static final String CHECK_UPPER_BOUND_INCLUSIVE = "check upper bound is inclusive";
private static final String CHECK_LOWER_BOUND = "check lower bound";
private static final String CHECK_LOWER_BOUND_INCLUSIVE = "check lower bound is inclusive";
private static final String CHECK_VERSION_RECOMMENDATION = "check version recommended";
public void testRange()
throws InvalidVersionSpecificationException
{
VersionRange range = VersionRange.createFromVersionSpec( "(,1.0]" );
List restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
Restriction restriction = (Restriction) restrictions.get( 0 );
assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound() );
assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "1.0" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 0, restrictions.size() );
assertEquals( CHECK_VERSION_RECOMMENDATION, "1.0", range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "[1.0]" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
restriction = (Restriction) restrictions.get( 0 );
assertEquals( CHECK_LOWER_BOUND, "1.0", restriction.getLowerBound() );
assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound() );
assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "[1.2,1.3]" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
restriction = (Restriction) restrictions.get( 0 );
assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound() );
assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertEquals( CHECK_UPPER_BOUND, "1.3", restriction.getUpperBound() );
assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "[1.0,2.0)" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
restriction = (Restriction) restrictions.get( 0 );
assertEquals( CHECK_LOWER_BOUND, "1.0", restriction.getLowerBound() );
assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertEquals( CHECK_UPPER_BOUND, "2.0", restriction.getUpperBound() );
assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "[1.5,)" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 1, restrictions.size() );
restriction = (Restriction) restrictions.get( 0 );
assertEquals( CHECK_LOWER_BOUND, "1.5", restriction.getLowerBound() );
assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
range = VersionRange.createFromVersionSpec( "(,1.0],[1.2,)" );
restrictions = range.getRestrictions();
assertEquals( CHECK_NUM_RESTRICTIONS, 2, restrictions.size() );
restriction = (Restriction) restrictions.get( 0 );
assertNull( CHECK_LOWER_BOUND, restriction.getLowerBound() );
assertFalse( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertEquals( CHECK_UPPER_BOUND, "1.0", restriction.getUpperBound() );
assertTrue( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
restriction = (Restriction) restrictions.get( 1 );
assertEquals( CHECK_LOWER_BOUND, "1.2", restriction.getLowerBound() );
assertTrue( CHECK_LOWER_BOUND_INCLUSIVE, restriction.isLowerBoundInclusive() );
assertNull( CHECK_UPPER_BOUND, restriction.getUpperBound() );
assertFalse( CHECK_UPPER_BOUND_INCLUSIVE, restriction.isUpperBoundInclusive() );
assertNull( CHECK_VERSION_RECOMMENDATION, range.getRecommendedVersion() );
}
public void testInvalidRanges()
{
checkInvalidRange( "(1.0)" );
checkInvalidRange( "[1.0)" );
checkInvalidRange( "(1.0]" );
checkInvalidRange( "(1.0,1.0]" );
checkInvalidRange( "[1.0,1.0)" );
checkInvalidRange( "(1.0,1.0)" );
checkInvalidRange( "[1.0,1.2),1.3" );
/* TODO: not testing this presently
// overlap
checkInvalidRange( "[1.0,1.2),(1.1,1.3]" );
// overlap
checkInvalidRange( "[1.1,1.3),(1.0,1.2]" );
*/
}
private void checkInvalidRange( String version )
{
try
{
VersionRange.createFromVersionSpec( version );
fail( "Version " + version + " should have failed to construct" );
}
catch ( InvalidVersionSpecificationException expected )
{
// expected
}
}
}