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

org.nuiton.util.VersionUtil Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton Utils
 * %%
 * 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 java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * Class of usefull methods on {@link Version} objects.
 *
 * There is some factory methods : {@code valueOf(XXX)} to obtain a new
 * version.
 *
 * Some methods to transform a version (since version are immutable, we can not
 * modify Version's property) :
 * 
 *   - inc(Version) : to increment a version
 *   - dec(Version) : to decrement a version
 *   - addClassifier(Version, String, Integer) : to add a classifier to a version
 *   - removeClassifier(Version) : to remove a classifier from a version
 * 
* * @author Tony Chemit - [email protected] * @since 1.1.0 * @deprecated since 3.0 (use now {@link org.nuiton.util.version.Version}). */ @Deprecated public class VersionUtil { /** * Pattern pour detecter une version (avec si classifier et numéro de * classifier séparé par un -, par exemple : 1.0-beta-1). * * Le pattern possède toujours 4 groupes de captures. * * - Le groupe 1 est le nombre de la version * - Le groupe 2 est le classifier (peut-etre null) * - Le groupe 3 est le numéro de classifier (peut-etre null) * - Le groupe 4 est le suffix -SNAPSHOT (peut-etre null) * * Dans le cas d'une version simple (sans classifier), le groupe 2, 3 et * 4 sont null. * * Dans le cas d'une version non snapshot, le groupe 4 est null. */ public static final Pattern VERSION_PATTERN = Pattern.compile("^(\\d+(?:\\.(?:\\d+))*)(?:-(\\w+?)-(\\d+?)){0,1}(-SNAPSHOT){0,1}$"); /** * Pattern pour detecter une version (avec si classifier et numéro de * classifier collé, par exemple : 1.0-rc1). * * Le pattern possède toujours 4 groupes de captures. * * - Le groupe 1 est le nombre de la version * - Le groupe 2 est le classifier (peut-etre null) * - Le groupe 3 est le numéro de classifier (peut-etre null) * - Le groupe 4 est le suffix -SNAPSHOT (peut-etre null) * * Dans le cas d'une version simple (sans classifier), le groupe 2, 3 et * 4 sont null. * * Dans le cas d'une version non snapshot, le groupe 4 est null. */ public static final Pattern VERSION_PATTERN2 = Pattern.compile("^(\\d+(?:\\.(?:\\d+))*)(?:-(\\w+?)(\\d+?)){0,1}(-SNAPSHOT){0,1}$"); /** * Shared instance of default version comparator. * * @see VersionComparator */ public static final VersionComparator DEFAULT_VERSION_COMPARATOR = new VersionComparator(); /** The snapshot suffix. */ public static final String SNAPSHOT_SUFFIX = "-SNAPSHOT"; /** * Recuperation d'une instance de version simple (sans classifier). * * @param numbers les nombres de la version * @param snapshot boolean pour indiquer que la version es une snapshot ou pas * @return l'instance de la version requise */ public static Version valueOf(boolean snapshot, int... numbers) { Version version = valueOf(null, null, snapshot, numbers); return version; } /** * Recuperation d'une instance de version simple (sans classifier). * * @param numbers les nombres de la version * @return l'instance de la version requise */ public static Version valueOf(int... numbers) { Version version = valueOf(null, null, false, numbers); return version; } /** * Recuperation d'une instance de version. * * @param classifier le classifier (peut-etre null) * @param classifierNumber la version du classifier (doit etre null si le * classifier est null) * @param numbers les nombres de la version * @return l'instance de la version requise */ public static Version valueOf(String classifier, Integer classifierNumber, int... numbers) { Version v = valueOf(classifier, classifierNumber, false, numbers); return v; } /** * Recuperation d'une instance de version. * * @param classifier le classifier (peut-etre null) * @param classifierNumber la version du classifier (doit etre null si le * classifier est null) * @param snapshot boolean pour indiquer que la version es une snapshot ou pas * @param numbers les nombres de la version * @return l'instance de la version requise */ public static Version valueOf(String classifier, Integer classifierNumber, boolean snapshot, int... numbers) { Version v = new Version(classifier, classifierNumber, snapshot, numbers); return v; } /** * Recuperation d'une instance de version a partir de sa version textuelle. * * @param version la representation textuelle de la version * @return l'instance de la version requise */ public static Version valueOf(String version) { Version v = new Version(version); return v; } /** * Construction d'une nouvelle version avec un classifier a partir d'une * version donnee. * * @param version la version de base (sans classifier) * @param classifier le classifier a ajouter * @param classifierNumber la version du classifier a ajouter * @return l'instance de la version requise * @throws NullPointerException si le classifier ou le * classifierNumber est null. * @throws IllegalArgumentException si la version donnee contient deja un * classifier. */ public static Version addClassifier(Version version, String classifier, Integer classifierNumber) throws NullPointerException, IllegalArgumentException { Version result; if (classifier == null) { throw new NullPointerException("classifier can not be null"); } if (classifierNumber == null) { throw new NullPointerException("classifierNumber can not be null"); } if (version.hasClassifier()) { throw new IllegalArgumentException( "version " + version + "contains already a classifier "); } result = valueOf(classifier, classifierNumber, version.isSnapshot(), version.getNumbers()); return result; } /** * Construction d'une nouvelle version sans classifier a partir d'une * version donnee (sans classifier). * * @param version la version de base (avec classifier) * @return l'instance de la version requise * @throws IllegalArgumentException si la version donnee contient deja * un classifier. */ public static Version removeClassifier(Version version) throws IllegalArgumentException { Version result; if (!version.hasClassifier()) { throw new IllegalArgumentException( "version " + version + "does no contain a classifier "); } result = valueOf(version.isSnapshot(), version.getNumbers()); return result; } public static Version addSnapshot(Version version) { if (version.isSnapshot()) { throw new IllegalArgumentException( "version " + version + "is already a snapshot"); } Version result = valueOf(version.getClassifier(), version.getClassifierNumber(), true, version.getNumbers()); return result; } public static Version removeSnapshot(Version version) { if (!version.isSnapshot()) { throw new IllegalArgumentException( "version " + version + "is already a snapshot"); } Version result = valueOf(version.getClassifier(), version.getClassifierNumber(), false, version.getNumbers()); return result; } /** * Incremente le numero de version donnee, seul le dernier constituant est * incremente: 1.2.3.4 → 1.2.3.5; null → 1; 0 → 1. * * Si la version a un classifier, alors c'est la version du classifier qui * change : 1.1-alpha-12 → 1.1-alpha-13 * * @param v la version a incrementer * @return la nouvelle version */ public static Version inc(Version v) { int nbComponents = v.getNbComponents(); int[] newNumbers = Arrays.copyOf(v.numbers, nbComponents); String newClassifier = v.classifier; Integer newClassifierNumber = v.classifierNumber; if (v.hasClassifier()) { newClassifierNumber++; } else { newNumbers[nbComponents - 1] = newNumbers[nbComponents - 1] + 1; } Version result = valueOf(newClassifier, newClassifierNumber, v.isSnapshot(), newNumbers); return result; } /** * Remove the suffix {@code -SNAPSHOT} stamp from a version (if any). * * @param version the string representation of the version * @return the string representation of the given version * without the {@code -SNAPSHOT} suffix (if any). * @throws NullPointerException if version is null */ public static String removeSnapshot(String version) throws NullPointerException { if (version == null) { throw new NullPointerException("version parameter can not be null"); } int index = version.indexOf(SNAPSHOT_SUFFIX); if (index > -1) { version = version.substring(0, index); } return version; } /** * Filter versions. * * @param versions versions to filter * @param min min version to accept * @param max max version to accept * @param includeMin flag to include min version * @param includeMax flag to include max version * @return versions between min and max */ public static List filterVersions(Set versions, Version min, Version max, boolean includeMin, boolean includeMax) { List toApply = new ArrayList(); for (Version v : versions) { int t; if (min != null) { t = v.compareTo(min); if (t < 0 || t == 0 && !includeMin) { // version trop ancienne continue; } } if (max != null) { t = v.compareTo(max); if (t > 0 || t == 0 && !includeMax) { // version trop recente continue; } } toApply.add(v); } return toApply; } /** * L'implantation d'un comparateur de versions permettant de controler * l'ordre du numero de version, classifier et numero de classifer. * * Toute implementation de ce contrat devrait suivre cet algorithme : * * 1) Si versions égales, on quitte. * * 2) On teste l'ordre des nombres {@link #compareNumbers(Version, Version)} * * Si différent, alors versions différentes, on quitte * * 3) On teste l'ordre des classifiers * {@link #compareClassifier(Version, Version)} * * Si différent, alors versions différentes, on quitte * * 4) On teste l'ordre des versions de classifiers * {@link #compareClassifierNumber(Version, Version)}. */ public static class VersionComparator implements Comparator { @Override public int compare(Version o1, Version o2) { if (o1.equals(o2)) { // versions are equals return 0; } // compare on numbers int result = compareNumbers(o1, o2); if (result != 0) { // compare snapshot return result; } // numbers are equals // compare on classifier result = compareClassifier(o1, o2); if (result != 0) { return result; } // classifier are equals // compare on classifierNumber result = compareClassifierNumber(o1, o2); if (result != 0) { return result; } // classifierNumber are equals // compare on snapshot result = compareSnapshot(o1, o2); return result; } public int compareNumbers(Version o1, Version o2) { int nbComponents1 = o1.numbers.length; int nbComponents2 = o2.numbers.length; int minlen = Math.min(nbComponents1, nbComponents2); for (int i = 0; i < minlen; i++) { int t1 = o1.numbers[i]; int t2 = o2.numbers[i]; if (t1 == t2) { continue; } return t1 - t2; } // common version are equals // the longer number wins // example : 1.0.0 > 1.0 > 1 return nbComponents1 - nbComponents2; } public int compareClassifier(Version o1, Version o2) { if (o1.hasClassifier() && o2.hasClassifier()) { // o1 et o2 ont un classifier return o1.classifier.compareTo(o2.classifier); } if (!o1.hasClassifier() && !o2.hasClassifier()) { // o1 et o2 n'ont un classifier return 0; } if (!o1.hasClassifier()) { // o1 n'a pas de classifier, o1 est donc plus recent return 1; } if (!o2.hasClassifier()) { // o2 n'a pas de classifier, o2 est donc plus recent return -1; } // o1 et o2 n'ont pas de classifier, il sont donc egaux return 0; } public int compareClassifierNumber(Version o1, Version o2) { if (!o1.hasClassifier() && !o2.hasClassifier()) { // o1 et o2 n'ont un classifier return 0; } return o1.classifierNumber - o2.classifierNumber; } public int compareSnapshot(Version o1, Version o2) { boolean snapshot1 = o1.isSnapshot(); boolean snapshot2 = o2.isSnapshot(); if ((snapshot1 && snapshot2) || (!snapshot1 && !snapshot2)) { // equals return 0; } if (snapshot1) { // !snapshot2, so v1 est before v2 return -1; } return 1; } } /** * Tests if two versions are equals. * * @param version0 the first version * @param version1 the second version * @return {@code true} if versions are equals, {@code false} otherwise. */ public static boolean equals(String version0, String version1) { Version v0 = valueOf(version0); Version v1 = valueOf(version1); boolean result = v0.equals(v1); return result; } /** * Tests if the first version is smaller than the second version. * * @param version0 the first version * @param version1 the second version * @return {@code true} if {@code version0} is before {@code version1}, * {@code false} otherwise. */ public static boolean smallerThan(String version0, String version1) { Version v0 = valueOf(version0); Version v1 = valueOf(version1); boolean result = v0.before(v1); return result; } /** * Tests if the first version is greater than the second version. * * @param version0 the first version * @param version1 the second version * @return {@code true} if {@code version0} is after {@code version1}, * {@code false} otherwise. */ public static boolean greaterThan(String version0, String version1) { Version v0 = valueOf(version0); Version v1 = valueOf(version1); boolean result = v0.after(v1); return result; } /** * Trier un ensemble de versions données en entrees * * On affiche le resultat dans la console * * @param args les versions */ public static void main(String... args) { List list = new ArrayList(); List snapshots = new ArrayList(); for (String a : args) { if (a.endsWith(SNAPSHOT_SUFFIX)) { snapshots.add(valueOf( a.substring(0, a.length() - VersionUtil.SNAPSHOT_SUFFIX.length()))); continue; } Version v = valueOf(a); list.add(v); } Collections.sort(list); List asString = new ArrayList(); for (Version v : list) { asString.add(v.toString()); } // repositionnement des snapshots for (Version snap : snapshots) { String v = snap.toString(); if (list.contains(snap)) { // on ajoute juste avant int index = asString.indexOf(v); asString.add(index, v + SNAPSHOT_SUFFIX); } else { // ajout dans la liste initiale list.add(snap); Collections.sort(list); int index = list.indexOf(snap); if (index == 0) { asString.add(0, v + SNAPSHOT_SUFFIX); } else { Version v2 = list.get(index - 1); index = asString.indexOf(v2.toString()); asString.add(index + 1, v + SNAPSHOT_SUFFIX); } list.remove(snap); } } StringBuilder buffer = new StringBuilder(); for (String s : asString) { buffer.append(s).append("\n"); } System.out.println(buffer.toString()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy