
org.nuiton.util.Version Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nuiton-utils Show documentation
Show all versions of nuiton-utils Show documentation
Library of usefull class to be used in any project.
/*
* #%L
* Nuiton Utils
*
* $Id: Version.java 2360 2012-06-11 10:24:36Z tchemit $
* $HeadURL: http://svn.nuiton.org/svn/nuiton-utils/tags/nuiton-utils-2.6.10/nuiton-utils/src/main/java/org/nuiton/util/Version.java $
* %%
* Copyright (C) 2004 - 2010 CodeLutin
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.util;
import org.apache.commons.lang3.ObjectUtils;
import java.io.Serializable;
import java.util.Arrays;
import java.util.regex.Matcher;
import static org.nuiton.i18n.I18n._;
/**
* A class to represent an application version with possible classifier.
*
* Replace previously org.nuiton.util.VersionNumber class.
*
* Simple version number is defined like this :
*
* 1.0.0 or 1
*
*
* A version can be more complex, with a classifier like this :
*
* 1.0.0-alpha-1, 1.0.0-beta-2, 1.0.0-rc-1
*
*
* A classifier (alpha, beta, rc, ...) must be follwed by a classifier number.
*
* Note :
*
* - initial value is 0
*
* - the equals order is defined on {@link #getVersion()} property.
*
* - the class is comparable, using the natural version order :
*
* 0 < 0.1 < 1 < 1.0 < 1.1-alpha-0 < 1.1-alpha-1 < 1.1-beta-0 <
* 1.1-rc-1 < 1.1
*
* - the class is immutable, you should not instanciate directly a Version,
* but prefer use the factory static methods
* VersionUtil.valueOf(...)
instead.
*
* @author tchemit
* @since 1.1.0
*/
public class Version implements Comparable, Serializable {
private static final long serialVersionUID = 1L;
/** Version V0 */
public static final Version VZERO = new Version();
/** optional classifier */
protected final String classifier;
/** optional classifier number (if no classifier should be null) */
protected final Integer classifierNumber;
/** main numbers of the version */
protected final int[] numbers;
/**
* boolean to define if version is a snapshot (if so a -SNAPSHOT is
* added at the end of the textual representation of the version).
*
* @since 2.4.3
*/
protected final boolean snapshot;
/**
* A flag to attach or not the classifier with his number.
*
* If set to false (the default cas then a - will be used to separe them).
*
* Even if the {@link Version} class is immutable, this state can be change
* since it is only used to build the string representation of a version.
*
* Notes that this state is NOT used to test equality of two version,
* neither for the comparaison.
*
* @since 2.4.3
*/
protected boolean classifierNumberAttached;
/**
* representation textuelle de la version (celle utilisee dans le
* {@link #toString()}.
*/
protected transient String version;
/** Constructeur par defaut, definit la version par defaut, i.e 0 */
public Version() {
this(0);
}
/**
* Constructeur d'une version simple (sans classifier).
*
* @param numbers les nombres de la version
*/
public Version(int... numbers) {
this(null, null, false, numbers);
}
/**
* Constructeur d'une version (simple ou avec classifier)
*
* @param classifier le classifier (peut-être null)
* @param classiferNumber la version du classifier (doit etre null si le
* classifier est null)
* @param numbers les nombres de la version
*/
public Version(String classifier, Integer classiferNumber, int... numbers) {
this(classifier, classiferNumber, false, numbers);
}
/**
* Constructeur d'une version (simple ou avec classifier)
*
* @param classifier le classifier (peut-être null)
* @param classiferNumber la version du classifier (doit etre null si le
* classifier est null)
* @param snapshot boolean pour renseigner le champ {@link #snapshot}.
* @param numbers les nombres de la version
* @since 2.4.3
*/
public Version(String classifier, Integer classiferNumber,
boolean snapshot, int... numbers) {
this.numbers = numbers.length == 0 ? new int[]{0} : numbers;
// always keep a lower case classifier
this.classifier = classifier == null ? null :
classifier.trim().toLowerCase();
classifierNumber = classiferNumber;
this.snapshot = snapshot;
}
/**
* Constructeur de version a partir de sa representation textuelle
*
* @param version la represention de la version a instancier
* @throws IllegalArgumentException si la version n'est pas valide
*/
public Version(String version) throws IllegalArgumentException {
if (version == null || version.trim().isEmpty()) {
// version par defaut
version = "0";
}
Matcher matcher = VersionUtil.VERSION_PATTERN.matcher(version);
if (!matcher.matches()) {
// try with classifier number attached to classifier
matcher = VersionUtil.VERSION_PATTERN2.matcher(version);
classifierNumberAttached = true;
}
if (!matcher.matches()) {
// not a known pattern
throw new IllegalArgumentException(
_("nuitonutil.error.version.pattern", version));
}
// get numbers as string
String[] strNumbers = matcher.group(1).split("\\.");
String strClassifier = matcher.group(2);
String strClassifierNumber = matcher.group(3);
String strSnapshot = matcher.group(4);
Integer intClassifierNumber = null;
if (strClassifier != null) {
// possede un classifier
// classifier number
intClassifierNumber = Integer.valueOf(strClassifierNumber);
}
snapshot = strSnapshot != null;
// numbers
numbers = new int[strNumbers.length];
for (int i = 0, j = strNumbers.length; i < j; i++) {
String number = strNumbers[i].trim();
numbers[i] = Integer.valueOf(number);
}
// classifier
classifier = strClassifier;
// classifier number
classifierNumber = intClassifierNumber;
}
public int[] getNumbers() {
return numbers;
}
public String getClassifier() {
return classifier;
}
public boolean hasClassifier() {
return classifier != null && !classifier.isEmpty();
}
public Integer getClassifierNumber() {
return classifierNumber;
}
public boolean isSnapshot() {
return snapshot;
}
public int getNbComponents() {
return numbers.length;
}
public boolean isClassifierNumberAttached() {
return classifierNumberAttached;
}
public int getNumber(int level) {
if (level < 0 || level >= numbers.length) {
throw new IllegalArgumentException(
"not a valid level " + level + " for the VersionNumber " +
this);
}
return numbers[level];
}
public String getVersion() {
if (version == null) {
StringBuilder sb = new StringBuilder();
for (int number : numbers) {
sb.append('.').append(number);
}
if (hasClassifier()) {
sb.append('-');
sb.append(classifier);
if (!classifierNumberAttached) {
sb.append('-');
}
sb.append(classifierNumber);
}
if (isSnapshot()) {
sb.append(VersionUtil.SNAPSHOT_SUFFIX);
}
version = sb.substring(1);
}
return version;
}
/**
* Convertit la representation textuelle de la version en identifiant java valide :
* - en java : "." interdit
* - en mysql, h2 ... : "." interdit
*
* @return la valeur ou les carateres interdits sont remplaces par '_'
*/
public String getValidName() {
String validName = getVersion();
// replace ". et -"
validName = validName.replaceAll("\\.|-", "_");
return validName;
}
/**
* Change the internal state {@link #classifierNumberAttached}.
*
* @param classifierNumberAttached the new value of the classifierNumberAttached state
*/
public void setClassifierNumberAttached(boolean classifierNumberAttached) {
if (version != null) {
// will force
version = null;
}
this.classifierNumberAttached = classifierNumberAttached;
}
@Override
public String toString() {
String t = getVersion();
return t;
}
@Override
public int compareTo(Version o) {
int result = VersionUtil.DEFAULT_VERSION_COMPARATOR.compare(this, o);
return result;
}
/**
* @param o the other version to test
* @return true
if current version is before the given one
*/
public boolean before(Version o) {
int result = compareTo(o);
return result < 0;
}
/**
* @param o the other version to test
* @return true
if current version is after the given one
*/
public boolean after(Version o) {
int result = compareTo(o);
return result > 0;
}
@Override
public boolean equals(Object obj) {
return obj != null && obj instanceof Version &&
Arrays.equals(numbers, ((Version) obj).numbers) &&
ObjectUtils.equals(classifier, ((Version) obj).classifier) &&
ObjectUtils.equals(classifierNumber, ((Version) obj).classifierNumber) &&
ObjectUtils.equals(snapshot, ((Version) obj).snapshot);
}
@Override
public int hashCode() {
return getVersion().hashCode();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy