All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.util.version.Version Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton Utils
 * %%
 * Copyright (C) 2014 CodeLutin, Tony Chemit
 * %%
 * 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.version;

import com.google.common.base.Preconditions;
import org.apache.commons.lang3.ObjectUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 

A class to represent a version.

*

Replace previously {@code org.nuiton.util.Version} class.

*

Definition

* A version is defined of n {@code componants} separated by {@code componantSeparator}. *

Componants

* Componants can be of two types: *
    *
  • Number componant: a strict positive integer value
  • *
  • String componant: a sequence of characters which can't be either number nor componant separators
  • *
*

Componant separators

*

* Componant separator are characters which can't be alphanumeric and can be {@code empty character}. *

*

* Componant separators are optional and componants will be detected as soon as a character changed from a numeric string sequence to a alpha (none numeric!) sequence. *

*

* For example, version {@code 1a2} is composed of three componants: {code 1}, {@code a} and {@code 3}. *

*

Snapshot flag

* Additionnaly version can be qualifed as a {@code SNAPSHOT} (see below section about ordering). *

Examples

*
 *  0 (one componant 0)
 *  0-SNAPSHOT (one componant 0 + SNAPSHOT flag)
 *  1.0 (two componants 1,0)
 *  1.1 (two componants 1,1)
 *  1.1-alpha-1 (four componants 1,1,alpha,1)
 *  1.1-beta (three componants 1,1,beta)
 *  1.1-rc-1 (four componants 1,1,rc,1)
 *  1.1-a  (three componants 1,1,a)
 *  1.1-a12-4.45_6432 (seven componants 1,1,a,12,4,45,643)
 * 
*

Ordering

* A version is comparable, to have all the detail of order see {@link VersionComparator}. *

Immutability

* The version is immutable, to create or modify a version, use the {@link VersionBuilder} API * or shortcut methods in {@link Versions}. * * @author Tony Chemit - [email protected] * @see VersionBuilder * @see VersionComparator * @since 3.0 * @deprecated since 3.0, use now Nuiton version */ @Deprecated public class Version implements Comparable, Serializable { private static final long serialVersionUID = 1L; /** * Suffix of a {@code SNAPSHOT} version in the text representation. */ public static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; /** * Version V0. */ public static final Version VZERO = VersionBuilder.create().build(); /** * Comparator of version used internaly to fulfill the compoarator contract. */ protected static final VersionComparator VERSION_COMPARATOR = new VersionComparator(); public static final char DEFAULT_JOIN_COMPONANT_SEPARATOR = '.'; /** * List of componants of the version. */ protected final List componants; /** * List of separators of the version. */ protected final List componantSeparators; /** * flag to define if version is a snapshot (if so a -SNAPSHOT is * added at the end of the textual representation of the version). */ protected final boolean snapshot; /** * string represention of the version. */ protected transient String version; protected Version(List componants, List componantSeparators, boolean snapshot) { this.componantSeparators = Collections.unmodifiableList(new ArrayList(componantSeparators)); this.componants = Collections.unmodifiableList(new ArrayList(componants)); this.snapshot = snapshot; } public List getComponants() { return componants; } public List getComponantSeparators() { return componantSeparators; } public boolean isSnapshot() { return snapshot; } public int getComponantCount() { return componants.size(); } public int getNumberComponant(int componantPosition) { VersionComponant comparable = getComponant(componantPosition); Preconditions.checkState(comparable instanceof NumberVersionComponant, "componant at " + componantPosition + " for version " + this + " is not a number (" + comparable + ")"); return (Integer) comparable.getValue(); } public String getTextComponant(int componantPosition) { VersionComponant comparable = getComponant(componantPosition); Preconditions.checkState(comparable instanceof StringVersionComponant, "componant at " + componantPosition + " for version " + this + " is not a string (" + comparable + ")"); return (String) comparable.getValue(); } public VersionComponant getComponant(int level) { Preconditions.checkArgument(level > 0 || level < getComponantCount(), "not a valid level " + level + " for the Version " + this); return componants.get(level); } /** * @return the string represention value of the version */ public String getVersion() { if (version == null) { version = String.valueOf(componants.get(0).getValue()); for (int i = 0, nb = componantSeparators.size(); i < nb; i++) { version += componantSeparators.get(i); version += componants.get(i + 1).getValue(); } if (snapshot) { version += SNAPSHOT_SUFFIX; } } return version; } /** * Convert the string representation to a java identifier compliant. * *
    *
  • in java: {@code .} is forbidden
  • *
  • in database (mysql, h2 ...): {@code .} is forbidden
  • *
* * Forbidden values are replaced by {@code _} character. * * @return the java compilant string representation of the version */ public String getValidName() { String validName = getVersion(); // replace ". et -" validName = validName.replaceAll("\\.|-", "_"); return validName; } /** * Creates a new version from this one incremented. * * If the last componant is a number, then just increments this number; otherwise add a new * number componant with value 1. * * Example: *
    *
  • 1 → 2
  • *
  • 1-a → 1-a.1
  • *
* * @return the incremented version * @deprecated use instead {@link Versions#increments(Version)} */ @Deprecated public Version increments() { Version newVersion = Versions.increments(this); return newVersion; } /** * Creates a new version from this one incremented. * * If the last componant is a number, then just increments this number; otherwise add a new * number componant with value 1. * * Example: *
    *
  • 1 → 2
  • *
  • 1-a → 1-a.1
  • *
* * @param componantSeperator the componant separator to use the last componant is a classifier * @return the incremented version * @deprecated use instead {@link Versions#increments(Version, char)} */ @Deprecated public Version increments(char componantSeperator) { Version newVersion = Versions.increments(this, componantSeperator); return newVersion; } /** * Creates a new version from this one with the number componant incremented at the given position. * * Note: * Will fail if the componant at the required position is not a number. * * @param componantPosition position of the version componant to increment * @return the incremented version * @deprecated use instead {@link Versions#increments(Version, int)} */ @Deprecated public Version increments(int componantPosition) { Version newVersion = Versions.increments(this, componantPosition); return newVersion; } /** * Creates a new version from this one with the number componant decremented at the given position. * * Note: * Will fail if the componant at the required position is not a number, or his value is 0. * * @param componantPosition position of the version componant to increment * @return the decremented version * @deprecated use {@link Versions#decrements(Version, int)} instead */ @Deprecated public Version decrements(int componantPosition) { Version newVersion = Versions.decrements(this, componantPosition); return newVersion; } @Override public int compareTo(Version o) { int result = VERSION_COMPARATOR.compare(this, o); return result; } /** * @param o the other version to test * @return {@code true} if current version is before or equals the given one */ public boolean beforeOrequals(Version o) { int result = compareTo(o); return result <= 0; } /** * @param o the other version to test * @return {@code 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 {@code true} if current version is after or equals the given one */ public boolean afterOrEquals(Version o) { int result = compareTo(o); return result >= 0; } /** * @param o the other version to test * @return {@code true} if current version is after the given one */ public boolean after(Version o) { int result = compareTo(o); return result > 0; } @Override public String toString() { return getVersion(); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Version)) return false; return compareTo((Version) o) == 0; } @Override public int hashCode() { int result = componants.hashCode(); result = 31 * result + (snapshot ? 1 : 0); return result; } protected VersionComponant getLastComponant() { return componants.get(getComponantCount() - 1); } public interface VersionComponant, V extends VersionComponant> extends Serializable, Comparable { C getValue(); } public static class NumberVersionComponant implements VersionComponant { private static final long serialVersionUID = 1L; protected final Integer value; public NumberVersionComponant(Integer value) { this.value = value; } @Override public Integer getValue() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof NumberVersionComponant)) return false; return compareTo((NumberVersionComponant) o) == 0; } @Override public int hashCode() { return value.hashCode(); } @Override public int compareTo(NumberVersionComponant o) { return value.compareTo(o.value); } } public static class StringVersionComponant implements VersionComponant { private static final long serialVersionUID = 1L; protected final boolean preRelease; protected final String value; protected final String lowerCaseValue; public StringVersionComponant(boolean preRelease, String value) { this.preRelease = preRelease; this.value = value; this.lowerCaseValue = value.toLowerCase(); } @Override public String getValue() { return value; } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof StringVersionComponant)) return false; return compareTo((StringVersionComponant) o) == 0; } @Override public int hashCode() { int result = preRelease ? 1 : 0; result = 31 * result + value.hashCode(); return result; } public boolean isPreRelease() { return preRelease; } @Override public int compareTo(StringVersionComponant o) { int result; if (ObjectUtils.notEqual(preRelease, o.preRelease)) { // compare on preRelease flag if (preRelease) { // preRelease is before any other string componant result = -1; } else { result = 1; } } else { // on same preRelease flag // compare on lowerCaseValue result = lowerCaseValue.compareTo(o.lowerCaseValue); } return result; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy