FHIRPath fixes (string handling)
This commit is contained in:
parent
816f1832d5
commit
7e8cace0fb
|
@ -2903,6 +2903,8 @@ public class FHIRPathEngine {
|
|||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Quantity);
|
||||
} else if (constant instanceof FHIRConstant) {
|
||||
return resolveConstantType(context, ((FHIRConstant) constant).getValue(), expr);
|
||||
} else if (constant == null) {
|
||||
return new TypeDetails(CollectionStatus.SINGLETON);
|
||||
} else {
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
|
@ -3140,60 +3142,60 @@ public class FHIRPathEngine {
|
|||
return types;
|
||||
}
|
||||
case Lower : {
|
||||
checkContextString(focus, "lower", exp);
|
||||
checkContextString(focus, "lower", exp, true);
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
case Upper : {
|
||||
checkContextString(focus, "upper", exp);
|
||||
checkContextString(focus, "upper", exp, true);
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
case ToChars : {
|
||||
checkContextString(focus, "toChars", exp);
|
||||
checkContextString(focus, "toChars", exp, true);
|
||||
return new TypeDetails(CollectionStatus.ORDERED, TypeDetails.FP_String);
|
||||
}
|
||||
case IndexOf : {
|
||||
checkContextString(focus, "indexOf", exp);
|
||||
checkContextString(focus, "indexOf", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer);
|
||||
}
|
||||
case Substring : {
|
||||
checkContextString(focus, "subString", exp);
|
||||
checkContextString(focus, "subString", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer), new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Integer));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
case StartsWith : {
|
||||
checkContextString(focus, "startsWith", exp);
|
||||
checkContextString(focus, "startsWith", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case EndsWith : {
|
||||
checkContextString(focus, "endsWith", exp);
|
||||
checkContextString(focus, "endsWith", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case Matches : {
|
||||
checkContextString(focus, "matches", exp);
|
||||
checkContextString(focus, "matches", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case MatchesFull : {
|
||||
checkContextString(focus, "matches", exp);
|
||||
checkContextString(focus, "matches", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case ReplaceMatches : {
|
||||
checkContextString(focus, "replaceMatches", exp);
|
||||
checkContextString(focus, "replaceMatches", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String), new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
case Contains : {
|
||||
checkContextString(focus, "contains", exp);
|
||||
checkContextString(focus, "contains", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_Boolean);
|
||||
}
|
||||
case Replace : {
|
||||
checkContextString(focus, "replace", exp);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, "string"), new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
checkContextString(focus, "replace", exp, true);
|
||||
checkParamTypes(exp, exp.getFunction().toCode(), paramTypes, new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String), new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String));
|
||||
return new TypeDetails(CollectionStatus.SINGLETON, TypeDetails.FP_String);
|
||||
}
|
||||
case Length : {
|
||||
|
@ -3427,37 +3429,39 @@ public class FHIRPathEngine {
|
|||
}
|
||||
|
||||
|
||||
private void checkContextString(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException {
|
||||
if (!focus.hasType(worker, "string") && !focus.hasType(worker, "code") && !focus.hasType(worker, "uri") && !focus.hasType(worker, "canonical") && !focus.hasType(worker, "id")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_STRING_ONLY, name, focus.describe());
|
||||
private void checkContextString(TypeDetails focus, String name, ExpressionNode expr, boolean sing) throws PathEngineException {
|
||||
if (!focus.hasNoTypes() && !focus.hasType(worker, "string") && !focus.hasType(worker, "code") && !focus.hasType(worker, "uri") && !focus.hasType(worker, "canonical") && !focus.hasType(worker, "id")) {
|
||||
throw makeException(expr, sing ? I18nConstants.FHIRPATH_STRING_SING_ONLY : I18nConstants.FHIRPATH_STRING_ORD_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkContextPrimitive(TypeDetails focus, String name, boolean canQty, ExpressionNode expr) throws PathEngineException {
|
||||
if (canQty) {
|
||||
if (!focus.hasType(primitiveTypes) && !focus.hasType("Quantity")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_PRIMITIVE_ONLY, name, focus.describe(), "Quantity, "+primitiveTypes.toString());
|
||||
if (!focus.hasNoTypes()) {
|
||||
if (canQty) {
|
||||
if (!focus.hasType(primitiveTypes) && !focus.hasType("Quantity")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_PRIMITIVE_ONLY, name, focus.describe(), "Quantity, "+primitiveTypes.toString());
|
||||
}
|
||||
} else if (!focus.hasType(primitiveTypes)) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_PRIMITIVE_ONLY, name, focus.describe(), primitiveTypes.toString());
|
||||
}
|
||||
} else if (!focus.hasType(primitiveTypes)) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_PRIMITIVE_ONLY, name, focus.describe(), primitiveTypes.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkContextNumerical(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException {
|
||||
if (!focus.hasType("integer") && !focus.hasType("decimal") && !focus.hasType("Quantity")) {
|
||||
if (!focus.hasNoTypes() && !focus.hasType("integer") && !focus.hasType("decimal") && !focus.hasType("Quantity")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_NUMERICAL_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkContextDecimal(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException {
|
||||
if (!focus.hasType("decimal") && !focus.hasType("integer")) {
|
||||
if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("integer")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_DECIMAL_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
||||
private void checkContextContinuous(TypeDetails focus, String name, ExpressionNode expr) throws PathEngineException {
|
||||
if (!focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") && !focus.hasType("time")) {
|
||||
if (!focus.hasNoTypes() && !focus.hasType("decimal") && !focus.hasType("date") && !focus.hasType("dateTime") && !focus.hasType("time")) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_CONTINUOUS_ONLY, name, focus.describe());
|
||||
}
|
||||
}
|
||||
|
@ -3672,7 +3676,10 @@ public class FHIRPathEngine {
|
|||
|
||||
|
||||
private List<Base> funcExp(ExecutionContext context, List<Base> focus, ExpressionNode expr) {
|
||||
if (focus.size() != 1) {
|
||||
if (focus.size() == 0) {
|
||||
return new ArrayList<Base>();
|
||||
}
|
||||
if (focus.size() > 1) {
|
||||
throw makeException(expr, I18nConstants.FHIRPATH_FOCUS_PLURAL, "exp", focus.size());
|
||||
}
|
||||
Base base = focus.get(0);
|
||||
|
@ -4218,15 +4225,19 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcReplace(ExecutionContext context, List<Base> focus, ExpressionNode expr) throws FHIRException, PathEngineException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
List<Base> tB = execute(context, focus, expr.getParameters().get(0), true);
|
||||
String t = convertToString(tB);
|
||||
List<Base> rB = execute(context, focus, expr.getParameters().get(1), true);
|
||||
String r = convertToString(rB);
|
||||
|
||||
if (focus.size() == 1) {
|
||||
if (focus.size() == 0 || tB.size() == 0 || rB.size() == 0) {
|
||||
//
|
||||
} else if (focus.size() == 1) {
|
||||
if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
String f = convertToString(focus.get(0));
|
||||
if (Utilities.noString(f)) {
|
||||
result.add(new StringType(""));
|
||||
} else {
|
||||
String t = convertToString(execute(context, focus, expr.getParameters().get(0), true));
|
||||
String r = convertToString(execute(context, focus, expr.getParameters().get(1), true));
|
||||
String n = f.replace(t, r);
|
||||
result.add(new StringType(n));
|
||||
}
|
||||
|
@ -4240,10 +4251,14 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcReplaceMatches(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String regex = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
String repl = convertToString(execute(context, focus, exp.getParameters().get(1), true));
|
||||
List<Base> regexB = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String regex = convertToString(regexB);
|
||||
List<Base> replB = execute(context, focus, exp.getParameters().get(1), true);
|
||||
String repl = convertToString(replB);
|
||||
|
||||
if (focus.size() == 1 && !Utilities.noString(regex)) {
|
||||
if (focus.size() == 0 || regexB.size() == 0 || replB.size() == 0) {
|
||||
//
|
||||
} else if (focus.size() == 1 && !Utilities.noString(regex)) {
|
||||
if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
result.add(new StringType(convertToString(focus.get(0)).replaceAll(regex, repl)).noExtensions());
|
||||
}
|
||||
|
@ -4256,10 +4271,13 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcEndsWith(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
List<Base> swb = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String sw = convertToString(swb);
|
||||
|
||||
if (focus.size() == 0) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
//
|
||||
} else if (swb.size() == 0) {
|
||||
//
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
|
@ -4929,9 +4947,12 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcMatches(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
List<Base> swb = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String sw = convertToString(swb);
|
||||
|
||||
if (focus.size() == 1 && !Utilities.noString(sw)) {
|
||||
if (focus.size() == 0 || swb.size() == 0) {
|
||||
//
|
||||
} else if (focus.size() == 1 && !Utilities.noString(sw)) {
|
||||
if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
String st = convertToString(focus.get(0));
|
||||
if (Utilities.noString(st)) {
|
||||
|
@ -4973,10 +4994,13 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcContains(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, baseToList(context.thisItem), exp.getParameters().get(0), true));
|
||||
List<Base> swb = execute(context, baseToList(context.thisItem), exp.getParameters().get(0), true);
|
||||
String sw = convertToString(swb);
|
||||
|
||||
if (focus.size() != 1) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
//
|
||||
} else if (swb.size() != 1) {
|
||||
//
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
|
@ -5018,10 +5042,13 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcStartsWith(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
List<Base> swb = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String sw = convertToString(swb);
|
||||
|
||||
if (focus.size() == 0) {
|
||||
result.add(new BooleanType(false).noExtensions());
|
||||
// no result
|
||||
} else if (swb.size() == 0) {
|
||||
// no result
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new BooleanType(true).noExtensions());
|
||||
} else if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
|
@ -5071,9 +5098,12 @@ public class FHIRPathEngine {
|
|||
private List<Base> funcIndexOf(ExecutionContext context, List<Base> focus, ExpressionNode exp) throws FHIRException {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
|
||||
String sw = convertToString(execute(context, focus, exp.getParameters().get(0), true));
|
||||
List<Base> swb = execute(context, focus, exp.getParameters().get(0), true);
|
||||
String sw = convertToString(swb);
|
||||
if (focus.size() == 0) {
|
||||
result.add(new IntegerType(0).noExtensions());
|
||||
// no result
|
||||
} else if (swb.size() == 0) {
|
||||
// no result
|
||||
} else if (Utilities.noString(sw)) {
|
||||
result.add(new IntegerType(0).noExtensions());
|
||||
} else if (focus.get(0).hasType(FHIR_TYPES_STRING) || doImplicitStringConversion) {
|
||||
|
|
Loading…
Reference in New Issue