001 /*--------------------------------------------------------------------------+
002 $Id: Version.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.version;
019
020 import java.io.Serializable;
021 import java.util.regex.Matcher;
022 import java.util.regex.Pattern;
023
024 import edu.tum.cs.commons.error.FormatException;
025
026 /**
027 * A class to describe versions of software (or other) artifacts. A version has
028 * a major and a minor version number. Version are ordered. This class is
029 * immutable.
030 *
031 * @author Florian Deissenboeck
032 * @author $Author: juergens $
033 * @version $Rev: 26283 $
034 * @levd.rating GREEN Hash: 9B19160CC477DC98C73F68A0DCD4C759
035 */
036 public class Version implements Comparable<Version>, Serializable {
037
038 /** Major version. */
039 private final int major;
040
041 /** Minor version. */
042 private final int minor;
043
044 /**
045 * Create a new version.
046 *
047 * @param major
048 * major version number.
049 * @param minor
050 * minor version number.
051 * @throws IllegalArgumentException
052 * if one of the version numbers is less than 0.
053 */
054 public Version(int major, int minor) {
055
056 if (major < 0 || minor < 0) {
057 throw new IllegalArgumentException(
058 "Versions may not be less than 0.");
059 }
060
061 this.major = major;
062 this.minor = minor;
063 }
064
065 /**
066 * Parses a version from a string. The format has to be "major.minor".
067 *
068 * @throws FormatException
069 * if the string does not follow the expected pattern.
070 */
071 public static Version parseVersion(String s) throws FormatException {
072 Matcher m = Pattern.compile("\\s*(\\d+)\\.(\\d+)\\s*").matcher(s);
073 if (!m.matches()) {
074 throw new FormatException(
075 "The provided string did not match the pattern!");
076 }
077 return new Version(Integer.parseInt(m.group(1)), Integer.parseInt(m
078 .group(2)));
079 }
080
081 /**
082 * Compares to version numbers by their major and minor numbers.
083 */
084 public int compareTo(Version other) {
085 if (major > other.major) {
086 return 1;
087 }
088 if (major < other.major) {
089 return -1;
090 }
091
092 // major numbers are equal
093 if (minor > other.minor) {
094 return 1;
095 }
096
097 if (minor < other.minor) {
098 return -1;
099 }
100
101 // both are equal
102 return 0;
103 }
104
105 /**
106 * Two version are equal if their major and minor version numbers are equal.
107 */
108 @Override
109 public boolean equals(Object other) {
110 if (other == this) {
111 return true;
112 }
113
114 if (!(other instanceof Version)) {
115 return false;
116 }
117
118 return compareTo((Version) other) == 0;
119
120 }
121
122 /** Get major version number. */
123 public int getMajor() {
124 return major;
125 }
126
127 /** Get minor version number. */
128 public int getMinor() {
129 return minor;
130 }
131
132 /**
133 * Hashcode is (major << 7) | minor;
134 */
135 @Override
136 public int hashCode() {
137 return (major << 7) | minor;
138 }
139
140 /**
141 * This method is used to check version compatibility in dependency
142 * management.
143 * <p>
144 * Consider the following situation and artefact A (the depender) depends on
145 * another artefact B (the dependee). A claims that it requires B in version
146 * 1.3. B states that it has version 1.5 but is downward compatible to
147 * version 1.1.
148 * <p>
149 * Using this method one can find out if the version provided by B satisfies
150 * A's requirement. It is satisfied iff
151 *
152 * <pre>
153 * requiredVersion <= currentVersion && requiredVersion >= compatibleVersion
154 * </pre>
155 *
156 * where <code>requiredVersion</code> is this instance and the other two
157 * are provided as method parameters.
158 *
159 * @throws IllegalArgumentException
160 * if <code>compatibleVersion</code> is greater than
161 * <code>currentVersion</code>.
162 */
163 public boolean isSatisfied(Version currentVersion, Version compatibleVersion) {
164
165 if (compatibleVersion.compareTo(currentVersion) > 0) {
166 throw new IllegalArgumentException(
167 "Compatible version greater than current version.");
168 }
169
170 return this.compareTo(currentVersion) <= 0
171 && this.compareTo(compatibleVersion) >= 0;
172 }
173
174 /**
175 * String representation: major.minor
176 */
177 @Override
178 public String toString() {
179 return major + "." + minor;
180 }
181
182 }