1 package net.sourceforge.simplegamenet.specs.to; 2 3 import java.io.Serializable; 4 5 /*** 6 * A version to check if a client and server are using compatible SimpleGameNet framework and game 7 * module packages. A version consists out of one or several levels of <code>int</code> values, each 8 * considered more important then the next. 9 * 10 * @author Geoffrey De Smet 11 * @version 1.0, 2003-06-18 12 * @see net.sourceforge.simplegamenet.specs.model.GameFactory 13 */ 14 public class Version implements Comparable, Serializable { 15 16 private int[] levelValues; 17 18 /*** 19 * Initializes a newly created <code>Version</code> object with 1 level. It is recommended not 20 * to use this constructor, but to use at least 2 levels to define a version instead. 21 * 22 * @param level0Value the value of the only level 23 */ 24 public Version(int level0Value) { 25 levelValues = new int[1]; 26 levelValues[0] = level0Value; 27 } 28 29 /*** 30 * Initializes a newly created <code>Version</code> object with 2 levels. 31 * 32 * @param level0Value the value of the first and most important level 33 * @param level1Value the value of the second and least important level 34 */ 35 public Version(int level0Value, int level1Value) { 36 levelValues = new int[2]; 37 levelValues[0] = level0Value; 38 levelValues[1] = level1Value; 39 } 40 41 /*** 42 * Initializes a newly created <code>Version</code> object with 3 levels. 43 * 44 * @param level0Value the value of the first and most important level 45 * @param level1Value the value of the second level 46 * @param level2Value the value of the third level 47 */ 48 public Version(int level0Value, int level1Value, int level2Value) { 49 levelValues = new int[3]; 50 levelValues[0] = level0Value; 51 levelValues[1] = level1Value; 52 levelValues[2] = level2Value; 53 } 54 55 /*** 56 * Initializes a newly created <code>Version</code> object with a variable amount of levels. 57 * 58 * @param levelValues the values of each level, starting with the most important level first 59 */ 60 public Version(int[] levelValues) { 61 if (levelValues == null || levelValues.length == 0) { 62 levelValues = new int[1]; 63 levelValues[0] = 0; 64 } 65 this.levelValues = levelValues; 66 } 67 68 /*** 69 * Compares this version to the specified object. The result is <code>true</code> if and only if 70 * the argument is not <code>null</code> and is a version that represents the same sequence of 71 * values as this version. 72 * <p/> 73 * Versions with a different amount of levels are compared to the same amount of levels by 74 * padding <code>0</code> values to the version with less levels. For example: 1.3, 1.3.0 and 75 * 1.3.0.0 are considered to be equal, while 1.4 and 1.4.1 are considered to be unequal. 76 * 77 * @param object the object to compare this version against 78 * @return <code>true</code> if the versions are equal 79 */ 80 public boolean equals(Object object) { 81 if (object == null || !(object instanceof Version)) { 82 return false; 83 } 84 Version version = (Version) object; 85 for (int i = 0; i < levelValues.length && i < version.levelValues.length; i++) { 86 if (levelValues[i] != version.levelValues[i]) { 87 return false; 88 } 89 } 90 if (levelValues.length < version.levelValues.length) { 91 for (int i = levelValues.length; i < version.levelValues.length; i++) { 92 if (version.levelValues[i] != 0) { 93 return false; 94 } 95 } 96 } else if (version.levelValues.length < levelValues.length) { 97 for (int i = version.levelValues.length; i < levelValues.length; i++) { 98 if (levelValues[i] != 0) { 99 return false; 100 } 101 } 102 } 103 return true; 104 } 105 106 /*** 107 * Compares two versions by comparing their level values, beginning from the highest level. For 108 * example: 1.8.12 will be considered older then 2.0.0. 109 * <p/> 110 * Versions with a different amount of levels are compared to the same amount of levels by 111 * padding <code>0</code> values to the version with less levels. For example: 1.3 compared to 112 * 1.3.0 will be considered equal, while 1.4 compared to 1.4.1 will be considered older. 113 * 114 * @param object the object to compare this version against 115 * @return the value <code>0</code> if the argument version is equal to this version, a value 116 * less than <code>0</code> if this version is older than the argument and a value 117 * greater than <code>0</code> if this version is newer than the argument. 118 */ 119 public int compareTo(Object object) { 120 if (object == null || !(object instanceof Version)) { 121 return -1; 122 } 123 Version version = (Version) object; 124 for (int i = 0; i < levelValues.length && i < version.levelValues.length; i++) { 125 if (levelValues[i] < version.levelValues[i]) { 126 return -1; 127 } else if (levelValues[i] > version.levelValues[i]) { 128 return 1; 129 } 130 } 131 if (levelValues.length < version.levelValues.length) { 132 for (int i = levelValues.length; i < version.levelValues.length; i++) { 133 if (version.levelValues[i] > 0) { 134 return -1; 135 } else if (version.levelValues[i] < 0) { 136 return 1; 137 } 138 } 139 } else if (version.levelValues.length < levelValues.length) { 140 for (int i = version.levelValues.length; i < levelValues.length; i++) { 141 if (levelValues[i] < 0) { 142 return -1; 143 } else if (levelValues[i] > 0) { 144 return 1; 145 } 146 } 147 } 148 return 0; 149 } 150 151 /*** 152 * Returns the string representation of this Version. The string is composed by appending each 153 * level and padding a "." between 2 levels. 154 * 155 * @return the string representation of this Version 156 */ 157 public String toString() { 158 StringBuffer stringBuffer = new StringBuffer((levelValues.length * 2) - 1); 159 for (int i = 0; i < levelValues.length; i++) { 160 stringBuffer.append(levelValues[i]); 161 if (i < levelValues.length - 1) { 162 stringBuffer.append('.'); 163 } 164 } 165 return stringBuffer.toString(); 166 } 167 168 }