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

Fix/63 array merge #71

Merged
merged 4 commits into from
Jan 30, 2024
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
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 -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That XML warning never occured to me. Seems to be an eclipse IDE issue. But does not harm

<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"
}
}
Loading