Skip to content

Commit

Permalink
Branch refactor version (#3471)
Browse files Browse the repository at this point in the history
  • Loading branch information
wanghbxxxx authored and lixiaojiee committed Feb 15, 2019
1 parent 9c049f6 commit d33784d
Showing 1 changed file with 83 additions and 65 deletions.
148 changes: 83 additions & 65 deletions dubbo-common/src/main/java/org/apache/dubbo/common/Version.java
Expand Up @@ -21,19 +21,24 @@
import org.apache.dubbo.common.utils.ClassHelper;
import org.apache.dubbo.common.utils.StringUtils;

import java.io.IOException;
import java.net.URL;
import java.security.CodeSource;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Version
*/
public final class Version {
private static final Logger logger = LoggerFactory.getLogger(Version.class);

private static final Pattern PREFIX_DIGITS_PATTERN = Pattern.compile("^([0-9]*).*");

// Dubbo RPC protocol version, for compatibility, it must not be between 2.0.10 ~ 2.6.2
public static final String DEFAULT_DUBBO_PROTOCOL_VERSION = "2.0.2";
Expand Down Expand Up @@ -120,73 +125,47 @@ private static int parseInt(String version) {
String[] vArr = version.split("\\.");
int len = vArr.length;
for (int i = 0; i < len; i++) {
v += Integer.parseInt(getDigital(vArr[i])) * Math.pow(10, (len - i - 1) * 2);
v += Integer.parseInt(getPrefixDigits(vArr[i])) * Math.pow(10, (len - i - 1) * 2);
}
return v;
}

private static String getDigital(String v) {
int index = 0;
for (int i = 0; i < v.length(); i++) {
char c = v.charAt(i);
if (Character.isDigit(c)) {
if (i == v.length() - 1) {
index = i + 1;
} else {
index = i;
}
} else {
index = i;
break;
}
}
return v.substring(0, index);
}

private static boolean hasResource(String path) {
try {
return Version.class.getClassLoader().getResource(path) != null;
} catch (Throwable t) {
return false;
/**
* get prefix digits from given version string
*/
private static String getPrefixDigits(String v) {
Matcher matcher = PREFIX_DIGITS_PATTERN.matcher(v);
if (matcher.find()) {
return matcher.group(1);
}
return "";
}

public static String getVersion(Class<?> cls, String defaultVersion) {
try {
// find version info from MANIFEST.MF first
String version = cls.getPackage().getImplementationVersion();
if (StringUtils.isEmpty(version)) {
version = cls.getPackage().getSpecificationVersion();
if (!StringUtils.isEmpty(version)) {
return version;
}
if (StringUtils.isEmpty(version)) {
// guess version fro jar file name if nothing's found from MANIFEST.MF
CodeSource codeSource = cls.getProtectionDomain().getCodeSource();
if (codeSource == null) {
logger.info("No codeSource for class " + cls.getName() + " when getVersion, use default version " + defaultVersion);
} else {
String file = codeSource.getLocation().getFile();
if (file != null && file.length() > 0 && file.endsWith(".jar")) {
file = file.substring(0, file.length() - 4);
int i = file.lastIndexOf('/');
if (i >= 0) {
file = file.substring(i + 1);
}
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
}
while (file.length() > 0 && !Character.isDigit(file.charAt(0))) {
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
} else {
break;
}
}
version = file;
}
}

version = cls.getPackage().getSpecificationVersion();
if (!StringUtils.isEmpty(version)) {
return version;
}

// guess version fro jar file name if nothing's found from MANIFEST.MF
CodeSource codeSource = cls.getProtectionDomain().getCodeSource();
if (codeSource == null) {
logger.info("No codeSource for class " + cls.getName() + " when getVersion, use default version " + defaultVersion);
return defaultVersion;
}

String file = codeSource.getLocation().getFile();
if (!StringUtils.isEmpty(file) && file.endsWith(".jar")) {
version = getFromFile(file);
}

// return default version if no version info is found
return StringUtils.isEmpty(version) ? defaultVersion : version;
} catch (Throwable e) {
Expand All @@ -196,6 +175,37 @@ public static String getVersion(Class<?> cls, String defaultVersion) {
}
}

/**
* get version from file: path/to/group-module-x.y.z.jar, returns x.y.z
*/
private static String getFromFile(String file) {
// remove suffix ".jar": "path/to/group-module-x.y.z"
file = file.substring(0, file.length() - 4);

// remove path: "group-module-x.y.z"
int i = file.lastIndexOf('/');
if (i >= 0) {
file = file.substring(i + 1);
}

// remove group: "module-x.y.z"
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
}

// remove module: "x.y.z"
while (file.length() > 0 && !Character.isDigit(file.charAt(0))) {
i = file.indexOf("-");
if (i >= 0) {
file = file.substring(i + 1);
} else {
break;
}
}
return file;
}

public static void checkDuplicate(Class<?> cls, boolean failOnError) {
checkDuplicate(cls.getName().replace('.', '/') + ".class", failOnError);
}
Expand All @@ -207,17 +217,7 @@ public static void checkDuplicate(Class<?> cls) {
public static void checkDuplicate(String path, boolean failOnError) {
try {
// search in caller's classloader
Enumeration<URL> urls = ClassHelper.getCallerClassLoader(Version.class).getResources(path);
Set<String> files = new HashSet<String>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String file = url.getFile();
if (file != null && file.length() > 0) {
files.add(file);
}
}
}
Set<String> files = getResources(path);
// duplicated jar is found
if (files.size() > 1) {
String error = "Duplicate class " + path + " in " + files.size() + " jar " + files;
Expand All @@ -232,4 +232,22 @@ public static void checkDuplicate(String path, boolean failOnError) {
}
}

/**
* search resources in caller's classloader
*/
private static Set<String> getResources(String path) throws IOException {
Enumeration<URL> urls = ClassHelper.getCallerClassLoader(Version.class).getResources(path);
Set<String> files = new HashSet<String>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
if (url != null) {
String file = url.getFile();
if (file != null && file.length() > 0) {
files.add(file);
}
}
}
return files;
}

}

0 comments on commit d33784d

Please sign in to comment.