GlueGen v2.6.0-rc-20250712
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 * String derived version number instantiation.
125 * <p>
126 * Utilizing the default {@link java.util.regex.Pattern pattern} parser with delimiter "<b>.</b>", see {@link #getDefaultVersionNumberPattern()}.
127 * </p>
128 * <p>
129 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
130 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
131 * </p>
132 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
133 *
134 * @see #hasMajor()
135 * @see #hasMinor()
136 * @see #hasSub()
137 */
138 public VersionNumber(final String versionString) {
139 this(versionString, getDefaultVersionNumberPattern());
140 }
141
142 /**
143 * String derived version number instantiation.
144 * <p>
145 * Utilizing {@link java.util.regex.Pattern pattern} parser created via {@link #getVersionNumberPattern(String)}.
146 * </p>
147 * <p>
148 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
149 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
150 * </p>
151 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
152 * @param delim the delimiter, e.g. "."
153 *
154 * @see #hasMajor()
155 * @see #hasMinor()
156 * @see #hasSub()
157 */
158 public VersionNumber(final String versionString, final String delim) {
159 this(versionString, getVersionNumberPattern(delim));
160 }
161
162 /**
163 * String derived version number instantiation.
164 * <p>
165 * You can query whether a component has been defined explicitly by the given <code>versionString</code>,
166 * via {@link #hasMajor()}, {@link #hasMinor()} and {@link #hasSub()}.
167 * </p>
168 * @param versionString should be given as [MAJOR[.MINOR[.SUB]]]
169 * @param versionPattern the {@link java.util.regex.Pattern pattern} parser, must be compatible w/ {@link #getVersionNumberPattern(String)}
170 *
171 * @see #hasMajor()
172 * @see #hasMinor()
173 * @see #hasSub()
174 */
175 public VersionNumber(final String versionString, final java.util.regex.Pattern versionPattern) {
176 // group1: \d* == digits major
177 // group2: \d* == digits minor
178 // group3: \d* == digits sub
179 final int[] val = new int[3];
180 int _strEnd = 0;
181 short _state = 0;
182 try {
183 final Matcher matcher = versionPattern.matcher( versionString );
184 if( matcher.lookingAt() ) {
185 _strEnd = matcher.end();
186 final int groupCount = matcher.groupCount();
187 if( 1 <= groupCount ) {
188 val[0] = Integer.parseInt(matcher.group(1));
189 _state = HAS_MAJOR;
190 if( 2 <= groupCount ) {
191 val[1] = Integer.parseInt(matcher.group(2));
192 _state |= HAS_MINOR;
193 if( 3 <= groupCount ) {
194 val[2] = Integer.parseInt(matcher.group(3));
195 _state |= HAS_SUB;
196 }
197 }
198 }
199 }
200 } catch (final Exception e) { }
201
202 major = val[0];
203 minor = val[1];
204 sub = val[2];
205 strEnd = _strEnd;
206 state = _state;
207 }
208
209 /** Returns <code>true</code>, if all version components are zero, otherwise <code>false</code>. */
210 public final boolean isZero() {
211 return major == 0 && minor == 0 && sub == 0;
212 }
213
214 /** Returns <code>true</code>, if the major component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
215 public final boolean hasMajor() { return 0 != ( HAS_MAJOR & state ); }
216 /** Returns <code>true</code>, if the optional minor component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
217 public final boolean hasMinor() { return 0 != ( HAS_MINOR & state ); }
218 /** Returns <code>true</code>, if the optional sub component is defined explicitly, otherwise <code>false</code>. Undefined components has the value <code>0</code>. */
219 public final boolean hasSub() { return 0 != ( HAS_SUB & state ); }
220
221 /**
222 * If constructed with <code>version-string</code>, returns the string offset <i>after</i> the last matching character,
223 * or <code>0</code> if none matched, or <code>-1</code> if not constructed with a string.
224 */
225 public final int endOfStringMatch() { return strEnd; }
226
227 @Override
228 public final int hashCode() {
229 // 31 * x == (x << 5) - x
230 int hash = 31 + major;
231 hash = ((hash << 5) - hash) + minor;
232 return ((hash << 5) - hash) + sub;
233 }
234
235 @Override
236 public final boolean equals(final Object o) {
237 if ( o instanceof VersionNumber ) {
238 return 0 == compareTo( (VersionNumber) o );
239 }
240 return false;
241 }
242
243 @Override
244 public final int compareTo(final Object o) {
245 if ( ! ( o instanceof VersionNumber ) ) {
246 final Class<?> c = (null != o) ? o.getClass() : null ;
247 throw new ClassCastException("Not a VersionNumber object: " + c);
248 }
249 return compareTo( (VersionNumber) o );
250 }
251
252 public final int compareTo(final VersionNumber vo) {
253 if (major > vo.major) {
254 return 1;
255 } else if (major < vo.major) {
256 return -1;
257 } else if (minor > vo.minor) {
258 return 1;
259 } else if (minor < vo.minor) {
260 return -1;
261 } else if (sub > vo.sub) {
262 return 1;
263 } else if (sub < vo.sub) {
264 return -1;
265 }
266 return 0;
267 }
268
269 public final int getMajor() {
270 return major;
271 }
272
273 public final int getMinor() {
274 return minor;
275 }
276
277 public final int getSub() {
278 return sub;
279 }
280
281 @Override
282 public String toString() {
283 return major + "." + minor + "." + sub ;
284 }
285}
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.
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,...