From 6385840071dfa93728ed36e562f98d8132c15cfc Mon Sep 17 00:00:00 2001 From: HttpMarco Date: Thu, 22 Feb 2024 23:51:07 +0100 Subject: [PATCH] Better object reflections --- build.gradle.kts | 5 +- gradle/libs.versions.toml | 3 +- ...tionClassAllocater.java => Allocator.java} | 7 +- .../osgan/reflections/Reflections.java | 83 +++++++++++++------ 4 files changed, 68 insertions(+), 30 deletions(-) rename osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/{allocator/ReflectionClassAllocater.java => Allocator.java} (87%) diff --git a/build.gradle.kts b/build.gradle.kts index c13b529..0a1f604 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -11,7 +11,7 @@ allprojects { group = "dev.httpmarco" - version = "1.0.15-SNAPSHOT" + version = "1.0.16-SNAPSHOT" repositories { mavenCentral() @@ -20,6 +20,9 @@ allprojects { dependencies { implementation(rootProject.libs.lombok) annotationProcessor(rootProject.libs.lombok) + + implementation(rootProject.libs.annotations) + annotationProcessor(rootProject.libs.annotations) } tasks.withType { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6abe8a0..311157b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,13 +2,14 @@ nexusPublish = "2.0.0-rc-2" +annotations = "24.1.0" lombok = "1.18.30" gson = "2.10.1" [libraries] lombok = { group = "org.projectlombok", name="lombok", version.ref = "lombok" } - +annotations = { group = "org.jetbrains", name="annotations", version.ref = "annotations" } gson = { group = "com.google.code.gson", name="gson", version.ref = "gson" } [plugins] diff --git a/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/allocator/ReflectionClassAllocater.java b/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Allocator.java similarity index 87% rename from osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/allocator/ReflectionClassAllocater.java rename to osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Allocator.java index 5c69b94..4503b35 100644 --- a/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/allocator/ReflectionClassAllocater.java +++ b/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Allocator.java @@ -1,12 +1,12 @@ -package dev.httpmarco.osgan.reflections.allocator; +package dev.httpmarco.osgan.reflections; import sun.misc.Unsafe; import java.lang.reflect.InvocationTargetException; -public final class ReflectionClassAllocater { +final class Allocator { - public static final Unsafe unsafe; + private static final Unsafe unsafe; static { try { @@ -18,6 +18,7 @@ public final class ReflectionClassAllocater { } } + @SuppressWarnings("unchecked") public static T allocate(Class tClass) { try { return (T) unsafe.allocateInstance(tClass); diff --git a/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Reflections.java b/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Reflections.java index 6c68575..ef99bfe 100644 --- a/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Reflections.java +++ b/osgan-reflections/src/main/java/dev/httpmarco/osgan/reflections/Reflections.java @@ -1,47 +1,80 @@ package dev.httpmarco.osgan.reflections; +import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import org.jetbrains.annotations.Nullable; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -public final class Reflections { +@RequiredArgsConstructor +public class Reflections { + + private final Class clazz; + private @Nullable T value; + + public static Reflections of(Class clazz) { + return new Reflections<>(clazz); + } + + public Reflections withValue(Object value) { + this.value = clazz.cast(value); + return this; + } @SneakyThrows - public static void modifyField(Field field, Object object, Object value) { + public Field field(String id) { + var field = this.clazz.getDeclaredField(id); field.setAccessible(true); - field.set(object, value); + return field; + } + + @SneakyThrows + public Method method(String id) { + var method = this.clazz.getDeclaredMethod(id); + method.setAccessible(true); + return method; } @SneakyThrows - public static Object getField(Field field, Object object) { + public T newInstanceWithNoArgs() { + return this.clazz.getConstructor().newInstance(); + } + + public T allocate() { + return Allocator.allocate(clazz); + } + + @SneakyThrows + @SuppressWarnings("unchecked") + public T value(Field field) { field.setAccessible(true); - return field.get(object); + return (T) field.get(this.value); } - public static T newInstance(Class clazz, Object... objects) { - try { - return clazz.getConstructor(Arrays.stream(objects).map(Object::getClass).toArray(Class[]::new)).newInstance(objects); - } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - throw new RuntimeException(e); - } + @SneakyThrows + public T value(String fieldId) { + return this.value(field(fieldId)); } - public static Object getField(String id, Object value) { - try { - return getField(value.getClass().getDeclaredField(id), value); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } + @SneakyThrows + public void modify(Field field, Object value) { + field.setAccessible(true); + field.set(this.value, value); } - public static void callMethod(Method method, Object object, Object... args) { - try { - method.invoke(object, args); - } catch (Exception e) { - throw new RuntimeException(e); - } + @SneakyThrows + public void modify(String fieldId, Object value) { + this.modify(field(fieldId), value); + } + + @SneakyThrows + public void applyMethod(Method method, Object... args) { + method.invoke(value, args); + } + + @SneakyThrows + public void applyMethod(String methodId, Object... args) { + method(methodId).invoke(value, args); } }