clone FHIRPath changes to R4/R4B

This commit is contained in:
Grahame Grieve 2024-08-23 21:49:46 +08:00
parent 69ab5975d5
commit 10d4ac0aad
2 changed files with 88 additions and 86 deletions

View File

@ -3658,23 +3658,22 @@ public class FHIRPathEngine {
case LowBoundary: case LowBoundary:
case HighBoundary: { case HighBoundary: {
checkContextContinuous(focus, exp.getFunction().toCode(), exp); checkContextContinuous(focus, exp.getFunction().toCode(), exp, true);
if (paramTypes.size() > 0) { if (paramTypes.size() > 0) {
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, checkParamTypes(exp, exp.getFunction().toCode(), paramTypes,
new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer)); new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer));
} }
if (focus.hasType("decimal") if ((focus.hasType("date") || focus.hasType("datetime") || focus.hasType("instant"))) {
&& (focus.hasType("date") || focus.hasType("datetime") || focus.hasType("instant"))) { return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal, TypeDetails.FP_DateTime);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal, TypeDetails.FP_DateTime); } else if (focus.hasType("decimal") || focus.hasType("integer")) {
} else if (focus.hasType("decimal")) { return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
} else { } else {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_DateTime); return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_DateTime);
} }
} }
case Precision: { case Precision: {
checkContextContinuous(focus, exp.getFunction().toCode(), exp); checkContextContinuous(focus, exp.getFunction().toCode(), exp, false);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer); return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer);
} }
case Custom: { case Custom: {
@ -3778,9 +3777,8 @@ public class FHIRPathEngine {
} }
} }
private void checkContextContinuous(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException { private void checkContextContinuous(TypeDetails focus, String name, ExpressionNode expr, boolean allowInteger) throws PathEngineException {
if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") && !focus.hasType("time") && !focus.hasType("Quantity") && !(allowInteger && focus.hasType("integer"))) {
&& !focus.hasType("time") && !focus.hasType("Quantity")) {
throw makeException(expr, I18nConstants.FHIRPATH_CONTINUOUS_ONLY, name, focus.describe()); throw makeException(expr, I18nConstants.FHIRPATH_CONTINUOUS_ONLY, name, focus.describe());
} }
} }
@ -4223,42 +4221,43 @@ public class FHIRPathEngine {
if (focus.size() > 1) { if (focus.size() > 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "lowBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "lowBoundary", focus.size());
} }
int precision = 0; Integer precision = null;
if (expr.getParameters().size() > 0) { if (expr.getParameters().size() > 0) {
List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true); List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true);
if (n1.size() != 1) { if (n1.size() != 1) {
throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", "integer");
"integer");
} }
precision = Integer.parseInt(n1.get(0).primitiveValue()); precision = Integer.parseInt(n1.get(0).primitiveValue());
} }
Base base = focus.get(0); Base base = focus.get(0);
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
if (base.hasType("decimal")) { if (base.hasType("decimal")) {
result if (precision == null || (precision >= 0 && precision < 17)) {
.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == 0 ? 8 : precision))); result.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("integer")) {
if (precision == null || (precision >= 0 && precision < 17)) {
result.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("date")) { } else if (base.hasType("date")) {
result result.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == null ? 10 : precision)));
.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == 0 ? 10 : precision)));
} else if (base.hasType("dateTime")) { } else if (base.hasType("dateTime")) {
result result.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == null ? 17 : precision)));
.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == 0 ? 17 : precision)));
} else if (base.hasType("time")) { } else if (base.hasType("time")) {
result.add(new TimeType(Utilities.lowBoundaryForTime(base.primitiveValue(), precision == 0 ? 9 : precision))); result.add(new TimeType(Utilities.lowBoundaryForTime(base.primitiveValue(), precision == null ? 9 : precision)));
} else if (base.hasType("Quantity")) { } else if (base.hasType("Quantity")) {
String value = getNamedValue(base, "value"); String value = getNamedValue(base, "value");
Base v = base.copy(); Base v = base.copy();
v.setProperty("value", new DecimalType(Utilities.lowBoundaryForDecimal(value, precision == 0 ? 8 : precision))); v.setProperty("value", new DecimalType(Utilities.lowBoundaryForDecimal(value, precision == null ? 8 : precision)));
result.add(v); result.add(v);
} else { } else {
makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "decimal or date");
"decimal or date");
} }
return result; return result;
} }
private List<Base> funcHighBoundary(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcHighBoundary(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
if (focus.size() == 0) { if (focus.size() == 0) {
return makeNull(); return makeNull();
@ -4266,41 +4265,43 @@ public class FHIRPathEngine {
if (focus.size() > 1) { if (focus.size() > 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size());
} }
int precision = 0; Integer precision = null;
if (expr.getParameters().size() > 0) { if (expr.getParameters().size() > 0) {
List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true); List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true);
if (n1.size() != 1) { if (n1.size() != 1) {
throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", "integer");
"integer");
} }
precision = Integer.parseInt(n1.get(0).primitiveValue()); precision = Integer.parseInt(n1.get(0).primitiveValue());
} }
Base base = focus.get(0); Base base = focus.get(0);
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
if (base.hasType("decimal")) { if (base.hasType("decimal")) {
result.add( if (precision == null || (precision >= 0 && precision < 17)) {
new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == 0 ? 8 : precision))); result.add(new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("integer")) {
if (precision == null || (precision >= 0 && precision < 17)) {
result.add(new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("date")) { } else if (base.hasType("date")) {
result result.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == null ? 10 : precision)));
.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == 0 ? 10 : precision)));
} else if (base.hasType("dateTime")) { } else if (base.hasType("dateTime")) {
result result.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == null ? 17 : precision)));
.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == 0 ? 17 : precision)));
} else if (base.hasType("time")) { } else if (base.hasType("time")) {
result.add(new TimeType(Utilities.highBoundaryForTime(base.primitiveValue(), precision == 0 ? 9 : precision))); result.add(new TimeType(Utilities.highBoundaryForTime(base.primitiveValue(), precision == null ? 9 : precision)));
} else if (base.hasType("Quantity")) { } else if (base.hasType("Quantity")) {
String value = getNamedValue(base, "value"); String value = getNamedValue(base, "value");
Base v = base.copy(); Base v = base.copy();
v.setProperty("value", new DecimalType(Utilities.highBoundaryForDecimal(value, precision == 0 ? 8 : precision))); v.setProperty("value", new DecimalType(Utilities.highBoundaryForDecimal(value, precision == null ? 8 : precision)));
result.add(v); result.add(v);
} else { } else {
makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "decimal or date");
"decimal or date");
} }
return result; return result;
} }
private List<Base> funcPrecision(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcPrecision(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
if (focus.size() != 1) { if (focus.size() != 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size());

View File

@ -3660,23 +3660,22 @@ public class FHIRPathEngine {
case LowBoundary: case LowBoundary:
case HighBoundary: { case HighBoundary: {
checkContextContinuous(focus, exp.getFunction().toCode(), exp); checkContextContinuous(focus, exp.getFunction().toCode(), exp, true);
if (paramTypes.size() > 0) { if (paramTypes.size() > 0) {
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, checkParamTypes(exp, exp.getFunction().toCode(), paramTypes,
new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer)); new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer));
} }
if (focus.hasType("decimal") if ((focus.hasType("date") || focus.hasType("datetime") || focus.hasType("instant"))) {
&& (focus.hasType("date") || focus.hasType("datetime") || focus.hasType("instant"))) { return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal, TypeDetails.FP_DateTime);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal, TypeDetails.FP_DateTime); } else if (focus.hasType("decimal") || focus.hasType("integer")) {
} else if (focus.hasType("decimal")) { return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Decimal);
} else { } else {
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_DateTime); return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_DateTime);
} }
} }
case Precision: { case Precision: {
checkContextContinuous(focus, exp.getFunction().toCode(), exp); checkContextContinuous(focus, exp.getFunction().toCode(), exp, false);
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer); return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer);
} }
case Custom: { case Custom: {
@ -3780,9 +3779,8 @@ public class FHIRPathEngine {
} }
} }
private void checkContextContinuous(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException { private void checkContextContinuous(TypeDetails focus, String name, ExpressionNode expr, boolean allowInteger) throws PathEngineException {
if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") && !focus.hasType("time") && !focus.hasType("Quantity") && !(allowInteger && focus.hasType("integer"))) {
&& !focus.hasType("time") && !focus.hasType("Quantity")) {
throw makeException(expr, I18nConstants.FHIRPATH_CONTINUOUS_ONLY, name, focus.describe()); throw makeException(expr, I18nConstants.FHIRPATH_CONTINUOUS_ONLY, name, focus.describe());
} }
} }
@ -4233,42 +4231,43 @@ public class FHIRPathEngine {
if (focus.size() > 1) { if (focus.size() > 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "lowBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "lowBoundary", focus.size());
} }
int precision = 0; Integer precision = null;
if (expr.getParameters().size() > 0) { if (expr.getParameters().size() > 0) {
List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true); List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true);
if (n1.size() != 1) { if (n1.size() != 1) {
throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", "integer");
"integer");
} }
precision = Integer.parseInt(n1.get(0).primitiveValue()); precision = Integer.parseInt(n1.get(0).primitiveValue());
} }
Base base = focus.get(0); Base base = focus.get(0);
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
if (base.hasType("decimal")) { if (base.hasType("decimal")) {
result if (precision == null || (precision >= 0 && precision < 17)) {
.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == 0 ? 8 : precision))); result.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("integer")) {
if (precision == null || (precision >= 0 && precision < 17)) {
result.add(new DecimalType(Utilities.lowBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("date")) { } else if (base.hasType("date")) {
result result.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == null ? 10 : precision)));
.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == 0 ? 10 : precision)));
} else if (base.hasType("dateTime")) { } else if (base.hasType("dateTime")) {
result result.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == null ? 17 : precision)));
.add(new DateTimeType(Utilities.lowBoundaryForDate(base.primitiveValue(), precision == 0 ? 17 : precision)));
} else if (base.hasType("time")) { } else if (base.hasType("time")) {
result.add(new TimeType(Utilities.lowBoundaryForTime(base.primitiveValue(), precision == 0 ? 9 : precision))); result.add(new TimeType(Utilities.lowBoundaryForTime(base.primitiveValue(), precision == null ? 9 : precision)));
} else if (base.hasType("Quantity")) { } else if (base.hasType("Quantity")) {
String value = getNamedValue(base, "value"); String value = getNamedValue(base, "value");
Base v = base.copy(); Base v = base.copy();
v.setProperty("value", new DecimalType(Utilities.lowBoundaryForDecimal(value, precision == 0 ? 8 : precision))); v.setProperty("value", new DecimalType(Utilities.lowBoundaryForDecimal(value, precision == null ? 8 : precision)));
result.add(v); result.add(v);
} else { } else {
makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "decimal or date");
"decimal or date");
} }
return result; return result;
} }
private List<Base> funcHighBoundary(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcHighBoundary(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
if (focus.size() == 0) { if (focus.size() == 0) {
return makeNull(); return makeNull();
@ -4276,41 +4275,43 @@ public class FHIRPathEngine {
if (focus.size() > 1) { if (focus.size() > 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size());
} }
int precision = 0; Integer precision = null;
if (expr.getParameters().size() > 0) { if (expr.getParameters().size() > 0) {
List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true); List<Base> n1 = execute(context, focus, expr.getParameters().get(0), true);
if (n1.size() != 1) { if (n1.size() != 1) {
throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", throw makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "lowBoundary", "0", "Multiple Values", "integer");
"integer");
} }
precision = Integer.parseInt(n1.get(0).primitiveValue()); precision = Integer.parseInt(n1.get(0).primitiveValue());
} }
Base base = focus.get(0); Base base = focus.get(0);
List<Base> result = new ArrayList<Base>(); List<Base> result = new ArrayList<Base>();
if (base.hasType("decimal")) { if (base.hasType("decimal")) {
result.add( if (precision == null || (precision >= 0 && precision < 17)) {
new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == 0 ? 8 : precision))); result.add(new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("integer")) {
if (precision == null || (precision >= 0 && precision < 17)) {
result.add(new DecimalType(Utilities.highBoundaryForDecimal(base.primitiveValue(), precision == null ? 8 : precision)));
}
} else if (base.hasType("date")) { } else if (base.hasType("date")) {
result result.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == null ? 10 : precision)));
.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == 0 ? 10 : precision)));
} else if (base.hasType("dateTime")) { } else if (base.hasType("dateTime")) {
result result.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == null ? 17 : precision)));
.add(new DateTimeType(Utilities.highBoundaryForDate(base.primitiveValue(), precision == 0 ? 17 : precision)));
} else if (base.hasType("time")) { } else if (base.hasType("time")) {
result.add(new TimeType(Utilities.highBoundaryForTime(base.primitiveValue(), precision == 0 ? 9 : precision))); result.add(new TimeType(Utilities.highBoundaryForTime(base.primitiveValue(), precision == null ? 9 : precision)));
} else if (base.hasType("Quantity")) { } else if (base.hasType("Quantity")) {
String value = getNamedValue(base, "value"); String value = getNamedValue(base, "value");
Base v = base.copy(); Base v = base.copy();
v.setProperty("value", new DecimalType(Utilities.highBoundaryForDecimal(value, precision == 0 ? 8 : precision))); v.setProperty("value", new DecimalType(Utilities.highBoundaryForDecimal(value, precision == null ? 8 : precision)));
result.add(v); result.add(v);
} else { } else {
makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), makeException(expr, I18nConstants.FHIRPATH_WRONG_PARAM_TYPE, "sqrt", "(focus)", base.fhirType(), "decimal or date");
"decimal or date");
} }
return result; return result;
} }
private List<Base> funcPrecision(ExecutionContext context, List<Base> focus, ExpressionNode expr) { private List<Base> funcPrecision(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
if (focus.size() != 1) { if (focus.size() != 1) {
throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size()); throw makeExceptionPlural(focus.size(), expr, I18nConstants.FHIRPATH_FOCUS, "highBoundary", focus.size());