// Generated by delombok at Sun Feb 26 12:31:38 KST 2017
package scouter.bytebuddy;
import scouter.bytebuddy.description.type.TypeDescription;
import scouter.bytebuddy.dynamic.ClassFileLocator;
import scouter.bytebuddy.jar.asm.ClassReader;
import scouter.bytebuddy.jar.asm.ClassVisitor;
import scouter.bytebuddy.jar.asm.Opcodes;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* A wrapper object for representing a validated class file version in the format that is specified by the
* <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html">JVMS</a>.
*/
public class ClassFileVersion implements Comparable<ClassFileVersion> {
/**
* Returns the minimal version number that is legal.
*/
protected static final int BASE_VERSION = 44;
/**
* The class file version of Java 1.
*/
public static final ClassFileVersion JAVA_V1 = new ClassFileVersion(Opcodes.V1_1);
/**
* The class file version of Java 2.
*/
public static final ClassFileVersion JAVA_V2 = new ClassFileVersion(Opcodes.V1_2);
/**
* The class file version of Java 3.
*/
public static final ClassFileVersion JAVA_V3 = new ClassFileVersion(Opcodes.V1_3);
/**
* The class file version of Java 4.
*/
public static final ClassFileVersion JAVA_V4 = new ClassFileVersion(Opcodes.V1_4);
/**
* The class file version of Java 5.
*/
public static final ClassFileVersion JAVA_V5 = new ClassFileVersion(Opcodes.V1_5);
/**
* The class file version of Java 6.
*/
public static final ClassFileVersion JAVA_V6 = new ClassFileVersion(Opcodes.V1_6);
/**
* The class file version of Java 7.
*/
public static final ClassFileVersion JAVA_V7 = new ClassFileVersion(Opcodes.V1_7);
/**
* The class file version of Java 8.
*/
public static final ClassFileVersion JAVA_V8 = new ClassFileVersion(Opcodes.V1_8);
/**
* The class file version of Java 9.
*/
public static final ClassFileVersion JAVA_V9 = new ClassFileVersion(53);
/**
* A version locator for the executing JVM.
*/
private static final VersionLocator VERSION_LOCATOR = AccessController.doPrivileged(VersionLocator.CreationAction.INSTANCE);
/**
* The version number that is represented by this class file version instance.
*/
private final int versionNumber;
/**
* Creates a wrapper for a given minor-major release of the Java class file file.
*
* @param versionNumber The minor-major release number.
*/
protected ClassFileVersion(int versionNumber) {
this.versionNumber = versionNumber;
}
/**
* Creates a wrapper for a given minor-major release of the Java class file file.
*
* @param versionNumber The minor-major release number.
* @return A representation of the version number.
*/
public static ClassFileVersion ofMinorMajor(int versionNumber) {
ClassFileVersion classFileVersion = new ClassFileVersion(versionNumber);
if (classFileVersion.getMajorVersion() <= BASE_VERSION) {
throw new IllegalArgumentException("Class version " + versionNumber + " is not valid");
}
return classFileVersion;
}
/**
* Creates a class file version for a given major release of Java. Currently, all versions reaching from
* Java 1 to Java 8 are supported.
*
* @param javaVersion The Java version.
* @return A wrapper for the given Java class file version.
*/
public static ClassFileVersion ofJavaVersion(int javaVersion) {
switch (javaVersion) {
case 1:
return JAVA_V1;
case 2:
return JAVA_V2;
case 3:
return JAVA_V3;
case 4:
return JAVA_V4;
case 5:
return JAVA_V5;
case 6:
return JAVA_V6;
case 7:
return JAVA_V7;
case 8:
return JAVA_V8;
case 9:
return JAVA_V9;
default:
throw new IllegalArgumentException("Unknown Java version: " + javaVersion);
}
}
/**
* Finds the highest class file version that is compatible to the current JVM version. Prior to Java 9, this is achieved
* by parsing the {@code java.version} property which is provided by {@link java.lang.System#getProperty(String)}. If the system
* property is not available, an {@link IllegalStateException} is thrown.
*
* @return The currently running Java process's class file version.
*/
public static ClassFileVersion ofThisVm() {
return VERSION_LOCATOR.locate();
}
/**
* Finds the highest class file version that is compatible to the current JVM version. Prior to Java 9, this is achieved
* by parsing the {@code java.version} property which is provided by {@link java.lang.System#getProperty(String)}. If the system
* property is not available, the {@code fallback} version is returned.
*
* @param fallback The version to fallback to if locating a class file version is not possible.
* @return The currently running Java process's class file version or the fallback if locating this version is impossible.
*/
public static ClassFileVersion ofThisVm(ClassFileVersion fallback) {
try {
return ofThisVm();
} catch (Exception ignored) {
return fallback;
}
}
/**
* Extracts a class' class version. The class' byte code is located by querying the {@link ClassLoader} of the class.
*
* @param type The type for which to locate a class file version.
* @return The type's class file version.
* @throws IOException If an error occurs while reading the class file.
*/
public static ClassFileVersion of(Class<?> type) throws IOException {
return of(type, ClassFileLocator.ForClassLoader.of(type.getClassLoader()));
}
/**
* Extracts a class' class version.
*
* @param type The type for which to locate a class file version.
* @param classFileLocator The class file locator to query for a class file.
* @return The type's class file version.
* @throws IOException If an error occurs while reading the class file.
*/
public static ClassFileVersion of(Class<?> type, ClassFileLocator classFileLocator) throws IOException {
return of(new TypeDescription.ForLoadedType(type), classFileLocator);
}
/**
* Extracts a class' class version.
*
* @param typeDescription The type for which to locate a class file version.
* @param classFileLocator The class file locator to query for a class file.
* @return The type's class file version.
* @throws IOException If an error occurs while reading the class file.
*/
public static ClassFileVersion of(TypeDescription typeDescription, ClassFileLocator classFileLocator) throws IOException {
ClassReader classReader = new ClassReader(classFileLocator.locate(typeDescription.getName()).resolve());
VersionExtractor versionExtractor = new VersionExtractor();
classReader.accept(versionExtractor, ClassReader.SKIP_CODE);
return ClassFileVersion.ofMinorMajor(versionExtractor.getClassFileVersionNumber());
}
/**
* Returns the minor-major release number of this class file version.
*
* @return The minor-major release number of this class file version.
*/
public int getMinorMajorVersion() {
return versionNumber;
}
/**
* Returns the major version this instance represents.
*
* @return The major version this instance represents.
*/
public int getMajorVersion() {
return versionNumber & 255;
}
/**
* Returns the minor version this instance represents.
*
* @return The minor version this instance represents.
*/
public int getMinorVersion() {
return versionNumber >> 16;
}
/**
* Returns the Java runtime version number of this class file version.
*
* @return The Java runtime version.
*/
public int getJavaVersion() {
return getMajorVersion() - BASE_VERSION;
}
/**
* Checks if this class file version is at least of the provided version.
*
* @param classFileVersion The version to check against.
* @return {@code true} if this version is at least of the given version.
*/
public boolean isAtLeast(ClassFileVersion classFileVersion) {
return compareTo(classFileVersion) > -1;
}
/**
* Checks if this class file version is less than the provided version.
*
* @param classFileVersion The version to check against.
* @return {@code true} if this version is less than the given version.
*/
public boolean isLessThan(ClassFileVersion classFileVersion) {
return compareTo(classFileVersion) < 0;
}
@Override
public int compareTo(ClassFileVersion other) {
return Integer.signum(getMajorVersion() == other.getMajorVersion() ? getMinorVersion() - other.getMinorVersion() : getMajorVersion() - other.getMajorVersion());
}
/**
* A locator for the executing VM's Java version.
*/
protected interface VersionLocator {
/**
* Locates the current VM's major version number.
*
* @return The current VM's major version number.
*/
ClassFileVersion locate();
/**
* A creation action for a version locator.
*/
enum CreationAction implements PrivilegedAction<VersionLocator> {
/**
* The singleton instance.
*/
INSTANCE;
@Override
public VersionLocator run() {
try {
return new VersionLocator.ForJava9CapableVm(Runtime.class.getMethod("version"), Class.forName("java.lang.Runtime$Version").getMethod("major"));
} catch (Exception ignored) {
return VersionLocator.ForLegacyVm.INSTANCE;
}
}
}
/**
* A version locator for a JVM of at least version 9.
*/
class ForJava9CapableVm implements VersionLocator {
/**
* Indicates that a reflective method call invokes a static method.
*/
private static final Object STATIC_METHOD = null;
/**
* The {@code java java.lang.Runtime#current()} method.
*/
private final Method current;
/**
* The {@code java.lang.Runtime.Version#major()} method.
*/
private final Method major;
/**
* Creates a new version locator for a Java 9 capable VM.
*
* @param current The {@code java.lang.Runtime#current()} method.
* @param major The {@code java.lang.Runtime.Version#major()} method.
*/
protected ForJava9CapableVm(Method current, Method major) {
this.current = current;
this.major = major;
}
@Override
public ClassFileVersion locate() {
try {
return ClassFileVersion.ofJavaVersion((Integer) major.invoke(current.invoke(STATIC_METHOD)));
} catch (IllegalAccessException exception) {
throw new IllegalStateException("Could not access VM version lookup", exception);
} catch (InvocationTargetException exception) {
throw new IllegalStateException("Could not look up VM version", exception.getCause());
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof ClassFileVersion.VersionLocator.ForJava9CapableVm)) return false;
final ClassFileVersion.VersionLocator.ForJava9CapableVm other = (ClassFileVersion.VersionLocator.ForJava9CapableVm) o;
if (!other.canEqual((java.lang.Object) this)) return false;
final java.lang.Object this$current = this.current;
final java.lang.Object other$current = other.current;
if (this$current == null ? other$current != null : !this$current.equals(other$current)) return false;
final java.lang.Object this$major = this.major;
final java.lang.Object other$major = other.major;
if (this$major == null ? other$major != null : !this$major.equals(other$major)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof ClassFileVersion.VersionLocator.ForJava9CapableVm;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final java.lang.Object $current = this.current;
result = result * PRIME + ($current == null ? 43 : $current.hashCode());
final java.lang.Object $major = this.major;
result = result * PRIME + ($major == null ? 43 : $major.hashCode());
return result;
}
}
/**
* A version locator for a JVM that does not provide the {@code jdk.Version} class.
*/
enum ForLegacyVm implements VersionLocator, PrivilegedAction<String> {
/**
* The singleton instance.
*/
INSTANCE;
/**
* The system property for this JVM's Java version.
*/
private static final String JAVA_VERSION_PROPERTY = "java.version";
@Override
public ClassFileVersion locate() {
String versionString = AccessController.doPrivileged(this);
int[] versionIndex = {-1, 0, 0};
for (int i = 1; i < 3; i++) {
versionIndex[i] = versionString.indexOf('.', versionIndex[i - 1] + 1);
if (versionIndex[i] == -1) {
throw new IllegalStateException("This JVM\'s version string does not seem to be valid: " + versionString);
}
}
return ClassFileVersion.ofJavaVersion(Integer.parseInt(versionString.substring(versionIndex[1] + 1, versionIndex[2])));
}
@Override
public String run() {
return System.getProperty(JAVA_VERSION_PROPERTY);
}
}
}
/**
* A simple visitor that extracts the class file version of a class file.
*/
protected static class VersionExtractor extends ClassVisitor {
/**
* The class file version extracted from a class.
*/
private int classFileVersionNumber;
/**
* Creates a new extractor.
*/
protected VersionExtractor() {
super(Opcodes.ASM5);
}
@Override
public void visit(int classFileVersionNumber, int modifier, String internalName, String signature, String superTypeName, String[] interfaceName) {
this.classFileVersionNumber = classFileVersionNumber;
}
/**
* Returns the class file version number found in a class file.
*
* @return The class file version number found in a class file.
*/
protected int getClassFileVersionNumber() {
return classFileVersionNumber;
}
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof ClassFileVersion)) return false;
final ClassFileVersion other = (ClassFileVersion) o;
if (!other.canEqual((java.lang.Object) this)) return false;
if (this.versionNumber != other.versionNumber) return false;
return true;
}
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
protected boolean canEqual(final java.lang.Object other) {
return other instanceof ClassFileVersion;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
@javax.annotation.Generated("lombok")
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.versionNumber;
return result;
}
}