Merge pull request #1569 from hapifhir/2024-02-gg-pat-cont-resources
2024 02 gg pat cont resources
This commit is contained in:
commit
d5de8052f2
|
@ -18,6 +18,7 @@
|
||||||
* Fix where validator was ignoring minimum cardinality for XML attributes (especially in CDA)
|
* Fix where validator was ignoring minimum cardinality for XML attributes (especially in CDA)
|
||||||
* Improved ConceptMap validation
|
* Improved ConceptMap validation
|
||||||
* Updated IG versions used for -cda and -ccda CLI validation options.
|
* Updated IG versions used for -cda and -ccda CLI validation options.
|
||||||
|
* Change validator so that it marks value properties in primitive data types as illegal
|
||||||
|
|
||||||
## Other code changes
|
## Other code changes
|
||||||
|
|
||||||
|
@ -32,3 +33,8 @@
|
||||||
* Fix wrong URLs rendering Profiles and Questionnaires
|
* Fix wrong URLs rendering Profiles and Questionnaires
|
||||||
* Fix bug using wrong version constant for R3
|
* Fix bug using wrong version constant for R3
|
||||||
* Updates for R5 StructureMap syntax
|
* Updates for R5 StructureMap syntax
|
||||||
|
* Support for case sensitive Code system tests
|
||||||
|
* Add TurtleGeneratorTests for R5
|
||||||
|
* Introduce new validator cliContext option disableDefaultResourceFetcher (#1526)
|
||||||
|
* Render contained resources when rendering Patient resources
|
||||||
|
* Fix bug in FML Parser
|
||||||
|
|
|
@ -66,14 +66,14 @@ class Convertor_Factory_40_50Test {
|
||||||
StructureMapUtilities smu5 = new StructureMapUtilities(context, mock(org.hl7.fhir.r5.utils.structuremap.ITransformerServices.class));
|
StructureMapUtilities smu5 = new StructureMapUtilities(context, mock(org.hl7.fhir.r5.utils.structuremap.ITransformerServices.class));
|
||||||
org.hl7.fhir.r5.model.StructureMap mapR5 = smu5.parse(CONTENT, "map");
|
org.hl7.fhir.r5.model.StructureMap mapR5 = smu5.parse(CONTENT, "map");
|
||||||
|
|
||||||
assertEquals("tgt", mapR5.getGroup().get(0).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueIdType().getValue());
|
assertEquals("tgt", mapR5.getGroup().get(0).getRule().get(0).getTarget().get(0).getContext());
|
||||||
assertEquals("item.answer.valueString", mapR5.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
assertEquals("item.answer.valueString", mapR5.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
||||||
assertEquals("item", mapR5.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(0).getValueIdType().getValueAsString());
|
assertEquals("item", mapR5.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(0).getValueIdType().getValueAsString());
|
||||||
assertEquals("patient", mapR5.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(1).getValueIdType().getValueAsString());
|
assertEquals("patient", mapR5.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(1).getValueIdType().getValueAsString());
|
||||||
|
|
||||||
|
|
||||||
org.hl7.fhir.r4.model.StructureMap mapR4 = (org.hl7.fhir.r4.model.StructureMap) VersionConvertorFactory_40_50.convertResource(mapR5);
|
org.hl7.fhir.r4.model.StructureMap mapR4 = (org.hl7.fhir.r4.model.StructureMap) VersionConvertorFactory_40_50.convertResource(mapR5);
|
||||||
assertEquals("tgt", mapR4.getGroup().get(0).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueIdType().getValue());
|
assertEquals("tgt", mapR4.getGroup().get(0).getRule().get(0).getTarget().get(0).getContext());
|
||||||
assertEquals("item.answer.valueString", mapR4.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
assertEquals("item.answer.valueString", mapR4.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
||||||
assertEquals("item", mapR4.getGroup().get(0).getRule().get(0).getDependent().get(0).getVariable().get(0).getValueAsString());
|
assertEquals("item", mapR4.getGroup().get(0).getRule().get(0).getDependent().get(0).getVariable().get(0).getValueAsString());
|
||||||
assertEquals("patient", mapR4.getGroup().get(0).getRule().get(0).getDependent().get(0).getVariable().get(1).getValueAsString());
|
assertEquals("patient", mapR4.getGroup().get(0).getRule().get(0).getDependent().get(0).getVariable().get(1).getValueAsString());
|
||||||
|
@ -87,7 +87,7 @@ class Convertor_Factory_40_50Test {
|
||||||
|
|
||||||
|
|
||||||
StructureMap mapR5Back = (StructureMap) VersionConvertorFactory_40_50.convertResource(mapR4);
|
StructureMap mapR5Back = (StructureMap) VersionConvertorFactory_40_50.convertResource(mapR4);
|
||||||
assertEquals("tgt", mapR5Back.getGroup().get(0).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueIdType().getValue());
|
assertEquals("tgt", mapR5Back.getGroup().get(0).getRule().get(0).getTarget().get(0).getContext());
|
||||||
assertEquals("item.answer.valueString", mapR5Back.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
assertEquals("item.answer.valueString", mapR5Back.getGroup().get(1).getRule().get(0).getTarget().get(0).getParameter().get(0).getValueStringType().getValue());
|
||||||
assertEquals("item", mapR5Back.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(0).getValueIdType().getValueAsString());
|
assertEquals("item", mapR5Back.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(0).getValueIdType().getValueAsString());
|
||||||
assertEquals("patient", mapR5Back.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(1).getValueIdType().getValueAsString());
|
assertEquals("patient", mapR5Back.getGroup().get(0).getRule().get(0).getDependent().get(0).getParameter().get(1).getValueIdType().getValueAsString());
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.hl7.fhir.r5.renderers.utils.BaseWrappers.BaseWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.PropertyWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
import org.hl7.fhir.r5.renderers.utils.BaseWrappers.ResourceWrapper;
|
||||||
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
import org.hl7.fhir.r5.renderers.utils.RenderingContext;
|
||||||
|
import org.hl7.fhir.r5.utils.EOperationOutcome;
|
||||||
import org.hl7.fhir.utilities.TextFile;
|
import org.hl7.fhir.utilities.TextFile;
|
||||||
import org.hl7.fhir.utilities.Utilities;
|
import org.hl7.fhir.utilities.Utilities;
|
||||||
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
import org.hl7.fhir.utilities.xhtml.XhtmlNode;
|
||||||
|
@ -269,7 +270,7 @@ public class PatientRenderer extends ResourceRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean render(XhtmlNode x, ResourceWrapper r) throws FHIRFormatError, DefinitionException, IOException {
|
public boolean render(XhtmlNode x, ResourceWrapper r) throws IOException, FHIRException, EOperationOutcome {
|
||||||
// banner
|
// banner
|
||||||
describe(makeBanner(x.para()), r);
|
describe(makeBanner(x.para()), r);
|
||||||
x.hr();
|
x.hr();
|
||||||
|
@ -295,9 +296,22 @@ public class PatientRenderer extends ResourceRenderer {
|
||||||
if (tbl.isEmpty()) {
|
if (tbl.isEmpty()) {
|
||||||
x.remove(tbl);
|
x.remove(tbl);
|
||||||
}
|
}
|
||||||
|
if (r.has("contained") && context.isTechnicalMode()) {
|
||||||
|
x.hr();
|
||||||
|
x.para().b().tx("Contained Resources");
|
||||||
|
addContained(x, r.getContained());
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addContained(XhtmlNode x, List<ResourceWrapper> list) throws FHIRFormatError, DefinitionException, FHIRException, IOException, EOperationOutcome {
|
||||||
|
for (ResourceWrapper c : list) {
|
||||||
|
x.hr();
|
||||||
|
x.an(c.getId());
|
||||||
|
new RendererFactory().factory(c, context).render(x, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addExtensions(XhtmlNode tbl, ResourceWrapper r) throws UnsupportedEncodingException, FHIRException, IOException {
|
private void addExtensions(XhtmlNode tbl, ResourceWrapper r) throws UnsupportedEncodingException, FHIRException, IOException {
|
||||||
Map<String, List<Extension>> extensions = new HashMap<>();
|
Map<String, List<Extension>> extensions = new HashMap<>();
|
||||||
PropertyWrapper pw = getProperty(r, "extension");
|
PropertyWrapper pw = getProperty(r, "extension");
|
||||||
|
|
|
@ -1141,6 +1141,7 @@ public class StructureMapUtilities {
|
||||||
}
|
}
|
||||||
lexer.token(")");
|
lexer.token(")");
|
||||||
} else if (name != null) {
|
} else if (name != null) {
|
||||||
|
if (target.getContext() != null) {
|
||||||
target.setTransform(StructureMapTransform.COPY);
|
target.setTransform(StructureMapTransform.COPY);
|
||||||
if (!isConstant) {
|
if (!isConstant) {
|
||||||
String id = name;
|
String id = name;
|
||||||
|
@ -1150,6 +1151,9 @@ public class StructureMapUtilities {
|
||||||
target.addParameter().setValue(new IdType(id));
|
target.addParameter().setValue(new IdType(id));
|
||||||
} else
|
} else
|
||||||
target.addParameter().setValue(readConstant(name, lexer));
|
target.addParameter().setValue(readConstant(name, lexer));
|
||||||
|
} else {
|
||||||
|
target.setContext(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (lexer.hasToken("as")) {
|
if (lexer.hasToken("as")) {
|
||||||
lexer.take();
|
lexer.take();
|
||||||
|
@ -1716,10 +1720,9 @@ public class StructureMapUtilities {
|
||||||
Base dest = null;
|
Base dest = null;
|
||||||
if (tgt.hasContext()) {
|
if (tgt.hasContext()) {
|
||||||
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
dest = vars.get(VariableMode.OUTPUT, tgt.getContext());
|
||||||
if (dest == null)
|
if (dest == null) {
|
||||||
throw new FHIRException("Rule \"" + rulePath + "\": target context not known: " + tgt.getContext());
|
throw new FHIRException("Rul \"" + rulePath + "\": target context not known: " + tgt.getContext());
|
||||||
if (!tgt.hasElement())
|
}
|
||||||
throw new FHIRException("Rule \"" + rulePath + "\": Not supported yet");
|
|
||||||
}
|
}
|
||||||
Base v = null;
|
Base v = null;
|
||||||
if (tgt.hasTransform()) {
|
if (tgt.hasTransform()) {
|
||||||
|
@ -1738,8 +1741,10 @@ public class StructureMapUtilities {
|
||||||
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
sharedVars.add(VariableMode.SHARED, tgt.getListRuleId(), v);
|
sharedVars.add(VariableMode.SHARED, tgt.getListRuleId(), v);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (tgt.hasElement()) {
|
||||||
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
v = dest.makeProperty(tgt.getElement().hashCode(), tgt.getElement());
|
||||||
|
} else {
|
||||||
|
v = dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tgt.hasVariable() && v != null)
|
if (tgt.hasVariable() && v != null)
|
||||||
|
|
|
@ -703,7 +703,11 @@ public class VersionUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getNameForVersion(String v) {
|
public static String getNameForVersion(String v) {
|
||||||
switch (getMajMin(v)) {
|
String mm = getMajMin(v);
|
||||||
|
if (mm == null) {
|
||||||
|
throw new Error("Unable to determine version for '"+v+"'");
|
||||||
|
}
|
||||||
|
switch (mm) {
|
||||||
case "1.0" : return "R2";
|
case "1.0" : return "R2";
|
||||||
case "1.4" : return "R2B";
|
case "1.4" : return "R2B";
|
||||||
case "3.0" : return "R3";
|
case "3.0" : return "R3";
|
||||||
|
|
|
@ -1059,6 +1059,7 @@ public class I18nConstants {
|
||||||
public static final String VALUESET_INCLUDE_CSVER_MULTI_FOUND = "VALUESET_INCLUDE_CSVER_MULTI_FOUND";
|
public static final String VALUESET_INCLUDE_CSVER_MULTI_FOUND = "VALUESET_INCLUDE_CSVER_MULTI_FOUND";
|
||||||
public static final String UNABLE_TO_INFER_CODESYSTEM = "UNABLE_TO_INFER_CODESYSTEM";
|
public static final String UNABLE_TO_INFER_CODESYSTEM = "UNABLE_TO_INFER_CODESYSTEM";
|
||||||
public static final String CODE_CASE_DIFFERENCE = "CODE_CASE_DIFFERENCE";
|
public static final String CODE_CASE_DIFFERENCE = "CODE_CASE_DIFFERENCE";
|
||||||
|
public static final String ILLEGAL_PROPERTY = "ILLEGAL_PROPERTY";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1117,3 +1117,4 @@ VALUESET_INCLUDE_CS_MULTI_FOUND = Multiple matching contained code systems found
|
||||||
VALUESET_INCLUDE_CSVER_MULTI_FOUND = Multiple matching contained code systems found for system ''{0}'' version ''{1}''
|
VALUESET_INCLUDE_CSVER_MULTI_FOUND = Multiple matching contained code systems found for system ''{0}'' version ''{1}''
|
||||||
CODE_CASE_DIFFERENCE = The code ''{0}'' differs from the correct code ''{1}'' by case. Although the code system ''{2}'' is case insensitive, implementers are strongly encouraged to use the correct case anyway
|
CODE_CASE_DIFFERENCE = The code ''{0}'' differs from the correct code ''{1}'' by case. Although the code system ''{2}'' is case insensitive, implementers are strongly encouraged to use the correct case anyway
|
||||||
SCT_NO_MRCM = Not validated against the Machine Readable Concept Model (MRCM)
|
SCT_NO_MRCM = Not validated against the Machine Readable Concept Model (MRCM)
|
||||||
|
ILLEGAL_PROPERTY = The property ''{0}'' is invalid
|
||||||
|
|
|
@ -2627,6 +2627,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
|
|
||||||
private boolean checkPrimitive(ValidationContext valContext, List<ValidationMessage> errors, String path, String type, ElementDefinition context, Element e, StructureDefinition profile, NodeStack node, NodeStack parentNode, Element resource) throws FHIRException {
|
private boolean checkPrimitive(ValidationContext valContext, List<ValidationMessage> errors, String path, String type, ElementDefinition context, Element e, StructureDefinition profile, NodeStack node, NodeStack parentNode, Element resource) throws FHIRException {
|
||||||
boolean ok = true;
|
boolean ok = true;
|
||||||
|
|
||||||
|
// sanity check. The only children allowed are id and extension, but value might slip through in some circumstances.
|
||||||
|
for (Element child : e.getChildren()) {
|
||||||
|
ok = rule(errors, "2024-02-28", IssueType.INVALID, child.line(), child.col(), path, !"value".equals(child.getName()), I18nConstants.ILLEGAL_PROPERTY, "value") && ok;
|
||||||
|
}
|
||||||
|
|
||||||
if (isBlank(e.primitiveValue())) {
|
if (isBlank(e.primitiveValue())) {
|
||||||
if (e.primitiveValue() == null)
|
if (e.primitiveValue() == null)
|
||||||
ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, e.hasChildren(), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_PRIMITIVE_VALUEEXT) && ok;
|
ok = rule(errors, NO_RULE_DATE, IssueType.INVALID, e.line(), e.col(), path, e.hasChildren(), I18nConstants.TYPE_SPECIFIC_CHECKS_DT_PRIMITIVE_VALUEEXT) && ok;
|
||||||
|
@ -6116,7 +6122,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
||||||
}
|
}
|
||||||
childDefinitions = getActualTypeChildren(valContext, element, actualType);
|
childDefinitions = getActualTypeChildren(valContext, element, actualType);
|
||||||
} else if (definition.getType().size() > 1) {
|
} else if (definition.getType().size() > 1) {
|
||||||
// this only happens when the profile constrains the abstract children but leaves th choice open.
|
// this only happens when the profile constrains the abstract children but leaves the choice open.
|
||||||
if (actualType == null) {
|
if (actualType == null) {
|
||||||
vi.setValid(false);
|
vi.setValid(false);
|
||||||
return false; // there'll be an error elsewhere in this case, and we're going to stop.
|
return false; // there'll be an error elsewhere in this case, and we're going to stop.
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package org.hl7.fhir.r5.test;
|
package org.hl7.fhir.validation.tests;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
File diff suppressed because it is too large
Load Diff
2
pom.xml
2
pom.xml
|
@ -20,7 +20,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<guava_version>32.0.1-jre</guava_version>
|
<guava_version>32.0.1-jre</guava_version>
|
||||||
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
<hapi_fhir_version>6.4.1</hapi_fhir_version>
|
||||||
<validator_test_case_version>1.4.29-SNAPSHOT</validator_test_case_version>
|
<validator_test_case_version>1.5.0-SNAPSHOT</validator_test_case_version>
|
||||||
<jackson_version>2.16.0</jackson_version>
|
<jackson_version>2.16.0</jackson_version>
|
||||||
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
<junit_jupiter_version>5.9.2</junit_jupiter_version>
|
||||||
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
<junit_platform_launcher_version>1.8.2</junit_platform_launcher_version>
|
||||||
|
|
Loading…
Reference in New Issue