support create object syntax in FML when valdiating FML

This commit is contained in:
Grahame Grieve 2024-07-01 06:29:41 +09:30
parent 8ba3d0e3c5
commit 36c3745c76
2 changed files with 63 additions and 2 deletions

View File

@ -208,6 +208,8 @@ public class IgLoader implements IValidationEngineLoader {
res.setFocus(t.getValue()); res.setFocus(t.getValue());
if (t.getKey().endsWith(".json")) if (t.getKey().endsWith(".json"))
res.setCntType(Manager.FhirFormat.JSON); res.setCntType(Manager.FhirFormat.JSON);
else if (t.getKey().endsWith(".ndjson"))
res.setCntType(Manager.FhirFormat.NDJSON);
else if (t.getKey().endsWith(".xml")) else if (t.getKey().endsWith(".xml"))
res.setCntType(Manager.FhirFormat.XML); res.setCntType(Manager.FhirFormat.XML);
else if (t.getKey().endsWith(".ttl")) else if (t.getKey().endsWith(".ttl"))

View File

@ -33,6 +33,7 @@ import org.hl7.fhir.r5.utils.structuremap.ResolvedGroup;
import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities; import org.hl7.fhir.r5.utils.structuremap.StructureMapUtilities;
import org.hl7.fhir.r5.utils.validation.IResourceValidator; import org.hl7.fhir.r5.utils.validation.IResourceValidator;
import org.hl7.fhir.utilities.CommaSeparatedStringBuilder; import org.hl7.fhir.utilities.CommaSeparatedStringBuilder;
import org.hl7.fhir.utilities.DebugUtilities;
import org.hl7.fhir.utilities.Utilities; import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.utilities.VersionUtilities; import org.hl7.fhir.utilities.VersionUtilities;
import org.hl7.fhir.utilities.i18n.I18nConstants; import org.hl7.fhir.utilities.i18n.I18nConstants;
@ -558,8 +559,12 @@ public class StructureMapValidator extends BaseValidator {
private boolean validateRule(List<ValidationMessage> errors, Element src, Element group, Element rule, NodeStack stack, VariableSet variables) { private boolean validateRule(List<ValidationMessage> errors, Element src, Element group, Element rule, NodeStack stack, VariableSet variables) {
String name = rule.getChildValue("name"); String name = rule.getChildValue("name");
if (name.equals("SetComposition")) {
DebugUtilities.breakpoint();
}
boolean ok = rule(errors, "2023-03-01", IssueType.INVALID, rule.line(), rule.col(), stack.getLiteralPath(), idIsValid(name), I18nConstants.SM_NAME_INVALID, name); boolean ok = rule(errors, "2023-03-01", IssueType.INVALID, rule.line(), rule.col(), stack.getLiteralPath(), idIsValid(name), I18nConstants.SM_NAME_INVALID, name);
DebugUtilities.ln(name+": "+variables.summary());
RuleInformation ruleInfo = new RuleInformation(); RuleInformation ruleInfo = new RuleInformation();
// process the sources // process the sources
VariableSet lvars = variables.copy(); VariableSet lvars = variables.copy();
@ -691,7 +696,61 @@ public class StructureMapValidator extends BaseValidator {
private boolean validateRuleTarget(List<ValidationMessage> errors, Element src, Element group, Element rule, Element target, NodeStack stack, VariableSet variables, RuleInformation ruleInfo) { private boolean validateRuleTarget(List<ValidationMessage> errors, Element src, Element group, Element rule, Element target, NodeStack stack, VariableSet variables, RuleInformation ruleInfo) {
String context = target.getChildValue("context"); String context = target.getChildValue("context");
if (context == null) { if (context == null) {
return true; // this would be something like
// RNDSEntry -> create('Composition') as IPSComposition
boolean ok = true;
VariableDefn vn = null;
String variable = target.getChildValue("variable");
if (variable != null) {
if (rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), idIsValid(variable), I18nConstants.SM_NAME_INVALID, variable)) {
vn = variables.add(variable, "target"); // may overwrite
} else {
ok = false;
}
}
String transform = target.getChildValue("transform");
List<Element> params = target.getChildren("parameter");
String type = null;
switch (transform) {
case "create":
if (rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), params.size() < 2, I18nConstants.SM_TARGET_TRANSFORM_PARAM_COUNT_RANGE, "create", "0", "1", params.size())) {
if (params.size() == 1) {
type = params.get(0).getChildValue("value");
// type can be a url, a native type, or an alias
if (!Utilities.isAbsoluteUrl(type)) {
type = resolveType(type, "target", src);
if (!Utilities.isAbsoluteUrl(type)) {
StructureDefinition sdt = this.context.fetchTypeDefinition(type);
if (sdt != null) {
type = sdt.getType();
}
}
}
warning(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(),type != null, I18nConstants.SM_TARGET_TRANSFORM_TYPE_UNPROCESSIBLE, "create");
} else {
// maybe can guess? maybe not ... type =
}
} else {
ok = false;
}
break;
case "uuid" :
ok = rule(errors, "2023-05-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), params.size() == 0, I18nConstants.SM_TARGET_TRANSFORM_MISSING_PARAMS, transform) && ok;
type = "string";
break;
default:
rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), false, I18nConstants.SM_TARGET_TRANSFORM_NOT_CHECKED, transform);
ok = false;
}
if (vn != null && type != null) {
StructureDefinition sdt = this.context.fetchTypeDefinition(type);
vn.setType(ruleInfo.getMaxCount(), sdt, sdt.getSnapshot().getElementFirstRep(), null); // may overwrite
}
return ok;
} }
boolean ok = rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), idIsValid(context), I18nConstants.SM_NAME_INVALID, context) && boolean ok = rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), idIsValid(context), I18nConstants.SM_NAME_INVALID, context) &&
rule(errors, "2023-03-01", IssueType.UNKNOWN, target.line(), target.col(), stack.getLiteralPath(), variables.hasVariable(context, TARGET), I18nConstants.SM_TARGET_CONTEXT_UNKNOWN, context); rule(errors, "2023-03-01", IssueType.UNKNOWN, target.line(), target.col(), stack.getLiteralPath(), variables.hasVariable(context, TARGET), I18nConstants.SM_TARGET_CONTEXT_UNKNOWN, context);
@ -805,7 +864,7 @@ public class StructureMapValidator extends BaseValidator {
case "append" : case "append" :
ok = rule(errors, "2023-05-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), params.size() > 0, I18nConstants.SM_TARGET_TRANSFORM_MISSING_PARAMS, transform) && ok; ok = rule(errors, "2023-05-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), params.size() > 0, I18nConstants.SM_TARGET_TRANSFORM_MISSING_PARAMS, transform) && ok;
for (int i = 0; i < params.size(); i++) { for (int i = 0; i < params.size(); i++) {
ok = checkParamExistsOrPrimitive(errors, params.get(1).getNamedChild("value", false), "cc", "parameter "+i, target, variables, stack, ok, false); ok = checkParamExistsOrPrimitive(errors, params.get(i).getNamedChild("value", false), "cc", "parameter "+i, target, variables, stack, ok, false);
} }
break; break;
case "uuid" : case "uuid" :