1 package be
.nikiroo
.utils
;
3 import java
.io
.ByteArrayOutputStream
;
4 import java
.io
.IOException
;
5 import java
.io
.InputStream
;
8 * This class describe a program {@link Version}.
12 public class Version
implements Comparable
<Version
> {
13 private String version
;
18 private int tagVersion
;
21 * Create a new, empty {@link Version}.
28 * Create a new {@link Version} with the given values.
37 public Version(int major
, int minor
, int patch
) {
38 this(major
, minor
, patch
, null, -1);
42 * Create a new {@link Version} with the given values.
51 * a tag name for this version
53 public Version(int major
, int minor
, int patch
, String tag
) {
54 this(major
, minor
, patch
, tag
, -1);
58 * Create a new {@link Version} with the given values.
65 * the patch version the patch version
67 * a tag name for this version
69 * the version of the tagged version
71 public Version(int major
, int minor
, int patch
, String tag
, int tagVersion
) {
72 if (tagVersion
>= 0 && tag
== null) {
73 throw new java
.lang
.IllegalArgumentException(
74 "A tag version cannot be used without a tag");
81 this.tagVersion
= tagVersion
;
83 String tagSuffix
= "";
86 + (tagVersion
>= 0 ? Integer
.toString(tagVersion
) : "");
89 this.version
= String
.format("%d.%d.%d%s", major
, minor
, patch
,
94 * Create a new {@link Version} with the given value, which must be in the
95 * form <tt>MAJOR.MINOR.PATCH(-TAG(TAG_VERSION))</tt>.
98 * the version (<tt>MAJOR.MINOR.PATCH</tt>,
99 * <tt>MAJOR.MINOR.PATCH-TAG</tt> or
100 * <tt>MAJOR.MINOR.PATCH-TAGVERSIONTAG</tt>)
102 public Version(String version
) {
104 String
[] tab
= version
.split("\\.");
105 this.major
= Integer
.parseInt(tab
[0]);
106 this.minor
= Integer
.parseInt(tab
[1]);
107 if (tab
[2].contains("-")) {
108 int posInVersion
= version
.indexOf('.');
109 posInVersion
= version
.indexOf('.', posInVersion
+ 1);
110 String rest
= version
.substring(posInVersion
+ 1);
112 int posInRest
= rest
.indexOf('-');
113 this.patch
= Integer
.parseInt(rest
.substring(0, posInRest
));
115 posInVersion
= version
.indexOf('-');
116 this.tag
= version
.substring(posInVersion
+ 1);
117 this.tagVersion
= -1;
119 StringBuilder str
= new StringBuilder();
120 while (!tag
.isEmpty() && tag
.charAt(tag
.length() - 1) >= '0'
121 && tag
.charAt(tag
.length() - 1) <= '9') {
122 str
.insert(0, tag
.charAt(tag
.length() - 1));
123 tag
= tag
.substring(0, tag
.length() - 1);
126 if (str
.length() > 0) {
127 this.tagVersion
= Integer
.parseInt(str
.toString());
130 this.patch
= Integer
.parseInt(tab
[2]);
132 this.tagVersion
= -1;
135 this.version
= toString();
136 } catch (Exception e
) {
141 this.tagVersion
= -1;
147 * The 'major' version.
149 * This version should only change when API-incompatible changes are made to
152 * @return the major version
154 public int getMajor() {
159 * The 'minor' version.
161 * This version should only change when new, backwards-compatible
162 * functionality has been added to the program.
164 * @return the minor version
166 public int getMinor() {
171 * The 'patch' version.
173 * This version should change when backwards-compatible bugfixes have been
174 * added to the program.
176 * @return the patch version
178 public int getPatch() {
183 * A tag name for this version.
187 public String
getTag() {
192 * The version of the tag.
194 * @return the tag version
196 public int getTagVersion() {
201 * Check if this {@link Version} is "empty" (i.e., the version was not
202 * parse-able or not given).
204 * An empty {@link Version} is always <tt>0.0.0</tt>.
206 * @return TRUE if it is empty
208 public boolean isEmpty() {
209 return major
== 0 && minor
== 0 && patch
== 0 && tag
== null;
213 * Check if we are more recent than the given {@link Version}.
215 * Note that a tagged version is considered newer than a non-tagged version,
216 * but two tagged versions with different tags are not comparable.
219 * the other {@link Version}
220 * @return TRUE if this {@link Version} is more recent than the given one
222 public boolean isNewerThan(Version o
) {
223 if (major
> o
.major
) {
227 if (major
== o
.major
&& minor
> o
.minor
) {
231 if (major
== o
.major
&& minor
== o
.minor
&& patch
> o
.patch
) {
235 // a tagged version is considered newer than a non-tagged one
236 if (major
== o
.major
&& minor
== o
.minor
&& patch
== o
.patch
237 && tag
!= null && o
.tag
== null) {
241 // 2 <> tagged versions are not comparable
242 boolean sameTag
= (tag
== null && o
.tag
== null)
243 || (tag
!= null && tag
.equals(o
.tag
));
244 if (major
== o
.major
&& minor
== o
.minor
&& patch
== o
.patch
&& sameTag
245 && tagVersion
> o
.tagVersion
) {
253 * Check if we are older than the given {@link Version}.
256 * the other {@link Version}
257 * @return TRUE if this {@link Version} is older than the given one
259 public boolean isOlderThan(Version o
) {
260 // 2 <> tagged versions are not comparable
261 boolean sameTag
= (tag
== null && o
.tag
== null)
262 || (tag
!= null && tag
.equals(o
.tag
));
263 if (major
== o
.major
&& minor
== o
.minor
&& patch
== o
.patch
268 return !equals(o
) && !isNewerThan(o
);
272 * Return the version of the running program if it follows the VERSION
273 * convention (i.e., if it has a file called VERSION containing the version
274 * as a {@link String} in its binary root, and if this {@link String}
275 * follows the Major/Minor/Patch convention).
277 * If it does not, return an empty {@link Version} object.
279 * @return the {@link Version} of the program, or an empty {@link Version}
280 * (does not return NULL)
282 public static Version
getCurrentVersion() {
283 String version
= null;
285 InputStream in
= IOUtils
.openResource("VERSION");
288 ByteArrayOutputStream ba
= new ByteArrayOutputStream();
289 IOUtils
.write(in
, ba
);
292 version
= ba
.toString("UTF-8").trim();
293 } catch (IOException e
) {
297 return new Version(version
);
300 public int compareTo(Version o
) {
303 } else if (isNewerThan(o
)) {
311 public boolean equals(Object obj
) {
312 if (obj
instanceof Version
) {
313 Version o
= (Version
) obj
;
314 boolean sameTag
= (tag
== null && o
.tag
== null)
315 || (tag
!= null && tag
.equals(o
.tag
));
316 return o
.major
== major
&& o
.minor
== minor
&& o
.patch
== patch
317 && sameTag
&& o
.tagVersion
== tagVersion
;
324 public int hashCode() {
325 return version
== null ?
0 : version
.hashCode();
329 * Return a user-readable form of this {@link Version}.
332 public String
toString() {
333 return version
== null ?
"[unknown]" : version
;