diff --git a/src/main/java/io/gitlab/jfronny/commons/reflect/LambdaFactory.java b/src/main/java/io/gitlab/jfronny/commons/reflect/LambdaFactory.java new file mode 100644 index 0000000..79f97e5 --- /dev/null +++ b/src/main/java/io/gitlab/jfronny/commons/reflect/LambdaFactory.java @@ -0,0 +1,79 @@ +package io.gitlab.jfronny.commons.reflect; + +import java.lang.invoke.*; +import java.util.function.*; + +@SuppressWarnings("unchecked") +public class LambdaFactory { + private static final MethodHandles.Lookup LOOKUP_ROOT = MethodHandles.lookup(); + + public static MethodHandles.Lookup lookup(Class klazz) throws IllegalAccessException { + return MethodHandles.privateLookupIn(klazz, LOOKUP_ROOT); + } + + public static Runnable runnable(MethodHandles.Lookup lookup, MethodHandle handle) throws Throwable { + return (Runnable) LambdaMetafactory.metafactory( + lookup, + "run", + MethodType.methodType(Runnable.class), + MethodType.methodType(Void.TYPE), + handle, + MethodType.methodType(Void.TYPE) + ).getTarget().invoke(); + } + + public static Consumer consumer(MethodHandles.Lookup lookup, MethodHandle handle, Class parameterType) throws Throwable { + return (Consumer) LambdaMetafactory.metafactory( + lookup, + "accept", + MethodType.methodType(Consumer.class), + MethodType.methodType(Void.TYPE, Object.class), + handle, + MethodType.methodType(Void.TYPE, parameterType) + ).getTarget().invoke(); + } + + public static BiConsumer consumer(MethodHandles.Lookup lookup, MethodHandle handle, Class parameterType1, Class parameterType2) throws Throwable { + return (BiConsumer) LambdaMetafactory.metafactory( + lookup, + "accept", + MethodType.methodType(BiConsumer.class), + MethodType.methodType(Void.TYPE, Object.class, Object.class), + handle, + MethodType.methodType(Void.TYPE, parameterType1, parameterType2) + ).getTarget().invoke(); + } + + public static Supplier supplier(MethodHandles.Lookup lookup, MethodHandle handle, Class returnType) throws Throwable { + return (Supplier) LambdaMetafactory.metafactory( + lookup, + "get", + MethodType.methodType(Supplier.class), + MethodType.methodType(Object.class), + handle, + MethodType.methodType(returnType) + ).getTarget().invoke(); + } + + public static Function function(MethodHandles.Lookup lookup, MethodHandle handle, Class returnType, Class parameterType) throws Throwable { + return (Function) LambdaMetafactory.metafactory( + lookup, + "apply", + MethodType.methodType(Function.class), + MethodType.methodType(Object.class, Object.class), + handle, + MethodType.methodType(returnType, parameterType) + ).getTarget().invoke(); + } + + public static BiFunction function(MethodHandles.Lookup lookup, MethodHandle handle, Class returnType, Class parameterType1, Class parameterType2) throws Throwable { + return (BiFunction) LambdaMetafactory.metafactory( + lookup, + "apply", + MethodType.methodType(BiFunction.class), + MethodType.methodType(Object.class, Object.class, Object.class), + handle, + MethodType.methodType(returnType, parameterType1, parameterType2) + ).getTarget().invoke(); + } +} diff --git a/src/main/java/io/gitlab/jfronny/commons/reflect/Reflect.java b/src/main/java/io/gitlab/jfronny/commons/reflect/Reflect.java index c0db2b3..0d98fa8 100644 --- a/src/main/java/io/gitlab/jfronny/commons/reflect/Reflect.java +++ b/src/main/java/io/gitlab/jfronny/commons/reflect/Reflect.java @@ -4,108 +4,78 @@ import io.gitlab.jfronny.commons.throwable.ThrowingBiFunction; import io.gitlab.jfronny.commons.throwable.ThrowingFunction; import io.gitlab.jfronny.commons.throwable.ThrowingSupplier; -import java.lang.invoke.*; +import java.lang.invoke.MethodHandles; import java.util.function.*; @SuppressWarnings("unchecked") public class Reflect { - private static final MethodHandles.Lookup LOOKUP_ROOT = MethodHandles.lookup(); - @Deprecated - public static ThrowingSupplier getConstructor(Class toConstruct) throws Throwable { + public static ThrowingSupplier getConstructor(Class toConstruct) throws Throwable { Supplier constructor = constructor(toConstruct); return constructor::get; } @Deprecated public static ThrowingSupplier getConstructor(String targetClassName) throws Throwable { - return getConstructor(Class.forName(targetClassName)); + return Reflect.getConstructor((Class) Class.forName(targetClassName)); } @Deprecated - public static ThrowingFunction getConstructor(Class toConstruct, Class parameterType) throws Throwable { + public static ThrowingFunction getConstructor(Class toConstruct, Class parameterType) throws Throwable { Function constructor = constructor(toConstruct, parameterType); return constructor::apply; } @Deprecated public static ThrowingFunction getConstructor(String targetClassName, Class parameterType) throws Throwable { - return getConstructor(Class.forName(targetClassName), parameterType); + return getConstructor((Class) Class.forName(targetClassName), parameterType); } @Deprecated - public static ThrowingBiFunction getConstructor(Class toConstruct, Class parameterType1, Class parameterType2) throws Throwable { + public static ThrowingBiFunction getConstructor(Class toConstruct, Class parameterType1, Class parameterType2) throws Throwable { BiFunction constructor = constructor(toConstruct, parameterType1, parameterType2); return constructor::apply; } @Deprecated public static ThrowingBiFunction getConstructor(String targetClassName, Class parameterType1, Class parameterType2) throws Throwable { - return getConstructor(Class.forName(targetClassName), parameterType1, parameterType2); + return getConstructor((Class) Class.forName(targetClassName), parameterType1, parameterType2); } // Constructor without parameters - public static Supplier constructor(Class toConstruct) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(toConstruct, LOOKUP_ROOT); - return (Supplier) LambdaMetafactory.metafactory( - lookup, - "get", - MethodType.methodType(Supplier.class), - MethodType.methodType(Object.class), - lookup.unreflectConstructor(toConstruct.getDeclaredConstructor()), - MethodType.methodType(toConstruct) - ).getTarget().invoke(); + public static Supplier constructor(Class toConstruct) throws Throwable { + MethodHandles.Lookup lookup = LambdaFactory.lookup(toConstruct); + return LambdaFactory.supplier(lookup, lookup.unreflectConstructor(toConstruct.getDeclaredConstructor()), toConstruct); } public static Supplier constructor(String targetClassName) throws Throwable { - return constructor(Class.forName(targetClassName)); + return (Supplier) constructor(Class.forName(targetClassName)); } // Constructor with one parameter - public static Function constructor(Class toConstruct, Class parameterType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(toConstruct, LOOKUP_ROOT); - return (Function) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(Function.class), - MethodType.methodType(Object.class, Object.class), - lookup.unreflectConstructor(toConstruct.getDeclaredConstructor(parameterType)), - MethodType.methodType(toConstruct, parameterType) - ).getTarget().invoke(); + public static Function constructor(Class toConstruct, Class parameterType) throws Throwable { + MethodHandles.Lookup lookup = LambdaFactory.lookup(toConstruct); + return LambdaFactory.function(lookup, lookup.unreflectConstructor(toConstruct.getDeclaredConstructor(parameterType)), toConstruct, parameterType); } public static Function constructor(String targetClassName, Class parameterType) throws Throwable { - return constructor(Class.forName(targetClassName), parameterType); + return (Function) constructor(Class.forName(targetClassName), parameterType); } // Constructor with two parameters - public static BiFunction constructor(Class toConstruct, Class parameterType1, Class parameterType2) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(toConstruct, LOOKUP_ROOT); - return (BiFunction) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(BiFunction.class), - MethodType.methodType(Object.class, Object.class, Object.class), - lookup.unreflectConstructor(toConstruct.getDeclaredConstructor(parameterType1, parameterType2)), - MethodType.methodType(toConstruct, parameterType1, parameterType2) - ).getTarget().invoke(); + public static BiFunction constructor(Class toConstruct, Class parameterType1, Class parameterType2) throws Throwable { + MethodHandles.Lookup lookup = LambdaFactory.lookup(toConstruct); + return LambdaFactory.function(lookup, lookup.unreflectConstructor(toConstruct.getDeclaredConstructor(parameterType1, parameterType2)), toConstruct, parameterType1, parameterType2); } public static BiFunction constructor(String targetClassName, Class parameterType1, Class parameterType2) throws Throwable { - return constructor(Class.forName(targetClassName), parameterType1, parameterType2); + return constructor((Class) Class.forName(targetClassName), parameterType1, parameterType2); } // Procedure without parameters public static Runnable staticProcedure(Class targetClass, String name) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Runnable) LambdaMetafactory.metafactory( - lookup, - "run", - MethodType.methodType(Runnable.class), - MethodType.methodType(Void.TYPE), - lookup.unreflect(targetClass.getDeclaredMethod(name)), - MethodType.methodType(Void.TYPE) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.runnable(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name))); } public static Runnable staticProcedure(String targetClassName, String name) throws Throwable { @@ -114,15 +84,8 @@ public class Reflect { // Procedure with one parameter public static Consumer staticProcedure(Class targetClass, String name, Class parameterType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Consumer) LambdaMetafactory.metafactory( - lookup, - "accept", - MethodType.methodType(Consumer.class), - MethodType.methodType(Void.TYPE, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), - MethodType.methodType(Void.TYPE, parameterType) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.consumer(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), parameterType); } public static Consumer staticProcedure(String targetClassName, String name, Class parameterType) throws Throwable { @@ -131,15 +94,8 @@ public class Reflect { // Procedure with two parameters public static BiConsumer staticProcedure(Class targetClass, String name, Class parameterType1, Class parameterType2) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (BiConsumer) LambdaMetafactory.metafactory( - lookup, - "accept", - MethodType.methodType(BiConsumer.class), - MethodType.methodType(Void.TYPE, Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType1, parameterType2)), - MethodType.methodType(Void.TYPE, parameterType1, parameterType2) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.consumer(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType1, parameterType2)), parameterType1, parameterType2); } public static BiConsumer staticProcedure(String targetClassName, String name, Class parameterType1, Class parameterType2) throws Throwable { @@ -148,15 +104,8 @@ public class Reflect { // Function without parameters public static Supplier staticFunction(Class targetClass, String name, Class returnType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Supplier) LambdaMetafactory.metafactory( - lookup, - "get", - MethodType.methodType(Supplier.class), - MethodType.methodType(Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name)), - MethodType.methodType(returnType) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.supplier(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name)), returnType); } public static Supplier staticFunction(String targetClassName, String name, Class returnType) throws Throwable { @@ -165,15 +114,8 @@ public class Reflect { // Function with one parameter public static Function staticFunction(Class targetClass, String name, Class returnType, Class parameterType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Function) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(Function.class), - MethodType.methodType(Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), - MethodType.methodType(returnType, parameterType) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.function(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), returnType, parameterType); } public static Function staticFunction(String targetClassName, String name, Class returnType, Class parameterType) throws Throwable { @@ -182,15 +124,8 @@ public class Reflect { // Function with two parameters public static BiFunction staticFunction(Class targetClass, String name, Class returnType, Class parameterType1, Class parameterType2) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (BiFunction) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(BiFunction.class), - MethodType.methodType(Object.class, Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType1, parameterType2)), - MethodType.methodType(returnType, parameterType1, parameterType2) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.function(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType1, parameterType2)), returnType, parameterType1, parameterType2); } public static BiFunction staticFunction(String targetClassName, String name, Class returnType, Class parameterType1, Class parameterType2) throws Throwable { @@ -199,15 +134,8 @@ public class Reflect { // Procedure without parameters public static Consumer instanceProcedure(Class targetClass, String name) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Consumer) LambdaMetafactory.metafactory( - lookup, - "accept", - MethodType.methodType(Consumer.class), - MethodType.methodType(Void.TYPE, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name)), - MethodType.methodType(Void.TYPE, targetClass) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.consumer(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name)), targetClass); } public static Consumer instanceProcedure(String targetClassName, String name) throws Throwable { @@ -216,15 +144,8 @@ public class Reflect { // Procedure with one parameter public static BiConsumer instanceProcedure(Class targetClass, String name, Class parameterType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (BiConsumer) LambdaMetafactory.metafactory( - lookup, - "accept", - MethodType.methodType(BiConsumer.class), - MethodType.methodType(Void.TYPE, Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), - MethodType.methodType(Void.TYPE, targetClass, parameterType) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.consumer(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), targetClass, parameterType); } public static BiConsumer instanceProcedure(String targetClassName, String name, Class parameterType) throws Throwable { @@ -233,15 +154,8 @@ public class Reflect { // Function without parameters public static Function instanceFunction(Class targetClass, String name, Class returnType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (Function) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(Function.class), - MethodType.methodType(Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name)), - MethodType.methodType(returnType, targetClass) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.function(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name)), returnType, targetClass); } public static Function instanceFunction(String targetClassName, String name, Class returnType) throws Throwable { @@ -250,15 +164,8 @@ public class Reflect { // Function with one parameter public static BiFunction instanceFunction(Class targetClass, String name, Class returnType, Class parameterType) throws Throwable { - MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(targetClass, LOOKUP_ROOT); - return (BiFunction) LambdaMetafactory.metafactory( - lookup, - "apply", - MethodType.methodType(BiFunction.class), - MethodType.methodType(Object.class, Object.class, Object.class), - lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), - MethodType.methodType(returnType, targetClass, parameterType) - ).getTarget().invoke(); + MethodHandles.Lookup lookup = LambdaFactory.lookup(targetClass); + return LambdaFactory.function(lookup, lookup.unreflect(targetClass.getDeclaredMethod(name, parameterType)), returnType, targetClass, parameterType); } public static BiFunction instanceFunction(String targetClassName, String name, Class returnType, Class parameterType) throws Throwable {