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 }