/*
* (C) Copyright 2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Contributors:
* Julien Carsique
*
*/
package org.nuxeo.common.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* Compare versions of files as they are usually set. Maven classifiers are not managed: a classifier will be considered
* as being part of the version. Maven "SNAPSHOT" keyword is taken in account. Rule is: x-SNAPSHOT < x <
* x-AnythingButSNAPSHOT < x.y-SNAPSHOT < x.y
*
* @since 5.5
*/
public class FileVersion implements Comparable<FileVersion> {
protected static final String SNAPSHOT = "-SNAPSHOT";
protected String version;
protected boolean snapshot;
protected boolean specialQualifier;
protected Integer[] splitVersion;
protected String qualifier = "";
private String separator = "";
private String tmpVersion;
private static final Pattern SPECIAL_QUALIFIER = Pattern.compile("^-(((RC)|(rc)|(alpha)|(ALPHA)|(beta)|(BETA)\\d+)|([a-zA-Z][0-9]{8})).*$");
public String getQualifier() {
return qualifier;
}
public Integer[] getSplitVersion() {
return splitVersion;
}
public FileVersion(String value) {
this.version = value;
this.snapshot = value.endsWith(SNAPSHOT);
split(getVersionWithoutSnapshot());
this.specialQualifier = SPECIAL_QUALIFIER.matcher(qualifier).matches();
}
public void split(String value) {
if (value.startsWith("r")) {
// special case for caja-r1234 versions
value = value.substring(1);
}
List<Integer> versions = new ArrayList<Integer>();
this.tmpVersion = value;
do {
if (".".equals(separator)) {
try {
versions.add(Integer.valueOf(tmpVersion));
break;
} catch (NumberFormatException e) {
}
}
if (splitWith(".", versions)) {
continue;
}
if (splitWith("-", versions)) {
continue;
}
if (splitWith("_", versions)) {
continue;
}
qualifier = separator + tmpVersion;
break;
} while (true);
splitVersion = versions.toArray(new Integer[0]);
}
private boolean splitWith(String token, List<Integer> versions) {
try {
int index = tmpVersion.indexOf(token);
if (index > 0) {
versions.add(Integer.valueOf(tmpVersion.substring(0, index)));
separator = tmpVersion.substring(index, index + 1);
tmpVersion = tmpVersion.substring(index + 1);
return true;
} else {
// treat versions containing only major versions: "1-q", "2"
// etc.
if (versions.isEmpty()) {
versions.add(Integer.valueOf(tmpVersion));
return false;
}
}
} catch (NumberFormatException e) {
}
return false;
}
@Override
public int compareTo(FileVersion o) {
if (snapshot && getVersionWithoutSnapshot().equals(o.getVersion()) || specialQualifier
&& getVersionWithoutQualifier().equals(o.getVersion())) {
return -1;
} else if (o.isSnapshot() && version.equals(o.getVersionWithoutSnapshot()) || o.hasSpecialQualifier()
&& version.equals(o.getVersionWithoutQualifier())) {
return 1;
}
int index = 0, number, oNumber, result;
do {
if (splitVersion.length > index) {
number = splitVersion[index];
} else {
number = 0;
}
if (o.getSplitVersion().length > index) {
oNumber = o.getSplitVersion()[index];
} else {
oNumber = 0;
}
result = number - oNumber;
index++;
} while (result == 0 && (splitVersion.length > index || o.getSplitVersion().length > index));
if (result == 0) {
result = qualifier.compareTo(o.getQualifier());
}
return result;
}
@Override
public boolean equals(Object o) {
return (this == o || o != null && (o instanceof FileVersion) && compareTo((FileVersion) o) == 0);
}
public String getVersion() {
return version;
}
public String getVersionWithoutSnapshot() {
if (snapshot) {
return version.substring(0, version.lastIndexOf(SNAPSHOT));
}
return version;
}
public boolean greaterThan(FileVersion other) {
return compareTo(other) > 0;
}
public boolean lessThan(FileVersion other) {
return compareTo(other) < 0;
}
public boolean isSnapshot() {
return snapshot;
}
/**
* @since 5.6
*/
public boolean hasSpecialQualifier() {
return specialQualifier;
}
/**
* @since 5.6
*/
public String getVersionWithoutQualifier() {
return version.substring(0, version.lastIndexOf(qualifier));
}
@Override
public String toString() {
return version;
}
}