diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/XmlDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/XmlDeserializer.java index f879cb68..bbda58c1 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/XmlDeserializer.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/XmlDeserializer.java @@ -28,19 +28,16 @@ import io.adminshell.aas.v3.dataformat.Deserializer; import io.adminshell.aas.v3.dataformat.core.ReflectionHelper; import io.adminshell.aas.v3.dataformat.core.deserialization.EnumDeserializer; -import io.adminshell.aas.v3.dataformat.xml.deserialization.KeyDeserializer; import io.adminshell.aas.v3.dataformat.xml.deserialization.SubmodelElementDeserializer; import io.adminshell.aas.v3.model.AssetAdministrationShellEnvironment; import io.adminshell.aas.v3.model.SubmodelElement; -import io.adminshell.aas.v3.model.impl.DefaultKey; public class XmlDeserializer implements Deserializer { protected XmlMapper mapper; protected SimpleAbstractTypeResolver typeResolver; protected static Map, com.fasterxml.jackson.databind.JsonDeserializer> customDeserializers = Map.of( - SubmodelElement.class, new SubmodelElementDeserializer(), - DefaultKey.class, new KeyDeserializer()); + SubmodelElement.class, new SubmodelElementDeserializer()); public XmlDeserializer() { initTypeResolver(); diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/CustomJsonNodeDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/CustomJsonNodeDeserializer.java index ad097795..66c83a22 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/CustomJsonNodeDeserializer.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/CustomJsonNodeDeserializer.java @@ -15,8 +15,11 @@ */ package io.adminshell.aas.v3.dataformat.xml.deserialization; +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; public interface CustomJsonNodeDeserializer { - public T readValue(JsonNode node); + public T readValue(JsonNode node, JsonParser parser) throws IOException; } diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeyDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeyDeserializer.java index 21d090fd..93908e0c 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeyDeserializer.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeyDeserializer.java @@ -18,42 +18,27 @@ import java.io.IOException; import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.node.ObjectNode; +import io.adminshell.aas.v3.model.Key; import io.adminshell.aas.v3.model.KeyElements; import io.adminshell.aas.v3.model.KeyType; import io.adminshell.aas.v3.model.impl.DefaultKey; -public class KeyDeserializer extends JsonDeserializer { +public class KeyDeserializer implements CustomJsonNodeDeserializer { - @Override - public DefaultKey deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException { - ObjectNode node = DeserializationHelper.getRootObjectNode(parser); - ObjectNode normalizeNode = normalizeNode(node); - return createDefaultKeyFromNode(parser, normalizeNode); - } - private DefaultKey createDefaultKeyFromNode(JsonParser parser, ObjectNode normalizeNode) throws IOException { - JsonNode idTypeNode = normalizeNode.get("idType"); - JsonNode typeNode = normalizeNode.get("type"); - JsonNode valueNode = normalizeNode.get(""); + @Override + public Key readValue(JsonNode node, JsonParser parser) throws IOException { + JsonNode idTypeNode = node.get("idType"); + JsonNode typeNode = node.get("type"); + JsonNode valueNode = node.get(""); KeyType idType = createKeyTypeFromNode(parser, idTypeNode); KeyElements type = createKeyElementsFromNode(parser, typeNode); String value = valueNode.asText(); return new DefaultKey.Builder().idType(idType).type(type).value(value).build(); } - private ObjectNode normalizeNode(ObjectNode node) { - if (node.has("key")) { - node = (ObjectNode) node.get("key"); - } - return node; - } - private KeyElements createKeyElementsFromNode(JsonParser parser, JsonNode typeNode) throws IOException { return DeserializationHelper.createInstanceFromNode(parser, typeNode, KeyElements.class); } diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeysDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeysDeserializer.java new file mode 100644 index 00000000..05a8888e --- /dev/null +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/KeysDeserializer.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e. V. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.adminshell.aas.v3.dataformat.xml.deserialization; + +import io.adminshell.aas.v3.model.Key; + +public class KeysDeserializer extends NoEntryWrapperListDeserializer { + public KeysDeserializer() { + super("key", new KeyDeserializer()); + } +} diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/LangStringNodeDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/LangStringNodeDeserializer.java index 37252417..c131853d 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/LangStringNodeDeserializer.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/LangStringNodeDeserializer.java @@ -15,13 +15,16 @@ */ package io.adminshell.aas.v3.dataformat.xml.deserialization; +import java.io.IOException; + +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.JsonNode; import io.adminshell.aas.v3.model.LangString; public class LangStringNodeDeserializer implements CustomJsonNodeDeserializer { @Override - public LangString readValue(JsonNode node) { + public LangString readValue(JsonNode node, JsonParser parser) throws IOException { String lang = node.get("lang").asText(); String text = node.get("").asText(); return new LangString(text, lang); diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/NoEntryWrapperListDeserializer.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/NoEntryWrapperListDeserializer.java index 78f73212..67dc9c92 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/NoEntryWrapperListDeserializer.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/deserialization/NoEntryWrapperListDeserializer.java @@ -47,23 +47,23 @@ public List deserialize(JsonParser parser, DeserializationContext ctxt) throw ObjectNode node = DeserializationHelper.getRootObjectNode(parser); JsonNode langStringNode = node.get(elementName); if (langStringNode.isObject()) { - return createEntriesFromObjectNode(langStringNode); + return createEntriesFromObjectNode(langStringNode, parser); } else { - return createEntriesFromArrayNode((ArrayNode) langStringNode); + return createEntriesFromArrayNode((ArrayNode) langStringNode, parser); } } - private List createEntriesFromArrayNode(ArrayNode langStringsNode) { + private List createEntriesFromArrayNode(ArrayNode langStringsNode, JsonParser parser) throws IOException { List entries = new ArrayList<>(); for (int i = 0; i < langStringsNode.size(); i++) { JsonNode nextNode = langStringsNode.get(i); - entries.add(nodeDeserializer.readValue(nextNode)); + entries.add(nodeDeserializer.readValue(nextNode, parser)); } return entries; } - private List createEntriesFromObjectNode(JsonNode langStringNode) { - T entry = nodeDeserializer.readValue(langStringNode); + private List createEntriesFromObjectNode(JsonNode langStringNode, JsonParser parser) throws IOException { + T entry = nodeDeserializer.readValue(langStringNode, parser); return Collections.singletonList(entry); } } diff --git a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/mixins/ReferenceMixin.java b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/mixins/ReferenceMixin.java index ee9dcd34..a48dc5ec 100644 --- a/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/mixins/ReferenceMixin.java +++ b/dataformat-xml/src/main/java/io/adminshell/aas/v3/dataformat/xml/mixins/ReferenceMixin.java @@ -17,14 +17,17 @@ import java.util.List; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper; import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty; import io.adminshell.aas.v3.dataformat.xml.AasXmlNamespaceContext; +import io.adminshell.aas.v3.dataformat.xml.deserialization.KeysDeserializer; import io.adminshell.aas.v3.model.Key; public interface ReferenceMixin { @JacksonXmlProperty(namespace = AasXmlNamespaceContext.AAS_URI, localName = "key") @JacksonXmlElementWrapper(namespace = AasXmlNamespaceContext.AAS_URI, localName = "keys") + @JsonDeserialize(using = KeysDeserializer.class) public List getKeys(); } diff --git a/dataformat-xml/src/test/resources/test_demo_full_example.xml b/dataformat-xml/src/test/resources/test_demo_full_example.xml index 58f876e8..424bc8d2 100644 --- a/dataformat-xml/src/test/resources/test_demo_full_example.xml +++ b/dataformat-xml/src/test/resources/test_demo_full_example.xml @@ -137,7 +137,7 @@ TestConceptDescription - An example concept description for the test application + An example concept description for the test application Ein Beispiel-ConceptDescription für eine Test-Anwendung @@ -156,9 +156,9 @@ https://acplt.org/Test_ConceptDescription_Mandatory - TestConceptDescription + TestConceptDescription1 - An example concept description for the test application + An example concept description for the test application Ein Beispiel-ConceptDescription für eine Test-Anwendung @@ -247,6 +247,7 @@ 0.9 http://acplt.org/Submodels/Assets/TestAsset/Identification + Instance http://acplt.org/SubmodelTemplates/AssetIdentification @@ -329,6 +330,7 @@ 0.9 http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial + Instance http://acplt.org/SubmodelTemplates/BillOfMaterial @@ -430,6 +432,7 @@ 0.9 https://acplt.org/Test_Submodel + Instance http://acplt.org/SubmodelTemplates/ExampleSubmodel @@ -451,11 +454,15 @@ + https://acplt.org/Test_Submodel + ExampleSubmodelCollectionOrdered ExampleProperty + http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial + ExampleEntity ExampleProperty2 @@ -476,11 +483,15 @@ + https://acplt.org/Test_Submodel + ExampleSubmodelCollectionOrdered ExampleProperty + http://acplt.org/Submodels/Assets/TestAsset/BillOfMaterial + ExampleEntity ExampleProperty2 @@ -513,7 +524,7 @@ - ExampleProperty + ExampleProperty3 Constant Example Property object @@ -537,7 +548,7 @@ - ExampleProperty + ExampleProperty1 Constant Example Property object @@ -561,7 +572,7 @@ - ExampleProperty + ExampleProperty2 Constant Example Property object @@ -614,6 +625,8 @@ + https://acplt.org/Test_Submodel + ExampleSubmodelCollectionOrdered ExampleProperty @@ -767,6 +780,8 @@ + https://acplt.org/Test_Submodel + ExampleSubmodelCollectionOrdered ExampleProperty @@ -780,18 +795,23 @@ https://acplt.org/Test_Submodel_Mandatory + Template ExampleRelationshipElement + https://acplt.org/Test_Submodel_Mandatory + ExampleSubmodelCollectionOrdered ExampleProperty - ExampleProperty + https://acplt.org/Test_Submodel_Mandatory + ExampleSubmodelCollectionOrdered + ExampleMultiLanguageProperty @@ -801,12 +821,16 @@ ExampleAnnotatedRelationshipElement + https://acplt.org/Test_Submodel_Mandatory + ExampleSubmodelCollectionOrdered ExampleProperty - ExampleProperty + https://acplt.org/Test_Submodel_Mandatory + ExampleSubmodelCollectionOrdered + ExampleMultiLanguageProperty @@ -827,6 +851,8 @@ ExampleBasicEvent + https://acplt.org/Test_Submodel_Mandatory + ExampleSubmodelCollectionOrdered ExampleProperty @@ -897,6 +923,7 @@ https://acplt.org/Test_Submodel2_Mandatory + Instance @@ -910,6 +937,7 @@ 0.9 https://acplt.org/Test_Submodel_Missing + Instance http://acplt.org/SubmodelTemplates/ExampleSubmodel @@ -931,12 +959,16 @@ + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered ExampleProperty - ExampleProperty + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered + ExampleMultiLanguageProperty @@ -956,12 +988,16 @@ + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered ExampleProperty - ExampleProperty + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered + ExampleMultiLanguageProperty @@ -993,7 +1029,7 @@ - ExampleProperty + ExampleProperty3 Constant Example Property object @@ -1018,7 +1054,7 @@ - ExampleProperty + ExampleProperty1 Constant Example Property object @@ -1043,7 +1079,7 @@ - ExampleProperty + ExampleProperty2 Constant Example Property object @@ -1097,6 +1133,8 @@ + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered ExampleProperty @@ -1246,6 +1284,8 @@ + https://acplt.org/Test_Submodel_Missing + ExampleSubmodelCollectionOrdered ExampleProperty