Fix cross version extension validation, and check that extensions are consistent wrt isModifier in profiles

This commit is contained in:
Grahame Grieve 2022-03-09 17:37:26 +11:00
parent d7754a321f
commit 89b912dde2
5 changed files with 31 additions and 2 deletions

View File

@ -117,16 +117,18 @@ public class XVerExtensionManager {
populateTypes(path, val, verSource, verTarget);
} else if (path.has("elements")) {
for (JsonElement i : path.getAsJsonArray("elements")) {
JsonObject elt = root.getAsJsonObject(e+"."+i.getAsString());
if (elt != null) {
String s = i.getAsString().replace("[x]", "");
sd.getDifferential().addElement().setPath("Extension.extension").setSliceName(s);
sd.getDifferential().addElement().setPath("Extension.extension.extension").setMax("0");
sd.getDifferential().addElement().setPath("Extension.extension.url").setFixed(new UriType(s));
ElementDefinition val = sd.getDifferential().addElement().setPath("Extension.extension.value[x]").setMin(1);
JsonObject elt = root.getAsJsonObject(e+"."+i.getAsString());
if (!elt.has("types")) {
throw new FHIRException("Internal error - nested elements not supported yet");
}
populateTypes(elt, val, verSource, verTarget);
}
}
sd.getDifferential().addElement().setPath("Extension.url").setFixed(new UriType(url));
sd.getDifferential().addElement().setPath("Extension.value[x]").setMax("0");

View File

@ -366,6 +366,8 @@ public class I18nConstants {
public static final String SD_ED_TYPE_PROFILE_UNKNOWN = "SD_ED_TYPE_PROFILE_UNKNOWN";
public static final String SD_ED_TYPE_PROFILE_NOTYPE = "SD_ED_TYPE_PROFILE_NOTYPE";
public static final String SD_ED_TYPE_PROFILE_WRONG = "SD_ED_TYPE_PROFILE_WRONG";
public static final String SD_ED_TYPE_PROFILE_IS_MODIFIER = "SD_ED_TYPE_PROFILE_IS_MODIFIER";
public static final String SD_ED_TYPE_PROFILE_NOT_MODIFIER = "SD_ED_TYPE_PROFILE_NOT_MODIFIER";
public static final String SD_ED_TYPE_PROFILE_WRONG_TARGET = "SD_ED_TYPE_PROFILE_WRONG_TARGET";
public static final String SD_ED_TYPE_NO_TARGET_PROFILE = "SD_ED_TYPE_NO_TARGET_PROFILE";
public static final String SD_ED_SHOULD_BIND = "SD_ED_SHOULD_BIND";

View File

@ -3,7 +3,7 @@ package org.hl7.fhir.utilities.npm;
public class CommonPackages {
public static final String ID_XVER = "hl7.fhir.xver-extensions";
public static final String VER_XVER = "0.0.9";
public static final String VER_XVER = "0.0.11";
public static final String ID_PUBPACK = "hl7.fhir.pubpack";
public static final String VER_PUBPACK = "0.0.9";

View File

@ -629,6 +629,8 @@ Unable_to_connect_to_terminology_server = Unable to connect to terminology serve
SD_ED_TYPE_PROFILE_UNKNOWN = Unable to resolve profile {0}
SD_ED_TYPE_PROFILE_NOTYPE = Found profile {0}, but unable to determine the type it applies to
SD_ED_TYPE_PROFILE_WRONG = Profile {0} is for type {1}, but the {3} element has type {2}
SD_ED_TYPE_PROFILE_IS_MODIFIER = Profile {0} is for not for a modifier extension, but the {3} element is a modifier
SD_ED_TYPE_PROFILE_NOT_MODIFIER = Profile {0} is for a modifier extension, but the {3} element is not a modifier
SD_ED_TYPE_PROFILE_WRONG_TARGET = Profile {0} is for type {1}, which is not a {4} (which is required because the {3} element has type {2})
SD_ED_TYPE_NO_TARGET_PROFILE = Type {0} does not allow for target Profiles
TERMINOLOGY_TX_NOSVC_BOUND_REQ = Could not confirm that the codes provided are from the required value set {0} because there is no terminology service

View File

@ -294,6 +294,15 @@ public class StructureDefinitionValidator extends BaseValidator {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
} else {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isInstanceOf(t, code), I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
if (t.getType().equals("Extension")) {
boolean isModifierDefinition = checkIsModifierExtension(sd);
boolean isModifierContext = path.endsWith(".modifierExtension");
if (isModifierDefinition) {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_NOT_MODIFIER, p, t, code, path);
} else {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_IS_MODIFIER, p, t, code, path);
}
}
}
}
}
@ -325,10 +334,24 @@ public class StructureDefinitionValidator extends BaseValidator {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_NOTYPE, p);
} else if (!isInstanceOf(t, code)) {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.SD_ED_TYPE_PROFILE_WRONG, p, t, code, path);
} else {
if (t.getType().equals("Extension")) {
boolean isModifierDefinition = checkIsModifierExtension(sd);
boolean isModifierContext = path.endsWith(".modifierExtension");
if (isModifierDefinition) {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_NOT_MODIFIER, p, t, code, path);
} else {
rule(errors, IssueType.EXCEPTION, stack.getLiteralPath(), !isModifierContext, I18nConstants.SD_ED_TYPE_PROFILE_IS_MODIFIER, p, t, code, path);
}
}
}
}
}
private boolean checkIsModifierExtension(StructureDefinition t) {
return t.getSnapshot().getElementFirstRep().getIsModifier();
}
private void validateTargetProfile(List<ValidationMessage> errors, Element profile, String code, NodeStack stack, String path) {
String p = profile.primitiveValue();
StructureDefinition sd = context.fetchResource(StructureDefinition.class, p);