Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ private boolean process(Map<String, Object> map, MatchCallback callback) {
* @since 4.1.3
*/
protected final Map<String, Object> getFlattenedMap(Map<String, Object> source) {
return getFlattenedMap(source, false);
return getFlattenedMap(source, false, null);
}

/**
Expand All @@ -313,21 +313,25 @@ protected final Map<String, Object> getFlattenedMap(Map<String, Object> source)
* source. When called with the Map from a {@link MatchCallback} the result will
* contain the same values as the {@link MatchCallback} Properties.
* @param source the source map
* @param includeNulls if {@code null} entries can be included in the result
* @param includeEmpty if empty entries should be included in the result
* @param emptyValue the value used to represent empty entries (e.g. {@code null} or an empty {@code String}
* @return a flattened map
* @since 7.0.4
*/
protected final Map<String, Object> getFlattenedMap(Map<String, Object> source, boolean includeNulls) {
protected final Map<String, Object> getFlattenedMap(Map<String, Object> source, boolean includeEmpty,
@Nullable Object emptyValue) {

Map<String, Object> result = new LinkedHashMap<>();
buildFlattenedMap(result, source, null, includeNulls);
buildFlattenedMap(result, source, null, includeEmpty, emptyValue);
return result;
}

@SuppressWarnings({"rawtypes", "unchecked"})
private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> source, @Nullable String path,
boolean includeNulls) {
if (includeNulls && source.isEmpty()) {
result.put(path, null);
boolean includeEmpty, @Nullable Object emptyValue) {

if (includeEmpty && source.isEmpty()) {
result.put(path, emptyValue);
return;
}
source.forEach((key, value) -> {
Expand All @@ -344,7 +348,7 @@ private void buildFlattenedMap(Map<String, Object> result, Map<String, Object> s
}
else if (value instanceof Map map) {
// Need a compound key
buildFlattenedMap(result, map, key, includeNulls);
buildFlattenedMap(result, map, key, includeEmpty, emptyValue);
}
else if (value instanceof Collection collection) {
// Need a compound key
Expand All @@ -355,12 +359,12 @@ else if (value instanceof Collection collection) {
int count = 0;
for (Object object : collection) {
buildFlattenedMap(result, Collections.singletonMap(
"[" + (count++) + "]", object), key, includeNulls);
"[" + (count++) + "]", object), key, includeEmpty, emptyValue);
}
}
}
else {
result.put(key, (value != null ? value : ""));
result.put(key, (value != null ? value : (includeEmpty ? emptyValue : "")));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,16 +183,34 @@ void customTypeNotSupportedDueToExplicitConfiguration() {

@Test
void processAndFlattenWithoutIncludedNulls() {
setYaml("foo: bar\nbar:\n spam: {}");
Map<String, Object> flattened = this.processor.processAndFlatten(false);
assertThat(flattened).containsEntry("foo", "bar").doesNotContainKey("bar.spam").hasSize(1);
setYaml("avalue: value\nanull: null\natilde: ~\nparent:\n anempty: {}\n");
Map<String, Object> flattened = this.processor.processAndFlatten(false, null);
assertThat(flattened).containsOnly(
entry("avalue", "value"),
entry("anull", ""),
entry("atilde", ""));
}

@Test
void processAndFlattenWithIncludedNulls() {
setYaml("foo: bar\nbar:\n spam: {}");
Map<String, Object> flattened = this.processor.processAndFlatten(true);
assertThat(flattened).containsEntry("foo", "bar").containsEntry("bar.spam", null).hasSize(2);
setYaml("avalue: value\nanull: null\natilde: ~\nparent:\n anempty: {}\n");
Map<String, Object> flattened = this.processor.processAndFlatten(true, null);
assertThat(flattened).containsOnly(
entry("avalue", "value"),
entry("anull", null),
entry("atilde", null),
entry("parent.anempty", null));
}

@Test
void processAndFlattenWithIncludedBlankString() {
setYaml("avalue: value\nanull: null\natilde: ~\nparent:\n anempty: {}\n");
Map<String, Object> flattened = this.processor.processAndFlatten(true, "");
assertThat(flattened).containsOnly(
entry("avalue", "value"),
entry("anull", ""),
entry("atilde", ""),
entry("parent.anempty", ""));
}

private void setYaml(String yaml) {
Expand All @@ -201,9 +219,9 @@ private void setYaml(String yaml) {

private static class TestYamlProcessor extends YamlProcessor {

Map<String, Object> processAndFlatten(boolean includeNulls) {
Map<String, Object> processAndFlatten(boolean includeEmpty, Object emptyValue) {
Map<String, Object> flattened = new LinkedHashMap<>();
process((properties, map) -> flattened.putAll(getFlattenedMap(map, includeNulls)));
process((properties, map) -> flattened.putAll(getFlattenedMap(map, includeEmpty, emptyValue)));
return flattened;
}

Expand Down