fix problem missing profiles on references in discriminators

This commit is contained in:
Grahame Grieve 2022-02-26 06:22:42 +11:00
parent f32895da67
commit c918f724ee
3 changed files with 36 additions and 7 deletions

View File

@ -235,6 +235,13 @@ public class FHIRPathEngine {
} }
return res; return res;
} }
public boolean hasType(String tn) {
if (type != null) {
return tn.equals(type);
} else {
return element.hasType(tn);
}
}
} }
private IWorkerContext worker; private IWorkerContext worker;
private IEvaluationContext hostServices; private IEvaluationContext hostServices;
@ -5472,7 +5479,7 @@ public class FHIRPathEngine {
* @throws PathEngineException * @throws PathEngineException
* @throws DefinitionException * @throws DefinitionException
*/ */
public TypedElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, TypedElementDefinition element, StructureDefinition source) throws DefinitionException { public TypedElementDefinition evaluateDefinition(ExpressionNode expr, StructureDefinition profile, TypedElementDefinition element, StructureDefinition source, boolean dontWalkIntoReferences) throws DefinitionException {
StructureDefinition sd = profile; StructureDefinition sd = profile;
TypedElementDefinition focus = null; TypedElementDefinition focus = null;
boolean okToNotResolve = false; boolean okToNotResolve = false;
@ -5584,10 +5591,19 @@ public class FHIRPathEngine {
} else { } else {
throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND, expr.toString(), source.getUrl(), element.getElement().getId(), profile.getUrl()); throw makeException(expr, I18nConstants.FHIRPATH_DISCRIMINATOR_CANT_FIND, expr.toString(), source.getUrl(), element.getElement().getId(), profile.getUrl());
} }
} else if (expr.getInner() == null) {
return focus;
} else { } else {
return evaluateDefinition(expr.getInner(), sd, focus, profile); // gdg 26-02-2022. If we're walking towards a resolve() and we're on a reference, and we try to walk into the reference
// then we don't do that. .resolve() is allowed on the Reference.reference, but the target of the reference will be defined
// on the Reference, not the reference.reference.
ExpressionNode next = expr.getInner();
if (dontWalkIntoReferences && focus.hasType("Reference") && next != null && next.getKind() == Kind.Name && next.getName().equals("reference")) {
next = next.getInner();
}
if (next == null) {
return focus;
} else {
return evaluateDefinition(next, sd, focus, profile, dontWalkIntoReferences);
}
} }
} }

View File

@ -3405,13 +3405,17 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
return elements; return elements;
} }
boolean dontFollowReference = false;
if (removeResolve) { // if we're doing profile slicing, we don't want to walk into the last resolve.. we need the profile on the source not the target if (removeResolve) { // if we're doing profile slicing, we don't want to walk into the last resolve.. we need the profile on the source not the target
if (discriminator.equals("resolve()")) { if (discriminator.equals("resolve()")) {
elements.add(element); elements.add(element);
return elements; return elements;
} }
if (discriminator.endsWith(".resolve()")) if (discriminator.endsWith(".resolve()")) {
discriminator = discriminator.substring(0, discriminator.length() - 10); discriminator = discriminator.substring(0, discriminator.length() - 10);
dontFollowReference = true;
}
} }
TypedElementDefinition ted = null; TypedElementDefinition ted = null;
@ -3424,7 +3428,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR_BAD_PATH, e.getMessage(), fp), e); throw new FHIRException(context.formatMessage(I18nConstants.DISCRIMINATOR_BAD_PATH, e.getMessage(), fp), e);
} }
long t2 = System.nanoTime(); long t2 = System.nanoTime();
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile); ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile, dontFollowReference);
timeTracker.sd(t2); timeTracker.sd(t2);
if (ted != null) if (ted != null)
elements.add(ted.getElement()); elements.add(ted.getElement());
@ -3449,7 +3453,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
} }
expr = fpe.parse(fp); expr = fpe.parse(fp);
t2 = System.nanoTime(); t2 = System.nanoTime();
ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile); ted = fpe.evaluateDefinition(expr, profile, new TypedElementDefinition(element), srcProfile, dontFollowReference);
timeTracker.sd(t2); timeTracker.sd(t2);
if (ted != null) if (ted != null)
elements.add(ted.getElement()); elements.add(ted.getElement());

View File

@ -343,3 +343,12 @@ v: {
"system" : "http://snomed.info/sct" "system" : "http://snomed.info/sct"
} }
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "11181000146103"
}, "valueSet" :null, "lang":"null", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"ALL_CHECKS", "versionFlexible":"false"}####
v: {
"severity" : "error",
"error" : "Unable to find code 11181000146103 in http://snomed.info/sct (version http://snomed.info/sct/900000000000207008/version/20210731); The code \"11181000146103\" is not valid in the system http://snomed.info/sct; The code provided (http://snomed.info/sct#11181000146103) is not valid in the value set 'All codes known to the system' (from http://tx.fhir.org/r3)"
}
-------------------------------------------------------------------------------------