R5 FHIRPath engine fixes for polymorphism + update R4B FHIRPath engine to match R5

This commit is contained in:
Grahame Grieve 2022-10-07 08:08:04 +11:00
parent e73f79103c
commit b9036524d5
2 changed files with 424 additions and 361 deletions

View File

@ -45,6 +45,7 @@ import org.hl7.fhir.r4b.model.ExpressionNode.CollectionStatus;
import org.hl7.fhir.r4b.model.ExpressionNode.Function; import org.hl7.fhir.r4b.model.ExpressionNode.Function;
import org.hl7.fhir.r4b.model.ExpressionNode.Kind; import org.hl7.fhir.r4b.model.ExpressionNode.Kind;
import org.hl7.fhir.r4b.model.ExpressionNode.Operation; import org.hl7.fhir.r4b.model.ExpressionNode.Operation;
import org.hl7.fhir.r4b.model.InstantType;
import org.hl7.fhir.r4b.model.Property.PropertyMatcher; import org.hl7.fhir.r4b.model.Property.PropertyMatcher;
import org.hl7.fhir.r4b.model.IntegerType; import org.hl7.fhir.r4b.model.IntegerType;
import org.hl7.fhir.r4b.model.Property; import org.hl7.fhir.r4b.model.Property;
@ -649,10 +650,10 @@ public class FHIRPathEngine {
} else if (left.getHour() > right.getHour()) { } else if (left.getHour() > right.getHour()) {
return 1; return 1;
// hour is not a valid precision // hour is not a valid precision
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.YEAR && dateRight.getPrecision() == TemporalPrecisionEnum.YEAR) { // } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.YEAR && dateRight.getPrecision() == TemporalPrecisionEnum.YEAR) {
// return 0; // return 0;
// } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.HOUR || dateRight.getPrecision() == TemporalPrecisionEnum.HOUR) { // } else if (dateLeft.getPrecision() == TemporalPrecisionEnum.HOUR || dateRight.getPrecision() == TemporalPrecisionEnum.HOUR) {
// return null; // return null;
} }
if (left.getMinute() < right.getMinute()) { if (left.getMinute() < right.getMinute()) {
@ -1400,7 +1401,7 @@ public class FHIRPathEngine {
} }
private List<Base> execute(ExecutionContext context, List<Base> focus, ExpressionNode exp, boolean atEntry) throws FHIRException { private List<Base> execute(ExecutionContext context, List<Base> focus, ExpressionNode exp, boolean atEntry) throws FHIRException {
// System.out.println("Evaluate {'"+exp.toString()+"'} on "+focus.toString()); // System.out.println("Evaluate {'"+exp.toString()+"'} on "+focus.toString());
List<Base> work = new ArrayList<Base>(); List<Base> work = new ArrayList<Base>();
switch (exp.getKind()) { switch (exp.getKind()) {
case Unary: case Unary:
@ -1454,13 +1455,13 @@ public class FHIRPathEngine {
} else { } else {
work2 = execute(context, focus, next, true); work2 = execute(context, focus, next, true);
work = operate(context, work, last.getOperation(), work2, last); work = operate(context, work, last.getOperation(), work2, last);
// System.out.println("Result of {'"+last.toString()+" "+last.getOperation().toCode()+" "+next.toString()+"'}: "+focus.toString()); // System.out.println("Result of {'"+last.toString()+" "+last.getOperation().toCode()+" "+next.toString()+"'}: "+focus.toString());
} }
last = next; last = next;
next = next.getOpNext(); next = next.getOpNext();
} }
} }
// System.out.println("Result of {'"+exp.toString()+"'}: "+work.toString()); // System.out.println("Result of {'"+exp.toString()+"'}: "+work.toString());
return work; return work;
} }
@ -1797,7 +1798,18 @@ public class FHIRPathEngine {
} else if ((left.get(0) instanceof Element) && ((Element) left.get(0)).isDisallowExtensions()) { } else if ((left.get(0) instanceof Element) && ((Element) left.get(0)).isDisallowExtensions()) {
result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn) || ("System."+Utilities.capitalize(left.get(0).fhirType())).equals(tn)).noExtensions()); result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn) || ("System."+Utilities.capitalize(left.get(0).fhirType())).equals(tn)).noExtensions());
} else { } else {
result.add(new BooleanType(left.get(0).hasType(tn)).noExtensions()); if (left.get(0).fhirType().equals(tn)) {
result.add(new BooleanType(true).noExtensions());
} else {
StructureDefinition sd = worker.fetchTypeDefinition(left.get(0).fhirType());
while (sd != null) {
if (tn.equals(sd.getType())) {
return makeBoolean(true);
}
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
}
return makeBoolean(false);
}
} }
} }
return result; return result;
@ -2411,7 +2423,7 @@ public class FHIRPathEngine {
ans = true; ans = true;
} }
} else { } else {
// System.out.println("unknown type in opMemberOf: "+l.fhirType()); // System.out.println("unknown type in opMemberOf: "+l.fhirType());
} }
} }
} }
@ -4187,7 +4199,7 @@ public class FHIRPathEngine {
} else if (l.fhirType().equals("CodeableConcept")) { } else if (l.fhirType().equals("CodeableConcept")) {
return makeBoolean(worker.validateCode(terminologyServiceOptions, TypeConvertor.castToCodeableConcept(l), vs).isOk()); return makeBoolean(worker.validateCode(terminologyServiceOptions, TypeConvertor.castToCodeableConcept(l), vs).isOk());
} else { } else {
// System.out.println("unknown type in funcMemberOf: "+l.fhirType()); // System.out.println("unknown type in funcMemberOf: "+l.fhirType());
return new ArrayList<Base>(); return new ArrayList<Base>();
} }
} }
@ -4345,18 +4357,18 @@ public class FHIRPathEngine {
} }
private List<Base> funcToDateTime(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcToDateTime(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
// List<Base> result = new ArrayList<Base>(); // List<Base> result = new ArrayList<Base>();
// result.add(new BooleanType(convertToBoolean(focus))); // result.add(new BooleanType(convertToBoolean(focus)));
// return result; // return result;
throw makeException(expr, I18nConstants.FHIRPATH_NOT_IMPLEMENTED, "toDateTime"); throw makeException(expr, I18nConstants.FHIRPATH_NOT_IMPLEMENTED, "toDateTime");
} }
private List<Base> funcToTime(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcToTime(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
// List<Base> result = new ArrayList<Base>(); // List<Base> result = new ArrayList<Base>();
// result.add(new BooleanType(convertToBoolean(focus))); // result.add(new BooleanType(convertToBoolean(focus)));
// return result; // return result;
throw makeException(expr, I18nConstants.FHIRPATH_NOT_IMPLEMENTED, "toTime"); throw makeException(expr, I18nConstants.FHIRPATH_NOT_IMPLEMENTED, "toTime");
} }
private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcToDecimal(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
@ -4502,7 +4514,18 @@ public class FHIRPathEngine {
return makeBoolean(false); return makeBoolean(false);
} }
} else if (ns.equals("FHIR")) { } else if (ns.equals("FHIR")) {
return makeBoolean(n.equals(focus.get(0).fhirType())); if (n.equals(focus.get(0).fhirType())) {
return makeBoolean(true);
} else {
StructureDefinition sd = worker.fetchTypeDefinition(focus.get(0).fhirType());
while (sd != null) {
if (n.equals(sd.getType())) {
return makeBoolean(true);
}
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
}
return makeBoolean(false);
}
} else { } else {
return makeBoolean(false); return makeBoolean(false);
} }
@ -4526,8 +4549,18 @@ public class FHIRPathEngine {
} }
} else if (tn.startsWith("FHIR.")) { } else if (tn.startsWith("FHIR.")) {
if (b.hasType(tn.substring(5))) { String tnp = tn.substring(5);
if (b.fhirType().equals(tnp)) {
result.add(b); result.add(b);
} else {
StructureDefinition sd = worker.fetchTypeDefinition(b.fhirType());
while (sd != null) {
if (tnp.equals(sd.getType())) {
result.add(b);
break;
}
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
}
} }
} }
} }
@ -5502,10 +5535,11 @@ public class FHIRPathEngine {
if (dt == null) { if (dt == null) {
throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(t.getCode(), worker.getOverrideVersionNs()), "getChildTypesByName"); throw makeException(expr, I18nConstants.FHIRPATH_NO_TYPE, ProfileUtilities.sdNs(t.getCode(), worker.getOverrideVersionNs()), "getChildTypesByName");
} }
sdl.add(dt); addTypeAndDescendents(sdl, dt, worker.allStructures());
// also add any descendant types
} }
} else { } else {
sdl.add(sd); addTypeAndDescendents(sdl, sd, worker.allStructures());
if (type.contains("#")) { if (type.contains("#")) {
tail = type.substring(type.indexOf("#")+1); tail = type.substring(type.indexOf("#")+1);
tail = tail.substring(tail.indexOf(".")); tail = tail.substring(tail.indexOf("."));
@ -5595,6 +5629,15 @@ public class FHIRPathEngine {
} }
} }
private void addTypeAndDescendents(List<StructureDefinition> sdl, StructureDefinition dt, List<StructureDefinition> types) {
sdl.add(dt);
for (StructureDefinition sd : types) {
if (sd.hasBaseDefinition() && sd.getBaseDefinition().equals(dt.getUrl()) && sd.getDerivation() == TypeDerivationRule.SPECIALIZATION) {
addTypeAndDescendents(sdl, sd, types);
}
}
}
private void getClassInfoChildTypesByName(String name, TypeDetails result) { private void getClassInfoChildTypesByName(String name, TypeDetails result) {
if (name.equals("namespace")) { if (name.equals("namespace")) {
result.addType(TypeDetails.FP_String); result.addType(TypeDetails.FP_String);
@ -5658,7 +5701,6 @@ public class FHIRPathEngine {
return list.size() != 1 ? true : Utilities.existsInList(list.get(0).getCode(), "Element", "BackboneElement", "Resource", "DomainResource"); return list.size() != 1 ? true : Utilities.existsInList(list.get(0).getCode(), "Element", "BackboneElement", "Resource", "DomainResource");
} }
private boolean hasType(ElementDefinition ed, String s) { private boolean hasType(ElementDefinition ed, String s) {
for (TypeRefComponent t : ed.getType()) { for (TypeRefComponent t : ed.getType()) {
if (s.equalsIgnoreCase(t.getCode())) { if (s.equalsIgnoreCase(t.getCode())) {

View File

@ -1798,7 +1798,18 @@ public class FHIRPathEngine {
} else if ((left.get(0) instanceof Element) && ((Element) left.get(0)).isDisallowExtensions()) { } else if ((left.get(0) instanceof Element) && ((Element) left.get(0)).isDisallowExtensions()) {
result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn) || ("System."+Utilities.capitalize(left.get(0).fhirType())).equals(tn)).noExtensions()); result.add(new BooleanType(Utilities.capitalize(left.get(0).fhirType()).equals(tn) || ("System."+Utilities.capitalize(left.get(0).fhirType())).equals(tn)).noExtensions());
} else { } else {
result.add(new BooleanType(left.get(0).hasType(tn)).noExtensions()); if (left.get(0).fhirType().equals(tn)) {
result.add(new BooleanType(true).noExtensions());
} else {
StructureDefinition sd = worker.fetchTypeDefinition(left.get(0).fhirType());
while (sd != null) {
if (tn.equals(sd.getType())) {
return makeBoolean(true);
}
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
}
return makeBoolean(false);
}
} }
} }
return result; return result;
@ -4538,8 +4549,18 @@ public class FHIRPathEngine {
} }
} else if (tn.startsWith("FHIR.")) { } else if (tn.startsWith("FHIR.")) {
if (b.hasType(tn.substring(5))) { String tnp = tn.substring(5);
if (b.fhirType().equals(tnp)) {
result.add(b); result.add(b);
} else {
StructureDefinition sd = worker.fetchTypeDefinition(b.fhirType());
while (sd != null) {
if (tnp.equals(sd.getType())) {
result.add(b);
break;
}
sd = worker.fetchResource(StructureDefinition.class, sd.getBaseDefinition());
}
} }
} }
} }