Explorar el Código

Refactored & improved transformation process

Lortseam hace 4 años
padre
commit
78c3151cfc

+ 13 - 17
lib/src/main/java/me/lortseam/completeconfig/data/BooleanEntry.java

@@ -12,25 +12,21 @@ public class BooleanEntry extends Entry<Boolean> {
 
 
     private final Function<Boolean, TranslationIdentifier> valueTranslationSupplier;
     private final Function<Boolean, TranslationIdentifier> valueTranslationSupplier;
 
 
-    BooleanEntry(AnnotatedEntryOrigin<ConfigEntry.Boolean> origin) {
-        super(origin);
-        ConfigEntry.Boolean annotation = origin.getAnnotation();
-        if (StringUtils.isBlank(annotation.trueTranslationKey()) && StringUtils.isBlank(annotation.falseTranslationKey())) {
-            valueTranslationSupplier = null;
-        } else {
-            valueTranslationSupplier = value -> {
-                String key = value ? annotation.trueTranslationKey() : annotation.falseTranslationKey();
-                if (!StringUtils.isBlank(key)) {
-                    return getTranslation().root().append(key);
-                }
-                return getTranslation().append(value ? "true" : "false");
-            };
-        }
-    }
-
     BooleanEntry(EntryOrigin origin) {
     BooleanEntry(EntryOrigin origin) {
         super(origin);
         super(origin);
-        valueTranslationSupplier = null;
+        valueTranslationSupplier = origin.getOptionalAnnotation(ConfigEntry.Boolean.class).map(annotation -> {
+            if (StringUtils.isBlank(annotation.trueTranslationKey()) && StringUtils.isBlank(annotation.falseTranslationKey())) {
+                return null;
+            } else {
+                return (Function<Boolean, TranslationIdentifier>) value -> {
+                    String key = value ? annotation.trueTranslationKey() : annotation.falseTranslationKey();
+                    if (!StringUtils.isBlank(key)) {
+                        return getTranslation().root().append(key);
+                    }
+                    return getTranslation().append(value ? "true" : "false");
+                };
+            }
+        }).orElse(null);
     }
     }
 
 
     public Function<Boolean, Text> getValueTextSupplier() {
     public Function<Boolean, Text> getValueTextSupplier() {

+ 2 - 2
lib/src/main/java/me/lortseam/completeconfig/data/ColorEntry.java

@@ -14,8 +14,8 @@ public class ColorEntry<T> extends Entry<T> {
         this.alphaMode = alphaMode;
         this.alphaMode = alphaMode;
     }
     }
 
 
-    ColorEntry(AnnotatedEntryOrigin<ConfigEntry.Color> origin) {
-        this(origin, origin.getAnnotation().alphaMode());
+    ColorEntry(EntryOrigin origin) {
+        this(origin, origin.getAnnotation(ConfigEntry.Color.class).alphaMode());
     }
     }
 
 
 }
 }

+ 26 - 22
lib/src/main/java/me/lortseam/completeconfig/data/Entry.java

@@ -1,6 +1,5 @@
 package me.lortseam.completeconfig.data;
 package me.lortseam.completeconfig.data;
 
 
-import com.google.common.base.Predicates;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.BiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.HashBiMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Lists;
@@ -11,10 +10,12 @@ import me.lortseam.completeconfig.api.ConfigContainer;
 import me.lortseam.completeconfig.api.ConfigEntry;
 import me.lortseam.completeconfig.api.ConfigEntry;
 import me.lortseam.completeconfig.data.entry.EntryOrigin;
 import me.lortseam.completeconfig.data.entry.EntryOrigin;
 import me.lortseam.completeconfig.data.entry.Transformation;
 import me.lortseam.completeconfig.data.entry.Transformation;
+import me.lortseam.completeconfig.data.entry.Transformer;
 import me.lortseam.completeconfig.data.structure.DataPart;
 import me.lortseam.completeconfig.data.structure.DataPart;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
 import me.lortseam.completeconfig.exception.IllegalAnnotationParameterException;
 import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
 import me.lortseam.completeconfig.extensions.ConfigExtensionPattern;
+import me.lortseam.completeconfig.util.TypeUtils;
 import net.minecraft.text.Text;
 import net.minecraft.text.Text;
 import net.minecraft.text.TextColor;
 import net.minecraft.text.TextColor;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -30,33 +31,36 @@ import java.util.function.UnaryOperator;
 @Log4j2
 @Log4j2
 public class Entry<T> extends EntryBase<T> implements DataPart {
 public class Entry<T> extends EntryBase<T> implements DataPart {
 
 
+    private static final Transformer DEFAULT_TRANSFORMER = Entry::new;
     private static final List<Transformation> transformations = Lists.newArrayList(
     private static final List<Transformation> transformations = Lists.newArrayList(
-            Transformation.byAnnotation(ConfigEntry.Boolean.class).andType(boolean.class, Boolean.class).transforms(BooleanEntry::new),
-            Transformation.byType(boolean.class, Boolean.class).transforms(BooleanEntry::new),
-            Transformation.byAnnotation(ConfigEntry.BoundedInteger.class).andType(int.class, Integer.class).transforms(origin -> {
-                ConfigEntry.BoundedInteger bounds = origin.getAnnotation();
-                return origin.getAnnotation(ConfigEntry.Slider.class).map(slider -> {
-                    return (Entry<Integer>) new SliderEntry<>(origin, bounds.min(), bounds.max(), slider);
-                }).orElse(new BoundedEntry<>(origin, bounds.min(), bounds.max()));
+            Transformation.builder().byType(boolean.class, Boolean.class).byAnnotation(ConfigEntry.Boolean.class, true).transforms(BooleanEntry::new),
+            Transformation.builder().byType(int.class, Integer.class).byAnnotation(ConfigEntry.BoundedInteger.class).transforms(origin -> {
+                ConfigEntry.BoundedInteger bounds = origin.getAnnotation(ConfigEntry.BoundedInteger.class);
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max());
+            }),
+            Transformation.builder().byType(int.class, Integer.class).byAnnotation(Arrays.asList(ConfigEntry.BoundedInteger.class, ConfigEntry.Slider.class)).transforms(origin -> {
+                ConfigEntry.BoundedInteger bounds = origin.getAnnotation(ConfigEntry.BoundedInteger.class);
+                return new SliderEntry<>(origin, bounds.min(), bounds.max());
+            }),
+            Transformation.builder().byType(long.class, Long.class).byAnnotation(ConfigEntry.BoundedLong.class).transforms(origin -> {
+                ConfigEntry.BoundedLong bounds = origin.getAnnotation(ConfigEntry.BoundedLong.class);
+                return new BoundedEntry<>(origin, bounds.min(), bounds.max());
             }),
             }),
-            Transformation.byAnnotation(ConfigEntry.BoundedLong.class).andType(long.class, Long.class).transforms(origin -> {
-                ConfigEntry.BoundedLong bounds = origin.getAnnotation();
-                return origin.getAnnotation(ConfigEntry.Slider.class).map(slider -> {
-                    return (Entry<Long>) new SliderEntry<>(origin, bounds.min(), bounds.max(), slider);
-                }).orElse(new BoundedEntry<>(origin, bounds.min(), bounds.max()));
+            Transformation.builder().byType(long.class, Long.class).byAnnotation(Arrays.asList(ConfigEntry.BoundedLong.class, ConfigEntry.Slider.class)).transforms(origin -> {
+                ConfigEntry.BoundedLong bounds = origin.getAnnotation(ConfigEntry.BoundedLong.class);
+                return new SliderEntry<>(origin, bounds.min(), bounds.max());
             }),
             }),
-            Transformation.byAnnotation(ConfigEntry.BoundedFloat.class).andType(float.class, Float.class).transforms(origin -> {
-                ConfigEntry.BoundedFloat bounds = origin.getAnnotation();
+            Transformation.builder().byType(float.class, Float.class).byAnnotation(ConfigEntry.BoundedFloat.class).transforms(origin -> {
+                ConfigEntry.BoundedFloat bounds = origin.getAnnotation(ConfigEntry.BoundedFloat.class);
                 return new BoundedEntry<>(origin, bounds.min(), bounds.max());
                 return new BoundedEntry<>(origin, bounds.min(), bounds.max());
             }),
             }),
-            Transformation.byAnnotation(ConfigEntry.BoundedDouble.class).andType(double.class, Double.class).transforms(origin -> {
-                ConfigEntry.BoundedDouble bounds = origin.getAnnotation();
+            Transformation.builder().byType(double.class, Double.class).byAnnotation(ConfigEntry.BoundedDouble.class).transforms(origin -> {
+                ConfigEntry.BoundedDouble bounds = origin.getAnnotation(ConfigEntry.BoundedDouble.class);
                 return new BoundedEntry<>(origin, bounds.min(), bounds.max());
                 return new BoundedEntry<>(origin, bounds.min(), bounds.max());
             }),
             }),
-            Transformation.by(base -> Enum.class.isAssignableFrom(base.typeClass)).transforms(EnumEntry::new),
-            Transformation.byAnnotation(ConfigEntry.Enum.class).and(base -> Enum.class.isAssignableFrom(base.typeClass)).transforms(origin -> new EnumEntry<>(origin, origin.getAnnotation().displayType())),
-            Transformation.byAnnotation(ConfigEntry.Color.class).transforms(ColorEntry::new),
-            Transformation.byType(TextColor.class).transforms(origin -> new ColorEntry<>(origin, false))
+            Transformation.builder().byType(type -> Enum.class.isAssignableFrom(TypeUtils.getTypeClass(type))).byAnnotation(ConfigEntry.Enum.class, true).transforms(EnumEntry::new),
+            Transformation.builder().byAnnotation(ConfigEntry.Color.class).transforms(ColorEntry::new),
+            Transformation.builder().byType(TextColor.class).transforms(origin -> new ColorEntry<>(origin, false))
     );
     );
     private static final BiMap<Key, EntryBase> entries = HashBiMap.create();
     private static final BiMap<Key, EntryBase> entries = HashBiMap.create();
 
 
@@ -260,7 +264,7 @@ public class Entry<T> extends EntryBase<T> implements DataPart {
         }
         }
 
 
         Entry<T> build(ConfigContainer parentObject, TranslationIdentifier parentTranslation) {
         Entry<T> build(ConfigContainer parentObject, TranslationIdentifier parentTranslation) {
-            Entry<T> entry = transformations.stream().filter(transformation -> transformation.test(this)).findFirst().orElse(Transformation.by(Predicates.alwaysTrue()).transforms(Entry::new)).transform(this, parentObject, parentTranslation);
+            Entry<T> entry = (Entry<T>) transformations.stream().filter(transformation -> transformation.test(this)).findFirst().map(Transformation::getTransformer).orElse(DEFAULT_TRANSFORMER).transform(new EntryOrigin(this, parentObject, parentTranslation));
             for (Consumer<Entry<T>> interaction : interactions) {
             for (Consumer<Entry<T>> interaction : interactions) {
                 interaction.accept(entry);
                 interaction.accept(entry);
             }
             }

+ 2 - 6
lib/src/main/java/me/lortseam/completeconfig/data/EnumEntry.java

@@ -13,13 +13,9 @@ public class EnumEntry<T extends Enum> extends Entry<T> {
     @Getter
     @Getter
     private final DisplayType displayType;
     private final DisplayType displayType;
 
 
-    public EnumEntry(EntryOrigin origin, DisplayType displayType) {
-        super(origin);
-        this.displayType = displayType;
-    }
-
     public EnumEntry(EntryOrigin origin) {
     public EnumEntry(EntryOrigin origin) {
-        this(origin, DisplayType.DEFAULT);
+        super(origin);
+        this.displayType = origin.getOptionalAnnotation(ConfigEntry.Enum.class).map(ConfigEntry.Enum::displayType).orElse(DisplayType.DEFAULT);
     }
     }
 
 
     public Function<Enum, Text> getEnumNameProvider() {
     public Function<Enum, Text> getEnumNameProvider() {

+ 2 - 1
lib/src/main/java/me/lortseam/completeconfig/data/SliderEntry.java

@@ -12,8 +12,9 @@ public class SliderEntry<T extends Number> extends BoundedEntry<T> {
 
 
     private final TranslationIdentifier valueTranslation;
     private final TranslationIdentifier valueTranslation;
 
 
-    public SliderEntry(EntryOrigin origin, T min, T max, ConfigEntry.Slider slider) {
+    public SliderEntry(EntryOrigin origin, T min, T max) {
         super(origin, min, max);
         super(origin, min, max);
+        ConfigEntry.Slider slider = origin.getAnnotation(ConfigEntry.Slider.class);
         if (!StringUtils.isBlank(slider.valueTranslationKey())) {
         if (!StringUtils.isBlank(slider.valueTranslationKey())) {
             valueTranslation = getTranslation().root().append(slider.valueTranslationKey());
             valueTranslation = getTranslation().root().append(slider.valueTranslationKey());
         } else {
         } else {

+ 14 - 7
lib/src/main/java/me/lortseam/completeconfig/data/entry/EntryOrigin.java

@@ -1,15 +1,15 @@
 package me.lortseam.completeconfig.data.entry;
 package me.lortseam.completeconfig.data.entry;
 
 
-import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import me.lortseam.completeconfig.api.ConfigContainer;
 import me.lortseam.completeconfig.api.ConfigContainer;
+import me.lortseam.completeconfig.data.Entry;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Field;
+import java.util.Objects;
+import java.util.Optional;
 
 
-@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
 public final class EntryOrigin {
 public final class EntryOrigin {
 
 
     @Getter
     @Getter
@@ -19,11 +19,18 @@ public final class EntryOrigin {
     @Getter
     @Getter
     private final TranslationIdentifier parentTranslation;
     private final TranslationIdentifier parentTranslation;
 
 
+    public EntryOrigin(Entry.Draft<?> draft, ConfigContainer parentObject, TranslationIdentifier parentTranslation) {
+        field = draft.getField();
+        this.parentObject = parentObject;
+        this.parentTranslation = parentTranslation;
+    }
+
     public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
     public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
-        if (!field.isAnnotationPresent(annotationType)) {
-            throw new IllegalArgumentException("Annotation " + annotationType + " is not present");
-        }
-        return field.getAnnotation(annotationType);
+        return Objects.requireNonNull(field.getDeclaredAnnotation(annotationType), "Missing required transformation annotation");
+    }
+
+    public <A extends Annotation> Optional<A> getOptionalAnnotation(Class<A> annotationType) {
+        return Optional.ofNullable(field.getDeclaredAnnotation(annotationType));
     }
     }
 
 
 }
 }

+ 34 - 37
lib/src/main/java/me/lortseam/completeconfig/data/entry/Transformation.java

@@ -1,48 +1,41 @@
 package me.lortseam.completeconfig.data.entry;
 package me.lortseam.completeconfig.data.entry;
 
 
 import lombok.AccessLevel;
 import lombok.AccessLevel;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.NoArgsConstructor;
-import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.RequiredArgsConstructor;
-import me.lortseam.completeconfig.api.ConfigContainer;
 import me.lortseam.completeconfig.data.Entry;
 import me.lortseam.completeconfig.data.Entry;
-import me.lortseam.completeconfig.data.EntryBase;
-import me.lortseam.completeconfig.data.text.TranslationIdentifier;
 import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.ArrayUtils;
 
 
 import java.lang.annotation.Annotation;
 import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
 import java.lang.reflect.Type;
 import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.function.Consumer;
+import java.util.*;
 import java.util.function.Predicate;
 import java.util.function.Predicate;
+import java.util.stream.Collectors;
 
 
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 @RequiredArgsConstructor(access = AccessLevel.PRIVATE)
 public final class Transformation {
 public final class Transformation {
 
 
-    private static final Set<Class<Annotation>> registeredAnnotations = new HashSet<>();
+    private static final Set<Class<? extends Annotation>> registeredAnnotations = new HashSet<>();
 
 
     public static Transformation.Builder builder() {
     public static Transformation.Builder builder() {
         return new Transformation.Builder();
         return new Transformation.Builder();
     }
     }
 
 
     private final Predicate<Entry.Draft<?>> predicate;
     private final Predicate<Entry.Draft<?>> predicate;
+    @Getter
     private final Transformer transformer;
     private final Transformer transformer;
 
 
-    public boolean test(Entry.Draft<?> base) {
-        return predicate.test(base);
-    }
-
-    public Entry<?> transform(Entry.Draft<?> draft, ConfigContainer parentObject, TranslationIdentifier parentTranslation) {
-        return transformer.transform(originCreator.create(draft.getField(), parentObject, parentTranslation));
+    public boolean test(Entry.Draft<?> draft) {
+        return predicate.test(draft);
     }
     }
 
 
     @NoArgsConstructor(access = AccessLevel.PRIVATE)
     @NoArgsConstructor(access = AccessLevel.PRIVATE)
     public static class Builder {
     public static class Builder {
 
 
         private Predicate<Entry.Draft<?>> predicate;
         private Predicate<Entry.Draft<?>> predicate;
+        private final Set<Class<? extends Annotation>> requiredAnnotations = new HashSet<>();
+        private final Set<Class<? extends Annotation>> optionalAnnotations = new HashSet<>();
 
 
         private Builder by(Predicate<Entry.Draft<?>> predicate) {
         private Builder by(Predicate<Entry.Draft<?>> predicate) {
             if (this.predicate == null) {
             if (this.predicate == null) {
@@ -57,36 +50,40 @@ public final class Transformation {
             return byType(type -> ArrayUtils.contains(types, type));
             return byType(type -> ArrayUtils.contains(types, type));
         }
         }
 
 
-        public Builder byTypeClass(Predicate<Class<?>> typeClassPredicate) {
-            return by(draft -> typeClassPredicate.test(draft.getTypeClass()));
-        }
-
         public Builder byType(Predicate<Type> typePredicate) {
         public Builder byType(Predicate<Type> typePredicate) {
             return by(draft -> typePredicate.test(draft.getType()));
             return by(draft -> typePredicate.test(draft.getType()));
         }
         }
 
 
-        public Builder byAnnotation(Class<Annotation>... annotations) {
-            registeredAnnotations.addAll(Arrays.asList(annotations));
-            return by(draft -> {
-                for (Class<Annotation> annotationType : annotations) {
-                    if (!draft.getField().isAnnotationPresent(annotationType)) {
-                        return false;
-                    }
-                }
-                return true;
-            });
+        public Builder byAnnotation(Class<? extends Annotation> annotation, boolean optional) {
+            registeredAnnotations.add(annotation);
+            (optional ? optionalAnnotations : requiredAnnotations).add(annotation);
+            return this;
         }
         }
 
 
-        public Transformation transforms(Transformer transformer) {
-            return new Transformation(predicate, transformer);
+        public Builder byAnnotation(Class<? extends Annotation> annotation) {
+            return byAnnotation(annotation, false);
         }
         }
 
 
-    }
-
-    @FunctionalInterface
-    private interface OriginCreator<O extends EntryOrigin> {
+        public Builder byAnnotation(List<Class<? extends Annotation>> annotations) {
+            for (Class<? extends Annotation> annotation : annotations) {
+                byAnnotation(annotation);
+            }
+            return this;
+        }
 
 
-        O create(Field field, ConfigContainer parentObject, TranslationIdentifier parentTranslation);
+        public Transformation transforms(Transformer transformer) {
+            if (predicate == null && requiredAnnotations.isEmpty()) {
+                throw new IllegalStateException("Missing transformation filter");
+            }
+            by(draft -> {
+                Set<Class<? extends Annotation>> declaredAnnotations = Arrays.stream(draft.getField().getDeclaredAnnotations()).map(Annotation::annotationType).filter(registeredAnnotations::contains).collect(Collectors.toSet());
+                for (Class<? extends Annotation> requiredAnnotation : requiredAnnotations) {
+                    if (!declaredAnnotations.remove(requiredAnnotation)) return false;
+                }
+                return optionalAnnotations.containsAll(declaredAnnotations);
+            });
+            return new Transformation(predicate, transformer);
+        }
 
 
     }
     }
 
 

+ 1 - 1
lib/src/main/java/me/lortseam/completeconfig/extensions/clothbasicmath/ClothBasicMathExtension.java

@@ -25,7 +25,7 @@ public final class ClothBasicMathExtension implements CompleteConfigExtension {
     @Override
     @Override
     public Collection<Transformation> getTransformations() {
     public Collection<Transformation> getTransformations() {
         return ImmutableList.of(
         return ImmutableList.of(
-                Transformation.byType(Color.class).transforms(origin -> new ColorEntry<>(origin, true))
+                Transformation.builder().byType(Color.class).transforms(origin -> new ColorEntry<>(origin, true))
         );
         );
     }
     }