Skip to content

Commit b5210a6

Browse files
committed
support JsonNode as input for ObjectPatcher
1 parent beedf13 commit b5210a6

File tree

1 file changed

+45
-16
lines changed

1 file changed

+45
-16
lines changed

react-admin-utils/src/main/java/io/amplicode/rautils/patch/ObjectPatcher.java

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public ObjectPatcher(ObjectMapper objectMapper,
6565
* @return the same modified or another created object with patched properties
6666
* @param <T> object class
6767
*/
68-
public <T> T patchAndValidate(T target, String patchJson) {
68+
public <T> T patchAndValidate(T target, JsonNode patchJson) {
6969
T patchedTarget = patch(target, patchJson);
7070
validate(patchedTarget);
7171
return patchedTarget;
@@ -75,16 +75,33 @@ public <T> T patchAndValidate(T target, String patchJson) {
7575
* Patches passed object with properties from passed json.
7676
* Supports immutable DTOs and Java 17 records.
7777
* May modify existing object or create a shallow copy.
78+
* Then validates patched object using globally configured validator.
7879
*
7980
* @param patchJson request body JSON containing fields to update
8081
* @param target target object (bean) that should be patched
8182
* @return the same modified or another created object with patched properties
8283
* @param <T> object class
8384
*/
85+
public <T> T patchAndValidate(T target, String patchJson) {
86+
T patchedTarget = patch(target, patchJson);
87+
validate(patchedTarget);
88+
return patchedTarget;
89+
}
90+
91+
/**
92+
* Patches passed object with properties from passed json.
93+
* Supports immutable DTOs and Java 17 records.
94+
* May modify existing object or create a shallow copy.
95+
*
96+
* @param patchJson JSON containing fields to update
97+
* @param target target object (bean) that should be patched
98+
* @return the same modified or another created object with patched properties
99+
* @param <T> object class
100+
*/
84101
@SuppressWarnings("unchecked")
85-
public <T> T patch(T target, String patchJson) {
102+
public <T> T patch(T target, JsonNode patchJson) {
86103
// 1. deserialize json into DTO_2
87-
// 2. deserialize json into Set of patched property names
104+
// 2. determine Set of patched property names
88105
// 3. gather Map of properties - take from target
89106
// 4. patch Map of properties - copy from DTO_2 only those that existed in json
90107
// 5. construct DTO_3 from patched properties.
@@ -102,8 +119,8 @@ public <T> T patch(T target, String patchJson) {
102119
// 1.
103120
T patchObject;
104121
try {
105-
patchObject = (T) objectMapper.readValue(patchJson, target.getClass());
106-
} catch (JsonProcessingException e) {
122+
patchObject = objectMapper.readerFor(target.getClass()).readValue(patchJson);
123+
} catch (IOException e) {
107124
throw new JsonConversionException("Failed to parse patch JSON", e);
108125
}
109126

@@ -129,10 +146,29 @@ public <T> T patch(T target, String patchJson) {
129146
return patchedObject;
130147
}
131148

132-
private <T> void patchBeanInPlace(String patchJson, T target) {
149+
/**
150+
* Patches passed object with properties from passed json.
151+
* Supports immutable DTOs and Java 17 records.
152+
* May modify existing object or create a shallow copy.
153+
*
154+
* @param patchJson JSON containing fields to update
155+
* @param target target object (bean) that should be patched
156+
* @return the same modified or another created object with patched properties
157+
* @param <T> object class
158+
*/
159+
public <T> T patch(T target, String patchJson) {
160+
try {
161+
JsonNode patchJsonNode = objectMapper.readTree(patchJson);
162+
return patch(target, patchJsonNode);
163+
} catch (JsonProcessingException e) {
164+
throw new JsonConversionException("Failed to parse patch JSON", e);
165+
}
166+
}
167+
168+
private <T> void patchBeanInPlace(JsonNode patchJson, T target) {
133169
try {
134170
objectMapper.readerForUpdating(target).readValue(patchJson);
135-
} catch (JsonProcessingException e) {
171+
} catch (IOException e) {
136172
throw new JsonConversionException("Failed to parse patch JSON", e);
137173
}
138174
}
@@ -212,16 +248,9 @@ private BeanDescription getBeanDescription(Class<?> targetClass) {
212248
return description;
213249
}
214250

215-
private Set<String> determinePatchedProperties(String patchJson) {
216-
JsonNode jsonNode;
217-
try {
218-
jsonNode = objectMapper.readTree(patchJson);
219-
} catch (JsonProcessingException e) {
220-
throw new JsonConversionException("Failed to parse patch JSON", e);
221-
}
222-
251+
private Set<String> determinePatchedProperties(JsonNode patchJson) {
223252
Set<String> propertyNames = new HashSet<>();
224-
for (var it = jsonNode.fields(); it.hasNext(); ) {
253+
for (var it = patchJson.fields(); it.hasNext(); ) {
225254
Map.Entry<String, JsonNode> entry = it.next();
226255
propertyNames.add(entry.getKey());
227256
}

0 commit comments

Comments
 (0)