Fix issue not retaining extension context when checking constraint expressions in profiles

This commit is contained in:
Grahame Grieve 2024-11-03 07:18:04 +10:30
parent 2666dad534
commit b493f3bb5c
2 changed files with 26 additions and 12 deletions

View File

@ -595,5 +595,17 @@ public class TypeDetails {
public boolean isChoice() { public boolean isChoice() {
return choice; return choice;
} }
public boolean isEmpty() {
return types.isEmpty();
}
public List<String> getProfiles(String t) {
t = ProfiledType.ns(t);
for (ProfiledType pt : types) {
if (t.equals(pt.uri)) {
return pt.getProfiles();
}
}
return new ArrayList<String>();
}
} }

View File

@ -22,8 +22,10 @@ import org.hl7.fhir.r5.elementmodel.Manager;
import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat; import org.hl7.fhir.r5.elementmodel.Manager.FhirFormat;
import org.hl7.fhir.r5.extensions.ExtensionConstants; import org.hl7.fhir.r5.extensions.ExtensionConstants;
import org.hl7.fhir.r5.fhirpath.ExpressionNode; import org.hl7.fhir.r5.fhirpath.ExpressionNode;
import org.hl7.fhir.r5.fhirpath.ExpressionNode.CollectionStatus;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine; import org.hl7.fhir.r5.fhirpath.FHIRPathEngine;
import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IssueMessage; import org.hl7.fhir.r5.fhirpath.FHIRPathEngine.IssueMessage;
import org.hl7.fhir.r5.fhirpath.TypeDetails;
import org.hl7.fhir.r5.formats.IParser.OutputStyle; import org.hl7.fhir.r5.formats.IParser.OutputStyle;
import org.hl7.fhir.r5.model.Base; import org.hl7.fhir.r5.model.Base;
import org.hl7.fhir.r5.model.Coding; import org.hl7.fhir.r5.model.Coding;
@ -673,18 +675,18 @@ public class StructureDefinitionValidator extends BaseValidator {
// we have to figure out the context, and we might be in type slicing. // we have to figure out the context, and we might be in type slicing.
String exp = expression; String exp = expression;
Element te = element; Element te = element;
List<String> types = getTypesForElement(elements, te, profileType); TypeDetails types = getTypesForElement(elements, te, profileType, profileUrl);
while (types.size() == 0 && te != null) { while (types.isEmpty() && te != null) {
Element oldte = te; Element oldte = te;
te = getParent(elements, te); te = getParent(elements, te);
if (te != null) { if (te != null) {
exp = tail(oldte, te)+".all("+exp+")"; exp = tail(oldte, te)+".all("+exp+")";
types = getTypesForElement(elements, te, profileType); types = getTypesForElement(elements, te, profileType, profileUrl);
} }
} }
if (types.size() == 0) { if (types.isEmpty()) {
// we got to the root before finding anything typed // we got to the root before finding anything typed
types.add(elements.get(0).getNamedChildValue("path", false)); types.addType(elements.get(0).getNamedChildValue("path", false));
} }
List<IssueMessage> warnings = new ArrayList<>(); List<IssueMessage> warnings = new ArrayList<>();
ValidationContext vc = new ValidationContext(invariant); ValidationContext vc = new ValidationContext(invariant);
@ -807,14 +809,14 @@ public class StructureDefinitionValidator extends BaseValidator {
return null; return null;
} }
private List<String> getTypesForElement(List<Element> elements, Element element, String profileType) { private TypeDetails getTypesForElement(List<Element> elements, Element element, String profileType, String profileUrl) {
List<String> types = new ArrayList<>(); TypeDetails types = new TypeDetails(CollectionStatus.SINGLETON);
if (element.hasChild("path", false) && !element.getNamedChildValue("path", false).contains(".")) { if (element.hasChild("path", false) && !element.getNamedChildValue("path", false).contains(".")) {
String t = element.getNamedChildValue("path", false); String t = element.getNamedChildValue("path", false);
if (profileType.equals(t)) { if (profileType.equals(t)) {
types.add(profileType); types.addType(profileType, profileUrl);
} else if (profileType.endsWith("/"+t)) { } else if (profileType.endsWith("/"+t)) {
types.add(profileType); types.addType(profileType, profileUrl);
} else { } else {
throw new Error("Error: this should not happen: '"+t+"' vs '"+profileType+"'?"); throw new Error("Error: this should not happen: '"+t+"' vs '"+profileType+"'?");
} }
@ -827,12 +829,12 @@ public class StructureDefinitionValidator extends BaseValidator {
if (t != null) { if (t != null) {
if (isAbstractType(t) && hasChildren(element, elements) ) { if (isAbstractType(t) && hasChildren(element, elements) ) {
if (!Utilities.isAbsoluteUrl(profileType)) { if (!Utilities.isAbsoluteUrl(profileType)) {
types.add(element.getNamedChildValue("path", false)); types.addType(profileUrl+ "#"+element.getNamedChildValue("path", false));
} else { } else {
types.add(profileType+"#"+element.getNamedChildValue("path", false)); types.addType(profileType+"#"+element.getNamedChildValue("path", false));
} }
} else { } else {
types.add(t); types.addType(t);
} }
} }
} }