diff options
author | LexManos <LexManos@gmail.com> | 2021-01-17 17:35:01 -0800 |
---|---|---|
committer | LexManos <LexManos@gmail.com> | 2021-01-17 17:40:39 -0800 |
commit | 4089917696fffbd4b818fb90958d20f0714f93fb (patch) | |
tree | 1f5de4972d9afe0328d7d0ce929aac06c3bca15e /src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java | |
parent | 631cd05e726092c51e95b52bb8a8bb6a2ae2cc42 (diff) | |
download | Artifactural-4089917696fffbd4b818fb90958d20f0714f93fb.tar.gz Artifactural-4089917696fffbd4b818fb90958d20f0714f93fb.tar.bz2 Artifactural-4089917696fffbd4b818fb90958d20f0714f93fb.zip |
Move to net.minecraftforge package, and update license headers.
Diffstat (limited to 'src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java')
-rw-r--r-- | src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java b/src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java new file mode 100644 index 0000000..4e18885 --- /dev/null +++ b/src/gradlecomp/java/net/minecraftforge/artifactural/gradle/ReflectionUtils.java @@ -0,0 +1,112 @@ +/* + * Artifactural + * Copyright (c) 2018-2021. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +package net.minecraftforge.artifactural.gradle; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.function.UnaryOperator; + +public class ReflectionUtils { + + @SuppressWarnings("unchecked") + public static <T> void alter(Object target, String name, UnaryOperator<T> operator) { + try { + int idx = name.lastIndexOf('.'); + if (idx != -1) { + target = drillField(target, name.substring(0, idx)); + if (target == null) throw new IllegalStateException("Could not find field '" + name + "'"); + name = name.substring(idx + 1); + } + Field f = findField(target.getClass(), name); + if (f == null) throw new IllegalStateException("Could not find '" + name + "'"); + + T oldV = (T)f.get(target); + T newV = operator.apply(oldV); + f.set(target, newV); + + if (f.get(target) != newV) { + throw new IllegalStateException("Failed to set new value on " + f.getDeclaringClass().getName() + "." + f.getName()); + } + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } + + private static Object drillField(Object obj, String path) { + for (String name : path.split("\\.")) { + if (obj == null) return null; + Field f = findField(obj.getClass(), name); + if (f == null) return null; + try { + obj = f.get(obj); + } catch (IllegalAccessException e) { + return null; + } + } + return obj; + } + + private static Field findField(Class<?> clazz, String name) { + while (clazz != Object.class) { + for (Field f : clazz.getDeclaredFields()) { + if (f.getName().equals(name)) { + f.setAccessible(true); + if (!ModifierAccess.definalize(f)) { + System.out.println("Could not definalize field " + f.getDeclaringClass().getName() + "." + f.getName() + " Exception ate, lets see if it works"); + } + return f; + } + } + clazz = clazz.getSuperclass(); + } + return null; + } + + /** + * Invokes a method (can be private). + */ + @SuppressWarnings("unchecked") + public static <T> T invoke(Object target, Class<?> type, String name, Object... args) { + try { + Method method = type.getDeclaredMethod(name); + method.setAccessible(true); + return (T) method.invoke(target, args); + } catch (Exception ex) { + throw new RuntimeException(ex); + } + } + + @SuppressWarnings("unchecked") + public static <T> T get(Object target, String name) { + try { + int idx = name.lastIndexOf('.'); + if (idx != -1) { + target = drillField(target, name.substring(0, idx)); + if (target == null) throw new IllegalStateException("Could not find field '" + name + "'"); + name = name.substring(idx + 1); + } + Field f = findField(target.getClass(), name); + if (f == null) throw new IllegalStateException("Could not find '" + name + "'"); + return (T)f.get(target); + } catch (IllegalAccessException ex) { + throw new RuntimeException(ex); + } + } +} |