[MNG-3047] Applying broader fix for comparisons and hashCode generation to ArtifactVersion.

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@565824 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
John Dennis Casey 2007-08-14 16:25:41 +00:00
parent 8795579469
commit beb9d73169
3 changed files with 197 additions and 86 deletions

View File

@ -40,4 +40,8 @@ public interface ArtifactVersion
String getQualifier();
void parseVersion( String version );
boolean equals( Object other );
int hashCode();
}

View File

@ -40,6 +40,8 @@ public class DefaultArtifactVersion
private String qualifier;
private String unparsed;
public DefaultArtifactVersion( String version )
{
parseVersion( version );
@ -47,38 +49,40 @@ public class DefaultArtifactVersion
public int compareTo( Object o )
{
DefaultArtifactVersion otherVersion = (DefaultArtifactVersion) o;
ArtifactVersion otherVersion = (ArtifactVersion) o;
int result = compareIntegers( majorVersion, otherVersion.majorVersion );
int result = getMajorVersion() - otherVersion.getMajorVersion();
if ( result == 0 )
{
result = compareIntegers( minorVersion, otherVersion.minorVersion );
result = getMinorVersion() - otherVersion.getMinorVersion();
}
if ( result == 0 )
{
result = compareIntegers( incrementalVersion, otherVersion.incrementalVersion );
result = getIncrementalVersion() - otherVersion.getIncrementalVersion();
}
if ( result == 0 )
{
if ( qualifier != null )
{
if ( otherVersion.qualifier != null )
String otherQualifier = otherVersion.getQualifier();
if ( otherQualifier != null )
{
if ( qualifier.length() > otherVersion.qualifier.length() &&
qualifier.startsWith( otherVersion.qualifier ) )
if ( ( qualifier.length() > otherQualifier.length() )
&& qualifier.startsWith( otherQualifier ) )
{
// here, the longer one that otherwise match is considered older
result = -1;
}
else if ( qualifier.length() < otherVersion.qualifier.length() &&
otherVersion.qualifier.startsWith( qualifier ) )
else if ( ( qualifier.length() < otherQualifier.length() )
&& otherQualifier.startsWith( qualifier ) )
{
// here, the longer one that otherwise match is considered older
result = 1;
}
else
{
result = qualifier.compareTo( otherVersion.qualifier );
result = qualifier.compareTo( otherQualifier );
}
}
else
@ -87,40 +91,19 @@ public class DefaultArtifactVersion
result = -1;
}
}
else if ( otherVersion.qualifier != null )
else if ( otherVersion.getQualifier() != null )
{
// otherVersion has a qualifier but we don't, we're newer
result = 1;
}
else if ( buildNumber != null || otherVersion.buildNumber != null )
else
{
result = compareIntegers( buildNumber, otherVersion.buildNumber );
result = getBuildNumber() - otherVersion.getBuildNumber();
}
}
return result;
}
private int compareIntegers( Integer i1, Integer i2 )
{
// treat null as 0 in comparison
if ( i1 == null ? i2 == null : i1.equals( i2 ) )
{
return 0;
}
else if ( i1 == null )
{
return -i2.intValue();
}
else if ( i2 == null )
{
return i1.intValue();
}
else
{
return i1.intValue() - i2.intValue();
}
}
public int getMajorVersion()
{
return majorVersion != null ? majorVersion.intValue() : 0;
@ -148,6 +131,8 @@ public class DefaultArtifactVersion
public final void parseVersion( String version )
{
unparsed = version;
int index = version.indexOf( "-" );
String part1;
@ -167,7 +152,7 @@ public class DefaultArtifactVersion
{
try
{
if ( part2.length() == 1 || !part2.startsWith( "0" ) )
if ( ( part2.length() == 1 ) || !part2.startsWith( "0" ) )
{
buildNumber = Integer.valueOf( part2 );
}
@ -182,7 +167,7 @@ public class DefaultArtifactVersion
}
}
if ( part1.indexOf( "." ) < 0 && !part1.startsWith( "0" ) )
if ( ( part1.indexOf( "." ) < 0 ) && !part1.startsWith( "0" ) )
{
try
{
@ -235,7 +220,7 @@ public class DefaultArtifactVersion
private static Integer getNextIntegerToken( StringTokenizer tok )
{
String s = tok.nextToken();
if ( s.length() > 1 && s.startsWith( "0" ) )
if ( ( s.length() > 1 ) && s.startsWith( "0" ) )
{
throw new NumberFormatException( "Number part has a leading 0: '" + s + "'" );
}
@ -244,34 +229,38 @@ public class DefaultArtifactVersion
public String toString()
{
StringBuffer buf = new StringBuffer();
if ( majorVersion != null )
return unparsed;
}
public boolean equals( Object other )
{
if ( this == other )
{
buf.append( majorVersion );
return true;
}
if ( minorVersion != null )
if ( false == ( other instanceof ArtifactVersion ) )
{
buf.append( "." );
buf.append( minorVersion );
return false;
}
if ( incrementalVersion != null )
return 0 == compareTo( other );
}
public int hashCode()
{
int result = 1229;
result = 1223 * result + getMajorVersion();
result = 1223 * result + getMinorVersion();
result = 1223 * result + getIncrementalVersion();
result = 1223 * result + getBuildNumber();
if ( null != getQualifier() )
{
buf.append( "." );
buf.append( incrementalVersion );
result = 1223 * result + getQualifier().hashCode();
}
if ( buildNumber != null )
{
buf.append( "-" );
buf.append( buildNumber );
}
else if ( qualifier != null )
{
if ( buf.length() > 0 )
{
buf.append( "-" );
}
buf.append( qualifier );
}
return buf.toString();
return result;
}
}

View File

@ -215,7 +215,6 @@ public class DefaultArtifactVersionTest
//assertVersionOlder( "2.0.1-xyz-SNAPSHOT", "2.0.1-123-SNAPSHOT" );
}
public void testSnapshotVsReleases()
{
assertVersionOlder( "1.0-RC1", "1.0-SNAPSHOT" );
@ -225,41 +224,160 @@ public class DefaultArtifactVersionTest
private void assertVersionOlder( String left, String right )
{
assertTrue( left + " should be older than " + right, new DefaultArtifactVersion( left ).compareTo( new DefaultArtifactVersion( right ) ) < 0 );
assertTrue( right + " should be newer than " + left, new DefaultArtifactVersion( right ).compareTo( new DefaultArtifactVersion( left ) ) > 0 );
assertTrue( left + " should be older than " + right,
new DefaultArtifactVersion( left ).compareTo( new DefaultArtifactVersion( right ) ) < 0 );
assertTrue( right + " should be newer than " + left,
new DefaultArtifactVersion( right ).compareTo( new DefaultArtifactVersion( left ) ) > 0 );
}
private void assertVersionEqual( String left, String right )
{
assertTrue( left + " should be equal to " + right, new DefaultArtifactVersion( left ).compareTo( new DefaultArtifactVersion( right ) ) == 0 );
assertTrue( right + " should be equal to " + left, new DefaultArtifactVersion( right ).compareTo( new DefaultArtifactVersion( left ) ) == 0 );
assertTrue( left + " should be equal to " + right,
new DefaultArtifactVersion( left ).compareTo( new DefaultArtifactVersion( right ) ) == 0 );
assertTrue( right + " should be equal to " + left,
new DefaultArtifactVersion( right ).compareTo( new DefaultArtifactVersion( left ) ) == 0 );
}
public void testVersionComparingWithBuildNumberZero()
{
DefaultArtifactVersion v1 = new DefaultArtifactVersion("2.0");
DefaultArtifactVersion v2 = new DefaultArtifactVersion("2.0-0");
DefaultArtifactVersion v3 = new DefaultArtifactVersion("2.0-alpha1");
DefaultArtifactVersion v4 = new DefaultArtifactVersion("2.0-1");
DefaultArtifactVersion v1 = new DefaultArtifactVersion( "2.0" );
DefaultArtifactVersion v2 = new DefaultArtifactVersion( "2.0-0" );
DefaultArtifactVersion v3 = new DefaultArtifactVersion( "2.0-alpha1" );
DefaultArtifactVersion v4 = new DefaultArtifactVersion( "2.0-1" );
// v1 and v2 are equal
assertTrue( v1.compareTo(v2) == 0 );
assertTrue( v2.compareTo(v1) == 0 );
assertTrue( v1.compareTo( v2 ) == 0 );
assertTrue( v2.compareTo( v1 ) == 0 );
// v1 is newer than v3
assertTrue( v1.compareTo(v3) > 0 );
assertTrue( v3.compareTo(v1) < 0 );
assertTrue( v1.compareTo( v3 ) > 0 );
assertTrue( v3.compareTo( v1 ) < 0 );
// ergo, v2 should also be newer than v3
assertTrue( v2.compareTo(v3) > 0 );
assertTrue( v3.compareTo(v1) < 0 );
assertTrue( v2.compareTo( v3 ) > 0 );
assertTrue( v3.compareTo( v1 ) < 0 );
// nonzero build numbers still respected
assertTrue( v1.compareTo(v4) < 0 ); // build number one is always newer
assertTrue( v4.compareTo(v1) > 0 );
assertTrue( v2.compareTo(v4) < 0 ); // same results as v1
assertTrue( v4.compareTo(v2) > 0 );
assertTrue( v3.compareTo(v4) < 0 ); // qualifier is always older
assertTrue( v4.compareTo(v3) > 0 );
assertTrue( v1.compareTo( v4 ) < 0 ); // build number one is always newer
assertTrue( v4.compareTo( v1 ) > 0 );
assertTrue( v2.compareTo( v4 ) < 0 ); // same results as v1
assertTrue( v4.compareTo( v2 ) > 0 );
assertTrue( v3.compareTo( v4 ) < 0 ); // qualifier is always older
assertTrue( v4.compareTo( v3 ) > 0 );
}
public void testCompareToEqualsHashCodeConsistency()
{
DefaultArtifactVersion v1;
DefaultArtifactVersion v2;
// equal to itself
v1 = new DefaultArtifactVersion( "1.3" );
v2 = v1;
assertTrue( v1.equals( v2 ) && v2.equals( v1 ) && ( v1.hashCode() == v2.hashCode() ) && ( v1.compareTo( v2 ) == 0 )
&& ( v2.compareTo( v1 ) == 0 ) );
// equal to something that means the same
v1 = new DefaultArtifactVersion( "1" );
v2 = new DefaultArtifactVersion( "1.0.0-0" );
assertTrue( v1.equals( v2 ) && v2.equals( v1 ) && ( v1.hashCode() == v2.hashCode() ) && ( v1.compareTo( v2 ) == 0 )
&& ( v2.compareTo( v1 ) == 0 ) );
// equal with qualifier
v1 = new DefaultArtifactVersion( "1.3-alpha1" );
v2 = new DefaultArtifactVersion( "1.3-alpha1" );
assertTrue( v1.equals( v2 ) && v2.equals( v1 ) && ( v1.hashCode() == v2.hashCode() ) && ( v1.compareTo( v2 ) == 0 )
&& ( v2.compareTo( v1 ) == 0 ) );
// longer qualifier with same start is *newer*
v1 = new DefaultArtifactVersion( "1.3-alpha1" );
v2 = new DefaultArtifactVersion( "1.3-alpha1-1" );
assertTrue( !v1.equals( v2 ) && !v2.equals( v1 ) && ( v1.compareTo( v2 ) > 0 ) && ( v2.compareTo( v1 ) < 0 ) );
// different qualifiers alpha compared
v1 = new DefaultArtifactVersion( "1.3-alpha1" );
v2 = new DefaultArtifactVersion( "1.3-beta1" );
assertTrue( !v1.equals( v2 ) && !v2.equals( v1 ) && ( v1.compareTo( v2 ) < 0 ) && ( v2.compareTo( v1 ) > 0 ) );
}
public void testTransitivity()
{
DefaultArtifactVersion v1 = new DefaultArtifactVersion( "1" );
DefaultArtifactVersion v2 = new DefaultArtifactVersion( "1.0-0" );
DefaultArtifactVersion v3 = new DefaultArtifactVersion( "1.0.1" );
DefaultArtifactVersion v4 = new DefaultArtifactVersion( "1.0-beta1" );
// v1 and v2 are equal
assertTrue( v1.equals( v2 ) && v2.equals( v1 ) && ( v1.compareTo( v2 ) == 0 ) && ( v2.compareTo( v1 ) == 0 ) );
// v1 is older than v3
assertTrue( !v1.equals( v3 ) && !v3.equals( v1 ) && ( v1.compareTo( v3 ) < 0 ) && ( v3.compareTo( v1 ) > 0 ) );
// ergo, v2 is older than v3
assertTrue( !v2.equals( v3 ) && !v3.equals( v2 ) && ( v2.compareTo( v3 ) < 0 ) && ( v3.compareTo( v2 ) > 0 ) );
// v1 is newer than v4
assertTrue( !v1.equals( v4 ) && !v4.equals( v1 ) && ( v1.compareTo( v4 ) > 0 ) && ( v4.compareTo( v1 ) < 0 ) );
// ergo, v2 is newer than v4
assertTrue( !v2.equals( v4 ) && !v4.equals( v2 ) && ( v2.compareTo( v4 ) > 0 ) && ( v4.compareTo( v2 ) < 0 ) );
}
private void testInterfaceCompare( String version )
{
final DefaultArtifactVersion dav = new DefaultArtifactVersion( version );
// create an anonymous instance to compare the big daddy to
ArtifactVersion av = new ArtifactVersion()
{
public int getMajorVersion()
{
return dav.getMajorVersion();
}
public int getMinorVersion()
{
return dav.getMinorVersion();
}
public int getIncrementalVersion()
{
return dav.getIncrementalVersion();
}
public int getBuildNumber()
{
return dav.getBuildNumber();
}
public String getQualifier()
{
return dav.getQualifier();
}
// required by interface but unused for our test
public int compareTo( Object o )
{
return 0; /* bogus */
}
public void parseVersion( String s )
{ /* bogus */
}
};
assertTrue( dav.equals( av ) );
assertTrue( dav.compareTo( av ) == 0 );
}
public void testInterfaceCompares()
{
testInterfaceCompare( "1" );
testInterfaceCompare( "1.2" );
testInterfaceCompare( "1.2.3" );
testInterfaceCompare( "1.2.3-4" );
testInterfaceCompare( "1.2.3-four" );
testInterfaceCompare( "1-2" );
testInterfaceCompare( "1-two" );
}
}