Indentations break the feed.
[SquirrelJME.git] / modules / cldc-compact / src / main / java / cc / squirreljme / jvm / suite / SuiteVersion.java
blob4ed9715616a194e3480668749393fcd1754a75fe
1 // -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // ---------------------------------------------------------------------------
10 package cc.squirreljme.jvm.suite;
12 import java.lang.ref.Reference;
13 import java.lang.ref.WeakReference;
15 /**
16 * This represents a suite version.
18 * @since 2016/10/12
20 public final class SuiteVersion
21 implements Comparable<SuiteVersion>
23 /** The minimum version number. */
24 public static final SuiteVersion MIN_VERSION =
25 new SuiteVersion(0, 0, 0);
27 /** The maximum version number. */
28 public static final SuiteVersion MAX_VERSION =
29 new SuiteVersion(99, 99, 99);
31 /** The major version. */
32 protected final int major;
34 /** The minor version. */
35 protected final int minor;
37 /** The release version. */
38 protected final int release;
40 /** The string representation. */
41 private Reference<String> _string;
43 /**
44 * Initializes the version.
46 * @param __v The value to parse.
47 * @throws InvalidSuiteException If there are too many or too little
48 * version fields, they contain illegal charactes, or have an out of range
49 * value.
50 * @throws NullPointerException On null arguments.
51 * @since 2016/10/12
53 public SuiteVersion(String __v)
54 throws InvalidSuiteException, NullPointerException
56 this(SuiteVersion.__decodeVersion(__v));
59 /**
60 * Initializes a Midlet version number from the specified array of
61 * integer values.
63 * @param __v The version triplet, up to the first three elements are
64 * used by the version number.
65 * @throws InvalidSuiteException If the version number has an out of
66 * range value.
67 * @throws NullPointerException On null arguments.
68 * @since 2016/10/12
70 public SuiteVersion(int[] __v)
71 throws InvalidSuiteException, NullPointerException
73 this((__v.length > 0 ? __v[0] : 0),
74 (__v.length > 1 ? __v[1] : 0),
75 (__v.length > 2 ? __v[2] : 0));
78 /**
79 * Decodes the midlet version, optionally allowing it to a reverse
80 * operation of the {@link #hashCode()} method.
82 * @param __hash If {@code true} then the value to decode is treated as
83 * the hash code returned by this class.
84 * @param __maj If {@code __hash} is {@code true} then this is the hash
85 * code of a SuiteVersion, otherwise it is the major version number.
86 * @throws InvalidSuiteException If the version number has an out of
87 * range value.
88 * @since 2016/10/13
90 public SuiteVersion(boolean __hash, int __maj)
91 throws InvalidSuiteException
93 this((__hash ? __maj / 10000 : __maj),
94 (__hash ? (__maj / 100) % 100 : 0),
95 (__hash ? __maj % 100 : 0));
98 /**
99 * Initializes the version.
101 * @param __maj The major version.
102 * @throws IllegalArgumentException If any value is out of range.
103 * @since 2016/10/12
105 public SuiteVersion(int __maj)
107 this(__maj, 0, 0);
111 * Initializes the version.
113 * @param __maj The major version.
114 * @param __min The minor version.
115 * @throws IllegalArgumentException If any value is out of range.
116 * @since 2016/10/12
118 public SuiteVersion(int __maj, int __min)
120 this(__maj, __min, 0);
124 * Initializes the version.
126 * @param __maj The major version.
127 * @param __min The minor version.
128 * @param __rel The release version.
129 * @throws InvalidSuiteException If any value is out of range.
130 * @since 2016/10/12
132 public SuiteVersion(int __maj, int __min, int __rel)
133 throws InvalidSuiteException
135 /* {@squirreljme.error DG0i Input version number is out of range, only
136 0 through 99 are valid. (The major version; The minor version; The
137 release version)} */
138 if (__maj < 0 || __maj > 99 || __min < 0 || __min > 99 ||
139 __rel < 0 || __rel > 99)
140 throw new InvalidSuiteException(String.format("AR0i %d %d %d",
141 __maj, __min, __rel));
143 // Set
144 this.major = __maj;
145 this.minor = __min;
146 this.release = __rel;
150 * Checks if this version at least the specified verison.
152 * @param __v The version to check against.
153 * @return {@code true} if this version is at least the other.
154 * @throws NullPointerException On nul arguments.
156 public boolean atLeast(SuiteVersion __v)
157 throws NullPointerException
159 // Check
160 if (__v == null)
161 throw new NullPointerException("NARG");
163 // Can compare the hashcodes
164 return this.hashCode() >= __v.hashCode();
168 * {@inheritDoc}
169 * @since 2016/10/12
171 @Override
172 public int compareTo(SuiteVersion __o)
174 // Major first
175 int amaj = this.major, bmaj = __o.major;
176 int rv = amaj - bmaj;
177 if (rv != 0)
178 return rv;
180 // Then minor
181 int amin = this.minor, bmin = __o.minor;
182 rv = amin - bmin;
183 if (rv != 0)
184 return rv;
186 // Then release
187 int arel = this.release, brel = __o.release;
188 rv = arel - brel;
189 if (rv != 0)
190 return rv;
192 // The same
193 return 0;
197 * {@inheritDoc}
198 * @since 2016/10/12
200 @Override
201 public boolean equals(Object __o)
203 // Check
204 if (!(__o instanceof SuiteVersion))
205 return false;
207 // Cast
208 SuiteVersion o = (SuiteVersion)__o;
209 return this.major == o.major &&
210 this.minor == o.minor &&
211 this.release == o.release;
215 * {@inheritDoc}
216 * @since 2016/10/12
218 @Override
219 public int hashCode()
221 return (this.major * 10000) +
222 (this.minor * 100) +
223 this.release;
227 * Returns the major version.
229 * @return The major version.
230 * @since 2017/02/22
232 public int major()
234 return this.major;
238 * Returns the minor version.
240 * @return The minor version.
241 * @since 2017/02/22
243 public int minor()
245 return this.minor;
249 * Returns the release version.
251 * @return The release version.
252 * @since 2017/02/22
254 public int release()
256 return this.release;
260 * {@inheritDoc}
261 * @since 2016/10/12
263 @Override
264 public String toString()
266 // Get
267 Reference<String> ref = this._string;
268 String rv;
270 // Cache?
271 if (ref == null || null == (rv = ref.get()))
272 this._string = new WeakReference<>((rv = this.major + "." +
273 this.minor + "." + this.release));
275 // Return it
276 return rv;
280 * Decodes the string based version number
282 * @param __v The input string.
283 * @return The version tuplet.
284 * @throws InvalidSuiteException If the input is not valid.
285 * @throws NullPointerException On null arguments.
286 * @since 2016/10/12
288 private static int[] __decodeVersion(String __v)
289 throws InvalidSuiteException, NullPointerException
291 // Check
292 if (__v == null)
293 throw new NullPointerException("NARG");
295 // Trim whitespace
296 __v = __v.trim();
298 // Output array
299 int[] rv = new int[3];
301 // Parse the input value
302 int n = __v.length(), at = 0;
303 StringBuilder sb = new StringBuilder();
304 for (int i = 0; i <= n; i++)
306 int c = (i == n ? -1 : __v.charAt(i));
308 // Decimal point? or end
309 if (c == '.' || c == -1)
311 rv[at++] = Integer.parseInt(sb.toString(), 10);
313 /* {@squirreljme.error DG0j Too many version fields in the
314 specified string. (The input string)} */
315 if (c != -1 && at >= 4)
316 throw new InvalidSuiteException(String.format("AR0j %s",
317 __v));
319 // Clear
320 sb.setLength(0);
323 // Add to string
324 else if (c >= '0' && c <= '9')
325 sb.append((char)c);
327 /* {@squirreljme.error DG0k An illegal character is in the
328 version string. (The input string; The illegal character)} */
329 else
330 throw new InvalidSuiteException(String.format("AR0k %s %04x",
331 __v, c));
334 // Return it
335 return rv;