From f8a19a1bae3554d08f295e94f8b112bce084f209 Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Sat, 18 Mar 2023 05:47:33 +1100 Subject: [PATCH] Refactor how mappings are handled when generating differentials: in R5, mapping names are unique --- .../conformance/profile/ProfileUtilities.java | 76 ++++++++++++++----- .../validation/special/R4R5MapTester.java | 6 +- pom.xml | 2 +- 3 files changed, 61 insertions(+), 23 deletions(-) diff --git a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java index 9b32e57e4..9b216e802 100644 --- a/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java +++ b/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/conformance/profile/ProfileUtilities.java @@ -130,6 +130,13 @@ import org.hl7.fhir.utilities.xml.SchematronWriter.Section; */ public class ProfileUtilities extends TranslatingUtilities { + public enum MappingMergeModeOption { + DUPLICATE, // if there's more than one mapping for the same URI, just keep them all + IGNORE, // if there's more than one, keep the first + OVERWRITE, // if there's opre than, keep the last + APPEND, // if there's more than one, append them with ';' + } + public enum AllowUnknownProfile { NONE, // exception if there's any unknown profiles (the default) NON_EXTNEIONS, // don't raise an exception except on Extension (because more is going on there @@ -280,6 +287,7 @@ public class ProfileUtilities extends TranslatingUtilities { private Set masterSourceFileNames; private Map childMapCache = new HashMap<>(); private AllowUnknownProfile allowUnknownProfile = AllowUnknownProfile.ALL_TYPES; + private MappingMergeModeOption mappingMergeMode = MappingMergeModeOption.APPEND; public ProfileUtilities(IWorkerContext context, List messages, ProfileKnowledgeProvider pkp, FHIRPathEngine fpe) { super(); @@ -2263,25 +2271,11 @@ public class ProfileUtilities extends TranslatingUtilities { } if (derived.hasMapping()) { - // todo: mappings are not cumulative - one replaces another - if (!Base.compareDeep(derived.getMapping(), base.getMapping(), false)) { - for (ElementDefinitionMappingComponent s : derived.getMapping()) { - boolean found = false; - for (ElementDefinitionMappingComponent d : base.getMapping()) { - found = found || (d.getIdentity().equals(s.getIdentity()) && d.getMap().equals(s.getMap())); - } - if (!found) { - base.getMapping().add(s); - } - } - } - else if (trimDifferential) { - derived.getMapping().clear(); - } else { - for (ElementDefinitionMappingComponent t : derived.getMapping()) { - t.setUserData(UD_DERIVATION_EQUALS, true); - } - } + List list = new ArrayList<>(); + list.addAll(base.getMapping()); + base.getMapping().clear(); + addMappings(base.getMapping(), list); + addMappings(base.getMapping(), derived.getMapping()); } for (ElementDefinitionMappingComponent m : base.getMapping()) { if (m.hasMap()) { @@ -2332,6 +2326,50 @@ public class ProfileUtilities extends TranslatingUtilities { } } + private void addMappings(List destination, List source) { + for (ElementDefinitionMappingComponent s : source) { + boolean found = false; + for (ElementDefinitionMappingComponent d : destination) { + if (compareMaps(s, d)) { + found = true; + d.setUserData(UD_DERIVATION_EQUALS, true); + break; + } + } + if (!found) { + destination.add(s); + } + } + } + + private boolean compareMaps(ElementDefinitionMappingComponent s, ElementDefinitionMappingComponent d) { + if (d.getIdentity().equals(s.getIdentity()) && d.getMap().equals(s.getMap())) { + return true; + } + if (VersionUtilities.isR5Plus(context.getVersion())) { + if (d.getIdentity().equals(s.getIdentity())) { + switch (mappingMergeMode) { + case APPEND: + d.setMap(d.getMap()+";"+s.getMap()); + return true; + case DUPLICATE: + return false; + case IGNORE: + d.setMap(s.getMap()); + return true; + case OVERWRITE: + return true; + default: + return false; + } + } else { + return false; + } + } else { + return false; + } + } + private void checkTypeDerivation(String purl, StructureDefinition srcSD, ElementDefinition base, ElementDefinition derived, TypeRefComponent ts) { boolean ok = false; CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/R4R5MapTester.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/R4R5MapTester.java index 1a1d9f2aa..e719d133f 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/R4R5MapTester.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/special/R4R5MapTester.java @@ -135,12 +135,12 @@ public class R4R5MapTester implements IValidatorResourceFetcher { back++; } - public void elements(int elementCountBefore) { - elements++; + public void elements(int i) { + elements = elements+i; } public void lost(int i) { - lostElements++; + lostElements = lostElements + i; } public int elementsCount() { diff --git a/pom.xml b/pom.xml index 2035a46fa..25c91ee1e 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 6.2.1 - 1.2.20 + 1.2.21-SNAPSHOT 5.7.1 1.8.2 3.0.0-M5