diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java index dba98e565..47aba330d 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java @@ -41,6 +41,7 @@ import com.dfsek.terra.config.fileloaders.FolderLoader; import com.dfsek.terra.config.fileloaders.ZIPLoader; import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader; import com.dfsek.terra.config.loaders.config.BufferedImageLoader; +import com.dfsek.terra.config.preprocessor.MetaListPreprocessor; import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor; import com.dfsek.terra.config.prototype.ProtoConfig; import com.dfsek.terra.registry.CheckedRegistryImpl; @@ -240,8 +241,13 @@ public class ConfigPackImpl implements ConfigPack { main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::put)); // Create all the configs. - selfLoader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurations)); - abstractConfigLoader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurations)); + MetaValuePreprocessor valuePreprocessor = new MetaValuePreprocessor(configurations); + selfLoader.registerPreprocessor(Meta.class, valuePreprocessor); + abstractConfigLoader.registerPreprocessor(Meta.class, valuePreprocessor); + + MetaListPreprocessor listPreprocessor = new MetaListPreprocessor(configurations); + selfLoader.registerPreprocessor(Meta.class, listPreprocessor); + abstractConfigLoader.registerPreprocessor(Meta.class, listPreprocessor); Map, List> configs = new HashMap<>(); diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaListPreprocessor.java b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaListPreprocessor.java new file mode 100644 index 000000000..efcb8f814 --- /dev/null +++ b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaListPreprocessor.java @@ -0,0 +1,62 @@ +package com.dfsek.terra.config.preprocessor; + +import com.dfsek.tectonic.config.Configuration; +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.preprocessor.Result; +import com.dfsek.tectonic.preprocessor.ValuePreprocessor; +import com.dfsek.terra.api.config.meta.Meta; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.ParameterizedType; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class MetaListPreprocessor extends MetaPreprocessor { + public MetaListPreprocessor(Map configs) { + super(configs); + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull Result process(AnnotatedType t, T c, ConfigLoader loader, Meta annotation) { + if(t.getType() instanceof ParameterizedType) { + ParameterizedType parameterizedType = (ParameterizedType) t.getType(); + if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways + Class baseClass = (Class) parameterizedType.getRawType(); + + if(List.class.isAssignableFrom(baseClass) && c instanceof List) { // List metaconfig + List list = (List) c; + + int offset = 0; + List newList = new ArrayList<>((List) c); + + for(int i = 0; i < list.size(); i++) { + Object o = list.get(i); + if(!(o instanceof String)) continue; + String s = ((String) o).trim(); + if(!s.startsWith("<< ")) continue; + String meta = s.substring(3); + + Object metaValue = getMetaValue(meta); + + if(!(metaValue instanceof List)) { + throw new LoadException("MetaList injection candidate must be list, is type " + metaValue.getClass().getCanonicalName()); + } + + List metaList = (List) metaValue; + + newList.addAll(i + offset, metaList); + offset += metaList.size(); + } + + return (Result) Result.overwrite(newList); + } + } + } + + return Result.noOp(); + } +} diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java index 9e8c659c2..edc2155bc 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java @@ -1,17 +1,12 @@ package com.dfsek.terra.config.preprocessor; import com.dfsek.tectonic.config.Configuration; -import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.preprocessor.Result; -import com.dfsek.tectonic.preprocessor.ValuePreprocessor; import com.dfsek.terra.api.config.meta.Meta; import org.jetbrains.annotations.NotNull; import java.lang.reflect.AnnotatedType; -import java.lang.reflect.ParameterizedType; -import java.util.ArrayList; -import java.util.List; import java.util.Map; public class MetaValuePreprocessor extends MetaPreprocessor { @@ -29,42 +24,6 @@ public class MetaValuePreprocessor extends MetaPreprocessor { return (Result) Result.overwrite(getMetaValue(value.substring(1))); } } - - if(t.getType() instanceof ParameterizedType) { - ParameterizedType parameterizedType = (ParameterizedType) t.getType(); - if(parameterizedType.getRawType() instanceof Class) { // Should always be true but we check anyways - Class baseClass = (Class) parameterizedType.getRawType(); - - if(List.class.isAssignableFrom(baseClass) && c instanceof List) { // List metaconfig - List list = (List) c; - - int offset = 0; - List newList = new ArrayList<>((List) c); - - for(int i = 0; i < list.size(); i++) { - Object o = list.get(i); - if(!(o instanceof String)) continue; - String s = ((String) o).trim(); - if(!s.startsWith("<< ")) continue; - String meta = s.substring(3); - - Object metaValue = getMetaValue(meta); - - if(!(metaValue instanceof List)) { - throw new LoadException("MetaList injection candidate must be list, is type " + metaValue.getClass().getCanonicalName()); - } - - List metaList = (List) metaValue; - - newList.addAll(i + offset, metaList); - offset += metaList.size(); - } - - return (Result) Result.overwrite(newList); - } - } - } - return Result.noOp(); } } diff --git a/common/implementation/src/test/java/MetaTest.java b/common/implementation/src/test/java/MetaTest.java index c0c278fa8..cc41f9c2e 100644 --- a/common/implementation/src/test/java/MetaTest.java +++ b/common/implementation/src/test/java/MetaTest.java @@ -4,6 +4,7 @@ import com.dfsek.tectonic.config.Configuration; import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.yaml.YamlConfiguration; import com.dfsek.terra.api.config.meta.Meta; +import com.dfsek.terra.config.preprocessor.MetaListPreprocessor; import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor; import org.junit.jupiter.api.Test; @@ -24,6 +25,7 @@ public class MetaTest { ConfigLoader loader = new ConfigLoader(); loader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurationMap)); + loader.registerPreprocessor(Meta.class, new MetaListPreprocessor(configurationMap)); loader.load(new ConfigTest(), meta).list.forEach(System.out::println); }