Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonObject : add further options on how to mergeIn JsonObject #5453

Open
rzorzorzo opened this issue Jan 20, 2025 · 2 comments
Open

JsonObject : add further options on how to mergeIn JsonObject #5453

rzorzorzo opened this issue Jan 20, 2025 · 2 comments
Assignees
Milestone

Comments

@rzorzorzo
Copy link

Describe the feature

currently config files are merged by overwriting null values and by overwriting array values.
in my use case however, array values need to be merged and null values should not override existing values.
example:

JsonObject o1 = JsonObject.of("m", null, "a", JsonArray.of(1));
JsonObject o2 = JsonObject.of("m", JsonObject.of(), "a", JsonArray.of(2));
JsonObject o3 = o2.mergeIn(o1, true, true, false);
System.out.println(o3);

should return:

{"m":{},"a":[1,2]}

Use cases

rational: configuration files are structured by module. a module may have a property which is not included in another, therefore null value should not override a non null value.

the values of arrays may need to be "collected" over multiple module configurations.

Contribution

JsonObject.java:

public JsonObject mergeIn(JsonObject other, int depth, boolean mergeArrays, boolean overwriteNull) {
if (depth < 1) {
return this;
}
if (depth == 1 && !mergeArrays && overwriteNull) {
map.putAll(other.map);
return this;
}
for (Map.Entry<String, Object> e : other.map.entrySet()) {
if (e.getValue() == null && overwriteNull) {
map.put(e.getKey(), null);
} else if (e.getValue() != null){
map.merge(e.getKey(), e.getValue(), (oldVal, newVal) -> {
if (oldVal instanceof Map) {
oldVal = new JsonObject((Map) oldVal);
}
if (newVal instanceof Map) {
newVal = new JsonObject((Map) newVal);
}
if (mergeArrays && oldVal instanceof JsonArray && newVal instanceof JsonArray)
return ((JsonArray)newVal).addAll((JsonArray)oldVal);
if (oldVal instanceof JsonObject && newVal instanceof JsonObject) {
return ((JsonObject) oldVal).mergeIn((JsonObject) newVal, depth - 1, mergeArrays, overwriteNull);
}
return newVal;
});
}
}
return this;
}

@tsegismont tsegismont self-assigned this Jan 21, 2025
@tsegismont tsegismont added this to the 5.0.0 milestone Jan 21, 2025
@tsegismont tsegismont changed the title JsonObject and ConfigRetriever: add further options on how to mergeIn JsonObject JsonObject : add further options on how to mergeIn JsonObject Jan 21, 2025
@tsegismont
Copy link
Contributor

@rzorzorzo I sent #5454

A merge function should be generic enough to handle your case (ignore nulls and merge arrays) as well as others.

@tsegismont
Copy link
Contributor

@vietj can you please take a look at #5454 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants