Index: src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java =================================================================== --- src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java (revision 546205) +++ src/test/java/org/apache/maven/artifact/versioning/DefaultArtifactVersionTest.java (working copy) @@ -247,4 +247,103 @@ // version = new DefaultArtifactVersion( "1.1-foo-10" ); // assertTrue( version.compareTo( new DefaultArtifactVersion( "1.1-foo-2" ) ) > 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"); + } } Index: src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java =================================================================== --- src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java (revision 546205) +++ src/main/java/org/apache/maven/artifact/versioning/ArtifactVersion.java (working copy) @@ -40,4 +40,7 @@ String getQualifier(); void parseVersion( String version ); + + boolean equals(Object obj); + int hashCode(); } Index: src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java =================================================================== --- src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java (revision 546205) +++ src/main/java/org/apache/maven/artifact/versioning/DefaultArtifactVersion.java (working copy) @@ -39,6 +39,8 @@ private Integer buildNumber; private String qualifier; + + private String unparsed; public DefaultArtifactVersion( String version ) { @@ -47,78 +49,96 @@ public int compareTo( Object o ) { - DefaultArtifactVersion otherVersion = (DefaultArtifactVersion) o; + ArtifactVersion otherVersion = (ArtifactVersion) o; - int result = compareIntegers( majorVersion, otherVersion.majorVersion ); + // compare all the integers in order, starting with major + int result = getMajorVersion() - otherVersion.getMajorVersion(); + if ( result == 0 ) { - result = compareIntegers( minorVersion, otherVersion.minorVersion ); + // majors are equal, check minors + result = getMinorVersion() - otherVersion.getMinorVersion(); } + if ( result == 0 ) { - result = compareIntegers( incrementalVersion, otherVersion.incrementalVersion ); + // minors are equal, check incrementals + result = getIncrementalVersion() - otherVersion.getIncrementalVersion(); } + if ( result == 0 ) { - if ( buildNumber != null || otherVersion.buildNumber != null ) + if ( getQualifier() != null ) { - result = compareIntegers( buildNumber, otherVersion.buildNumber ); - } - else if ( qualifier != null ) - { - if ( otherVersion.qualifier != null ) + if ( otherVersion.getQualifier() != null ) { - if ( qualifier.length() > otherVersion.qualifier.length() && - qualifier.startsWith( otherVersion.qualifier ) ) + if ( getQualifier().length() > otherVersion.getQualifier().length() && + getQualifier().startsWith( otherVersion.getQualifier() ) ) { // 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 ( getQualifier().length() < otherVersion.getQualifier().length() && + otherVersion.getQualifier().startsWith( getQualifier() ) ) { // here, the longer one that otherwise match is considered older result = 1; } else { - result = qualifier.compareTo( otherVersion.qualifier ); + result = getQualifier().compareTo( otherVersion.getQualifier() ); } } else { - // otherVersion has no qualifier but we do - that's newer + // otherVersion has no getQualifier() but we do - that's newer 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 + { + // neither has qualifiers, compare build numbers + result = getBuildNumber() - otherVersion.getBuildNumber(); + } } + return result; } - - private int compareIntegers( Integer i1, Integer i2 ) + + public boolean equals(Object obj) { - // treat null as 0 in comparison - if ( i1 == null ? i2 == null : i1.equals( i2 ) ) + if (this == obj) { - return 0; + return true; } - else if ( i1 == null ) + + if (false == obj instanceof ArtifactVersion) { - return -i2.intValue(); + return false; } - else if ( i2 == null ) + + return 0 == compareTo(obj); + } + + 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()) { - return i1.intValue(); + result = 1223 * result + getQualifier().hashCode(); } - else - { - return i1.intValue() - i2.intValue(); - } + + return result; } public int getMajorVersion() @@ -148,6 +168,8 @@ public final void parseVersion( String version ) { + unparsed = version; + int index = version.indexOf( "-" ); String part1; @@ -244,34 +266,6 @@ public String toString() { - StringBuffer buf = new StringBuffer(); - if ( majorVersion != null ) - { - buf.append( majorVersion ); - } - if ( minorVersion != null ) - { - buf.append( "." ); - buf.append( minorVersion ); - } - if ( incrementalVersion != null ) - { - buf.append( "." ); - buf.append( incrementalVersion ); - } - 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 unparsed; } }