com.buession.core.utils.VersionUtils Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to you 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.
*
* =================================================================================================
*
* This software consists of voluntary contributions made by many individuals on behalf of the
* Apache Software Foundation. For more information on the Apache Software Foundation, please see
* .
*
* +------------------------------------------------------------------------------------------------+
* | License: http://www.apache.org/licenses/LICENSE-2.0.txt |
* | Author: Yong.Teng |
* | Copyright @ 2013-2021 Buession.com Inc. |
* +------------------------------------------------------------------------------------------------+
*/
package com.buession.core.utils;
import com.buession.core.validator.Validate;
import java.io.File;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.CodeSource;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
/**
* 版本工具类
*
* @author Yong.Teng
*/
public class VersionUtils {
private final static String NAN = "#N#";
private final static char ZERO = '0';
private final static Map SPECIAL_VERSIONS = new LinkedHashMap<>(10);
static{
SPECIAL_VERSIONS.put("dev", 0);
SPECIAL_VERSIONS.put("alpha", 1);
SPECIAL_VERSIONS.put("a", 1);
SPECIAL_VERSIONS.put("beta", 2);
SPECIAL_VERSIONS.put("b", 2);
SPECIAL_VERSIONS.put("rc", 3);
SPECIAL_VERSIONS.put("#", 4);
SPECIAL_VERSIONS.put("release", 4);
SPECIAL_VERSIONS.put("pl", 5);
SPECIAL_VERSIONS.put("p", 5);
}
/**
* 版本号比较
*
* @param version1
* 第一个版本号
* @param version2
* 第二个版本号
*
* @return 当 version1 < version2 时,返回 -1;当 version1 = version2 时,返回 0;当 version1 > version2 时返回 1
*/
public final static int compare(final String version1, final String version2){
char first1 = version1.charAt(0);
char first2 = version2.charAt(0);
if(first1 == ZERO || first2 == ZERO){
return first1 == ZERO && first2 == ZERO ? 0 : (first2 != ZERO ? 1 : -1);
}
String ver1 = first1 == '#' ? version1 : cannibalizeVersion(version1);
String ver2 = first2 == '#' ? version2 : cannibalizeVersion(version2);
String p1;
String p2;
int result = 0;
while(ver1 != null && ver2 != null){
int nd1 = ver1.indexOf('.');
int nd2 = ver2.indexOf('.');
p1 = nd1 == -1 ? ver1 : ver1.substring(0, nd1);
p2 = nd2 == -1 ? ver2 : ver2.substring(0, nd2);
if(Validate.isDigit(p1) && Validate.isDigit(p2)){
result = normalize(Integer.parseInt(p1) - Integer.parseInt(p2));
}else if(Validate.isDigit(p1) == false && Validate.isDigit(p2) == false){
result = compareSpecialVersion(p1, p2);
}else{
result = Validate.isDigit(p1.charAt(0)) ? compareSpecialVersion(NAN, p2) : compareSpecialVersion(p1,
NAN);
}
if(result != 0){
break;
}
ver1 = nd1 == -1 ? null : ver1.substring(nd1 + 1);
ver2 = nd2 == -1 ? null : ver2.substring(nd2 + 1);
}
if(result == 0){
if(ver1 != null){
result = Validate.isDigit(ver1.charAt(0)) ? 1 : compare(ver1, NAN);
}else if(ver2 != null){
result = Validate.isDigit(ver2.charAt(0)) ? -1 : compare(NAN, ver2);
}
}
return result;
}
public final static String determineClassVersion(final Class> clazz){
String implementationVersion = clazz.getPackage().getImplementationVersion();
if(implementationVersion != null){
return implementationVersion;
}
CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
if(codeSource == null){
return null;
}
URL codeSourceLocation = codeSource.getLocation();
try{
URLConnection connection = codeSourceLocation.openConnection();
if(connection instanceof JarURLConnection){
return getJarFileImplementationVersion(((JarURLConnection) connection).getJarFile());
}
JarFile jarFile = new JarFile(new File(codeSourceLocation.toURI()));
return getJarFileImplementationVersion(jarFile);
}catch(Exception ex){
return null;
}
}
public final static String getJarFileImplementationVersion(final JarFile jarFile) throws IOException{
return jarFile.getManifest().getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
}
private final static String cannibalizeVersion(final String version){
if(version == null){
return null;
}
int length = version.length();
if(length == 0){
return version;
}
StringBuilder sb = new StringBuilder(length + 4);
for(int i = 0; i < length; i++){
char c = version.charAt(i);
char next = i + 1 < length ? version.charAt(i + 1) : '\0';
if(isSpecialVer(c)){ // replace "-","_","+" to "."
sb.append('.');
}else if(next != '\0' && (Validate.isDigit(c) && Validate.isDigit(next) == false || Validate.isDigit(c) == false && Validate.isDigit(next))){ // Insert '.' before and after a non-digit
sb.append(c);
if(c != '.' && next != '.'){
sb.append('.');
}
}else if(Validate.isAlnum(c) == false){ // Non-letters and numbers
sb.append('.');
}else{
sb.append(c);
}
}
return sb.toString();
}
private final static int compareSpecialVersion(final String version1, final String version2){
int found1 = -1;
int found2 = -1;
for(Map.Entry e : SPECIAL_VERSIONS.entrySet()){
String ver = e.getKey();
int order = e.getValue();
if(StringUtils.equals(ver, version1, ver.length())){
found1 = order;
}
if(StringUtils.equals(ver, version2, ver.length())){
found2 = order;
}
}
return normalize(found1 - found2);
}
private final static boolean isSpecialVer(final char c){
return c == '-' || c == '_' || c == '+';
}
private final static int normalize(final int value){
return value == 0 ? 0 : (value < 0 ? -1 : 1);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy