1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.geronimo.kernel.repository;
17
18 import java.util.StringTokenizer;
19 import java.io.Serializable;
20
21 /**
22 * Default implementation of artifact versioning.
23 *
24 * @author <a href="mailto:brett@apache.org">Brett Porter</a>
25 * @version $Id: Version.java 410741 2006-06-01 04:35:48Z jsisson $
26 */
27
28 public class Version implements Comparable, Serializable {
29
30 private static final long serialVersionUID = 7941704456058067109L;
31
32 private Integer majorVersion;
33
34 private Integer minorVersion;
35
36 private Integer incrementalVersion;
37
38 private Integer buildNumber;
39
40 private String qualifier;
41
42 public Version(String version) {
43 parseVersion(version);
44 }
45
46 public int compareTo(Object o) {
47 Version otherVersion = (Version) o;
48
49 int result = compareIntegers(majorVersion, otherVersion.majorVersion);
50 if (result == 0) {
51 result = compareIntegers(minorVersion, otherVersion.minorVersion);
52 }
53 if (result == 0) {
54 result = compareIntegers(incrementalVersion, otherVersion.incrementalVersion);
55 }
56 if (result == 0) {
57 if (buildNumber != null || otherVersion.buildNumber != null) {
58 result = compareIntegers(buildNumber, otherVersion.buildNumber);
59 } else if (qualifier != null) {
60 if (otherVersion.qualifier != null) {
61 if (qualifier.length() > otherVersion.qualifier.length() &&
62 qualifier.startsWith(otherVersion.qualifier)) {
63
64 result = -1;
65 } else if (qualifier.length() < otherVersion.qualifier.length() &&
66 otherVersion.qualifier.startsWith(qualifier)) {
67
68 result = 1;
69 } else {
70 result = qualifier.compareTo(otherVersion.qualifier);
71 }
72 } else {
73
74 result = -1;
75 }
76 } else if (otherVersion.qualifier != null) {
77
78 result = 1;
79 }
80 }
81 return result;
82 }
83
84 private int compareIntegers(Integer i1, Integer i2) {
85
86 if (i1 == null ? i2 == null : i1.equals(i2)) {
87 return 0;
88 } else if (i1 == null) {
89 return -i2.intValue();
90 } else if (i2 == null) {
91 return i1.intValue();
92 } else {
93 return i1.intValue() - i2.intValue();
94 }
95 }
96
97 public int getMajorVersion() {
98 return majorVersion != null ? majorVersion.intValue() : 0;
99 }
100
101 public int getMinorVersion() {
102 return minorVersion != null ? minorVersion.intValue() : 0;
103 }
104
105 public int getIncrementalVersion() {
106 return incrementalVersion != null ? incrementalVersion.intValue() : 0;
107 }
108
109 public int getBuildNumber() {
110 return buildNumber != null ? buildNumber.intValue() : 0;
111 }
112
113 public String getQualifier() {
114 return qualifier;
115 }
116
117 public final void parseVersion(String version) {
118 int index = version.indexOf("-");
119
120 String part1;
121 String part2 = null;
122
123 if (index < 0) {
124 part1 = version;
125 } else {
126 part1 = version.substring(0, index);
127 part2 = version.substring(index + 1);
128 }
129
130 if (part2 != null) {
131 try {
132 if (part2.length() == 1 || !part2.startsWith("0")) {
133 buildNumber = Integer.valueOf(part2);
134 } else {
135 qualifier = part2;
136 }
137 }
138 catch (NumberFormatException e) {
139 qualifier = part2;
140 }
141 }
142
143 if (part1.indexOf(".") < 0 && !part1.startsWith("0")) {
144 try {
145 majorVersion = Integer.valueOf(part1);
146 }
147 catch (NumberFormatException e) {
148
149 qualifier = version;
150 buildNumber = null;
151 }
152 } else {
153 boolean fallback = false;
154 StringTokenizer tok = new StringTokenizer(part1, ".");
155 try {
156 majorVersion = getNextIntegerToken(tok);
157 if (tok.hasMoreTokens()) {
158 minorVersion = getNextIntegerToken(tok);
159 }
160 if (tok.hasMoreTokens()) {
161 incrementalVersion = getNextIntegerToken(tok);
162 }
163 if (tok.hasMoreTokens()) {
164 fallback = true;
165 }
166 }
167 catch (NumberFormatException e) {
168 fallback = true;
169 }
170
171 if (fallback) {
172
173 qualifier = version;
174 majorVersion = null;
175 minorVersion = null;
176 incrementalVersion = null;
177 }
178 }
179 }
180
181 private static Integer getNextIntegerToken(StringTokenizer tok) {
182 String s = tok.nextToken();
183 if (s.length() > 1 && s.startsWith("0")) {
184 throw new NumberFormatException("Number part has a leading 0: '" + s + "'");
185 }
186 return Integer.valueOf(s);
187 }
188
189 public String toString() {
190 StringBuffer buf = new StringBuffer();
191 if (majorVersion != null) {
192 buf.append(majorVersion);
193 }
194 if (minorVersion != null) {
195 buf.append(".");
196 buf.append(minorVersion);
197 }
198 if (incrementalVersion != null) {
199 buf.append(".");
200 buf.append(incrementalVersion);
201 }
202 if (buildNumber != null) {
203 buf.append("-");
204 buf.append(buildNumber);
205 } else if (qualifier != null) {
206 if (buf.length() > 0) {
207 buf.append("-");
208 }
209 buf.append(qualifier);
210 }
211 return buf.toString();
212 }
213
214 public boolean equals(Object other) {
215 if (this == other) {
216 return true;
217 }
218 if (other == null || this.getClass() != other.getClass()) {
219 return false;
220 }
221 Version v = (Version) other;
222 if (majorVersion == null? v.majorVersion != null: !majorVersion.equals(v.majorVersion)) {
223 return false;
224 }
225 if (minorVersion == null? v.minorVersion != null: !minorVersion.equals(v.minorVersion)) {
226 return false;
227 }
228 if (incrementalVersion == null? v.incrementalVersion != null: !incrementalVersion.equals(v.incrementalVersion)) {
229 return false;
230 }
231 if (buildNumber == null? v.buildNumber != null: !buildNumber.equals(v.buildNumber)) {
232 return false;
233 }
234 return qualifier == null ? v.qualifier == null : qualifier.equals(v.qualifier);
235 }
236
237 public int hashCode() {
238 int hashCode = 0;
239 if (majorVersion != null) {
240 hashCode = majorVersion.intValue();
241 }
242 if (minorVersion != null) {
243 hashCode = 37 * hashCode + minorVersion.intValue();
244 }
245 if (incrementalVersion != null) {
246 hashCode = 37 * hashCode + incrementalVersion.intValue();
247 }
248 if (buildNumber != null) {
249 hashCode = 37 * hashCode + buildNumber.intValue();
250 }
251 if (qualifier != null) {
252 hashCode = 37 * hashCode + qualifier.hashCode();
253 }
254 return hashCode;
255 }
256 }