Refactor how mappings are handled when generating differentials: in R5, mapping names are unique

This commit is contained in:
Grahame Grieve 2023-03-18 05:47:33 +11:00
parent 8dd61f4b2e
commit f8a19a1bae
3 changed files with 61 additions and 23 deletions

View File

@ -130,6 +130,13 @@ import org.hl7.fhir.utilities.xml.SchematronWriter.Section;
*/ */
public class ProfileUtilities extends TranslatingUtilities { 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 { public enum AllowUnknownProfile {
NONE, // exception if there's any unknown profiles (the default) 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 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<String> masterSourceFileNames; private Set<String> masterSourceFileNames;
private Map<ElementDefinition, SourcedChildDefinitions> childMapCache = new HashMap<>(); private Map<ElementDefinition, SourcedChildDefinitions> childMapCache = new HashMap<>();
private AllowUnknownProfile allowUnknownProfile = AllowUnknownProfile.ALL_TYPES; private AllowUnknownProfile allowUnknownProfile = AllowUnknownProfile.ALL_TYPES;
private MappingMergeModeOption mappingMergeMode = MappingMergeModeOption.APPEND;
public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp, FHIRPathEngine fpe) { public ProfileUtilities(IWorkerContext context, List<ValidationMessage> messages, ProfileKnowledgeProvider pkp, FHIRPathEngine fpe) {
super(); super();
@ -2263,25 +2271,11 @@ public class ProfileUtilities extends TranslatingUtilities {
} }
if (derived.hasMapping()) { if (derived.hasMapping()) {
// todo: mappings are not cumulative - one replaces another List<ElementDefinitionMappingComponent> list = new ArrayList<>();
if (!Base.compareDeep(derived.getMapping(), base.getMapping(), false)) { list.addAll(base.getMapping());
for (ElementDefinitionMappingComponent s : derived.getMapping()) { base.getMapping().clear();
boolean found = false; addMappings(base.getMapping(), list);
for (ElementDefinitionMappingComponent d : base.getMapping()) { addMappings(base.getMapping(), derived.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);
}
}
} }
for (ElementDefinitionMappingComponent m : base.getMapping()) { for (ElementDefinitionMappingComponent m : base.getMapping()) {
if (m.hasMap()) { if (m.hasMap()) {
@ -2332,6 +2326,50 @@ public class ProfileUtilities extends TranslatingUtilities {
} }
} }
private void addMappings(List<ElementDefinitionMappingComponent> destination, List<ElementDefinitionMappingComponent> 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) { private void checkTypeDerivation(String purl, StructureDefinition srcSD, ElementDefinition base, ElementDefinition derived, TypeRefComponent ts) {
boolean ok = false; boolean ok = false;
CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder(); CommaSeparatedStringBuilder b = new CommaSeparatedStringBuilder();

View File

@ -135,12 +135,12 @@ public class R4R5MapTester implements IValidatorResourceFetcher {
back++; back++;
} }
public void elements(int elementCountBefore) { public void elements(int i) {
elements++; elements = elements+i;
} }
public void lost(int i) { public void lost(int i) {
lostElements++; lostElements = lostElements + i;
} }
public int elementsCount() { public int elementsCount() {

View File

@ -19,7 +19,7 @@
<properties> <properties>
<hapi_fhir_version>6.2.1</hapi_fhir_version> <hapi_fhir_version>6.2.1</hapi_fhir_version>
<validator_test_case_version>1.2.20</validator_test_case_version> <validator_test_case_version>1.2.21-SNAPSHOT</validator_test_case_version>
<junit_jupiter_version>5.7.1</junit_jupiter_version> <junit_jupiter_version>5.7.1</junit_jupiter_version>
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version> <junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
<maven_surefire_version>3.0.0-M5</maven_surefire_version> <maven_surefire_version>3.0.0-M5</maven_surefire_version>