Skip to content

Commit

Permalink
Merge pull request #71 from catenax-ng/fix/63-ArrayMerge
Browse files Browse the repository at this point in the history
Fix/63 array merge
  • Loading branch information
SebastianBezold authored Jan 30, 2024
2 parents 0c9a433 + 6f6c94b commit 8b54681
Show file tree
Hide file tree
Showing 6 changed files with 317 additions and 12 deletions.
6 changes: 5 additions & 1 deletion remoting/resources/web/rdf4j.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>RDF4J Server</display-name>
<!-- absolute ordering to prevent IllegalArgumentExcepition on startup -->
<absolute-ordering>
<name>spring_web</name>
</absolute-ordering>
<description>RDF4J Server</description>
<!-- Uncomment this and the associated filter-mapping to enable cross-origin requests.
See https://github.com/eBay/cors-filter to change default configuration settings.
Expand Down Expand Up @@ -137,4 +141,4 @@
<welcome-file-list>
<welcome-file>overview.view</welcome-file>
</welcome-file-list>
</web-app>
</web-app>
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -832,6 +833,70 @@ protected Iterator<Collection<MutableBindingSet>> produceBatches(BindingHost hos
return batches.values().iterator();
}

/**
* merges two given ObjectNodes
*
* @param source the ObjectNodes to be merged
* @param target the ObjectNodes where source needs to be merged into
*/
public static ObjectNode mergeObjectNodes(ObjectNode target, ObjectNode source) {
if (source == null) {
return target;
}

Iterator<Entry<String, JsonNode>> fields = source.fields();
while (fields.hasNext()) {
Entry<String, JsonNode> entry = fields.next();
String key = entry.getKey();
JsonNode sourceValue = entry.getValue();
JsonNode targetValue = target.get(key);

if (targetValue != null && targetValue.isObject() && sourceValue.isObject()) {
// Recursively merge nested objects
mergeObjectNodes((ObjectNode) targetValue, (ObjectNode) sourceValue);
} else if (targetValue != null && targetValue.isArray() && sourceValue.isArray()) {
// Merge arrays
mergeArrays((ArrayNode) targetValue, (ArrayNode) sourceValue);
} else {
// Add the field to target
target.set(key, sourceValue);
}
}

return target;
}

/**
* merges two given ArrayNodes
*
* @param source the ArrayNode to be merged
* @param target the ArrayNode where source needs to be merged into
*/
private static void mergeArrays(ArrayNode target, ArrayNode source) {
int sourceLength = source.size();
int targetLength = target.size();

for (int i = 0; i < sourceLength; i++) {
// target shorter than source?
if (targetLength < i + 1) {
target.add(source.get(i));
return;
}
JsonNode targetElement = target.get(i);
JsonNode sourceElement = source.get(i);
if (targetElement.isObject() && sourceElement.isObject()) {
// Recursively merge JSON objects
mergeObjectNodes((ObjectNode) targetElement, (ObjectNode) sourceElement);
} else if (targetElement.isArray() && sourceElement.isArray()) {
// Recursively merge arrays
mergeArrays((ArrayNode) targetElement, (ArrayNode) sourceElement);
} else {
target.set(i, source.get(i));
}
}
}


/**
* sets a given node under a possible recursive path
*
Expand All @@ -847,17 +912,10 @@ public static void setNode(ObjectMapper objectMapper, ObjectNode finalInput, Str
JsonNode traverse = finalInput;
int depth = 0;
if (argPath.length == depth) {
// https://jira.catena-x.net/browse/TEST-1170 make sure top-level updates are also merged and not overwritten
ObjectReader updater = objectMapper.readerForUpdating(finalInput);
try {
render = updater.readValue(render);
} catch (IOException e) {
throw new RuntimeException(e);
}
finalInput.setAll((ObjectNode) render);
finalInput = (ObjectNode) mergeObjectNodes(finalInput, (ObjectNode) render);
return;
}
for (String argField : argPath) {
for (String argField : argPath) {
if (depth != argPath.length - 1) {
if (hasField(traverse, argField)) {
JsonNode next = getField(traverse, argField);
Expand All @@ -876,8 +934,8 @@ public static void setNode(ObjectMapper objectMapper, ObjectNode finalInput, Str
setObject(objectMapper, traverse, argField, render);
}
depth++;
} // set argument in input
}
} // set argument in input
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package org.eclipse.tractusx.agents.remoting;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.io.IOException;
import java.io.InputStream;

import org.junit.jupiter.api.Test;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

public class MergeObjectNodesTest {

private final ObjectMapper objectMapper = new ObjectMapper();

@Test
public void testMerge() throws Exception {

// Load input resources
JsonNode input1 = loadJsonResource("MergeObjectNodesIn1.json");
JsonNode input2 = loadJsonResource("MergeObjectNodesIn2.json");

// Load expected result resource
JsonNode expectedResult = loadJsonResource("MergeObjectNodesResult.json");

// Invoke merge method with the input resources
input1 = Invocation.mergeObjectNodes((ObjectNode)input1, (ObjectNode)input2);

// Assert the result against the expected result
assertEquals(expectedResult, input1);
}

private JsonNode loadJsonResource(String resourceName) throws IOException {
// Use the class loader to load the resource
ClassLoader classLoader = getClass().getClassLoader();
try (InputStream inputStream = classLoader.getResourceAsStream(resourceName)) {

// Parse JSON content into ObjectNode
return objectMapper.readTree(inputStream);
}
}

}
83 changes: 83 additions & 0 deletions remoting/src/test/resources/MergeObjectNodesIn1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"Koepfchen in das Wasser":"Schwänzchen in die Höh",
"content":{
"endurancePredictorInputs":[
{
"alle":"meine Entchen",
"classifiedLoadSpectrumGearSet":{
"schwimmen":"auf dem See",
"metadata":{
"projectDescription":"pnr_76543",
"routeDescription":"logged",
"status":{
"mileage":865432,
"operatingHours":32137.9,
"date":"2023-02-28T01:27:20.020Z"
},
"componentDescription":"GearSet"
},
"bammId":"urn:bamm:io.openmanufacturing.digitaltwin:1.0.0#ClassifiedLoadSpectrum",
"targetComponentId":"urn:uuid:2",
"header":{
"countingMethod":"TimeAtLevel",
"countingValue":"Time",
"channels":[
{
"channelName":"TC_SU",
"unit":"unit:degreeCelsius",
"lowerLimit":0,
"upperLimit":640,
"numberOfBins":128
}
],
"countingUnit":"unit:secondUnitOfTime"
},
"body":{
"counts":{
"countsName":"Time",
"countsList":[
34968.93,
739782.51,
4013185.15,
4.675505556E7,
2.526895835E7,
8649735.95,
9383635.35,
1.918926077E7,
1353867.54
]
},
"classes":[
{
"className":"TC_SU-class",
"classList":[
14,
15,
16,
17,
18,
19,
20,
21,
22
]
}
]
}
},
"componentId":"urn:uuid:2"
}
]
},
"header":{
"classification":"RemainingUsefulLifePredictor",
"targetDate":"2042-04-06T05:53:40.040Z",
"timeStamp":"2022-12-03T02:09:20.020Z",
"senderBPN":"bpn:legal:BPNLOEM",
"severity":"MINOR",
"recipientBPN":"bpn:legal:BPNLSUPPLIER",
"senderAddress":"edc://sender",
"status":"SENT",
"recipientAddress":"edc://recipient"
}
}
31 changes: 31 additions & 0 deletions remoting/src/test/resources/MergeObjectNodesIn2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"Koepfchen in das Wasser":"Schwänzchen in die Höh",
"content":{
"endurancePredictorInputs":[
{
"alle":"meine Entchen",
"classifiedLoadSpectrumGearSet":{
"schwimmen":"auf dem See",
"body":{
"counts":{
"countsName":"Time",
"countsList": [
4711.0815,
739782.51,
4013185.15,
4.675505556E7,
2.526895835E7,
8649735.95,
9383635.35,
1.918926077E7,
1353867.54,
123.456
]
}
}
}

}
]
}
}
84 changes: 84 additions & 0 deletions remoting/src/test/resources/MergeObjectNodesResult.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
{
"Koepfchen in das Wasser":"Schwänzchen in die Höh",
"content":{
"endurancePredictorInputs":[
{
"alle":"meine Entchen",
"classifiedLoadSpectrumGearSet":{
"schwimmen":"auf dem See",
"metadata":{
"projectDescription":"pnr_76543",
"routeDescription":"logged",
"status":{
"mileage":865432,
"operatingHours":32137.9,
"date":"2023-02-28T01:27:20.020Z"
},
"componentDescription":"GearSet"
},
"bammId":"urn:bamm:io.openmanufacturing.digitaltwin:1.0.0#ClassifiedLoadSpectrum",
"targetComponentId":"urn:uuid:2",
"header":{
"countingMethod":"TimeAtLevel",
"countingValue":"Time",
"channels":[
{
"channelName":"TC_SU",
"unit":"unit:degreeCelsius",
"lowerLimit":0,
"upperLimit":640,
"numberOfBins":128
}
],
"countingUnit":"unit:secondUnitOfTime"
},
"body":{
"counts":{
"countsName":"Time",
"countsList":[
4711.0815,
739782.51,
4013185.15,
4.675505556E7,
2.526895835E7,
8649735.95,
9383635.35,
1.918926077E7,
1353867.54,
123.456
]
},
"classes":[
{
"className":"TC_SU-class",
"classList":[
14,
15,
16,
17,
18,
19,
20,
21,
22
]
}
]
}
},
"componentId":"urn:uuid:2"
}
]
},
"header":{
"classification":"RemainingUsefulLifePredictor",
"targetDate":"2042-04-06T05:53:40.040Z",
"timeStamp":"2022-12-03T02:09:20.020Z",
"senderBPN":"bpn:legal:BPNLOEM",
"severity":"MINOR",
"recipientBPN":"bpn:legal:BPNLSUPPLIER",
"senderAddress":"edc://sender",
"status":"SENT",
"recipientAddress":"edc://recipient"
}
}

0 comments on commit 8b54681

Please sign in to comment.