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 }