GlueGen v2.6.0-rc-20250722
GlueGen, Native Binding Generator for Java™ (public API).
VersionNumber.java
Go to the documentation of this file.
1/**
2 * Copyright 2010 JogAmp Community. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification, are
5 * permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
15 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
16 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * The views and conclusions contained in the software and documentation are those of the
25 * authors and should not be interpreted as representing official policies, either expressed
26 * or implied, of JogAmp Community.
27 */
28
29package com.jogamp.common.util;
30
31import java.util.regex.Matcher;
32
33/**
34 * Simple version number class containing a version number
35 * either being {@link #VersionNumber(int, int, int) defined explicit}
36 * or {@link #VersionNumber(String, String) derived from a string}.
37 * <p>
38 * For the latter case, you can query whether a component has been defined explicitly by the given <code>versionString</code>,
39 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
40 * </p>
41 * <p>
42 * The state whether a component is defined explicitly <i>is not considered</i>
43 * in the {@link #hashCode()}, {@link #equals(Object)} or {@link #compareTo(Object)} methods,
44 * since the version number itself is treated regardless.
45 * </p>
46 */
47public class VersionNumber implements Comparable<Object> {
48
49 /**
50 * A {@link #isZero() zero} version instance, w/o any component defined explicitly.
51 * @see #hasMajor()
52 * @see #hasMinor()
53 * @see #hasSub()
54 */
55 public static final VersionNumber zeroVersion = new VersionNumber(0, 0, 0, -1, (short)0);
56
57 /**
58 * Returns the {@link java.util.regex.Pattern pattern}
59 * with Perl regular expression:
60 * <pre>
61 * "\\D*(\\d+)[^\\"+delim+"\\s]*(?:\\"+delim+"\\D*(\\d+)[^\\"+delim+"\\s]*(?:\\"+delim+"\\D*(\\d+))?)?"
62 * </pre>
63 * </p>
64 * <p>
65 * A whitespace within the version number will end the parser.
66 * </p>
67 * <p>
68 * Capture groups represent the major (1), optional minor (2) and optional sub version number (3) component in this order.
69 * </p>
70 * <p>
71 * Each capture group ignores any leading non-digit and uses only contiguous digits, i.e. ignores pending non-digits.
72 * </p>
73 * @param delim the delimiter, e.g. "."
74 */
75 public static java.util.regex.Pattern getVersionNumberPattern(final String delim) {
76 return java.util.regex.Pattern.compile("\\D*(\\d+)[^\\"+delim+"\\s]*(?:\\"+delim+"\\D*(\\d+)[^\\"+delim+"\\s]*(?:\\"+delim+"\\D*(\\d+))?)?");
77 }
78
79 /**
80 * Returns the default {@link java.util.regex.Pattern pattern} using {@link #getVersionNumberPattern(String)}
81 * with delimiter "<b>.</b>".
82 * <p>
83 * Instance is cached.
84 * </p>
85 */
86 public static java.util.regex.Pattern getDefaultVersionNumberPattern() {
87 if( null == defPattern ) { // volatile dbl-checked-locking OK
88 synchronized( VersionNumber.class ) {
89 if( null == defPattern ) {
90 defPattern = getVersionNumberPattern(".");
91 }
92 }
93 }
94 return defPattern;
95 }
96 private static volatile java.util.regex.Pattern defPattern = null;
97
98 protected final int major, minor, sub, strEnd;
99
100 protected final short state;
101 protected final static short HAS_MAJOR = 1 << 0 ;
102 protected final static short HAS_MINOR = 1 << 1 ;
103 protected final static short HAS_SUB = 1 << 2 ;
104
105 protected VersionNumber(final int majorRev, final int minorRev, final int subMinorRev, final int _strEnd, final short _state) {
106 major = majorRev;
107 minor = minorRev;
108 sub = subMinorRev;
109 strEnd = _strEnd;
110 state = _state;
111 }
112
113 /**
114 * Explicit version number instantiation, with all components defined explicitly.
115 * @see #hasMajor()
116 * @see #hasMinor()
117 * @see #hasSub()
118 */
119 public VersionNumber(final int majorRev, final int minorRev, final int subMinorRev) {
120 this(majorRev, minorRev, subMinorRev, -1, (short)(HAS_MAJOR | HAS_MINOR | HAS_SUB));
121 }
122
123 /**
124 * Explicit version number instantiation, with major and minor components defined explicitly, no sub.
125 * @see #hasMajor()
126 * @see #hasMinor()
127 */
128 public VersionNumber(final int majorRev, final int minorRev) {
129 this(majorRev, minorRev, 0, -1, (short)(HAS_MAJOR | HAS_MINOR));
130 }
131
132 /**
133 * String derived version number instantiation.
134 * <p>
135 * Utilizing the default {@link java.util.regex.Pattern pattern} parser with delimiter "<b>.</b>", see {@link #getDefaultVersionNumberPattern()}.
136 * </p>
137 * <p>
138 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
139 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
140 * </p>
141 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
142 *
143 * @see #hasMajor()
144 * @see #hasMinor()
145 * @see #hasSub()
146 */
147 public VersionNumber(final String versionString) {
148 this(versionString, getDefaultVersionNumberPattern());
149 }
150
151 /**
152 * String derived version number instantiation.
153 * <p>
154 * Utilizing {@link java.util.regex.Pattern pattern} parser created via {@link #getVersionNumberPattern(String)}.
155 * </p>
156 * <p>
157 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
158 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
159 * </p>
160 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
161 * @param delim the delimiter, e.g. "."
162 *
163 * @see #hasMajor()
164 * @see #hasMinor()
165 * @see #hasSub()
166 */
167 public VersionNumber(final String versionString, final String delim) {
168 this(versionString, getVersionNumberPattern(delim));
169 }
170
171 /**
172 * String derived version number instantiation.
173 * <p>
174 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
175 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
176 * </p>
177 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
178 * @param versionPattern the {@link java.util.regex.Pattern pattern} parser, must be compatible w/ {@link #getVersionNumberPattern(String)}
179 *
180 * @see #hasMajor()
181 * @see #hasMinor()
182 * @see #hasSub()
183 */
184 public VersionNumber(final String versionString, final java.util.regex.Pattern versionPattern) {
185 // group1: \d* == digits major
186 // group2: \d* == digits minor
187 // group3: \d* == digits sub
188 final int[] val = new int[3];
189 int _strEnd = 0;
190 short _state = 0;
191 try {
192 final Matcher matcher = versionPattern.matcher( versionString );
193 if( matcher.lookingAt() ) {
194 _strEnd = matcher.end();
195 final int groupCount = matcher.groupCount();
196 if( 1 <= groupCount ) {
197 val[0] = Integer.parseInt(matcher.group(1));
198 _state = HAS_MAJOR;
199 if( 2 <= groupCount ) {
200 val[1] = Integer.parseInt(matcher.group(2));
201 _state |= HAS_MINOR;
202 if( 3 <= groupCount ) {
203 val[2] = Integer.parseInt(matcher.group(3));
204 _state |= HAS_SUB;
205 }
206 }
207 }
208 }
209 } catch (final Exception e) { }
210
211 major = val[0];
212 minor = val[1];
213 sub = val[2];
214 strEnd = _strEnd;
215 state = _state;
216 }
217
218 /** Returns <code>true</code>, if all version components are zero, otherwise <code>false</code>. */
219 public final boolean isZero() {
220 return major == 0 && minor == 0 && sub == 0;
221 }
222
223 /** Returns <code>true</code>, if the major component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
224 public final boolean hasMajor() { return 0 != ( HAS_MAJOR & state ); }
225 /** Returns <code>true</code>, if the optional minor component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
226 public final boolean hasMinor() { return 0 != ( HAS_MINOR & state ); }
227 /** Returns <code>true</code>, if the optional sub component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
228 public final boolean hasSub() { return 0 != ( HAS_SUB & state ); }
229
230 /**
231 * If constructed with <code>version-string</code>, returns the string offset <i>after</i> the last matching character,
232 * or <code>0</code> if none matched, or <code>-1</code> if not constructed with a string.
233 */
234 public final int endOfStringMatch() { return strEnd; }
235
236 @Override
237 public final int hashCode() {
238 // 31 * x == (x << 5) - x
239 int hash = 31 + major;
240 hash = ((hash << 5) - hash) + minor;
241 return ((hash << 5) - hash) + sub;
242 }
243
244 @Override
245 public final boolean equals(final Object o) {
246 if ( o instanceof VersionNumber ) {
247 return 0 == compareTo( (VersionNumber) o );
248 }
249 return false;
250 }
251
252 @Override
253 public final int compareTo(final Object o) {
254 if ( ! ( o instanceof VersionNumber ) ) {
255 final Class<?> c = (null != o) ? o.getClass() : null ;
256 throw new ClassCastException("Not a VersionNumber object: " + c);
257 }
258 return compareTo( (VersionNumber) o );
259 }
260
261 public final int compareTo(final VersionNumber vo) {
262 if (major > vo.major) {
263 return 1;
264 } else if (major < vo.major) {
265 return -1;
266 } else if (minor > vo.minor) {
267 return 1;
268 } else if (minor < vo.minor) {
269 return -1;
270 } else if (sub > vo.sub) {
271 return 1;
272 } else if (sub < vo.sub) {
273 return -1;
274 }
275 return 0;
276 }
277
278 public final int getMajor() {
279 return major;
280 }
281
282 public final int getMinor() {
283 return minor;
284 }
285
286 public final int getSub() {
287 return sub;
288 }
289
290 @Override
291 public String toString() {
292 if( hasSub() ) {
293 return major + "." + minor + "." + sub ;
294 } else if( hasMinor() ) {
295 return major + "." + minor ;
296 } else {
297 return Integer.toString(major);
298 }
299 }
300}
Simple version number class containing a version number either being defined explicit or derived from...
VersionNumber(final String versionString, final java.util.regex.Pattern versionPattern)
String derived version number instantiation.
static java.util.regex.Pattern getVersionNumberPattern(final String delim)
Returns the pattern with Perl regular expression:
final boolean isZero()
Returns true, if all version components are zero, otherwise false.
final int compareTo(final Object o)
static java.util.regex.Pattern getDefaultVersionNumberPattern()
Returns the default pattern using getVersionNumberPattern(String) with delimiter "<b>....
VersionNumber(final String versionString, final String delim)
String derived version number instantiation.
final int compareTo(final VersionNumber vo)
VersionNumber(final int majorRev, final int minorRev, final int subMinorRev)
Explicit version number instantiation, with all components defined explicitly.
static final VersionNumber zeroVersion
A zero version instance, w/o any component defined explicitly.
VersionNumber(final int majorRev, final int minorRev, final int subMinorRev, final int _strEnd, final short _state)
final boolean hasSub()
Returns true, if the optional sub component is defined explicitly, otherwise false.
VersionNumber(final String versionString)
String derived version number instantiation.
VersionNumber(final int majorRev, final int minorRev)
Explicit version number instantiation, with major and minor components defined explicitly,...
final boolean hasMajor()
Returns true, if the major component is defined explicitly, otherwise false.
final boolean hasMinor()
Returns true, if the optional minor component is defined explicitly, otherwise false.
final boolean equals(final Object o)
final int endOfStringMatch()
If constructed with version-string, returns the string offset after the last matching character,...