From 0ac3aa732aa0189bf432af2880cfcbbd07de6e95 Mon Sep 17 00:00:00 2001 From: Amarok Date: Sat, 5 Oct 2024 19:18:49 +0800 Subject: [PATCH] opti reflection again. (#16) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * πŸΊπŸ› οΈβŒπŸͺ„πŸ₯“πŸ’»πŸ’Ύβœ¨πŸ * πŸΊβ‰οΈπŸ¦€ * πŸΊβ‰οΈπŸ¦€ * πŸΊπŸ’Ύ * Use action to setup gradle (#10) use action to setup gradle * 🐺πŸͺΆ * 🐺πŸͺΆ * 🐺πŸͺΆ * 🐺πŸͺΆ * πŸΊπŸ¦€πŸ’»πŸš€β‰οΈβœ¨πŸŽ‰ * πŸΊπŸ’» * πŸΊπŸ’» * πŸ’Ž :anger: This reverts commit 00824b81b561f1d0914514e3297252721b3ceea6. * Revert "πŸΊπŸ’»" This reverts commit 5d8efb82b35de736c13ec03007b6b3379280273f. * πŸ’Žβ˜• * πŸ’ŽπŸ’¦ * move it --------- Co-authored-by: H2Sxxa Co-authored-by: RawDiamondMC --- .../lib/api/base/reflect/ModifiersUtil.java | 55 +++++++++++++++++++ .../lib/api/base/reflect/ReflectUtil.java | 14 +++++ .../lib/api/config/AbstractConfig.java | 32 +++++------ .../config/serializers/Json5Serializer.java | 8 ++- 4 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 base/common/src/main/java/band/kessoku/lib/api/base/reflect/ModifiersUtil.java create mode 100644 base/common/src/main/java/band/kessoku/lib/api/base/reflect/ReflectUtil.java diff --git a/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ModifiersUtil.java b/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ModifiersUtil.java new file mode 100644 index 00000000..c26a1aa4 --- /dev/null +++ b/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ModifiersUtil.java @@ -0,0 +1,55 @@ +package band.kessoku.lib.api.base.reflect; + +import java.lang.reflect.Member; +import java.lang.reflect.Modifier; + +public final class ModifiersUtil { + private ModifiersUtil() { + } + + /* === Common === */ + + public static boolean isPublic(Member field) { + return Modifier.isPublic(field.getModifiers()); + } + + public static boolean isStatic(Member field) { + return Modifier.isStatic(field.getModifiers()); + } + + /* === Common Combo === */ + + public static boolean isPublicAndStatic(Member field) { + return isPublic(field) && isStatic(field); + } + + public static boolean isPublicOrStatic(Member field, boolean shouldPublic, boolean shouldStatic) { + return shouldPublic == isPublic(field) && shouldStatic == isStatic(field); + } + + /* === Common End === */ + + /* === Data Object === */ + + public static boolean isVolatile(Member field) { + return Modifier.isVolatile(field.getModifiers()); + } + + public static boolean isTransient(Member field) { + return Modifier.isTransient(field.getModifiers()); + } + + /* === Data Object End === */ + + /* === Low Usage Tools === */ + + public static boolean isFinal(Member field) { + return Modifier.isFinal(field.getModifiers()); + } + + public static boolean isProtected(Member field) { + return Modifier.isProtected(field.getModifiers()); + } + + /* === Low Usage Tools End === */ +} diff --git a/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ReflectUtil.java b/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ReflectUtil.java new file mode 100644 index 00000000..ef6df4db --- /dev/null +++ b/base/common/src/main/java/band/kessoku/lib/api/base/reflect/ReflectUtil.java @@ -0,0 +1,14 @@ +package band.kessoku.lib.api.base.reflect; + +import java.lang.reflect.Field; +import java.util.Arrays; + +public final class ReflectUtil { + private ReflectUtil() { + } + + public static boolean isAssignableFrom(Field field, Class... clazzs) { + var flag = Arrays.stream(clazzs).anyMatch(clazz -> !field.getType().isAssignableFrom(clazz)); + return !flag; + } +} diff --git a/config/common/src/main/java/band/kessoku/lib/api/config/AbstractConfig.java b/config/common/src/main/java/band/kessoku/lib/api/config/AbstractConfig.java index dee3d9be..d3e35313 100644 --- a/config/common/src/main/java/band/kessoku/lib/api/config/AbstractConfig.java +++ b/config/common/src/main/java/band/kessoku/lib/api/config/AbstractConfig.java @@ -27,6 +27,8 @@ import java.util.function.Consumer; import band.kessoku.lib.api.KessokuLib; +import band.kessoku.lib.api.base.reflect.ModifiersUtil; +import band.kessoku.lib.api.base.reflect.ReflectUtil; import band.kessoku.lib.api.config.annotations.Comment; import band.kessoku.lib.api.config.annotations.Comments; import band.kessoku.lib.api.config.annotations.Name; @@ -83,7 +85,9 @@ public boolean load() { // Check the value is public and not static try { Field field = this.getClass().getField(key); - if (!Modifier.isPublic(field.getModifiers()) || Modifier.isStatic(field.getModifiers())) continue; + if (!ModifiersUtil.isPublicOrStatic(field, true, false)) { + continue; + } value = (ConfigValue) ReflectionUtil.getFieldValue(field, this); } catch (NoSuchFieldException e) { continue; @@ -142,12 +146,9 @@ public void reset() { List fields = new ArrayList<>(); for (Field declaredField : this.getClass().getDeclaredFields()) { - declaredField.setAccessible(true); - - final boolean flag0 = declaredField.getDeclaringClass().isAssignableFrom(ConfigValue.class); - final boolean flag1 = Modifier.isPublic(declaredField.getModifiers()); - final boolean flag2 = !Modifier.isStatic(declaredField.getModifiers()); - if (flag0 && flag1 && flag2) { + final boolean flag0 = ReflectUtil.isAssignableFrom(declaredField, ConfigValue.class); + final boolean flag1 = ModifiersUtil.isPublicOrStatic(declaredField, true, false); + if (flag0 && flag1) { fields.add(declaredField); } } @@ -166,8 +167,8 @@ public ImmutableList getValidCategories() { for (Field declaredField : this.getClass().getDeclaredFields()) { declaredField.setAccessible(true); - final boolean flag0 = declaredField.getDeclaringClass().isAssignableFrom(AbstractConfig.class); - final boolean flag1 = Modifier.isPublic(declaredField.getModifiers()); + final boolean flag0 = ReflectUtil.isAssignableFrom(declaredField, AbstractConfig.class); + final boolean flag1 = ModifiersUtil.isPublic(declaredField); if (flag0 && flag1){ fields.add(declaredField); } @@ -180,15 +181,10 @@ public ImmutableList getValidCategories() { private ImmutableList getValidFields() { ImmutableList.Builder builder = ImmutableList.builder(); for (Field declaredField : this.getClass().getDeclaredFields()) { - declaredField.setAccessible(true); - - final boolean flag0 = declaredField.getDeclaringClass().isAssignableFrom(AbstractConfig.class); - final boolean flag1 = declaredField.getDeclaringClass().isAssignableFrom(ConfigValue.class); - final boolean flag2 = Modifier.isPublic(declaredField.getModifiers()); - - final var flag = flag0 || flag1; + final boolean flag0 = ReflectUtil.isAssignableFrom(declaredField, AbstractConfig.class, ConfigValue.class); + final boolean flag1 = Modifier.isPublic(declaredField.getModifiers()); - if (flag && flag2){ + if (flag0 && flag1){ builder.add(declaredField); } } @@ -198,7 +194,7 @@ private ImmutableList getValidFields() { private Map serialize() { ImmutableMap.Builder builder = ImmutableMap.builder(); for (Field field : this.getValidFields()) { - field.setAccessible(true); + ReflectionUtil.makeAccessible(field); final String name = field.isAnnotationPresent(Name.class) ? field.getAnnotation(Name.class).value() : field.getName(); final String[] comments = field.isAnnotationPresent(Comments.class) ? (String[]) Arrays.stream(field.getAnnotation(Comments.class).value()).map(Comment::value).toArray() : new String[0]; diff --git a/config/common/src/main/java/band/kessoku/lib/api/config/serializers/Json5Serializer.java b/config/common/src/main/java/band/kessoku/lib/api/config/serializers/Json5Serializer.java index e27b59df..76920690 100644 --- a/config/common/src/main/java/band/kessoku/lib/api/config/serializers/Json5Serializer.java +++ b/config/common/src/main/java/band/kessoku/lib/api/config/serializers/Json5Serializer.java @@ -45,9 +45,13 @@ private Json5Builder.ObjectBean toBean(Map { - for (String comment : valueWithComment.comments()) objectBean.addNote(comment); - if (valueWithComment.object() instanceof Map) + for (String comment : valueWithComment.comments()) { + objectBean.addNote(comment); + } + + if (valueWithComment.object() instanceof Map) { objectBean.addBean(s, this.toBean((Map) valueWithComment.object())); + } }); return objectBean; }