diff --git a/base/common/src/main/java/band/kessoku/lib/base/reflect/ModifiersUtil.java b/base/common/src/main/java/band/kessoku/lib/base/reflect/ModifiersUtil.java new file mode 100644 index 00000000..58bd6d3f --- /dev/null +++ b/base/common/src/main/java/band/kessoku/lib/base/reflect/ModifiersUtil.java @@ -0,0 +1,86 @@ +package band.kessoku.lib.base.reflect; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; + +public final class ModifiersUtil { + + /* === Common === */ + + public static boolean isPublic(Field field) { + return Modifier.isPublic(field.getModifiers()); + } + + public static boolean isPublic(Method method) { + return Modifier.isPublic(method.getModifiers()); + } + + public static boolean isStatic(Field field) { + return Modifier.isStatic(field.getModifiers()); + } + + public static boolean isStatic(Method method) { + return Modifier.isStatic(method.getModifiers()); + } + + /* === Common Combo === */ + + public static boolean isPublicAndStatic(Field field) { + return isPublic(field) && isStatic(field); + } + + public static boolean isPublicAndStatic(Method method) { + return isPublic(method) && isStatic(method); + } + + public static boolean isPublicOrStatic(Field field, boolean shouldPublic, boolean shouldStatic) { + return shouldPublic == isPublic(field) && shouldStatic == isStatic(field); + } + + public static boolean isPublicOrStatic(Method method, boolean shouldPublic, boolean shouldStatic) { + return shouldPublic == isPublic(method) && shouldStatic == isStatic(method); + } + + /* === Common End === */ + + /* === Data Object === */ + + public static boolean isVolatile(Field field) { + return Modifier.isVolatile(field.getModifiers()); + } + + public static boolean isVolatile(Method method) { + return Modifier.isVolatile(method.getModifiers()); + } + + public static boolean isTransient(Field field) { + return Modifier.isTransient(field.getModifiers()); + } + + public static boolean isTransient(Method method) { + return Modifier.isTransient(method.getModifiers()); + } + + /* === Data Object End === */ + + /* === Low Usage Tools === */ + + public static boolean isFinal(Field field) { + return Modifier.isFinal(field.getModifiers()); + } + + public static boolean isFinal(Method method) { + return Modifier.isFinal(method.getModifiers()); + } + + public static boolean isProtected(Field field) { + return Modifier.isProtected(field.getModifiers()); + } + + public static boolean isProtected(Method method) { + return Modifier.isProtected(method.getModifiers()); + } + + /* === Low Usage Tools End === */ +} diff --git a/base/common/src/main/java/band/kessoku/lib/base/reflect/ReflectUtil.java b/base/common/src/main/java/band/kessoku/lib/base/reflect/ReflectUtil.java new file mode 100644 index 00000000..ad8bd9cb --- /dev/null +++ b/base/common/src/main/java/band/kessoku/lib/base/reflect/ReflectUtil.java @@ -0,0 +1,22 @@ +package band.kessoku.lib.base.reflect; + +import org.apache.logging.log4j.core.util.ReflectionUtil; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; + +public final class ReflectUtil { + public static void makeAccessible(Field field) { + ReflectionUtil.makeAccessible(field); + } + + public static void makeAccessible(Method method) { + ReflectionUtil.makeAccessible(method); + } + + 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/config/api/AbstractConfig.java b/config/common/src/main/java/band/kessoku/lib/config/api/AbstractConfig.java index 416d6827..e7c8bd89 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/AbstractConfig.java +++ b/config/common/src/main/java/band/kessoku/lib/config/api/AbstractConfig.java @@ -16,6 +16,8 @@ package band.kessoku.lib.config.api; import band.kessoku.lib.base.ModUtils; +import band.kessoku.lib.base.reflect.ModifiersUtil; +import band.kessoku.lib.base.reflect.ReflectUtil; import band.kessoku.lib.config.KessokuConfig; import band.kessoku.lib.config.api.annotations.Comment; import band.kessoku.lib.config.api.annotations.Comments; @@ -84,7 +86,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; @@ -143,12 +147,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); } } @@ -167,8 +168,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); } @@ -181,15 +182,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); } } @@ -199,7 +195,7 @@ private ImmutableList getValidFields() { private Map serialize() { ImmutableMap.Builder builder = ImmutableMap.builder(); for (Field field : this.getValidFields()) { - field.setAccessible(true); + ReflectUtil.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/config/api/serializers/Json5Serializer.java b/config/common/src/main/java/band/kessoku/lib/config/serializers/Json5Serializer.java similarity index 87% rename from config/common/src/main/java/band/kessoku/lib/config/api/serializers/Json5Serializer.java rename to config/common/src/main/java/band/kessoku/lib/config/serializers/Json5Serializer.java index 3e5c3f40..9630be0e 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/serializers/Json5Serializer.java +++ b/config/common/src/main/java/band/kessoku/lib/config/serializers/Json5Serializer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.serializers; +package band.kessoku.lib.config.serializers; import band.kessoku.lib.config.api.AbstractConfig; import band.kessoku.lib.config.api.ConfigSerializer; @@ -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; } diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/serializers/JsonSerializer.java b/config/common/src/main/java/band/kessoku/lib/config/serializers/JsonSerializer.java similarity index 97% rename from config/common/src/main/java/band/kessoku/lib/config/api/serializers/JsonSerializer.java rename to config/common/src/main/java/band/kessoku/lib/config/serializers/JsonSerializer.java index 38d331a4..4de1e205 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/serializers/JsonSerializer.java +++ b/config/common/src/main/java/band/kessoku/lib/config/serializers/JsonSerializer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.serializers; +package band.kessoku.lib.config.serializers; import band.kessoku.lib.config.api.AbstractConfig; import band.kessoku.lib.config.api.ConfigSerializer; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/serializers/TomlSerializer.java b/config/common/src/main/java/band/kessoku/lib/config/serializers/TomlSerializer.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/serializers/TomlSerializer.java rename to config/common/src/main/java/band/kessoku/lib/config/serializers/TomlSerializer.java index 5b5afe5b..7b714eac 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/serializers/TomlSerializer.java +++ b/config/common/src/main/java/band/kessoku/lib/config/serializers/TomlSerializer.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.serializers; +package band.kessoku.lib.config.serializers; import band.kessoku.lib.config.api.AbstractConfig; import band.kessoku.lib.config.api.ConfigSerializer; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/BooleanValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/BooleanValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/BooleanValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/BooleanValue.java index b9120543..f2848618 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/BooleanValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/BooleanValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/DefaultConfigValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/DefaultConfigValue.java similarity index 97% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/DefaultConfigValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/DefaultConfigValue.java index 460c8623..1caf0932 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/DefaultConfigValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/DefaultConfigValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import band.kessoku.lib.config.api.ConfigValue; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/DoubleValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/DoubleValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/DoubleValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/DoubleValue.java index 3c05a1b7..e80ffd27 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/DoubleValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/DoubleValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/FloatValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/FloatValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/FloatValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/FloatValue.java index 1d66d0ff..fb28087b 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/FloatValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/FloatValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/IntegerValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/IntegerValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/IntegerValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/IntegerValue.java index ce7539cb..99214ef0 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/IntegerValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/IntegerValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/ListValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/ListValue.java similarity index 91% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/ListValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/ListValue.java index ecf17e84..eab4155f 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/ListValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/ListValue.java @@ -13,9 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Sets; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Unmodifiable; @@ -113,7 +114,11 @@ public boolean remove(Object o) { @Override public boolean containsAll(@NotNull Collection c) { - return this.value.containsAll(c); + /* Amarok Note: + * ArrayList 的数据存储量不可知的情况下,悲观假设有大量数据,那么 ArrayList#containsAll 的效率会低的令人发指... + * 虽说如果数据量少的话套一层 Set 也是无端浪费性能... 但我依然建议悲观演算。 + * */ + return Sets.newHashSet(this.value).containsAll(c); } @Override diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/LongValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/LongValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/LongValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/LongValue.java index 2de89dc5..2e4aa9bc 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/LongValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/LongValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/MapValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/MapValue.java similarity index 98% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/MapValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/MapValue.java index 39858f37..4afc78c8 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/MapValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/MapValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import com.google.common.collect.ImmutableMap; import org.jetbrains.annotations.Contract; diff --git a/config/common/src/main/java/band/kessoku/lib/config/api/values/StringValue.java b/config/common/src/main/java/band/kessoku/lib/config/values/StringValue.java similarity index 96% rename from config/common/src/main/java/band/kessoku/lib/config/api/values/StringValue.java rename to config/common/src/main/java/band/kessoku/lib/config/values/StringValue.java index 6d75a28e..3b0bd6fd 100644 --- a/config/common/src/main/java/band/kessoku/lib/config/api/values/StringValue.java +++ b/config/common/src/main/java/band/kessoku/lib/config/values/StringValue.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package band.kessoku.lib.config.api.values; +package band.kessoku.lib.config.values; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull;