From 06df973c54eb1ff10c18edf0311c6b3ea76514fe Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 17 Oct 2013 10:29:33 +0200 Subject: [PATCH] DATACMNS-384 - Introduced value object for Version. --- .../springframework/data/util/Version.java | 181 ++++++++++++++++++ .../data/util/VersionUnitTests.java | 114 +++++++++++ 2 files changed, 295 insertions(+) create mode 100644 src/main/java/org/springframework/data/util/Version.java create mode 100644 src/test/java/org/springframework/data/util/VersionUnitTests.java diff --git a/src/main/java/org/springframework/data/util/Version.java b/src/main/java/org/springframework/data/util/Version.java new file mode 100644 index 000000000..ac81cc20c --- /dev/null +++ b/src/main/java/org/springframework/data/util/Version.java @@ -0,0 +1,181 @@ +package org.springframework.data.util; + +import org.springframework.util.Assert; + +/** + * Value object to represent a Version consisting of major, minor and bugfix part. + * + * @author Oliver Gierke + */ +public class Version implements Comparable { + + private final int major; + private final int minor; + private final int bugfix; + private final int build; + + /** + * Creates a new {@link Version} from the given integer values. At least one value has to be given but a maximum of 4. + * + * @param parts must not be {@literal null} or empty. + */ + public Version(int... parts) { + + Assert.notNull(parts); + Assert.isTrue(parts.length > 0 && parts.length < 5); + + this.major = parts[0]; + this.minor = parts.length > 1 ? parts[1] : 0; + this.bugfix = parts.length > 2 ? parts[2] : 0; + this.build = parts.length > 3 ? parts[3] : 0; + + Assert.isTrue(major >= 0, "Major version must be greater or equal zero!"); + Assert.isTrue(minor >= 0, "Minor version must be greater or equal zero!"); + Assert.isTrue(bugfix >= 0, "Bugfix version must be greater or equal zero!"); + Assert.isTrue(build >= 0, "Build version must be greater or equal zero!"); + } + + /** + * Parses the given string representation of a version into a {@link Version} object. + * + * @param version must not be {@literal null} or empty. + * @return + */ + public static Version parse(String version) { + + Assert.hasText(version); + + String[] parts = version.trim().split("\\."); + int[] intParts = new int[parts.length]; + + for (int i = 0; i < parts.length; i++) { + intParts[i] = Integer.parseInt(parts[i]); + } + + return new Version(intParts); + } + + /** + * Returns whether the current {@link Version} is greater (newer) than the given one. + * + * @param version + * @return + */ + public boolean isGreaterThan(Version version) { + return compareTo(version) > 0; + } + + /** + * Returns whether the current {@link Version} is greater (newer) or the same as the given one. + * + * @param version + * @return + */ + public boolean isGreaterThanOrEqualTo(Version version) { + return compareTo(version) >= 0; + } + + /** + * Returns whether the current {@link Version} is the same as the given one. + * + * @param version + * @return + */ + public boolean is(Version version) { + return equals(version); + } + + /** + * Returns whether the current {@link Version} is less (older) than the given one. + * + * @param version + * @return + */ + public boolean isLessThan(Version version) { + return compareTo(version) < 0; + } + + /** + * Returns whether the current {@link Version} is less (older) or equal to the current one. + * + * @param version + * @return + */ + public boolean isLessThanOrEqualTo(Version version) { + return compareTo(version) <= 0; + } + + /* + * (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(Version that) { + + if (that == null) { + return 1; + } + + if (major != that.major) { + return major - that.major; + } + + if (minor != that.minor) { + return minor - that.minor; + } + + if (bugfix != that.bugfix) { + return bugfix - that.bugfix; + } + + if (build != that.build) { + return build - that.build; + } + + return 0; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + + if (this == obj) { + return true; + } + + if (!(obj instanceof Version)) { + return false; + } + + Version that = (Version) obj; + + return this.major == that.major && this.minor == that.minor && this.bugfix == that.bugfix + && this.build == that.build; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + + int result = 17; + result += 31 * major; + result += 31 * minor; + result += 31 * bugfix; + result += 31 * build; + return result; + } + + /* + * (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() { + return String.format("%d.%d.%d.%d", major, minor, bugfix, build); + } +} diff --git a/src/test/java/org/springframework/data/util/VersionUnitTests.java b/src/test/java/org/springframework/data/util/VersionUnitTests.java new file mode 100644 index 000000000..e9e052577 --- /dev/null +++ b/src/test/java/org/springframework/data/util/VersionUnitTests.java @@ -0,0 +1,114 @@ +package org.springframework.data.util; + +import static org.hamcrest.Matchers.*; +import static org.junit.Assert.*; + +import org.junit.Test; + +/** + * Unit tests for {@link Version}. + * + * @author Oliver Gierke + */ +public class VersionUnitTests { + + @Test + public void sameVersionsEqualOneDigits() { + + Version first = new Version(6); + Version second = new Version(6); + + assertThat(first, is(second)); + assertThat(second, is(first)); + } + + @Test + public void sameVersionsEqualTwoDigits() { + + Version first = new Version(5, 2); + Version second = new Version(5, 2); + + assertThat(first, is(second)); + assertThat(second, is(first)); + } + + @Test + public void sameVersionsEqualThreeDigits() { + + Version first = new Version(1, 2, 3); + Version second = new Version(1, 2, 3); + + assertThat(first, is(second)); + assertThat(second, is(first)); + } + + @Test + public void sameVersionsEqualFourDigits() { + + Version first = new Version(1, 2, 3, 1000); + Version second = new Version(1, 2, 3, 1000); + + assertThat(first, is(second)); + assertThat(second, is(first)); + } + + @Test + public void parsesVersionCorrectlyOneDigits() { + + Version version = Version.parse("5"); + assertThat(version, is(new Version(5))); + } + + @Test + public void parsesVersionCorrectlyTwoDigits() { + + Version version = Version.parse("5.2"); + assertThat(version, is(new Version(5, 2))); + } + + @Test + public void parsesVersionCorrectlyThreeDigits() { + + Version version = Version.parse("12.1.3"); + assertThat(version, is(new Version(12, 1, 3))); + } + + @Test + public void parsesVersionCorrectlyFourDigits() { + + Version version = Version.parse("12.1.3.1000"); + assertThat(version, is(new Version(12, 1, 3, 1000))); + } + + @Test + public void comparesToCorrectly() { + + Version version = new Version(1, 2, 3, 1000); + Version nextBuild = new Version(1, 2, 3, 1001); + Version nextBugfix = new Version(1, 2, 4); + Version nextMinor = new Version(1, 3); + Version nextMajor = new Version(2); + + assertThat(nextMajor.isGreaterThan(nextMinor), is(true)); + assertThat(nextMajor.isGreaterThan(nextMajor), is(false)); + assertThat(nextMajor.is(nextMajor), is(true)); + assertThat(nextMinor.isLessThan(nextMajor), is(true)); + assertThat(nextMinor.isLessThan(nextMinor), is(false)); + + assertThat(nextMajor.compareTo(nextMajor), is(0)); + assertThat(nextMinor.compareTo(nextMinor), is(0)); + assertThat(nextBugfix.compareTo(nextBugfix), is(0)); + assertThat(nextBuild.compareTo(nextBuild), is(0)); + + assertThat(version.compareTo(nextMajor), is(lessThan(0))); + assertThat(version.compareTo(nextMinor), is(lessThan(0))); + assertThat(version.compareTo(nextBugfix), is(lessThan(0))); + assertThat(version.compareTo(nextBuild), is(lessThan(0))); + + assertThat(version.compareTo(null), is(greaterThan(0))); + assertThat(nextMajor.compareTo(version), is(greaterThan(0))); + assertThat(nextMinor.compareTo(version), is(greaterThan(0))); + assertThat(nextBugfix.compareTo(version), is(greaterThan(0))); + assertThat(nextBuild.compareTo(version), is(greaterThan(0))); + } +}