Skip to content

Commit d59f31f

Browse files
authored
Merge pull request #537 from AuthMe/372-revise-property-reader-methods
#372 Move path methods from PropertyReader to PathProvider
2 parents f4c71be + 7a9e40b commit d59f31f

38 files changed

Lines changed: 267 additions & 215 deletions

src/main/java/ch/jalu/configme/properties/TypeBasedProperty.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public TypeBasedProperty(@NotNull String path, @NotNull PropertyType<T> type, @N
3232

3333
@Override
3434
protected @Nullable T getFromReader(@NotNull PropertyReader reader, @NotNull ConvertErrorRecorder errorRecorder) {
35-
return type.convert(reader.getObject(getPath()), errorRecorder);
35+
return type.convert(reader.getValue(getPath()), errorRecorder);
3636
}
3737

3838
@Override
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package ch.jalu.configme.resource;
2+
3+
import org.jetbrains.annotations.NotNull;
4+
5+
import java.util.Set;
6+
7+
/**
8+
* Exposes the paths available in a configuration resource.
9+
* <p>
10+
* This interface is an optional extension for {@link PropertyReader} implementations that support path enumeration.
11+
*/
12+
public interface PathProvider {
13+
14+
/**
15+
* Returns all paths available in the resource, including intermediate paths.
16+
* <p>
17+
* For a configuration like:
18+
* <pre>
19+
* header:
20+
* title: Hello
21+
* font:
22+
* color: red
23+
* size: 12
24+
* </pre>
25+
* this method returns {@code ["header", "header.title", "header.font", "header.font.color", "header.font.size"]}.
26+
*
27+
* @return all paths (in encounter order)
28+
*/
29+
@NotNull Set<String> getPaths();
30+
31+
/**
32+
* Returns all leaf paths in the resource.
33+
* <p>
34+
* For the configuration example in {@link #getPaths()}, this method returns
35+
* {@code ["header.title", "header.font.color", "header.font.size"]}.
36+
*
37+
* @return all leaf paths (in encounter order)
38+
*/
39+
@NotNull Set<String> getLeafPaths();
40+
41+
/**
42+
* Returns the direct child paths of the given path. Returns an empty set
43+
* if the path does not exist or has no children.
44+
* <p>
45+
* For the configuration example in {@link #getPaths()},
46+
* {@code getChildPaths("header")} returns {@code ["header.title", "header.font"]}.
47+
* <p>
48+
* If {@code path} is empty, the top-level paths are returned.
49+
*
50+
* @param path the path whose direct child paths should be looked up
51+
* @return all direct child paths (in encounter order, never null)
52+
*/
53+
@NotNull Set<String> getChildPaths(@NotNull String path);
54+
55+
}
Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
package ch.jalu.configme.resource;
22

3+
import ch.jalu.configme.properties.BooleanProperty;
4+
import ch.jalu.configme.properties.DoubleProperty;
5+
import ch.jalu.configme.properties.IntegerProperty;
6+
import ch.jalu.configme.properties.StringProperty;
7+
import ch.jalu.configme.properties.convertresult.PropertyValue;
38
import org.jetbrains.annotations.NotNull;
49
import org.jetbrains.annotations.Nullable;
10+
511
import java.util.List;
6-
import java.util.Set;
712

813
/**
914
* A property reader provides values from a resource (e.g. a YAML file) based on whose data the values of properties
@@ -24,69 +29,97 @@ public interface PropertyReader {
2429
boolean contains(@NotNull String path);
2530

2631
/**
27-
* Returns the keys available in the file. Depending on the parameter either all keys are returned,
28-
* or only the keys of the leaf nodes are considered.
29-
*
30-
* @param onlyLeafNodes true if only the paths of leaf nodes should be returned (no intermediate paths)
31-
* @return set of all existing keys (ordered)
32-
*/
33-
@NotNull Set<String> getKeys(boolean onlyLeafNodes);
34-
35-
/**
36-
* Returns the direct children of the given path which are available in the file. Returns an empty set
37-
* if the path does not exist in the file (never null).
32+
* Returns the object at the given path, or null if absent.
3833
*
39-
* @param path the path whose direct child paths should be looked up
40-
* @return set of all direct children (ordered, never null)
34+
* @param path the path to retrieve the value for
35+
* @return the value, or null if there is none
4136
*/
42-
@NotNull Set<String> getChildKeys(@NotNull String path);
37+
@Nullable Object getValue(@NotNull String path);
4338

4439
/**
4540
* Returns the object at the given path, or null if absent.
4641
*
4742
* @param path the path to retrieve the value for
4843
* @return the value, or null if there is none
44+
* @deprecated Use {@link #getValue}
4945
*/
50-
@Nullable Object getObject(@NotNull String path);
46+
@Deprecated
47+
default @Nullable Object getObject(@NotNull String path) {
48+
return getValue(path);
49+
}
5150

5251
/**
5352
* Returns the value of the given path as a String if available.
5453
*
5554
* @param path the path to retrieve a String for
5655
* @return the value as a String, or null if not applicable or unavailable
56+
* @deprecated read the value with a {@link StringProperty},
57+
* or call {@link #getValue} and perform your own casts
5758
*/
58-
@Nullable String getString(@NotNull String path);
59+
@Deprecated
60+
default @Nullable String getString(@NotNull String path) {
61+
StringProperty strProperty = new StringProperty(path, "");
62+
PropertyValue<String> value = strProperty.determineValue(this);
63+
return value.isValidInResource() ? value.getValue() : null;
64+
}
5965

6066
/**
6167
* Returns the value of the given path as an integer if available.
6268
*
6369
* @param path the path to retrieve an integer for
6470
* @return the value as integer, or null if not applicable or unavailable
71+
* @deprecated read the value with an {@link IntegerProperty},
72+
* or call {@link #getValue} and perform your own casts
6573
*/
66-
@Nullable Integer getInt(@NotNull String path);
74+
@Deprecated
75+
default @Nullable Integer getInt(@NotNull String path) {
76+
IntegerProperty intProperty = new IntegerProperty(path, 0);
77+
PropertyValue<Integer> value = intProperty.determineValue(this);
78+
return value.isValidInResource() ? value.getValue() : null;
79+
}
6780

6881
/**
6982
* Returns the value of the given path as a double if available.
7083
*
7184
* @param path the path to retrieve a double for
7285
* @return the value as a double, or null if not applicable or unavailable
86+
* @deprecated read the value with an {@link DoubleProperty},
87+
* or call {@link #getValue} and perform your own casts
7388
*/
74-
@Nullable Double getDouble(@NotNull String path);
89+
@Deprecated
90+
default @Nullable Double getDouble(@NotNull String path) {
91+
DoubleProperty doubleProperty = new DoubleProperty(path, 0);
92+
PropertyValue<Double> value = doubleProperty.determineValue(this);
93+
return value.isValidInResource() ? value.getValue() : null;
94+
}
7595

7696
/**
7797
* Returns the value of the given path as a boolean if available.
7898
*
7999
* @param path the path to retrieve a boolean for
80100
* @return the value as a boolean, or null if not applicable or unavailable
101+
* @deprecated read the value with a {@link BooleanProperty},
102+
* or call {@link #getValue} and perform your own casts
81103
*/
82-
@Nullable Boolean getBoolean(@NotNull String path);
104+
@Deprecated
105+
default @Nullable Boolean getBoolean(@NotNull String path) {
106+
BooleanProperty boolProperty = new BooleanProperty(path, true);
107+
PropertyValue<Boolean> value = boolProperty.determineValue(this);
108+
return value.isValidInResource() ? value.getValue() : null;
109+
}
83110

84111
/**
85112
* Returns the value of the given path as a list if available.
86113
*
87114
* @param path the path to retrieve a list for
88115
* @return the value as a list, or null if not applicable or unavailable
116+
* @deprecated read the value with a {@link ch.jalu.configme.properties.ListProperty ListProperty},
117+
* or call {@link #getValue} and perform your own casts
89118
*/
90-
@Nullable List<?> getList(@NotNull String path);
119+
@Deprecated
120+
default @Nullable List<?> getList(@NotNull String path) {
121+
Object value = getValue(path);
122+
return value instanceof List<?> ? (List<?>) value : null;
123+
}
91124

92125
}

src/main/java/ch/jalu/configme/resource/YamlFileReader.java

Lines changed: 28 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import ch.jalu.configme.exception.ConfigMeException;
44
import ch.jalu.configme.internal.PathUtils;
5-
65
import org.jetbrains.annotations.NotNull;
76
import org.jetbrains.annotations.Nullable;
87
import org.yaml.snakeyaml.Yaml;
@@ -17,15 +16,14 @@
1716
import java.nio.file.Path;
1817
import java.util.Collections;
1918
import java.util.LinkedHashSet;
20-
import java.util.List;
2119
import java.util.Map;
2220
import java.util.Set;
2321
import java.util.stream.Collectors;
2422

2523
/**
2624
* YAML file reader.
2725
*/
28-
public class YamlFileReader implements PropertyReader {
26+
public class YamlFileReader implements PropertyReader, PathProvider {
2927

3028
private final Path path;
3129
private final Charset charset;
@@ -54,7 +52,7 @@ public YamlFileReader(@NotNull Path path, @NotNull Charset charset) {
5452
}
5553

5654
@Override
57-
public @Nullable Object getObject(@NotNull String path) {
55+
public @Nullable Object getValue(@NotNull String path) {
5856
if (path.isEmpty()) {
5957
return root;
6058
}
@@ -71,54 +69,23 @@ public YamlFileReader(@NotNull Path path, @NotNull Charset charset) {
7169
}
7270

7371
@Override
74-
public @Nullable String getString(@NotNull String path) {
75-
return getTypedObject(path, String.class);
76-
}
77-
78-
@Override
79-
public @Nullable Integer getInt(@NotNull String path) {
80-
Number n = getTypedObject(path, Number.class);
81-
return (n == null)
82-
? null
83-
: n.intValue();
84-
}
85-
86-
@Override
87-
public @Nullable Double getDouble(@NotNull String path) {
88-
Number n = getTypedObject(path, Number.class);
89-
return (n == null)
90-
? null
91-
: n.doubleValue();
92-
}
93-
94-
@Override
95-
public @Nullable Boolean getBoolean(@NotNull String path) {
96-
return getTypedObject(path, Boolean.class);
97-
}
98-
99-
@Override
100-
public @Nullable List<?> getList(@NotNull String path) {
101-
return getTypedObject(path, List.class);
72+
public boolean contains(@NotNull String path) {
73+
return getValue(path) != null;
10274
}
10375

10476
@Override
105-
public boolean contains(@NotNull String path) {
106-
return getObject(path) != null;
77+
public @NotNull Set<String> getPaths() {
78+
return collectPaths(false);
10779
}
10880

10981
@Override
110-
public @NotNull Set<String> getKeys(boolean onlyLeafNodes) {
111-
if (root == null) {
112-
return Collections.emptySet();
113-
}
114-
Set<String> allKeys = new LinkedHashSet<>();
115-
collectKeysIntoSet("", root, allKeys, onlyLeafNodes);
116-
return allKeys;
82+
public @NotNull Set<String> getLeafPaths() {
83+
return collectPaths(true);
11784
}
11885

11986
@Override
120-
public @NotNull Set<String> getChildKeys(@NotNull String path) {
121-
Object object = getObject(path);
87+
public @NotNull Set<String> getChildPaths(@NotNull String path) {
88+
Object object = getValue(path);
12289
if (object instanceof Map) {
12390
String pathPrefix = path.isEmpty() ? "" : path + ".";
12491
return ((Map<String, Object>) object).keySet().stream()
@@ -128,24 +95,33 @@ public boolean contains(@NotNull String path) {
12895
return Collections.emptySet();
12996
}
13097

98+
private @NotNull Set<String> collectPaths(boolean onlyLeafNodes) {
99+
if (root == null) {
100+
return Collections.emptySet();
101+
}
102+
Set<String> allPaths = new LinkedHashSet<>();
103+
collectPathsIntoSet("", root, allPaths, onlyLeafNodes);
104+
return allPaths;
105+
}
106+
131107
/**
132-
* Recursively collects keys from maps into the given set.
108+
* Recursively collects keys from maps and adds them as paths to {@code result}.
133109
*
134-
* @param path the path of the given map
110+
* @param path the path to the given map
135111
* @param map the map to process recursively
136-
* @param result set to save keys to
112+
* @param result set to save paths to
137113
* @param onlyLeafNodes whether only leaf nodes should be added to the result set
138114
*/
139-
private void collectKeysIntoSet(@NotNull String path, @NotNull Map<String, Object> map, @NotNull Set<String> result,
140-
boolean onlyLeafNodes) {
115+
private static void collectPathsIntoSet(@NotNull String path, @NotNull Map<String, Object> map,
116+
@NotNull Set<String> result, boolean onlyLeafNodes) {
141117
for (Map.Entry<String, Object> entry : map.entrySet()) {
142118
String childPath = PathUtils.concat(path, entry.getKey());
143119
if (!onlyLeafNodes || isLeafValue(entry.getValue())) {
144120
result.add(childPath);
145121
}
146122

147123
if (entry.getValue() instanceof Map) {
148-
collectKeysIntoSet(childPath, (Map) entry.getValue(), result, onlyLeafNodes);
124+
collectPathsIntoSet(childPath, (Map) entry.getValue(), result, onlyLeafNodes);
149125
}
150126
}
151127
}
@@ -183,6 +159,9 @@ private static boolean isLeafValue(@Nullable Object o) {
183159
return new MapNormalizer().normalizeMap(map);
184160
}
185161

162+
/**
163+
* @return the file this reader read from
164+
*/
186165
protected final @NotNull Path getPath() {
187166
return path;
188167
}
@@ -196,23 +175,6 @@ private static boolean isLeafValue(@Nullable Object o) {
196175
return root;
197176
}
198177

199-
/**
200-
* Gets the object at the given path and safely casts it to the given class's type. Returns null
201-
* if no value is available or if it cannot be cast.
202-
*
203-
* @param path the path to retrieve
204-
* @param clazz the class to cast to
205-
* @param <T> the class type
206-
* @return cast value at the given path, null if not applicable
207-
*/
208-
protected <T> @Nullable T getTypedObject(@NotNull String path, @NotNull Class<T> clazz) {
209-
Object value = getObject(path);
210-
if (clazz.isInstance(value)) {
211-
return clazz.cast(value);
212-
}
213-
return null;
214-
}
215-
216178
private static @Nullable Object getEntryIfIsMap(@NotNull String key, @Nullable Object value) {
217179
if (value instanceof Map<?, ?>) {
218180
return ((Map<?, ?>) value).get(key);

0 commit comments

Comments
 (0)