| Version.java |
1 /**
2 * Distribution License:
3 * JSword is free software; you can redistribute it and/or modify it under
4 * the terms of the GNU Lesser General Public License, version 2.1 as published by
5 * the Free Software Foundation. This program is distributed in the hope
6 * that it will be useful, but WITHOUT ANY WARRANTY; without even the
7 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
8 * See the GNU Lesser General Public License for more details.
9 *
10 * The License is available on the internet at:
11 * http://www.gnu.org/copyleft/lgpl.html
12 * or by writing to:
13 * Free Software Foundation, Inc.
14 * 59 Temple Place - Suite 330
15 * Boston, MA 02111-1307, USA
16 *
17 * Copyright: 2011
18 * The copyright to this program is held by it's authors.
19 *
20 * ID: $Id: Version.java 2238 2012-03-29 13:35:27Z dmsmith $
21 */
22 package org.crosswire.common.util;
23
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 /**
28 * Version is an immutable representation of dotted "number" consisting of 1 to 4 parts.
29 *
30 * <p>
31 * Here is the grammar for version strings:
32 *
33 * <pre>
34 * version ::= major('.'minor('.'micro('.'nano)?)?)?
35 * major ::= [0-9]+
36 * minor ::= [0-9]+
37 * micro ::= [0-9]+
38 * nano ::= [0-9]+
39 * </pre>
40 *
41 * @see gnu.lgpl.License for license details.<br>
42 * The copyright to this program is held by it's authors.
43 * @author DM Smith [dmsmith555 at yahoo dot com]
44 */
45 public class Version implements Comparable<Version> {
46
47 /**
48 * The default version "1.0".
49 */
50 public static final Version DEFAULT_VERSION = new Version("1.0");
51
52 /**
53 * Created a version identifier from the specified string.
54 *
55 * @param version String representation of the version identifier.
56 * @throws IllegalArgumentException If <code>version</code> is improperly
57 * formatted.
58 */
59 public Version(String version) {
60 if (version == null) {
61 throw new IllegalArgumentException("Null version not allowed.");
62 }
63 this.original = version;
64 this.parts = new int[] { -1, -1, -1, -1 };
65 Pattern regexp = Pattern.compile("^(\\d+)(?:.(\\d+))?(?:.(\\d+))?(?:.(\\d+))?$");
66 Matcher matcher = regexp.matcher(this.original);
67 if (matcher.matches()) {
68 int count = matcher.groupCount();
69 for (int i = 1; i <= count; i++) {
70 String part = matcher.group(i);
71 if (part == null) {
72 break;
73 }
74 parts[i - 1] = Integer.parseInt(part);
75 }
76 } else {
77 throw new IllegalArgumentException("invalid: " + version);
78 }
79 }
80
81 /**
82 * Returns the original string representation of this version identifier.
83 *
84 * @return The original string representation of this version identifier.
85 */
86 @Override
87 public String toString() {
88 return original;
89 }
90
91 @Override
92 public int hashCode() {
93 return original.hashCode();
94 }
95
96 /**
97 * Compares this <code>Version object to another object.
98 *
99 * <p>
100 * A version is considered to be equal to another version if all the
101 * parts are equal.
102 *
103 * @param object The <code>Version</code> object to be compared.
104 * @return true if the two objects are equal.
105 */
106 @Override
107 public boolean equals(Object object) {
108 if (!(object instanceof Version)) {
109 return false;
110 }
111
112 Version that = (Version) object;
113 if (that == this) {
114 return true;
115 }
116
117 for (int i = 0; i < parts.length; i++) {
118 if (parts[i] != that.parts[i]) {
119 return false;
120 }
121 }
122
123 return true;
124 }
125
126 /**
127 * Compares this <code>Version</code> object to another object.
128 *
129 * <p>
130 * The comparison considers each of the parts (major, minor, micro, nano) in turn,
131 * comparing like with like. At any point the comparison is not equal, a result is
132 * known.
133 * </p>
134 *
135 * @param object The <code>Version</code> object to be compared.
136 * @return A negative integer, zero, or a positive integer if this object is
137 * less than, equal to, or greater than the specified
138 * <code>Version</code> object.
139 * @throws ClassCastException If the specified object is not a <code>Version</code>.
140 */
141 public int compareTo(Version object) {
142 if (object == this) {
143 return 0;
144 }
145
146 for (int i = 0; i < parts.length; i++) {
147 int result = parts[i] - object.parts[i];
148 if (result != 0) {
149 return result;
150 }
151 }
152
153 return 0;
154 }
155
156 private final String original;
157 private final int[] parts;
158
159 }
160