diff --git a/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/ContextualApplicationEnvironment.java b/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/ContextualApplicationEnvironment.java index 5c609f741..34ef78330 100644 --- a/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/ContextualApplicationEnvironment.java +++ b/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/ContextualApplicationEnvironment.java @@ -310,19 +310,19 @@ public Set observers(Class type) { throw new IllegalArgumentException("type cannot be null"); } - Set observers = new HashSet<>(); + Set allObservers = new HashSet<>(); this.observers.stream() .filter(type::isInstance) .map(type::cast) - .forEach(observers::add); + .forEach(allObservers::add); this.lazyObservers.stream() .filter(type::isAssignableFrom) .map(this.applicationContext::get) .map(type::cast) - .forEach(observers::add); + .forEach(allObservers::add); - return observers; + return allObservers; } private void printBanner(Class mainClass) { diff --git a/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/EnvironmentPropertyRegistryFactory.java b/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/EnvironmentPropertyRegistryFactory.java index dd4e9809a..0c82c95a9 100644 --- a/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/EnvironmentPropertyRegistryFactory.java +++ b/hartshorn-launchpad/src/main/java/org/dockbox/hartshorn/launchpad/environment/EnvironmentPropertyRegistryFactory.java @@ -16,13 +16,13 @@ import java.io.IOException; import java.net.URI; -import java.util.List; +import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; public class EnvironmentPropertyRegistryFactory { - public PropertyRegistry createRegistry(List propertySourceResolvers, ResourceLookup resourceLookup) { + public PropertyRegistry createRegistry(Collection propertySourceResolvers, ResourceLookup resourceLookup) { Set propertyRegistryLoaders = this.resolveRegistryLoaders(); PropertyRegistryLoader propertyRegistryLoader = this.createRegistryLoader(propertyRegistryLoaders); PropertyRegistryFactory propertyRegistryFactory = new InstantLoadingPropertyRegistryFactory(propertyRegistryLoader); @@ -35,7 +35,7 @@ public PropertyRegistry createRegistry(List propertySour } } - private Set resolveResources(List propertySourceResolvers, ResourceLookup resourceLookup) { + private Set resolveResources(Collection propertySourceResolvers, ResourceLookup resourceLookup) { Set sources = propertySourceResolvers.stream() .flatMap(resolver -> resolver.resolve().stream()) .collect(Collectors.toSet()); @@ -55,7 +55,7 @@ private Set resolveRegistryLoaders() { return propertyRegistryLoaders; } - private PropertyRegistryLoader createRegistryLoader(Set propertyRegistryLoaders) { + private PropertyRegistryLoader createRegistryLoader(Collection propertyRegistryLoaders) { PropertyRegistryLoader propertyRegistryLoader; if (propertyRegistryLoaders.size() == 1) { propertyRegistryLoader = CollectionUtilities.first(propertyRegistryLoaders); diff --git a/hartshorn-profiles/src/main/java/org/dockbox/hartshorn/profiles/ConfigurationProfileRegistryFactory.java b/hartshorn-profiles/src/main/java/org/dockbox/hartshorn/profiles/ConfigurationProfileRegistryFactory.java index 192d5e006..d6ca3ed34 100644 --- a/hartshorn-profiles/src/main/java/org/dockbox/hartshorn/profiles/ConfigurationProfileRegistryFactory.java +++ b/hartshorn-profiles/src/main/java/org/dockbox/hartshorn/profiles/ConfigurationProfileRegistryFactory.java @@ -9,7 +9,7 @@ import org.dockbox.hartshorn.properties.PropertyRegistry; import org.dockbox.hartshorn.properties.loader.PropertyRegistryLoader; -import org.dockbox.hartshorn.properties.value.StandardPropertyParsers; +import org.dockbox.hartshorn.properties.value.StandardValuePropertyParsers; import org.dockbox.hartshorn.util.ApplicationRuntimeException; public class ConfigurationProfileRegistryFactory implements ProfileRegistryFactory { @@ -36,7 +36,7 @@ public ProfileRegistry create(PropertyRegistry rootRegistry) { profileRegistry.register(0, defaultProfile); // TODO: Complex parser using predicate matching - List additionalProfiles = rootRegistry.value("hartshorn.profiles", StandardPropertyParsers.STRING_LIST) + List additionalProfiles = rootRegistry.value("hartshorn.profiles", StandardValuePropertyParsers.STRING_LIST) .map(this::profiles) .orElseGet(List::of); diff --git a/hartshorn-profiles/src/test/java/test/org/dockbox/hartshorn/profiles/ProfileLoaderTests.java b/hartshorn-profiles/src/test/java/test/org/dockbox/hartshorn/profiles/ProfileLoaderTests.java index 3d3ef9ca6..762cafd47 100644 --- a/hartshorn-profiles/src/test/java/test/org/dockbox/hartshorn/profiles/ProfileLoaderTests.java +++ b/hartshorn-profiles/src/test/java/test/org/dockbox/hartshorn/profiles/ProfileLoaderTests.java @@ -1,19 +1,20 @@ package test.org.dockbox.hartshorn.profiles; -import java.io.File; -import java.io.IOException; -import java.net.URI; -import java.nio.file.Path; -import java.util.Set; - import org.dockbox.hartshorn.profiles.ConfigurationProfileRegistryFactory; +import org.dockbox.hartshorn.profiles.ProfileRegistryFactory; import org.dockbox.hartshorn.properties.MapPropertyRegistry; +import org.dockbox.hartshorn.properties.PropertyRegistry; import org.dockbox.hartshorn.properties.loader.support.CompositePredicatePropertyRegistryLoader; import org.dockbox.hartshorn.properties.loader.support.JacksonJavaPropsPropertyRegistryLoader; import org.dockbox.hartshorn.properties.loader.support.JacksonYamlPropertyRegistryLoader; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Set; + public class ProfileLoaderTests { @Test @@ -22,13 +23,13 @@ void testLoadProfilesInOrder() throws IOException { propertyRegistryLoader.addLoader(new JacksonYamlPropertyRegistryLoader()); propertyRegistryLoader.addLoader(new JacksonJavaPropsPropertyRegistryLoader()); - var profileRegistryFactory = new ConfigurationProfileRegistryFactory(propertyRegistryLoader, name -> { + ProfileRegistryFactory profileRegistryFactory = new ConfigurationProfileRegistryFactory(propertyRegistryLoader, name -> { return Set.of( new File("C:\\Projects\\Temp\\Hartshorn\\hartshorn-profiles\\src\\test\\resources\\application-%s.yml".formatted(name)).toURI() ); }, MapPropertyRegistry::new); - var rootRegistry = new MapPropertyRegistry(); + PropertyRegistry rootRegistry = new MapPropertyRegistry(); propertyRegistryLoader.loadRegistry(rootRegistry, Path.of("C:\\Projects\\Temp\\Hartshorn\\hartshorn-profiles\\src\\test\\resources\\application.yml")); var profileRegistry = profileRegistryFactory.create(rootRegistry); var profilesInOrder = profileRegistry.profiles(); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/AbstractMapProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/AbstractMapProperty.java new file mode 100644 index 000000000..5cc70a320 --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/AbstractMapProperty.java @@ -0,0 +1,108 @@ +package org.dockbox.hartshorn.properties; + +import org.dockbox.hartshorn.properties.list.SimpleListProperty; +import org.dockbox.hartshorn.properties.parse.support.ValueConfiguredPropertyParser; +import org.dockbox.hartshorn.properties.value.SimpleValueProperty; +import org.dockbox.hartshorn.properties.value.StandardValuePropertyParsers; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public abstract class AbstractMapProperty { + + private final Map properties; + private final String name; + + protected AbstractMapProperty(String name, Map properties) { + this.properties = new TreeMap<>(properties); + this.name = name; + } + + protected Map properties() { + return this.properties; + } + + public String name() { + return this.name; + } + + public Option get(T key) { + return Option.of(this.properties.get(valueAccessor(key))) + .flatMap(ValueConfiguredPropertyParser.INSTANCE::parse); + } + + protected abstract String valueAccessor(T key); + + public Option object(T key) { + Map propertyMap = this.collectToMap(key, (name, property) -> { + return name.startsWith(this.accessor(key) + "."); + }).entrySet().stream().collect(Collectors.toMap( + // Strip trailing . from key + entry -> entry.getKey().substring(1), + Map.Entry::getValue + )); + ObjectProperty property = new MapObjectProperty(this.name() + this.accessor(key), propertyMap); + return Option.of(property); + } + + protected abstract String accessor(T key); + + public Option list(T key) { + return this.list(key, value -> { + Option values = StandardValuePropertyParsers.STRING_LIST.parse(value); + List valueList = values.stream().flatMap(Arrays::stream).toList(); + List listProperties = new ArrayList<>(); + for (int i = 0; i < valueList.size(); i++) { + listProperties.add(i, new SimpleValueProperty(this.name() + this.accessor(key) + "[" + i + "]", valueList.get(i))); + } + return new SimpleListProperty(this.name() + this.accessor(key), listProperties); + }); + } + + public Option list(T key, Function singleValueMapper) { + if (this.contains(key)) { + return this.get(key).map(singleValueMapper); + } else { + Map propertyMap = this.collectToMap(key, (name, property) -> { + return name.startsWith(key + "["); + }); + ListProperty property = new MapListProperty(this.name() + this.accessor(key), propertyMap); + return Option.of(property); + } + } + + public boolean contains(T key) { + if (this.properties().containsKey(this.valueAccessor(key))) { + return true; + } else { + String accessor = this.accessor(key); + return this.properties().keySet().stream().anyMatch(propertyKey -> + propertyKey.startsWith(accessor + ".") || propertyKey.startsWith(accessor + "[") + ); + } + } + + public List find(BiPredicate predicate) { + return this.properties().entrySet().stream() + .filter(entry -> predicate.test(entry.getKey(), entry.getValue())) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + } + + private Map collectToMap(T key, BiPredicate predicate) { + return this.find(predicate).stream() + .collect(Collectors.toMap( + property -> this.key(key, property), + Function.identity() + )); + } + + protected abstract String key(T prefix, ConfiguredProperty property); +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/ListProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/ListProperty.java index 0efc5caed..9ca55fc51 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/ListProperty.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/ListProperty.java @@ -1,13 +1,19 @@ package org.dockbox.hartshorn.properties; -import java.util.Collection; -import java.util.List; - import org.dockbox.hartshorn.properties.list.ListPropertyParser; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.Collection; public non-sealed interface ListProperty extends Property { - List elements(); + int size(); + + Option get(int index); + + Option object(int index); + + Option list(int index); Collection parse(ListPropertyParser parser); } diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapListProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapListProperty.java new file mode 100644 index 000000000..c27ff4884 --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapListProperty.java @@ -0,0 +1,59 @@ +package org.dockbox.hartshorn.properties; + +import org.dockbox.hartshorn.properties.list.ListPropertyParser; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.Collection; +import java.util.Map; + +public class MapListProperty extends AbstractMapProperty implements ListProperty { + + public MapListProperty(String name, Map properties) { + super(name, properties); + } + + @Override + protected String valueAccessor(Integer key) { + return "[" + key + "]"; + } + + @Override + protected String accessor(Integer key) { + return "[" + key + "]"; + } + + @Override + protected String key(Integer prefix, ConfiguredProperty property) { + return property.name().substring(this.name().length() + this.accessor(prefix).length()); + } + + @Override + public int size() { + return this.properties().keySet().stream() + .map(key -> key.split("\\[")[1].split("]")[0]) + .map(Integer::parseInt) + .max(Integer::compareTo) + .map(i -> i + 1) // Add one to get the size, as the max index is zero-based + .orElse(0); + } + + @Override + public Option get(int index) { + return this.get(Integer.valueOf(index)); + } + + @Override + public Option object(int index) { + return this.object(Integer.valueOf(index)); + } + + @Override + public Option list(int index) { + return this.list(Integer.valueOf(index)); + } + + @Override + public Collection parse(ListPropertyParser parser) { + return parser.parse(this); + } +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapObjectProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapObjectProperty.java new file mode 100644 index 000000000..e255e0749 --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapObjectProperty.java @@ -0,0 +1,45 @@ +package org.dockbox.hartshorn.properties; + +import org.dockbox.hartshorn.properties.object.ObjectPropertyParser; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.List; +import java.util.Map; + +public class MapObjectProperty extends AbstractMapProperty implements ObjectProperty { + + public MapObjectProperty(String name, Map properties) { + super(name, properties); + } + + @Override + protected String valueAccessor(String key) { + return key; + } + + @Override + protected String accessor(String key) { + return this.name().isBlank() + ? key + : "." + key; + } + + @Override + protected String key(String prefix, ConfiguredProperty property) { + // Remove prefix from name + return property.name().substring(this.name().length() + this.accessor(prefix).length()); + } + + @Override + public List keys() { + return this.properties().keySet().stream() + .map(key -> key.split("\\.")[0]) + .distinct() + .toList(); + } + + @Override + public Option parse(ObjectPropertyParser parser) { + return parser.parse(this); + } +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapPropertyRegistry.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapPropertyRegistry.java index 80d1aac72..b515d3edc 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapPropertyRegistry.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/MapPropertyRegistry.java @@ -2,53 +2,43 @@ import java.util.List; import java.util.Map; -import java.util.TreeMap; import java.util.function.Predicate; -import org.dockbox.hartshorn.util.option.Option; +public class MapPropertyRegistry extends MapObjectProperty implements PropertyRegistry { -public class MapPropertyRegistry implements PropertyRegistry { - - private final Map properties = new TreeMap<>(); + public MapPropertyRegistry() { + this(""); + } - @Override - public List keys() { - return List.copyOf(properties.keySet()); + public MapPropertyRegistry(String name) { + super(name, Map.of()); } @Override - public Option get(String name) { - ValueProperty property = properties.get(name); - return Option.of(property); + public List find(Predicate predicate) { + return this.find((name, property) -> predicate.test(property)); } @Override - public void register(ValueProperty property) { + public void register(ConfiguredProperty property) { if (this.contains(property.name())) { throw new IllegalArgumentException("Property with name " + property.name() + " already exists. If you intended to load a property with multiple values, implement the appropriate ConfiguredProperty"); } - this.properties.put(property.name(), property); - } - - @Override - public void unregister(String name) { - this.properties.remove(name); + this.properties().put(property.name(), property); } @Override - public void clear() { - this.properties.clear(); + public void registerAll(Map properties) { + this.properties().putAll(properties); } @Override - public boolean contains(String name) { - return this.properties.containsKey(name); + public void unregister(String name) { + this.properties().remove(name); } @Override - public List valuesMatching(Predicate predicate) { - return this.properties.values().stream() - .filter(predicate) - .toList(); + public void clear() { + this.properties().clear(); } } diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyInitializer.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyInitializer.java index ef7c13b7d..8d427c614 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyInitializer.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyInitializer.java @@ -1,7 +1,7 @@ package org.dockbox.hartshorn.properties; import org.dockbox.hartshorn.properties.value.ValuePropertyParser; -import org.dockbox.hartshorn.properties.value.StandardPropertyParsers; +import org.dockbox.hartshorn.properties.value.StandardValuePropertyParsers; import org.dockbox.hartshorn.properties.value.support.EnumValuePropertyParser; import org.dockbox.hartshorn.util.OptionInitializer; import org.dockbox.hartshorn.util.SingleElementContext; @@ -22,39 +22,39 @@ public static PropertyInitializer of(String property, ValuePropertyParser } public static PropertyInitializer booleanProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.BOOLEAN); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.BOOLEAN); } public static PropertyInitializer integerProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.INTEGER); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.INTEGER); } public static PropertyInitializer longProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.LONG); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.LONG); } public static PropertyInitializer doubleProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.DOUBLE); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.DOUBLE); } public static PropertyInitializer floatProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.FLOAT); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.FLOAT); } public static PropertyInitializer stringProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.STRING); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.STRING); } public static PropertyInitializer charProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.CHARACTER); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.CHARACTER); } public static PropertyInitializer shortProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.SHORT); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.SHORT); } public static PropertyInitializer byteProperty(String property) { - return new PropertyInitializer<>(property, StandardPropertyParsers.BYTE); + return new PropertyInitializer<>(property, StandardValuePropertyParsers.BYTE); } public static > PropertyInitializer enumProperty(String property, Class type) { diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyRegistry.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyRegistry.java index 931bbb6a8..6cde1db72 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyRegistry.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/PropertyRegistry.java @@ -1,24 +1,20 @@ package org.dockbox.hartshorn.properties; -import java.util.List; -import java.util.function.Function; - import org.dockbox.hartshorn.properties.value.ValuePropertyParser; import org.dockbox.hartshorn.util.option.Option; -public interface PropertyRegistry { - - List keys(); - - Option get(String name); - - Option object(String name); +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; - Option list(String name); +public interface PropertyRegistry extends ObjectProperty { // mapper used if value is (e.g.) a,b,c instead of 'proper' list Option list(String name, Function singleValueMapper); + List find(Predicate predicate); + default Option value(String name) { return this.get(name).flatMap(ValueProperty::value); } @@ -27,7 +23,9 @@ default Option value(String name, ValuePropertyParser parser) { return this.get(name).flatMap(parser::parse); } - void register(ValueProperty property); + void register(ConfiguredProperty property); + + void registerAll(Map properties); void unregister(String name); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ObjectListPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ObjectListPropertyParser.java deleted file mode 100644 index 0fd5d484d..000000000 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ObjectListPropertyParser.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.dockbox.hartshorn.properties.list; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.dockbox.hartshorn.properties.ListProperty; -import org.dockbox.hartshorn.properties.Property; -import org.dockbox.hartshorn.properties.ValueProperty; -import org.dockbox.hartshorn.properties.value.ValuePropertyParser; - -public class ObjectListPropertyParser implements ListPropertyParser { - - private final ValuePropertyParser delegate; - - public ObjectListPropertyParser(ValuePropertyParser delegate) { - this.delegate = delegate; - } - - @Override - public Collection parse(ListProperty property) { - List values = new ArrayList<>(); - for(Property element : property.elements()) { - if (element instanceof ValueProperty valueProperty) { - values.add(this.delegate.parse(valueProperty).orNull()); - } - else { - throw new IllegalArgumentException("Expected ValueProperty, got " + element.getClass().getSimpleName()); - } - } - return values; - } -} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SimpleListProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SimpleListProperty.java index ff3474de8..c090a94db 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SimpleListProperty.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SimpleListProperty.java @@ -1,10 +1,13 @@ package org.dockbox.hartshorn.properties.list; -import java.util.Collection; -import java.util.List; - import org.dockbox.hartshorn.properties.ListProperty; +import org.dockbox.hartshorn.properties.ObjectProperty; import org.dockbox.hartshorn.properties.Property; +import org.dockbox.hartshorn.properties.ValueProperty; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.Collection; +import java.util.List; public record SimpleListProperty(String name, List elements) implements ListProperty { @@ -13,6 +16,26 @@ public List elements() { return List.copyOf(this.elements); } + @Override + public int size() { + return this.elements().size(); + } + + @Override + public Option get(int index) { + return Option.of(this.elements().get(index)).ofType(ValueProperty.class); + } + + @Override + public Option object(int index) { + return Option.of(this.elements().get(index)).ofType(ObjectProperty.class); + } + + @Override + public Option list(int index) { + return Option.of(this.elements().get(index)).ofType(ListProperty.class); + } + @Override public Collection parse(ListPropertyParser parser) { return parser.parse(this); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SingleValueListPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SingleValueListPropertyParser.java deleted file mode 100644 index 82aedf4dc..000000000 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/SingleValueListPropertyParser.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.dockbox.hartshorn.properties.list; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.dockbox.hartshorn.properties.ListProperty; -import org.dockbox.hartshorn.properties.Property; -import org.dockbox.hartshorn.properties.ValueProperty; -import org.dockbox.hartshorn.properties.value.ValuePropertyParser; - -public class SingleValueListPropertyParser implements ListPropertyParser { - - private final ValuePropertyParser delegate; - - public SingleValueListPropertyParser(ValuePropertyParser delegate) { - this.delegate = delegate; - } - - @Override - public Collection parse(ListProperty property) { - List values = new ArrayList<>(); - for(Property element : property.elements()) { - if (element instanceof ValueProperty valueProperty) { - values.add(this.delegate.parse(valueProperty).orNull()); - } - else { - throw new IllegalArgumentException("Expected ValueProperty, got " + element.getClass().getSimpleName()); - } - } - return values; - } -} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ValueListPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ValueListPropertyParser.java new file mode 100644 index 000000000..2d2c2fdcb --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/list/ValueListPropertyParser.java @@ -0,0 +1,28 @@ +package org.dockbox.hartshorn.properties.list; + +import org.dockbox.hartshorn.properties.ListProperty; +import org.dockbox.hartshorn.properties.value.ValuePropertyParser; + +import java.util.ArrayList; +import java.util.Collection; + +public class ValueListPropertyParser implements ListPropertyParser { + + private final ValuePropertyParser delegate; + + public ValueListPropertyParser(ValuePropertyParser delegate) { + this.delegate = delegate; + } + + @Override + public Collection parse(ListProperty property) { + Collection values = new ArrayList<>(); + for (int i = 0; i < property.size(); i++) { + property.get(i) + .peek(value -> { + values.add(this.delegate.parse(value).orNull()); + }); + } + return values; + } +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/StandardPropertyPathFormatter.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/StandardPropertyPathFormatter.java index 74ee1a8fd..e41e71951 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/StandardPropertyPathFormatter.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/StandardPropertyPathFormatter.java @@ -17,11 +17,11 @@ public String formatPath(PropertyPathNode pathNode) { private String formatPath(PropertyPathNode pathNode, StringBuilder builder) { return switch(pathNode) { case PropertyFieldPathNode fieldPathNode -> { - builder.insert(0, formatField(fieldPathNode)); + builder.insert(0, this.formatField(fieldPathNode)); yield this.formatPath(fieldPathNode.parent(), builder); } case PropertyIndexPathNode indexPathNode -> { - builder.insert(0, formatIndex(indexPathNode)); + builder.insert(0, this.formatIndex(indexPathNode)); yield this.formatPath(indexPathNode.parent(), builder); } case PropertyRootPathNode ignored -> builder.toString(); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/support/JacksonPropertyRegistryLoader.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/support/JacksonPropertyRegistryLoader.java index 1667dbf97..e426f5eb8 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/support/JacksonPropertyRegistryLoader.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/loader/support/JacksonPropertyRegistryLoader.java @@ -1,18 +1,5 @@ package org.dockbox.hartshorn.properties.loader.support; -import java.io.IOException; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; - -import org.dockbox.hartshorn.properties.ValueProperty; -import org.dockbox.hartshorn.properties.PropertyRegistry; -import org.dockbox.hartshorn.properties.loader.PredicatePropertyRegistryLoader; -import org.dockbox.hartshorn.properties.loader.path.PropertyPathFormatter; -import org.dockbox.hartshorn.properties.loader.path.PropertyPathNode; -import org.dockbox.hartshorn.properties.loader.path.PropertyRootPathNode; -import org.dockbox.hartshorn.util.CollectionUtilities; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -20,9 +7,19 @@ import com.fasterxml.jackson.databind.node.ValueNode; import org.dockbox.hartshorn.properties.ConfiguredProperty; +import org.dockbox.hartshorn.properties.PropertyRegistry; import org.dockbox.hartshorn.properties.SingleConfiguredProperty; +import org.dockbox.hartshorn.properties.loader.PredicatePropertyRegistryLoader; +import org.dockbox.hartshorn.properties.loader.path.PropertyPathFormatter; +import org.dockbox.hartshorn.properties.loader.path.PropertyPathNode; +import org.dockbox.hartshorn.properties.loader.path.PropertyRootPathNode; +import org.dockbox.hartshorn.util.CollectionUtilities; import org.dockbox.hartshorn.util.FileUtilities; +import java.io.IOException; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Set; public abstract class JacksonPropertyRegistryLoader implements PredicatePropertyRegistryLoader { @@ -58,19 +55,18 @@ public void loadRegistry(PropertyRegistry registry, Path path) throws IOExceptio } } - protected PropertyRegistry loadRegistry(PropertyRegistry registry, JsonNode node) { + protected void loadRegistry(PropertyRegistry registry, JsonNode node) { List properties = this.loadProperties(node); for(ConfiguredProperty property : properties) { registry.register(property); } - return registry; } protected List loadProperties(JsonNode node) { return this.loadProperties(new PropertyRootPathNode(), node); } - protected List loadProperties(PropertyPathNode path, JsonNode node) { + protected List loadProperties(PropertyPathNode path, JsonNode node) { return switch(node) { case ArrayNode arrayNode -> this.loadArrayProperties(path, arrayNode); case ObjectNode objectNode -> this.loadObjectProperties(path, objectNode); @@ -84,8 +80,8 @@ protected ConfiguredProperty loadSingleProperty(PropertyPathNode path, ValueNode return new SingleConfiguredProperty(propertyPath, valueNode.asText()); } - protected List loadArrayProperties(PropertyPathNode path, ArrayNode arrayNode) { - List properties = new ArrayList<>(); + protected List loadArrayProperties(PropertyPathNode path, ArrayNode arrayNode) { + List properties = new ArrayList<>(); CollectionUtilities.indexed(arrayNode.elements(), (index, element) -> { PropertyPathNode nextPath = path.index(index); properties.addAll(this.loadProperties(nextPath, element)); @@ -93,8 +89,8 @@ protected List loadArrayProperties(PropertyPathNode path, ArrayNo return properties; } - protected List loadObjectProperties(PropertyPathNode path, ObjectNode objectNode) { - List properties = new ArrayList<>(); + protected List loadObjectProperties(PropertyPathNode path, ObjectNode objectNode) { + List properties = new ArrayList<>(); CollectionUtilities.iterateEntries(objectNode.fields(), (name, value) -> { PropertyPathNode nextPath = path.property(name); properties.addAll(this.loadProperties(nextPath, value)); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/AbstractMapObjectProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/AbstractMapObjectProperty.java new file mode 100644 index 000000000..b51c53f04 --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/AbstractMapObjectProperty.java @@ -0,0 +1,42 @@ +package org.dockbox.hartshorn.properties.object; + +import org.dockbox.hartshorn.properties.ObjectProperty; +import org.dockbox.hartshorn.util.option.Option; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public abstract class AbstractMapObjectProperty implements ObjectProperty { + + private final String name; + private final Map properties; + + protected AbstractMapObjectProperty(String name, Map properties) { + this.name = name; + this.properties = new HashMap<>(properties); + } + + @Override + public List keys() { + return List.copyOf(this.properties.keySet()); + } + + @Override + public Option parse(ObjectPropertyParser parser) { + return parser.parse(this); + } + + @Override + public String name() { + return this.name; + } + + protected Option property(String name) { + return Option.of(this.properties.get(name)); + } + + protected Map properties() { + return this.properties; + } +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/ObjectPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/ObjectPropertyParser.java index 477017a56..bfa63221d 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/ObjectPropertyParser.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/ObjectPropertyParser.java @@ -3,6 +3,7 @@ import org.dockbox.hartshorn.properties.ObjectProperty; import org.dockbox.hartshorn.util.option.Option; +@FunctionalInterface public interface ObjectPropertyParser { Option parse(ObjectProperty property); diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/SimpleObjectProperty.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/SimpleObjectProperty.java index ba2aa6e08..ed17e4650 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/SimpleObjectProperty.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/object/SimpleObjectProperty.java @@ -1,52 +1,31 @@ package org.dockbox.hartshorn.properties.object; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - import org.dockbox.hartshorn.properties.ListProperty; import org.dockbox.hartshorn.properties.ObjectProperty; import org.dockbox.hartshorn.properties.Property; import org.dockbox.hartshorn.properties.ValueProperty; import org.dockbox.hartshorn.util.option.Option; -public class SimpleObjectProperty implements ObjectProperty { +import java.util.Map; - private final String name; - private final Map properties; +public class SimpleObjectProperty extends AbstractMapObjectProperty { public SimpleObjectProperty(String name, Map properties) { - this.name = name; - this.properties = new HashMap<>(properties); - } - - @Override - public List keys() { - return List.copyOf(this.properties.keySet()); + super(name, properties); } @Override public Option get(String name) { - return Option.of(this.properties.get(name)).ofType(ValueProperty.class); + return Option.of(this.properties().get(name)).ofType(ValueProperty.class); } @Override public Option object(String name) { - return Option.of(this.properties.get(name)).ofType(ObjectProperty.class); + return Option.of(this.properties().get(name)).ofType(ObjectProperty.class); } @Override public Option list(String name) { - return Option.of(this.properties.get(name)).ofType(ListProperty.class); - } - - @Override - public Option parse(ObjectPropertyParser parser) { - return parser.parse(this); - } - - @Override - public String name() { - return this.name; + return Option.of(this.properties().get(name)).ofType(ListProperty.class); } } diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/StandardPropertyParsers.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/StandardPropertyParsers.java deleted file mode 100644 index 72ad9f3ef..000000000 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/StandardPropertyParsers.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.dockbox.hartshorn.properties.parse; - -import org.dockbox.hartshorn.properties.ConfiguredProperty; - -public final class StandardPropertyParsers { - - private StandardPropertyParsers() { - // Static access only - } - - public static final ConfiguredPropertyParser BOOLEAN = property -> property.value().map(Boolean::parseBoolean); - - public static final ConfiguredPropertyParser INTEGER = property -> property.value().map(Integer::parseInt); - - public static final ConfiguredPropertyParser LONG = property -> property.value().map(Long::parseLong); - - public static final ConfiguredPropertyParser DOUBLE = property -> property.value().map(Double::parseDouble); - - public static final ConfiguredPropertyParser FLOAT = property -> property.value().map(Float::parseFloat); - - public static final ConfiguredPropertyParser STRING = ConfiguredProperty::value; - - public static final ConfiguredPropertyParser CHARACTER = property -> property.value().map(value -> value.charAt(0)); - - public static final ConfiguredPropertyParser SHORT = property -> property.value().map(Short::parseShort); - - public static final ConfiguredPropertyParser BYTE = property -> property.value().map(Byte::parseByte); - - public static final ConfiguredPropertyParser HEX_BYTE = property -> property.value().map(value -> (byte) Integer.parseInt(value, 16)); - -} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ConverterConfiguredPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ConverterConfiguredPropertyParser.java index 04d1007a9..4d68936f1 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ConverterConfiguredPropertyParser.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ConverterConfiguredPropertyParser.java @@ -15,6 +15,6 @@ public ConverterConfiguredPropertyParser(Converter converter) { @Override public Option parse(ConfiguredProperty property) { - return property.value().map(converter::convert); + return property.value().map(this.converter::convert); } } diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ValueConfiguredPropertyParser.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ValueConfiguredPropertyParser.java new file mode 100644 index 000000000..9d99dc92e --- /dev/null +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/parse/support/ValueConfiguredPropertyParser.java @@ -0,0 +1,18 @@ +package org.dockbox.hartshorn.properties.parse.support; + +import org.dockbox.hartshorn.properties.ConfiguredProperty; +import org.dockbox.hartshorn.properties.ValueProperty; +import org.dockbox.hartshorn.properties.parse.ConfiguredPropertyParser; +import org.dockbox.hartshorn.properties.value.SimpleValueProperty; +import org.dockbox.hartshorn.util.option.Option; + +public class ValueConfiguredPropertyParser implements ConfiguredPropertyParser { + + public static final ValueConfiguredPropertyParser INSTANCE = new ValueConfiguredPropertyParser(); + + @Override + public Option parse(ConfiguredProperty property) { + return property.value() + .map(value -> new SimpleValueProperty(property.name(), value)); + } +} diff --git a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardPropertyParsers.java b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardValuePropertyParsers.java similarity index 94% rename from hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardPropertyParsers.java rename to hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardValuePropertyParsers.java index 8f850a820..e919db353 100644 --- a/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardPropertyParsers.java +++ b/hartshorn-properties/src/main/java/org/dockbox/hartshorn/properties/value/StandardValuePropertyParsers.java @@ -4,9 +4,9 @@ import org.dockbox.hartshorn.properties.value.support.GenericConverterValuePropertyParser; import org.dockbox.hartshorn.util.introspect.convert.support.StringToArrayConverter; -public final class StandardPropertyParsers { +public final class StandardValuePropertyParsers { - private StandardPropertyParsers() { + private StandardValuePropertyParsers() { // Static access only } diff --git a/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/PropertyRegistryTests.java b/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/PropertyRegistryTests.java new file mode 100644 index 000000000..c601519f5 --- /dev/null +++ b/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/PropertyRegistryTests.java @@ -0,0 +1,90 @@ +package test.org.dockbox.hartshorn.properties; + +import org.dockbox.hartshorn.properties.ListProperty; +import org.dockbox.hartshorn.properties.MapPropertyRegistry; +import org.dockbox.hartshorn.properties.ObjectProperty; +import org.dockbox.hartshorn.properties.PropertyRegistry; +import org.dockbox.hartshorn.properties.ValueProperty; +import org.dockbox.hartshorn.properties.loader.PropertyRegistryLoader; +import org.dockbox.hartshorn.properties.loader.StandardPropertyPathFormatter; +import org.dockbox.hartshorn.properties.loader.support.JacksonYamlPropertyRegistryLoader; +import org.dockbox.hartshorn.util.option.Option; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.nio.file.Path; + +public class PropertyRegistryTests { + + @Test + void testComplexRegistryAccessing() throws IOException { + PropertyRegistryLoader loader = new JacksonYamlPropertyRegistryLoader(new StandardPropertyPathFormatter()); + Path path = Path.of("src/test/resources/complex-configuration.yml"); + + PropertyRegistry registry = new MapPropertyRegistry(); + loader.loadRegistry(registry, path); + + Option complexObject = registry.object("sample.complex"); + Assertions.assertTrue(complexObject.present()); + complexObject.peek(object -> { + Assertions.assertEquals("sample.complex", object.name()); + + Option configurationList = object.list("configuration"); + Assertions.assertTrue(configurationList.present()); + configurationList.peek(list -> { + Assertions.assertEquals(3, list.size()); + Assertions.assertEquals("sample.complex.configuration", list.name()); + + assertConfigurationObject(list, 0, "name1", "value1"); + assertConfigurationObject(list, 1, "name2", "value2"); + assertConfigurationObject(list, 2, "name3", "value3"); + }); + + Option valuesList = object.list("values"); + Assertions.assertTrue(valuesList.present()); + valuesList.peek(list -> { + Assertions.assertEquals(3, list.size()); + Assertions.assertEquals("sample.complex.values", list.name()); + + Option valueOne = list.get(0); + Assertions.assertTrue(valueOne.present()); + Assertions.assertEquals("value1", valueOne.get().value().get()); + Assertions.assertEquals("sample.complex.values[0]", valueOne.get().name()); + + Option valueTwo = list.get(1); + Assertions.assertTrue(valueTwo.present()); + Assertions.assertEquals("value2", valueTwo.get().value().get()); + Assertions.assertEquals("sample.complex.values[1]", valueTwo.get().name()); + + Option valueThree = list.get(2); + Assertions.assertTrue(valueThree.present()); + Assertions.assertEquals("value3", valueThree.get().value().get()); + Assertions.assertEquals("sample.complex.values[2]", valueThree.get().name()); + }); + + Option flatValue = object.get("flat"); + Assertions.assertTrue(flatValue.present()); + Assertions.assertEquals("value1", flatValue.get().value().get()); + Assertions.assertEquals("sample.complex.flat", flatValue.get().name()); + }); + } + + private static void assertConfigurationObject(ListProperty listProperty, int index, String expectedName, String expectedValue) { + Option configurationObject = listProperty.object(index); + Assertions.assertTrue(configurationObject.present()); + configurationObject.peek(object -> { + Assertions.assertEquals("sample.complex.configuration[" + index + "]", object.name()); + + Option name = object.get("name"); + Assertions.assertTrue(name.present()); + Assertions.assertEquals(expectedName, name.get().value().get()); + Assertions.assertEquals("sample.complex.configuration[" + index + "].name", name.get().name()); + + Option value = object.get("value"); + Assertions.assertTrue(value.present()); + Assertions.assertEquals(expectedValue, value.get().value().get()); + Assertions.assertEquals("sample.complex.configuration[" + index + "].value", value.get().name()); + }); + } +} diff --git a/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/loader/JacksonPropertyRegistryLoaderTests.java b/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/loader/JacksonPropertyRegistryLoaderTests.java index c74157c3e..a11913fb2 100644 --- a/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/loader/JacksonPropertyRegistryLoaderTests.java +++ b/hartshorn-properties/src/test/java/test/org/dockbox/hartshorn/properties/loader/JacksonPropertyRegistryLoaderTests.java @@ -1,25 +1,25 @@ package test.org.dockbox.hartshorn.properties.loader; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Iterator; -import java.util.List; - import org.dockbox.hartshorn.properties.MapPropertyRegistry; import org.dockbox.hartshorn.properties.PropertyRegistry; -import org.dockbox.hartshorn.properties.loader.support.JacksonPropertyRegistryLoader; -import org.dockbox.hartshorn.properties.loader.support.JacksonYamlPropertyRegistryLoader; +import org.dockbox.hartshorn.properties.loader.PropertyRegistryLoader; import org.dockbox.hartshorn.properties.loader.StandardPropertyPathFormatter; -import org.dockbox.hartshorn.properties.value.StandardPropertyParsers; +import org.dockbox.hartshorn.properties.loader.support.JacksonYamlPropertyRegistryLoader; +import org.dockbox.hartshorn.properties.value.StandardValuePropertyParsers; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.nio.file.Path; +import java.util.Iterator; +import java.util.List; + public class JacksonPropertyRegistryLoaderTests { @Test void testComplexYamlConfigurationCanBeLoaded() throws IOException { // Given - JacksonPropertyRegistryLoader loader = new JacksonYamlPropertyRegistryLoader(new StandardPropertyPathFormatter()); + PropertyRegistryLoader loader = new JacksonYamlPropertyRegistryLoader(new StandardPropertyPathFormatter()); Path path = Path.of("src/test/resources/complex-configuration.yml"); // When: Loading registry @@ -32,18 +32,18 @@ void testComplexYamlConfigurationCanBeLoaded() throws IOException { // Then: Keys should be ordered Iterator iterator = keys.iterator(); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[0].name"); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[0].value"); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[1].name"); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[1].value"); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[2].name"); - Assertions.assertEquals(iterator.next(), "sample.complex.configuration[2].value"); - Assertions.assertEquals(iterator.next(), "sample.complex.flat"); - Assertions.assertEquals(iterator.next(), "sample.complex.list[0].name"); - Assertions.assertEquals(iterator.next(), "sample.complex.list[0].value"); - Assertions.assertEquals(iterator.next(), "sample.complex.list[1].name"); - Assertions.assertEquals(iterator.next(), "sample.complex.list[1].value"); - Assertions.assertEquals(iterator.next(), "sample.complex.values"); + Assertions.assertEquals("sample.complex.configuration[0].name", iterator.next()); + Assertions.assertEquals("sample.complex.configuration[0].value", iterator.next()); + Assertions.assertEquals("sample.complex.configuration[1].name", iterator.next()); + Assertions.assertEquals("sample.complex.configuration[1].value", iterator.next()); + Assertions.assertEquals("sample.complex.configuration[2].name", iterator.next()); + Assertions.assertEquals("sample.complex.configuration[2].value", iterator.next()); + Assertions.assertEquals("sample.complex.flat", iterator.next()); + Assertions.assertEquals("sample.complex.list[0].name", iterator.next()); + Assertions.assertEquals("sample.complex.list[0].value", iterator.next()); + Assertions.assertEquals("sample.complex.list[1].name", iterator.next()); + Assertions.assertEquals("sample.complex.list[1].value", iterator.next()); + Assertions.assertEquals("sample.complex.values", iterator.next()); // Then: Property values should be loaded correctly registry.value("sample.complex.configuration[0].name") @@ -67,7 +67,7 @@ void testComplexYamlConfigurationCanBeLoaded() throws IOException { .peek(value -> Assertions.assertEquals("value3", value)) .orElseThrow(() -> new AssertionError("Property not found")); - registry.value("sample.complex.values", StandardPropertyParsers.STRING_LIST) + registry.value("sample.complex.values", StandardValuePropertyParsers.STRING_LIST) .peek(values -> { Assertions.assertEquals(3, values.length); Assertions.assertEquals("value1", values[0]);