fix bugs in FHIRPath engine, and work around wrong FHIRPath statements in the validator
This commit is contained in:
parent
960e56705f
commit
f2b619b08e
|
@ -1736,7 +1736,7 @@ public class FHIRPathEngine {
|
||||||
return makeBoolean(!res);
|
return makeBoolean(!res);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static String[] FHIR_TYPES_STRING = new String[] {"string", "uri", "code", "oid", "id", "uuid", "sid", "markdown", "base64Binary"};
|
private final static String[] FHIR_TYPES_STRING = new String[] {"string", "uri", "code", "oid", "id", "uuid", "sid", "markdown", "base64Binary", "canonical", "url"};
|
||||||
|
|
||||||
private List<Base> opLessThan(List<Base> left, List<Base> right) throws FHIRException {
|
private List<Base> opLessThan(List<Base> left, List<Base> right) throws FHIRException {
|
||||||
if (left.size() == 0 || right.size() == 0)
|
if (left.size() == 0 || right.size() == 0)
|
||||||
|
@ -3200,7 +3200,7 @@ public class FHIRPathEngine {
|
||||||
|
|
||||||
private List<Base> funcIsDistinct(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
private List<Base> funcIsDistinct(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||||
if (focus.size() < 1)
|
if (focus.size() < 1)
|
||||||
return new ArrayList<Base>();
|
return makeBoolean(true);
|
||||||
if (focus.size() == 1)
|
if (focus.size() == 1)
|
||||||
return makeBoolean(true);
|
return makeBoolean(true);
|
||||||
|
|
||||||
|
@ -4239,22 +4239,29 @@ public class FHIRPathEngine {
|
||||||
private Equality asBool(Base item) {
|
private Equality asBool(Base item) {
|
||||||
if (item instanceof BooleanType)
|
if (item instanceof BooleanType)
|
||||||
return boolToTriState(((BooleanType) item).booleanValue());
|
return boolToTriState(((BooleanType) item).booleanValue());
|
||||||
else if (item instanceof IntegerType)
|
else if (item.isBooleanPrimitive()) {
|
||||||
|
if (Utilities.existsInList(item.primitiveValue(), "true"))
|
||||||
|
return Equality.True;
|
||||||
|
else if (Utilities.existsInList(item.primitiveValue(), "false"))
|
||||||
|
return Equality.False;
|
||||||
|
else
|
||||||
|
return Equality.Null;
|
||||||
|
} else if (item instanceof IntegerType || Utilities.existsInList(item.fhirType(), "integer", "positiveint", "unsignedInt"))
|
||||||
return asBoolFromInt(item.primitiveValue());
|
return asBoolFromInt(item.primitiveValue());
|
||||||
else if (item instanceof DecimalType)
|
else if (item instanceof DecimalType || Utilities.existsInList(item.fhirType(), "decimal"))
|
||||||
return asBoolFromDec(item.primitiveValue());
|
return asBoolFromDec(item.primitiveValue());
|
||||||
else if (Utilities.existsInList(item.fhirType(), FHIR_TYPES_STRING)) {
|
else if (Utilities.existsInList(item.fhirType(), FHIR_TYPES_STRING)) {
|
||||||
if (Utilities.existsInList(item.primitiveValue(), "true", "t", "yes", "y"))
|
if (Utilities.existsInList(item.primitiveValue(), "true", "t", "yes", "y"))
|
||||||
return Equality.False;
|
|
||||||
else if (Utilities.existsInList(item.primitiveValue(), "false", "f", "no", "n"))
|
|
||||||
return Equality.True;
|
return Equality.True;
|
||||||
|
else if (Utilities.existsInList(item.primitiveValue(), "false", "f", "no", "n"))
|
||||||
|
return Equality.False;
|
||||||
else if (Utilities.isInteger(item.primitiveValue()))
|
else if (Utilities.isInteger(item.primitiveValue()))
|
||||||
return asBoolFromInt(item.primitiveValue());
|
return asBoolFromInt(item.primitiveValue());
|
||||||
else if (Utilities.isDecimal(item.primitiveValue()))
|
else if (Utilities.isDecimal(item.primitiveValue()))
|
||||||
return asBoolFromDec(item.primitiveValue());
|
return asBoolFromDec(item.primitiveValue());
|
||||||
else
|
else
|
||||||
return Equality.Null;
|
return Equality.Null;
|
||||||
} else
|
}
|
||||||
return Equality.Null;
|
return Equality.Null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2023,7 +2023,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
ElementDefinition ed = null;
|
ElementDefinition ed = null;
|
||||||
ExpressionNode expr = fpe.parse(discriminator);
|
ExpressionNode expr = fpe.parse(fixExpr(discriminator));
|
||||||
long t2 = System.nanoTime();
|
long t2 = System.nanoTime();
|
||||||
ed = fpe.evaluateDefinition(expr, profile, element);
|
ed = fpe.evaluateDefinition(expr, profile, element);
|
||||||
sdTime = sdTime + (System.nanoTime() - t2);
|
sdTime = sdTime + (System.nanoTime() - t2);
|
||||||
|
@ -2048,7 +2048,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (element == null)
|
if (element == null)
|
||||||
throw new DefinitionException("Unable to resolve element "+id+" in profile "+p);
|
throw new DefinitionException("Unable to resolve element "+id+" in profile "+p);
|
||||||
}
|
}
|
||||||
expr = fpe.parse(discriminator);
|
expr = fpe.parse(fixExpr(discriminator));
|
||||||
t2 = System.nanoTime();
|
t2 = System.nanoTime();
|
||||||
ed = fpe.evaluateDefinition(expr, profile, element);
|
ed = fpe.evaluateDefinition(expr, profile, element);
|
||||||
sdTime = sdTime + (System.nanoTime() - t2);
|
sdTime = sdTime + (System.nanoTime() - t2);
|
||||||
|
@ -2586,7 +2586,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
n = fpe.parse(expression.toString());
|
n = fpe.parse(fixExpr(expression.toString()));
|
||||||
} catch (FHIRLexerException e) {
|
} catch (FHIRLexerException e) {
|
||||||
throw new FHIRException("Problem processing expression "+expression +" in profile " + profile.getUrl() + " path " + path + ": " + e.getMessage());
|
throw new FHIRException("Problem processing expression "+expression +" in profile " + profile.getUrl() + " path " + path + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -3911,7 +3911,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
long t = System.nanoTime();
|
long t = System.nanoTime();
|
||||||
try {
|
try {
|
||||||
n = fpe.parse(inv.getExpression());
|
n = fpe.parse(fixExpr(inv.getExpression()));
|
||||||
} catch (FHIRLexerException e) {
|
} catch (FHIRLexerException e) {
|
||||||
throw new FHIRException("Problem processing expression "+inv.getExpression() +" in profile " + profile.getUrl() + " path " + path + ": " + e.getMessage());
|
throw new FHIRException("Problem processing expression "+inv.getExpression() +" in profile " + profile.getUrl() + " path " + path + ": " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -3931,12 +3931,6 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
msg = ex.getMessage();
|
msg = ex.getMessage();
|
||||||
}
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
// GDG 18-feb 2018 - why do it again? just to waste cycles?
|
|
||||||
// try {
|
|
||||||
// ok = fpe.evaluateToBoolean(hostContext, resource, element, n);
|
|
||||||
// } catch (PathEngineException e) {
|
|
||||||
// throw new FHIRException("Problem processing expression "+inv.getExpression() +" in profile " + profile.getUrl() + " path " + path + ": " + e.getMessage());
|
|
||||||
// }
|
|
||||||
if (!Utilities.noString(msg))
|
if (!Utilities.noString(msg))
|
||||||
msg = " ("+msg+")";
|
msg = " ("+msg+")";
|
||||||
if (inv.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice") &&
|
if (inv.hasExtension("http://hl7.org/fhir/StructureDefinition/elementdefinition-bestpractice") &&
|
||||||
|
@ -4311,7 +4305,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
try {
|
try {
|
||||||
ExpressionNode n = (ExpressionNode) inv.getUserData("validator.expression.cache");
|
ExpressionNode n = (ExpressionNode) inv.getUserData("validator.expression.cache");
|
||||||
if (n == null) {
|
if (n == null) {
|
||||||
n = fpe.parse(inv.getExpression());
|
n = fpe.parse(fixExpr(inv.getExpression()));
|
||||||
inv.setUserData("validator.expression.cache", n);
|
inv.setUserData("validator.expression.cache", n);
|
||||||
}
|
}
|
||||||
fpe.check(null, sd.getKind() == StructureDefinitionKind.RESOURCE ? sd.getType() : "DomainResource", ed.getPath(), n);
|
fpe.check(null, sd.getKind() == StructureDefinitionKind.RESOURCE ? sd.getType() : "DomainResource", ed.getPath(), n);
|
||||||
|
@ -4325,4 +4319,26 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String fixExpr(String expr) {
|
||||||
|
// this is a hack work around for past publication of wrong FHIRPath expressions
|
||||||
|
if ("(component.empty() and hasMember.empty()) implies (dataAbsentReason or value)".equals(expr))
|
||||||
|
return "(component.empty() and hasMember.empty()) implies (dataAbsentReason.exists() or value.exists())";
|
||||||
|
if ("isModifier implies isModifierReason.exists()".equals(expr))
|
||||||
|
return "(isModifier.exists() and isModifier) implies isModifierReason.exists()";
|
||||||
|
if ("(%resource.kind = 'logical' or element.first().path.startsWith(%resource.type)) and (element.tail().not() or element.tail().all(path.startsWith(%resource.differential.element.first().path.replaceMatches('\\\\..*','')&'.')))".equals(expr))
|
||||||
|
return "(%resource.kind = 'logical' or element.first().path.startsWith(%resource.type)) and (element.tail().empty() or element.tail().all(path.startsWith(%resource.differential.element.first().path.replaceMatches('\\\\..*','')&'.')))";
|
||||||
|
if ("differential.element.all(id) and differential.element.id.trace('ids').isDistinct()".equals(expr))
|
||||||
|
return "differential.element.all(id.exists()) and differential.element.id.trace('ids').isDistinct()";
|
||||||
|
if ("snapshot.element.all(id) and snapshot.element.id.trace('ids').isDistinct()".equals(expr))
|
||||||
|
return "snapshot.element.all(id.exists()) and snapshot.element.id.trace('ids').isDistinct()";
|
||||||
|
if ("".equals(expr))
|
||||||
|
return "";
|
||||||
|
if ("".equals(expr))
|
||||||
|
return "";
|
||||||
|
if ("".equals(expr))
|
||||||
|
return "";
|
||||||
|
return expr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue