package freenet.support;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* JVM version utilities.
*
* See documentation:
* http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html (pre-9)
* http://openjdk.java.net/jeps/223 (post-9)
*/
public class JVMVersion {
public static final String REQUIRED = "1.8";
/**
* Pre-9 is formatted as: major.feature[.maintenance[_update]]-ident
* Post-9 is formatted as: major[.minor[.security[. ...]]]-ident
* For comparison of compatibility, information beyong the major, feature/minor,
* maintenance/security and pre-9 update fields should not be of interest.
* We find a common denominator in major(.a(.b([._]c)?)?)?, skipping any additional postfix.
* The regex omits leading zeroes.
*/
private static final Pattern VERSION_PATTERN =
Pattern.compile("^0*(\\d+)(?:\\.0*(\\d+)(?:\\.0*(\\d+)(?:[_.]0*(\\d+))?)?)?.*$");
public static boolean isTooOld() {
return isTooOld(getCurrent());
}
public static String getCurrent() {
return System.getProperty("java.version");
}
static boolean isTooOld(String version) {
if (version == null) return false;
return compareVersion(version, REQUIRED) < 0;
}
public static final boolean is32Bit() {
boolean is32bitOS = System.getProperty("os.arch").equalsIgnoreCase("x86");
String prop = System.getProperty("sun.arch.data.model");
if (prop != null) {
return prop.startsWith("32") || is32bitOS;
} else {
return is32bitOS;
}
}
/**
* Decomposes a version string into major, feature, and optional maintenance and update
* components.
* Missing optional components are set to 0, failed parses return all zeroes.
*/
static int[] parse(String version) {
int[] parsed = new int[4];
if (version == null) {
return parsed;
}
Matcher m = VERSION_PATTERN.matcher(version);
if (m.matches()) {
for (int i = 0; i < 4; i++) {
String component = m.group(i + 1);
if (component != null) {
parsed[i] = Integer.parseInt(component);
}
}
}
return parsed;
}
/**
* Compares two version strings, ignoring optional identifiers.
* Version strings that cannot be parsed are treated as version 0.0.0_0.
* @return A value < 0 if version1 is less than version2, 0 if they are equal, > 0 otherwise.
*/
static int compareVersion(String version1, String version2) {
int[] parsed1 = parse(version1);
int[] parsed2 = parse(version2);
for (int i = 0; i < 4; i++) {
if (parsed1[i] < parsed2[i]) {
return -1;
}
if (parsed1[i] > parsed2[i]) {
return 1;
}
}
return 0;
}
}