Allow target to be treated as source when validating FML

This commit is contained in:
Grahame Grieve 2023-06-29 13:18:01 +10:00
parent 236cf06946
commit bb66eccf45
4 changed files with 83 additions and 9 deletions

View File

@ -821,6 +821,7 @@ public class I18nConstants {
public static final String SM_TARGET_TRANSFORM_EXPRESSION_ERROR = "SM_TARGET_TRANSFORM_EXPRESSION_ERROR";
public static final String SM_IMPORT_NOT_FOUND = "SM_IMPORT_NOT_FOUND";
public static final String SM_TARGET_TYPE_MULTIPLE_POSSIBLE = "SM_TARGET_TYPE_MULTIPLE_POSSIBLE";
public static final String SM_TARGET_TRANSFORM_TYPE_UNKNOWN = "SM_TARGET_TRANSFORM_TYPE_UNKNOWN";
public static final String SM_DEPENDENT_PARAM_NOT_FOUND = "SM_DEPENDENT_PARAM_NOT_FOUND";
public static final String SM_DEPENDENT_PARAM_MODE_MISMATCH = "SM_DEPENDENT_PARAM_MODE_MISMATCH";
public static final String SM_DEPENDENT_PARAM_TYPE_MISMATCH = "SM_DEPENDENT_PARAM_TYPE_MISMATCH";
@ -915,6 +916,7 @@ public class I18nConstants {
public static final String ED_INVARIANT_NO_EXPRESSION = "ED_INVARIANT_NO_EXPRESSION";
public static final String ED_INVARIANT_EXPRESSION_CONFLICT = "ED_INVARIANT_EXPRESSION_CONFLICT";
public static final String ED_INVARIANT_EXPRESSION_ERROR = "ED_INVARIANT_EXPRESSION_ERROR";
public static final String SNAPSHOT_IS_EMPTY = "SNAPSHOT_IS_EMPTY";
}

View File

@ -186,7 +186,7 @@ Terminology_TX_System_Relative = Coding.system must be an absolute reference, no
Terminology_TX_System_Unknown = Unknown Code System ''{0}''
Terminology_TX_System_ValueSet = Invalid System URI: {0} - cannot use a value set URI as a system
Terminology_TX_System_ValueSet2 = The Coding references a value set, not a code system (''{0}'')
Terminology_TX_ValueSet_NotFound = ValueSet {0} not found by validator
Terminology_TX_ValueSet_NotFound = ValueSet {0} not found
Terminology_TX_ValueSet_NotFound_CS = Found a reference to a CodeSystem ({0}) where a ValueSet belongs
Type_Specific_Checks_DT_Base64_Valid = The value ''{0}'' is not a valid Base64 value
Type_Specific_Checks_DT_Boolean_Value = Boolean values must be ''true'' or ''false''
@ -848,9 +848,9 @@ SM_NAME_INVALID = The name {0} is not valid
SM_GROUP_NAME_DUPLICATE = The Group name ''{0}'' is already used
SM_GROUP_INPUT_DUPLICATE = The name {0} is already used
SM_GROUP_INPUT_MODE_INVALID = The group parameter {0} mode {1} isn''t valid
SM_GROUP_INPUT_NO_TYPE = The group parameter {0} has no type, so the paths cannot be validated
SM_GROUP_INPUT_NO_TYPE = Group {1} parameter {0} has no type, so the paths cannot be validated
SM_GROUP_INPUT_TYPE_NOT_DECLARED = The type {0} is not declared and is unknown
SM_GROUP_INPUT_MODE_MISMATCH = The type {0} has mode {1} which doesn''t match the structure definition {2}
SM_GROUP_INPUT_MODE_MISMATCH = The type ''{0}'' has mode ''{1}'' which doesn''t match the structure definition mode of ''{2}''
SM_GROUP_INPUT_TYPE_UNKNOWN_STRUCTURE = The type {0} which maps to the canonical URL {1} is not known, so the paths cannot be validated
SM_GROUP_INPUT_TYPE_UNKNOWN_TYPE = The type {0} is not known, so the paths cannot be validated
SM_SOURCE_CONTEXT_UNKNOWN = The source context {0} is not known at this point
@ -875,6 +875,7 @@ SM_TARGET_TRANSFORM_PARAM_UNPROCESSIBLE = The parameter at index {0} could not b
SM_TARGET_TRANSFORM_EXPRESSION_ERROR = The FHIRPath expression passed as the evaluate parameter is invalid: {0}
SM_IMPORT_NOT_FOUND = No maps were found to match {0} - validation may be wrong
SM_TARGET_TYPE_MULTIPLE_POSSIBLE = Multiple types are possible here ({0}) so further type checking is not possible
SM_TARGET_TRANSFORM_TYPE_UNKNOWN = The type ''{0}'' is not known
SM_DEPENDENT_PARAM_MODE_MISMATCH = The parameter {0} refers to the variable {1} but it''s mode is {2} which is not the same as the mode required for the group {3}
SM_DEPENDENT_PARAM_NOT_FOUND = The {1} parameter ''{0}'' was not found
SM_DEPENDENT_PARAM_TYPE_MISMATCH = The parameter ''{0}'' refers to the variable ''{1}'' but it''s type is ''{2}'' which is not compatible with the type required for the group ''{3}'', which is ''{4}'' (from map ''{5}'')
@ -969,4 +970,4 @@ ED_INVARIANT_NO_KEY = The invariant has no key, so the content cannot be validat
ED_INVARIANT_NO_EXPRESSION = The invariant ''{0}'' has no computable expression, so validators will not be able to check it
ED_INVARIANT_EXPRESSION_CONFLICT = The invariant ''{0}'' has an expression ''{1}'', which differs from the earlier expression provided of ''{2}'' (invariants are allowed to repeat, but cannot differ)
ED_INVARIANT_EXPRESSION_ERROR = Error in invariant ''{0}'' with expression ''{1}'': {2}
SNAPSHOT_IS_EMPTY = The snapshot for the profile ''{0}'' is empty (which should not happen)

View File

@ -470,14 +470,20 @@ public class StructureMapValidator extends BaseValidator {
private boolean validateInput(List<ValidationMessage> errors, Element src, Element group, Element input, NodeStack stack, List<Element> structures, VariableSet variables, VariableSet pvars) {
boolean ok = false;
String gname = group.getChildValue("name");
String name = input.getChildValue("name");
String mode = input.getChildValue("mode");
String type = input.getChildValue("type");
VariableDefn pv = null;
if (type == null && pvars != null) {
pv = pvars.getVariable(name, mode.equals("source"));
pv = pvars.getVariable(name, mode.equals("source"));
if (pv != null) {
type = pv.getWorkingType();
} else {
pv = pvars.getVariable(name, mode.equals("target")); // target can become source
if (pv != null) {
type = pv.getWorkingType();
}
}
}
@ -485,7 +491,7 @@ public class StructureMapValidator extends BaseValidator {
rule(errors, "2023-03-01", IssueType.DUPLICATE, input.line(), input.col(), stack.getLiteralPath(), !variables.hasVariable(name), I18nConstants.SM_GROUP_INPUT_DUPLICATE, name)) { // the name {0} is not valid)
VariableDefn v = variables.add(name, mode);
if (rule(errors, "2023-03-01", IssueType.INVALID, input.line(), input.col(), stack.getLiteralPath(), Utilities.existsInList(mode, "source", "target"), I18nConstants.SM_GROUP_INPUT_MODE_INVALID, name, mode) && // the group parameter {0} mode {1} isn't valid
warning(errors, "2023-03-01", IssueType.NOTSUPPORTED, input.line(), input.col(), stack.getLiteralPath(), type != null, I18nConstants.SM_GROUP_INPUT_NO_TYPE, name)) { // the group parameter {0} has no type, so the paths cannot be validated
warning(errors, "2023-03-01", IssueType.NOTSUPPORTED, input.line(), input.col(), stack.getLiteralPath(), type != null, I18nConstants.SM_GROUP_INPUT_NO_TYPE, name, gname)) { // the group parameter {0} has no type, so the paths cannot be validated
String smode = null;
StructureDefinition sd = null;
ElementDefinition ed = null;
@ -514,7 +520,7 @@ public class StructureMapValidator extends BaseValidator {
ed = sd.getSnapshot().getElementFirstRep();
}
}
if (rule(errors, "2023-03-01", IssueType.NOTSUPPORTED, input.line(), input.col(), stack.getLiteralPath(), smode == null || mode.equals(smode), I18nConstants.SM_GROUP_INPUT_MODE_MISMATCH, type, mode, smode)) { // the type {0} has mode {1} which doesn't match the structure definition {2}
if (rule(errors, "2023-03-01", IssueType.NOTSUPPORTED, input.line(), input.col(), stack.getLiteralPath(), smode == null || mode.equals(smode) || (smode.equals("target") && mode.equals("source")), I18nConstants.SM_GROUP_INPUT_MODE_MISMATCH, type, mode, smode)) { // the type {0} has mode {1} which doesn't match the structure definition {2}
v.setType(1, sd, ed, null);
ok = true;
}
@ -840,7 +846,16 @@ public class StructureMapValidator extends BaseValidator {
// it's just a warning: maybe this'll work out at run time?
warning(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), type != null, I18nConstants.SM_TARGET_TYPE_MULTIPLE_POSSIBLE, el.getEd().typeSummary());
vn.setType(ruleInfo.getMaxCount(), el.getSd(), el.getEd(), type); // may overwrite
if (ProfileUtilities.isResourceBoundary(el.getEd()) && type != null) {
StructureDefinition sdt = this.context.fetchTypeDefinition(type);
if (rule(errors, "2023-03-01", IssueType.INVALID, target.line(), target.col(), stack.getLiteralPath(), sdt != null, I18nConstants.SM_TARGET_TRANSFORM_TYPE_UNKNOWN, type)) {
vn.setType(ruleInfo.getMaxCount(), sdt, sdt.getSnapshot().getElementFirstRep(), null); // may overwrite
} else {
vn.setType(ruleInfo.getMaxCount(), el.getSd(), el.getEd(), type); // may overwrite
}
} else {
vn.setType(ruleInfo.getMaxCount(), el.getSd(), el.getEd(), type); // may overwrite
}
}
}
@ -1143,8 +1158,13 @@ public class StructureMapValidator extends BaseValidator {
String iType = resolveType(grp, input, src);
String pname = input.getName();
VariableDefn v = getParameter(errors, param, pstack, variables, input.getMode());
if (v == null && input.getMode() == StructureMapInputMode.SOURCE) {
// target can transition to the source
v = getParameter(errors, param, pstack, variables, StructureMapInputMode.TARGET);
}
if (rule(errors, "2023-06-27", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), v != null, I18nConstants.SM_DEPENDENT_PARAM_NOT_FOUND, pname, input.getMode().toCode())) {
if (rule(errors, "2023-03-01", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), v.mode.equals(input.getMode().toCode()), I18nConstants.SM_DEPENDENT_PARAM_MODE_MISMATCH, param.getChildValue("name"), v.mode, input.getMode().toCode(), grp.getTargetGroup().getName()) &&
if (rule(errors, "2023-03-01", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(),
v.mode.equals(input.getMode().toCode()) || (v.mode.equals("target") && input.getMode() == StructureMapInputMode.SOURCE), I18nConstants.SM_DEPENDENT_PARAM_MODE_MISMATCH, param.getChildValue("name"), v.mode, input.getMode().toCode(), grp.getTargetGroup().getName()) &&
rule(errors, "2023-03-01", IssueType.INVALID, param.line(), param.col(), pstack.getLiteralPath(), typesMatch(v, iType), I18nConstants.SM_DEPENDENT_PARAM_TYPE_MISMATCH,
pname, v.summary(), input.getType(), grp.getTargetGroup().getName(), input.getType(), grp.getTargetMap() == null ? "$this" : grp.getTargetMap().getVersionedUrl())) {
lvars.add(pname, v);

View File

@ -2221,3 +2221,54 @@ v: {
"class" : "UNKNOWN"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "371525003"
}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode--0", "version": "2.0.10-cibuild", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"severity" : "error",
"error" : "The provided code http://snomed.info/sct#371525003 is not in the value set 'http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode--0|2.0.10-cibuild' (from Tx-Server)",
"class" : "UNKNOWN"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "371525003"
}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode--1", "version": "2.0.10-cibuild", "langs":"[en]", "useServer":"true", "useClient":"false", "guessSystem":"false", "valueSetMode":"CHECK_MEMERSHIP_ONLY", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Clinical procedure report (record artifact)",
"code" : "371525003",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/2011000195101/version/20230607"
}
-------------------------------------------------------------------------------------
{"code" : {
"system" : "http://snomed.info/sct",
"code" : "371525003",
"display" : "Clinical procedure report"
}, "url": "http://fhir.ch/ig/ch-epr-term/ValueSet/DocumentEntry.classCode", "version": "2.0.10-cibuild", "langs":"[en]", "useServer":"true", "useClient":"true", "guessSystem":"false", "valueSetMode":"NO_MEMBERSHIP_CHECK", "displayWarningMode":"false", "versionFlexible":"false", "profile": {
"resourceType" : "Parameters",
"parameter" : [{
"name" : "profile-url",
"valueString" : "http://hl7.org/fhir/ExpansionProfile/dc8fd4bc-091a-424a-8a3b-6198ef146891"
}]
}}####
v: {
"display" : "Clinical procedure report",
"code" : "371525003",
"system" : "http://snomed.info/sct",
"version" : "http://snomed.info/sct/900000000000207008/version/20230131"
}
-------------------------------------------------------------------------------------