All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dev.array21.bukkitreflectionlib.ReflectionUtil Maven / Gradle / Ivy

There is a newer version: 1.3.1
Show newest version
package dev.array21.bukkitreflectionlib;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.StringJoiner;

public class ReflectionUtil {

	public static String SERVER_VERSION;
	private static boolean useNewSpigotPackaging;
	private static int majorVersion;

	static {
		try {
			Class bukkitClass = Class.forName("org.bukkit.Bukkit");
			Object serverObject = getMethod(bukkitClass, "getServer").invoke(null);
			String serverPackageName = serverObject.getClass().getPackage().getName();

			SERVER_VERSION = serverPackageName.substring(serverPackageName.lastIndexOf('.') +1);

			String major = SERVER_VERSION.split("_")[1];

			majorVersion = Integer.parseInt(major);
			useNewSpigotPackaging = majorVersion >= 17;

		} catch (ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) {
			e.printStackTrace();
		}
	}

	/**
	 * Check if the new way of packaging Spigot is used
* For >=1.17 this will be true, for =<1.16 this will be false.
* * This dictates if you should use {@link #getNmsClass(String)} (<=1.16) or {@link #getMinecraftClass(String)} (>=1.17). * @return Returns true if it is, false if it is now */ public static boolean isUseNewSpigotPackaging() { return useNewSpigotPackaging; } /** * Get the current major Minecraft version. * * E.g for Minecraft 1.18 this is 18. * @return The current major Minecraft version */ public static int getMajorVersion() { return majorVersion; } /** * Get a Class from the org.bukkit.craftbukkit.SERVER_VERSION. package * @param className The name of the class * @return Returns the Class * @throws ClassNotFoundException Thrown when the Class was not found */ public static Class getBukkitClass(String className) throws ClassNotFoundException { return Class.forName("org.bukkit.craftbukkit." + SERVER_VERSION + "." + className); } /** * 1.16 and older only * * Get a Class from the net.minecraft.server.SERVER_VERSION. package * @param className The name of the class * @return Returns the Class * @throws ClassNotFoundException Thrown when the Class was not found */ @Deprecated public static Class getNmsClass(String className) throws ClassNotFoundException { return Class.forName("net.minecraft.server." + SERVER_VERSION + "." + className); } /** * 1.17 and newer only * * Get a Class from the net.minecraft package * @param className The name of the class * @return Returns the class * @throws ClassNotFoundException Thrown when the Class was not found */ public static Class getMinecraftClass(String className) throws ClassNotFoundException { return Class.forName("net.minecraft." + className); } /** * Get the Constructor of a Class * @param clazz The Class in which the Constructor is defined * @param args Arguments taken by the Constructor * @return Returns the Constructor * @throws NoSuchMethodException Thrown when no Constructor in the Class was found with the provided combination of arguments */ public static Constructor getConstructor(Class clazz, Class... args) throws NoSuchMethodException { Constructor con = clazz.getConstructor(args); con.setAccessible(true); return con; } /** * Get an Enum from an Enum constant * @param clazz The Class in which the Enum is defined * @param constant The name of the Enum Constant * @return Returns the Enum or null if the Enum does not have a member called constant */ public static Enum getEnum(Class clazz, String constant) { Enum[] constants = (Enum[]) clazz.getEnumConstants(); for(Enum e : constants) { if(e.name().equalsIgnoreCase(constant)) { return e; } } return null; } /** * Get an Enum constant by it's name and constant * @param clazz The Class in which the Enum is defined * @param enumname The name of the Enum * @param constant The name of the Constant * @return Returns the Enum or null if the Enum does not have a member called constant * @throws ClassNotFoundException If the Class does not have an Enum called enumname */ public static Enum getEnum(Class clazz, String enumname, String constant) throws ClassNotFoundException { Class c = Class.forName(clazz.getName() + "$" + enumname); return getEnum(c, constant); } /** * Get a Field * @param clazz The Class in which the Field is defined * @param fieldName The name of the Field * @return Returns the Field * @throws NoSuchFieldException Thrown when the Field was not present in the Class */ public static Field getField(Class clazz, String fieldName) throws NoSuchFieldException { Field f = clazz.getDeclaredField(fieldName); f.setAccessible(true); return f; } /** * Get a Method * @param clazz The Class in which the Method is defined * @param methodName The name of the method * @param args The argument types the method takes * @return Returns the Method * @throws NoSuchMethodException */ public static Method getMethod(Class clazz, String methodName, Class... args) throws NoSuchMethodException { Method m = clazz.getDeclaredMethod(methodName, args); m.setAccessible(true); return m; } /** * Invoke a Method which takes no arguments. The Class in which the Method is defined is derived from the provided Object * @param obj The object to invoke the method on * @param methodName The name of the Method * @return Returns the result of the method, can be null if the method returns void * @throws NoSuchMethodException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeMethod(Object obj, String methodName) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { return invokeMethod(obj.getClass(), obj, methodName); } /** * Invoke a Method where the argument types are derived from the provided arguments. The Class in which the Method is defined is derived from the provided Object * @param obj The object to invoke the method on * @param methodName The name of the Method * @param args The arguments to pass to the Method * @return Returns the result of the method, can be null if the method returns void * @throws NoSuchMethodException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeMethod(Object obj, String methodName, Object[] args) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { return invokeMethod(obj.getClass(), obj, methodName, args); } /** * Invoke a Method where the argument types are explicitly given (Helpful when working with primitives). The Class in which the Method is defined is derived from the provided Object. * @param obj The Object to invoke the method on * @param methodName The name of the Method * @param argTypes The types of arguments as a Class array * @param args The arguments as an object array * @return Returns the result of the method, can be null if the method returns void * @throws NoSuchMethodException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeMethod(Object obj, String methodName, Class[] argTypes, Object[] args) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { return invokeMethod(obj.getClass(), obj, methodName, argTypes, args); } /** * Invoke a Method where the Class where to find the method is explicitly given (Helpful if the method is located in a superclass). The argument types are derived from the provided arguments * @param clazz The Class where the method is located * @param obj The Object to invoke the method on * @param methodName The name of the method * @param args The arguments to be passed to the method * @return Returns the result of the method, can be null if the method returns void * @throws NoSuchMethodException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeMethod(Class clazz, Object obj, String methodName, Object... args) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class[] argTypes = new Class[args.length]; for(int i = 0; i < args.length; i++) { argTypes[i] = args[i].getClass(); } return invokeMethod(clazz, obj, methodName, argTypes, args); } /** * Invoke a Method where the Class where the Method is defined is explicitly given, and the argument types are explicitly given * @param clazz The Class in which the Method is located * @param obj The Object on which to invoke the Method * @param methodName The name of the Method * @param argTypes Argument types * @param args Arguments to pass to the method * @return Returns the result of the method, can be null if the method returns void * @throws NoSuchMethodException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeMethod(Class clazz, Object obj, String methodName, Class[] argTypes, Object[] args) throws NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Method m = getMethod(clazz, methodName, argTypes); return m.invoke(obj, args); } /** * Get the value of a Field, where the Class in which the field is defined is derived from the provided Object * @param obj The object in which the field is located, and from which to get the value * @param name The name of the Field to get the value from * @return Returns the value of the Field * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static Object getObject(Object obj, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { return getObject(obj.getClass(), obj, name); } /** * Get the value of a Field, where the Class in which the Field is defined is explicitly given. (Helpful when the Field is in a superclass) * @param obj The Object to get the value from * @param clazz The Class in which the Field is defined * @param name The name of the Field * @return Returns the value of the Field * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException * @deprecated Use {@link #getObject(Class, Object, String)} instead */ @Deprecated public static Object getObject(Object obj, Class clazz, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { return getObject(clazz, obj, name); } /** * Get the value of a Field, where the Class in which the Field is defined is explicitly given. (Helpful when the Field is in a superclass) * @param clazz The Class in which the Field is defined * @param obj The Object to get the value from * @param name The name of the Field * @return Returns the value of the Field * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */ public static Object getObject(Class clazz, Object obj, String name) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { Field f = getField(clazz, name); f.setAccessible(true); return f.get(obj); } /** * Invoke a Class' constructor. The argument types are derived from the provided arguments * @param clazz The Class in which the Constructor is defined * @param args The arguments to pass to the Constructor * @return Returns an instance of the provided Class in which the Constructor is located * @throws NoSuchMethodException * @throws InstantiationException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeConstructor(Class clazz, Object... args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class[] argTypes = new Class[args.length]; for(int i = 0; i < args.length; i++) { argTypes[i] = args[i].getClass(); } return invokeConstructor(clazz, argTypes, args); } /** * Invoke a Class' Constructor, where the argument types are explicitly given (Helpful when working with primitives) * @param clazz The Class in which the Constructor is defined * @param argTypes The argument types * @param args The arguments to pass to the constructor * @return Returns an instance of the provided Class in which the Constructor is located * @throws NoSuchMethodException * @throws InstantiationException * @throws IllegalAccessException * @throws IllegalArgumentException * @throws InvocationTargetException */ public static Object invokeConstructor(Class clazz, Class[] argTypes, Object[] args) throws NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Constructor con = getConstructor(clazz, argTypes); return con.newInstance(args); } /** * Print all Methods in a Class with their parameters. Will print the Method's modifiers, return type, name and arguments and their types * @param clazz The class to get methods from */ public static void printMethodsInClass(Class clazz) { System.out.println("Methods in " + clazz.getName() + ":"); for(Method m : clazz.getDeclaredMethods()) { StringBuilder print = new StringBuilder(128); print.append(getModifiers(m.getModifiers())).append(" "); print.append(m.getReturnType().getName()).append(" "); print.append(m.getName()).append("("); Class[] parameterTypes = m.getParameterTypes(); int parameterTypesLength = parameterTypes.length; for(int i = 0; i < parameterTypesLength; i++) { print.append(parameterTypes[i].getName()); if(i != parameterTypesLength - 1) { print.append(", "); } } print.append(")"); System.out.println(print.toString().strip()); } } /** * Print all Fields in a Class. Will print the Field's modifiers, type and name * @param clazz The class to get fields from */ public static void printFieldsInClass(Class clazz) { System.out.println("Fields in " + clazz.getName() + ":"); for(Field f : clazz.getDeclaredFields()) { String print = getModifiers(f.getModifiers()) + " " + f.getType().getName() + " " + f.getName(); System.out.println(print.strip()); } } /** * Get modifiers as a String * @param modifiers int value of the modifiers * @return Returns the modifiers as a String * @see Field#getModifiers() * @see Class#getModifiers() * @see Method#getModifiers() */ private static String getModifiers(int modifiers) { StringJoiner modifiersStr = new StringJoiner(" "); if(Modifier.isPrivate(modifiers)) { modifiersStr.add("private"); } if(Modifier.isProtected(modifiers)) { modifiersStr.add("protected"); } if(Modifier.isPublic(modifiers)) { modifiersStr.add("public"); } if(Modifier.isAbstract(modifiers)) { modifiersStr.add("abstract"); } if(Modifier.isStatic(modifiers)) { modifiersStr.add("static"); } if(Modifier.isFinal(modifiers)) { modifiersStr.add("static"); } if(Modifier.isTransient(modifiers)) { modifiersStr.add("transient"); } if(Modifier.isVolatile(modifiers)) { modifiersStr.add("volatile"); } if(Modifier.isNative(modifiers)) { modifiersStr.add("native"); } if(Modifier.isStrict(modifiers)) { modifiersStr.add("strictfp"); } if(Modifier.isSynchronized(modifiers)) { modifiersStr.add("synchronized"); } if(Modifier.isInterface(modifiers)) { modifiersStr.add("interface"); } return modifiersStr.toString().strip(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy