From 0eb96f1f0a09ffc3143a4ccc727fc20556d164ba Mon Sep 17 00:00:00 2001 From: Grahame Grieve Date: Mon, 31 Jul 2023 20:46:30 +1000 Subject: [PATCH] fixes for extensions IG testing --- .../fhir/utilities/i18n/I18nConstants.java | 1 + .../src/main/resources/Messages.properties | 3 +- .../instance/InstanceValidator.java | 53 +++++++++++-------- .../type/StructureDefinitionValidator.java | 25 +++++++++ 4 files changed, 59 insertions(+), 23 deletions(-) diff --git a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java index e98520386..c60c6d763 100644 --- a/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java +++ b/org.hl7.fhir.utilities/src/main/java/org/hl7/fhir/utilities/i18n/I18nConstants.java @@ -949,6 +949,7 @@ public class I18nConstants { public static final String ED_INVARIANT_KEY_ALREADY_USED = "ED_INVARIANT_KEY_ALREADY_USED"; public static final String FHIRPATH_OFTYPE_IMPOSSIBLE = "FHIRPATH_OFTYPE_IMPOSSIBLE"; public static final String ED_SEARCH_EXPRESSION_ERROR = "ED_SEARCH_EXPRESSION_ERROR"; + public static final String SD_EXTENSION_URL_MISMATCH = "SD_EXTENSION_URL_MISMATCH"; diff --git a/org.hl7.fhir.utilities/src/main/resources/Messages.properties b/org.hl7.fhir.utilities/src/main/resources/Messages.properties index 9784c3d44..5aefff864 100644 --- a/org.hl7.fhir.utilities/src/main/resources/Messages.properties +++ b/org.hl7.fhir.utilities/src/main/resources/Messages.properties @@ -1004,4 +1004,5 @@ ED_INVARIANT_DIFF_NO_SOURCE = The invariant {0} defined in the differential must FHIRPATH_COLLECTION_STATUS_OPERATION_LEFT = The left side is inherently a collection, and so the expression ''{0}'' may fail or return false if there is more than one item in the content being evaluated FHIRPATH_COLLECTION_STATUS_OPERATION_RIGHT = The right side is inherently a collection, and so this expression ''{0}'' may fail or return false if there is more than one item in the content being evaluated FHIRPATH_OFTYPE_IMPOSSIBLE = The type specified in ofType is {1} which is not a possible candidate for the existing types ({0}) in the expression {2}. Check the paths and types to be sure this is what is intended -ED_SEARCH_EXPRESSION_ERROR = Error in search expression ''{0}'': {1} \ No newline at end of file +ED_SEARCH_EXPRESSION_ERROR = Error in search expression ''{0}'': {1} +SD_EXTENSION_URL_MISMATCH = The fixed value for the extension URL is {1} which doesn''t match the canonical URL {0} \ No newline at end of file diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java index e65c83ba2..b8200a386 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/InstanceValidator.java @@ -2038,36 +2038,45 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat if (en.contains("#")) { pu = en.substring(0, en.indexOf("#")); en = en.substring(en.indexOf("#")+1); + } else { + //pu = en; } if (Utilities.existsInList(en, "Element", "Any")) { ok = true; } else if (en.equals("Resource") && container.isResource()) { ok = true; + } else if (en.equals("CanonicalResource") && VersionUtilities.getCanonicalResourceNames(context.getVersion()).contains(stack.getLiteralPath())) { + ok = true; + } else if (plist.contains(en) && pu == null) { + ok = true; } - if (checkConformsToProfile(appContext, errors, resource, container, stack, extUrl, ctxt.getExpression(), pu)) { - for (String p : plist) { - if (ok) { - break; - } - if (p.equals(en)) { - ok = true; - } else { - String pn = p; - String pt = ""; - if (p.contains(".")) { - pn = p.substring(0, p.indexOf(".")); - pt = p.substring(p.indexOf(".")); + + if (!ok) { + if (checkConformsToProfile(appContext, errors, resource, container, stack, extUrl, ctxt.getExpression(), pu)) { + for (String p : plist) { + if (ok) { + break; } - StructureDefinition sd = context.fetchTypeDefinition(pn); - while (sd != null) { - if ((sd.getType() + pt).equals(en)) { - ok = true; - break; + if (p.equals(en)) { + ok = true; + } else { + String pn = p; + String pt = ""; + if (p.contains(".")) { + pn = p.substring(0, p.indexOf(".")); + pt = p.substring(p.indexOf(".")); } - if (sd.getBaseDefinition() != null) { - sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd); - } else { - sd = null; + StructureDefinition sd = context.fetchTypeDefinition(pn); + while (sd != null) { + if ((sd.getType() + pt).equals(en)) { + ok = true; + break; + } + if (sd.getBaseDefinition() != null) { + sd = context.fetchResource(StructureDefinition.class, sd.getBaseDefinition(), sd); + } else { + sd = null; + } } } } diff --git a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java index 0e20e2636..960ece31e 100644 --- a/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java +++ b/org.hl7.fhir.validation/src/main/java/org/hl7/fhir/validation/instance/type/StructureDefinitionValidator.java @@ -78,6 +78,8 @@ public class StructureDefinitionValidator extends BaseValidator { StructureDefinition sd = null; String typeName = null; try { + String url = src.getNamedChildValue("url"); + sd = loadAsSD(src); checkExtensionContext(errors, src, stack); @@ -160,6 +162,16 @@ public class StructureDefinitionValidator extends BaseValidator { } c++; } + + // if this is defining an extension, make sure that the extension fixed value matches the URL + String type = src.getNamedChildValue("type"); + if ("Extension".equals(type)) { + String baseD = src.getNamedChildValue("baseDefinition"); + if ("http://hl7.org/fhir/StructureDefinition/Extension".equals(baseD) && url != null) { + String fixedUrl = getFixedValue(src); + ok = rule(errors, "2023-05-27", IssueType.INVALID, stack.getLiteralPath(), url.equals(fixedUrl), I18nConstants.SD_EXTENSION_URL_MISMATCH, url, fixedUrl) && ok; + } + } } catch (Exception e) { rule(errors, NO_RULE_DATE, IssueType.EXCEPTION, stack.getLiteralPath(), false, I18nConstants.ERROR_GENERATING_SNAPSHOT, e.getMessage()); ok = false; @@ -168,6 +180,19 @@ public class StructureDefinitionValidator extends BaseValidator { } + private String getFixedValue(Element src) { + Element diff = src.getNamedChild("differential"); + if (diff != null) { + for (Element ed : diff.getChildrenByName("element")) { + String path = ed.getNamedChildValue("path"); + if ("Extension.url".equals(path)) { + return ed.getNamedChildValue("fixed"); + } + } + } + return null; + } + private boolean validateInheritsObligationProfile(List errors, Element extension, NodeStack stack, Element src) { String tgt = extension.getNamedChildValue("value"); if (rule(errors, "2023-05-27", IssueType.INVALID, stack.getLiteralPath(), tgt != null,