/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library 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 2.1 of the License, or (at your option)
* any later version.
*
* This library 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 Lesser General Public License for more
* details.
*/
package com.liferay.portal.kernel.plugin;
import com.liferay.portal.kernel.util.CharPool;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.Validator;
import java.io.Serializable;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author Jorge Ferrer
*/
public class Version implements Comparable<Version>, Serializable {
public static final String SNAPSHOT = "SNAPSHOT";
public static final String UNKNOWN = "unknown";
public static Version getInstance(String version) {
Version versionObj = _versions.get(version);
if (versionObj == null) {
versionObj = new Version(version);
_versions.put(version, versionObj);
}
return versionObj;
}
public static Version incrementBugFix(Version version) {
String bugFix = version.getBugFix();
int bugFixInt = GetterUtil.getInteger(bugFix);
if (bugFixInt > 0) {
bugFix = String.valueOf(bugFixInt + 1);
}
return getInstance(
_toString(
version.getMajor(), version.getMinor(), bugFix,
version.getBuildNumber(), version.getQualifier()));
}
public static Version incrementBuildNumber(Version version) {
String buildNumber = version.getBuildNumber();
int buildNumberInt = GetterUtil.getInteger(buildNumber);
if (buildNumberInt > 0) {
buildNumber = String.valueOf(buildNumberInt + 1);
}
return getInstance(
_toString(
version.getMajor(), version.getMinor(), version.getBugFix(),
buildNumber, version.getQualifier()));
}
public static Version incrementMajor(Version version) {
String major = version.getMajor();
int majorInt = GetterUtil.getInteger(major);
if (majorInt > 0) {
major = String.valueOf(majorInt + 1);
}
return getInstance(
_toString(
major, version.getMinor(), version.getBugFix(),
version.getBuildNumber(), version.getQualifier()));
}
public static Version incrementMinor(Version version) {
String minor = version.getMinor();
int minorInt = GetterUtil.getInteger(minor);
if (minorInt > 0) {
minor = String.valueOf(minorInt + 1);
}
return getInstance(
_toString(
version.getMajor(), minor, version.getBugFix(),
version.getBuildNumber(), version.getQualifier()));
}
@Override
public int compareTo(Version version) {
if (version == null) {
return 1;
}
// Unknown is always considered a lower version
if (version.toString().equals(UNKNOWN)) {
return 1;
}
if (toString().equals(UNKNOWN)) {
return -1;
}
int result = _compareAsIntegers(getMajor(), version.getMajor());
if (result != 0) {
return result;
}
result = _compareAsIntegers(getMinor(), version.getMinor());
if (result != 0) {
return result;
}
result = _compareAsIntegers(getBugFix(), version.getBugFix());
if (result != 0) {
return result;
}
result = _compareAsIntegers(getBuildNumber(), version.getBuildNumber());
if (result != 0) {
return result;
}
return _compareAsQualifiers(getQualifier(), version.getQualifier());
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Version)) {
return false;
}
Version version = (Version)obj;
String versionString1 = toString();
String versionString2 = version.toString();
if (versionString1.equals(UNKNOWN) || versionString2.equals(UNKNOWN)) {
return false;
}
return versionString1.equals(versionString2);
}
public String getBugFix() {
if (_bugFix == null) {
return "0";
}
return _bugFix;
}
public String getBuildNumber() {
return _buildNumber;
}
public String getMajor() {
if (_major == null) {
return "0";
}
return _major;
}
public String getMinor() {
if (_minor == null) {
return "0";
}
return _minor;
}
public String getQualifier() {
if (_qualifier == null) {
return StringPool.BLANK;
}
return _qualifier;
}
@Override
public int hashCode() {
return toString().hashCode();
}
public boolean includes(Version version) {
if (equals(version)) {
return true;
}
if (getMajor().equals(StringPool.STAR)) {
return true;
}
if (getMajor().equals(version.getMajor())) {
if (getMinor().equals(StringPool.STAR)) {
return true;
}
if (getMinor().equals(version.getMinor())) {
if (getBugFix().equals(StringPool.STAR)) {
return true;
}
if (getBugFix().equals(version.getBugFix())) {
if (getBuildNumber().equals(StringPool.STAR) ||
getBuildNumber().equals(version.getBuildNumber())) {
return true;
}
else if (_contains(
getBuildNumber(), version.getBuildNumber())) {
return true;
}
}
else if (_contains(getBugFix(), version.getBugFix())) {
return true;
}
}
else if (_contains(getMinor(), version.getMinor())) {
return true;
}
}
else if (_contains(getMajor(), version.getMajor())) {
return true;
}
return false;
}
public boolean isLaterVersionThan(String version) {
if (compareTo(getInstance(version)) > 0) {
return true;
}
else {
return false;
}
}
public boolean isPreviousVersionThan(String version) {
if (compareTo(getInstance(version)) < 0) {
return true;
}
else {
return false;
}
}
public boolean isSameVersionAs(String version) {
if (compareTo(getInstance(version)) == 0) {
return true;
}
else {
return false;
}
}
@Override
public String toString() {
return _toString(_major, _minor, _bugFix, _buildNumber, _qualifier);
}
protected Version(String version) {
int index = version.indexOf(CharPool.DASH);
if (index != -1) {
_qualifier = version.substring(index + 1);
version = version.substring(0, index);
}
StringTokenizer st = new StringTokenizer(version, _SEPARATOR);
_major = st.nextToken();
if (st.hasMoreTokens()) {
_minor = st.nextToken();
}
if (st.hasMoreTokens()) {
_bugFix = st.nextToken();
}
if (st.hasMoreTokens()) {
_buildNumber = st.nextToken();
}
else {
_buildNumber = null;
}
}
private static boolean _contains(
String containerString, String numberString) {
if (containerString.endsWith(StringPool.PLUS)) {
String containerNumberString = containerString.substring(
0, containerString.length() - 1);
try {
int containerNumber = GetterUtil.getInteger(
containerNumberString);
int number = GetterUtil.getInteger(numberString);
if (containerNumber <= number) {
return true;
}
return false;
}
catch (NumberFormatException nfe) {
return false;
}
}
return false;
}
private static String _toString(
String major, String minor, String bugFix, String buildNumber,
String qualifier) {
StringBundler sb = new StringBundler(7);
sb.append(major);
if (Validator.isNotNull(minor)) {
sb.append(_SEPARATOR);
sb.append(minor);
if (Validator.isNotNull(bugFix)) {
sb.append(_SEPARATOR);
sb.append(bugFix);
if (Validator.isNotNull(buildNumber)) {
sb.append(_SEPARATOR);
sb.append(buildNumber);
}
}
}
if (Validator.isNotNull(qualifier)) {
sb.append(CharPool.DASH);
sb.append(qualifier);
}
return sb.toString();
}
private int _compareAsIntegers(String first, String second) {
int firstInteger = GetterUtil.getInteger(first);
int secondInteger = GetterUtil.getInteger(second);
if (firstInteger < secondInteger) {
return -1;
}
else if (firstInteger == secondInteger) {
return 0;
}
else {
return 1;
}
}
private int _compareAsQualifiers(String first, String second) {
String firstString = GetterUtil.getString(first);
String secondString = GetterUtil.getString(second);
if (StringUtil.equalsIgnoreCase(firstString, SNAPSHOT) &&
!StringUtil.equalsIgnoreCase(secondString, SNAPSHOT)) {
return -1;
}
else if (!StringUtil.equalsIgnoreCase(firstString, SNAPSHOT) &&
StringUtil.equalsIgnoreCase(secondString, SNAPSHOT)) {
return 1;
}
return 0;
}
private static final String _SEPARATOR = StringPool.PERIOD;
private static final Map<String, Version> _versions =
new ConcurrentHashMap<>();
private String _bugFix;
private final String _buildNumber;
private String _major;
private String _minor;
private String _qualifier;
}