diff --git a/aom/src/main/java/com/nedap/archie/aom/ResourceDescription.java b/aom/src/main/java/com/nedap/archie/aom/ResourceDescription.java index 0794e4943..632202cba 100644 --- a/aom/src/main/java/com/nedap/archie/aom/ResourceDescription.java +++ b/aom/src/main/java/com/nedap/archie/aom/ResourceDescription.java @@ -3,7 +3,6 @@ import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonSetter; -import com.fasterxml.jackson.databind.JsonNode; import javax.annotation.Nullable; import java.util.ArrayList; @@ -102,22 +101,21 @@ public void setLifecycleState(String lifecycleState) { * * This deserializer ensures backward compatibility by accepting both formats * and always setting the lifecycle state value as a plain String. + * Object parameter instead of JsonNode keeps this compatible with both Jackson 2 and 3. */ @JsonSetter("lifecycle_state") - private void setLifecycleState(JsonNode node) { - if (node == null || node.isNull()) { + private void setLifecycleState(Object node) { + if (node == null) { + this.lifecycleState = null; + } else if (node instanceof String) { + this.lifecycleState = (String) node; + } else if (node instanceof Map) { + Object codeString = ((Map) node).get("code_string"); + this.lifecycleState = (codeString != null) ? codeString.toString() : null; + } else { + // Empty list or other unexpected type: treat as absent this.lifecycleState = null; - return; - } - - if (node.isTextual()) { - this.lifecycleState = node.asText(); - return; } - - JsonNode codeString = node.get("code_string"); - - this.lifecycleState = (codeString != null && !codeString.isNull()) ? codeString.asText() : null; } public String getCustodianNamespace() { diff --git a/aom/src/main/java/com/nedap/archie/rules/ExpressionType.java b/aom/src/main/java/com/nedap/archie/rules/ExpressionType.java index 0c3f6f986..6a4e704e3 100644 --- a/aom/src/main/java/com/nedap/archie/rules/ExpressionType.java +++ b/aom/src/main/java/com/nedap/archie/rules/ExpressionType.java @@ -1,5 +1,7 @@ package com.nedap.archie.rules; +import com.fasterxml.jackson.annotation.JsonCreator; + /** * TODO: this should contain all primitive types and primitive types should be merged into this * Created by pieter.bos on 27/10/15. @@ -7,6 +9,7 @@ public enum ExpressionType { BOOLEAN, STRING, INTEGER, REAL, DATE, TIME, DATETIME, DURATION, C_STRING; + @JsonCreator public static ExpressionType fromString(String string) { switch(string) { case "Boolean": @@ -28,30 +31,26 @@ public static ExpressionType fromString(String string) { case "CString": return C_STRING; } + // Fall back to case-insensitive match against enum constant names (e.g. "C_STRING") + for (ExpressionType type : values()) { + if (type.name().equalsIgnoreCase(string)) { + return type; + } + } return null; } public String toString() { - switch(this) { - case BOOLEAN: - return "Boolean"; - case STRING: - return "String"; - case INTEGER: - return "Integer"; - case REAL: - return "Real"; - case DATE: - return "Date"; - case TIME: - return "Time"; - case DATETIME: - return "DateTime"; - case DURATION: - return "Duration"; - case C_STRING: - return "CString"; - } - return null; + return switch (this) { + case BOOLEAN -> "Boolean"; + case STRING -> "String"; + case INTEGER -> "Integer"; + case REAL -> "Real"; + case DATE -> "Date"; + case TIME -> "Time"; + case DATETIME -> "DateTime"; + case DURATION -> "Duration"; + case C_STRING -> "CString"; + }; } } diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializer.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializer.java index 490936fe8..b5554ed10 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializer.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLArchetypeSerializer.java @@ -4,6 +4,7 @@ import com.nedap.archie.rminfo.RMObjectMapperProvider; import java.util.function.Function; +import java.util.function.Supplier; /** * @author markopi @@ -12,17 +13,23 @@ abstract public class ADLArchetypeSerializer { protected final T archetype; final RMObjectMapperProvider rmObjectMapperProvider; Function flatArchetypeProvider; - protected final ADLStringBuilder builder = new ADLStringBuilder(); + protected final ADLStringBuilder builder; private final ADLDefinitionSerializer definitionSerializer; private final ADLRulesSerializer rulesSerializer; + // Default constructor — uses the Jackson 2 backed ADLStringBuilder. protected ADLArchetypeSerializer(T archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider) { + this(archetype, flatArchetypeProvider, rmObjectMapperProvider, new ADLStringBuilder()); + } + + // Use this constructor to supply a custom ADLStringBuilder, e.g. new ADLStringBuilder3() for Jackson 3. + protected ADLArchetypeSerializer(T archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider, ADLStringBuilder builder) { this.archetype = archetype; this.flatArchetypeProvider = flatArchetypeProvider; this.rmObjectMapperProvider = rmObjectMapperProvider; - + this.builder = builder; this.definitionSerializer = new ADLDefinitionSerializer(builder, flatArchetypeProvider, rmObjectMapperProvider); this.rulesSerializer = new ADLRulesSerializer(builder, definitionSerializer); } @@ -51,6 +58,23 @@ public static String serialize(Archetype archetype, Function } + /** + * Serialize the archetype to ADL, using a custom ADLStringBuilder (e.g. one backed by Jackson 3). + */ + public static String serialize(Archetype archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider, Supplier builderSupplier) { + if (archetype instanceof Template) { + return new ADLTemplateSerializer((Template) archetype, flatArchetypeProvider, rmObjectMapperProvider, builderSupplier.get()).serialize(); + } else if (archetype instanceof OperationalTemplate) { + return new ADLOperationalTemplateSerializer((OperationalTemplate) archetype, flatArchetypeProvider, rmObjectMapperProvider, builderSupplier.get()).serialize(); + } else if (archetype instanceof TemplateOverlay) { + return new ADLTemplateOverlaySerializer((TemplateOverlay) archetype, flatArchetypeProvider, rmObjectMapperProvider, builderSupplier.get()).serialize(); + } else if (archetype instanceof AuthoredArchetype) { + return new ADLAuthoredArchetypeSerializer<>((AuthoredArchetype) archetype, flatArchetypeProvider, rmObjectMapperProvider, builderSupplier.get()).serialize(); + } + throw new AssertionError("Could not serialize archetype of class " + + (archetype == null ? null : archetype.getClass().getName())); + } + /** * Serialize the archetype to ADL * @param archetype the archetype to serialize diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLAuthoredArchetypeSerializer.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLAuthoredArchetypeSerializer.java index 63c5ab41c..f13fdf37c 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLAuthoredArchetypeSerializer.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLAuthoredArchetypeSerializer.java @@ -16,10 +16,16 @@ */ public class ADLAuthoredArchetypeSerializer extends ADLArchetypeSerializer { + // Default constructor — uses the Jackson 2 backed ADLStringBuilder. public ADLAuthoredArchetypeSerializer(T archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider) { super(archetype, flatArchetypeProvider, rmObjectMapperProvider); } + // Use this constructor to supply a custom ADLStringBuilder, e.g. new ADLStringBuilder3() for Jackson 3. + public ADLAuthoredArchetypeSerializer(T archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider, ADLStringBuilder builder) { + super(archetype, flatArchetypeProvider, rmObjectMapperProvider, builder); + } + @Override protected void appendLanguage() { if (archetype.getOriginalLanguage() == null) return; diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLOperationalTemplateSerializer.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLOperationalTemplateSerializer.java index d47753c8b..4e9cb1547 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLOperationalTemplateSerializer.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLOperationalTemplateSerializer.java @@ -11,10 +11,16 @@ */ class ADLOperationalTemplateSerializer extends ADLAuthoredArchetypeSerializer { + // Default constructor — uses the Jackson 2 backed ADLStringBuilder. public ADLOperationalTemplateSerializer(OperationalTemplate archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider) { super(archetype, flatArchetypeProvider, rmObjectMapperProvider); } + // Use this constructor to supply a custom ADLStringBuilder, e.g. new ADLStringBuilder3() for Jackson 3. + public ADLOperationalTemplateSerializer(OperationalTemplate archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider, ADLStringBuilder builder) { + super(archetype, flatArchetypeProvider, rmObjectMapperProvider, builder); + } + @Override protected String serialize() { super.serialize(); diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLStringBuilder.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLStringBuilder.java index 39ec6c218..b00a497a2 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLStringBuilder.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLStringBuilder.java @@ -55,7 +55,7 @@ public ADLStringBuilder indent() { public ADLStringBuilder odin(Object structure) { try { - // Pass the current ident depth to the ODINPrettyPrinter + // Pass the current indent depth to the ODINPrettyPrinter ObjectWriter objectWriter = odinMapper.writer().with(new ODINPrettyPrinter(builder.getIndentDepth())); String odin = objectWriter.writeValueAsString(structure).trim(); @@ -138,8 +138,4 @@ public int getIndentDepth() { return builder.getIndentDepth(); } - public ODINMapper getOdinMapper() { - return odinMapper; - } } - diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateOverlaySerializer.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateOverlaySerializer.java index 97e4243d3..739f2c40a 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateOverlaySerializer.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateOverlaySerializer.java @@ -12,10 +12,16 @@ class ADLTemplateOverlaySerializer extends ADLArchetypeSerializer { + // Default constructor — uses the Jackson 2 backed ADLStringBuilder. public ADLTemplateOverlaySerializer(TemplateOverlay archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider) { super(archetype, flatArchetypeProvider, rmObjectMapperProvider); } + // Use this constructor to supply a custom ADLStringBuilder, e.g. new ADLStringBuilder3() for Jackson 3. + public ADLTemplateOverlaySerializer(TemplateOverlay archetype, Function flatArchetypeProvider, RMObjectMapperProvider rmObjectMapperProvider, ADLStringBuilder builder) { + super(archetype, flatArchetypeProvider, rmObjectMapperProvider, builder); + } + @Override protected String headTag() { return "template_overlay"; diff --git a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateSerializer.java b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateSerializer.java index 197d9682a..86f5610f2 100644 --- a/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateSerializer.java +++ b/aom/src/main/java/com/nedap/archie/serializer/adl/ADLTemplateSerializer.java @@ -12,10 +12,16 @@ */ class ADLTemplateSerializer extends ADLAuthoredArchetypeSerializer