[GF#21240]: support for pattern primitive Types and CodeableConcept
This commit is contained in:
parent
9a0c619d28
commit
e6f0b26e81
|
@ -121,6 +121,7 @@ import org.hl7.fhir.r5.model.TypeDetails;
|
|||
import org.hl7.fhir.r5.model.UriType;
|
||||
import org.hl7.fhir.r5.model.ValueSet;
|
||||
import org.hl7.fhir.r5.model.ValueSet.ValueSetExpansionContainsComponent;
|
||||
import org.hl7.fhir.r5.test.utils.TestingUtilities;
|
||||
import org.hl7.fhir.r5.utils.FHIRLexer.FHIRLexerException;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine;
|
||||
import org.hl7.fhir.r5.utils.FHIRPathEngine.IEvaluationContext;
|
||||
|
@ -872,15 +873,55 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkCodeableConcept(List<ValidationMessage> errors, String path, Element focus, CodeableConcept fixed) {
|
||||
|
||||
|
||||
private boolean hasErrors(List<ValidationMessage> errors) {
|
||||
if (errors!=null) {
|
||||
for (ValidationMessage vm : errors) {
|
||||
if (vm.getLevel() == IssueSeverity.FATAL || vm.getLevel() == IssueSeverity.ERROR) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void checkCodeableConcept(List<ValidationMessage> errors, String path, Element focus, CodeableConcept fixed,
|
||||
boolean pattern) {
|
||||
checkFixedValue(errors, path + ".text", focus.getNamedChild("text"), fixed.getTextElement(), "text", focus);
|
||||
List<Element> codings = new ArrayList<Element>();
|
||||
focus.getNamedChildren("coding", codings);
|
||||
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(),
|
||||
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size()) + " coding elements")) {
|
||||
for (int i = 0; i < codings.size(); i++)
|
||||
checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), "coding", focus);
|
||||
if (pattern) {
|
||||
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() >= fixed.getCoding().size(),
|
||||
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size())
|
||||
+ " coding elements")) {
|
||||
for (int i = 0; i < fixed.getCoding().size(); i++) {
|
||||
Coding fixedCoding = fixed.getCoding().get(i);
|
||||
boolean found = false;
|
||||
List<ValidationMessage> errorsFixed = null;
|
||||
for (int j = 0; j < codings.size() && !found; ++j) {
|
||||
errorsFixed = new ArrayList<ValidationMessage>();
|
||||
checkFixedValue(errorsFixed, path + ".coding", codings.get(j), fixedCoding, "coding", focus);
|
||||
if (!hasErrors(errorsFixed)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, false,
|
||||
"Expected patternCodeableConcept not found for"+
|
||||
" system: " + fixedCoding.getSystemElement().asStringValue() +
|
||||
" code: " + fixedCoding.getCodeElement().asStringValue() +
|
||||
" display: " + fixedCoding.getDisplayElement().asStringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rule(errors, IssueType.VALUE, focus.line(), focus.col(), path, codings.size() == fixed.getCoding().size(),
|
||||
"Expected " + Integer.toString(fixed.getCoding().size()) + " but found " + Integer.toString(codings.size())
|
||||
+ " coding elements")) {
|
||||
for (int i = 0; i < codings.size(); i++)
|
||||
checkFixedValue(errors, path + ".coding", codings.get(i), fixed.getCoding().get(i), "coding", focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1292,8 +1333,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
// return b.toString();
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
private void checkFixedValue(List<ValidationMessage> errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String propName, Element parent) {
|
||||
checkFixedValue(errors, path, focus, fixed, propName, parent, false);
|
||||
}
|
||||
|
||||
private void checkFixedValue(List<ValidationMessage> errors, String path, Element focus, org.hl7.fhir.r5.model.Element fixed, String propName, Element parent, boolean pattern) {
|
||||
if ((fixed == null || fixed.isEmpty()) && focus == null)
|
||||
; // this is all good
|
||||
else if (fixed == null && focus != null)
|
||||
|
@ -1356,7 +1401,7 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
else if (fixed instanceof HumanName)
|
||||
checkHumanName(errors, path, focus, (HumanName) fixed);
|
||||
else if (fixed instanceof CodeableConcept)
|
||||
checkCodeableConcept(errors, path, focus, (CodeableConcept) fixed);
|
||||
checkCodeableConcept(errors, path, focus, (CodeableConcept) fixed, pattern);
|
||||
else if (fixed instanceof Timing)
|
||||
checkTiming(errors, path, focus, (Timing) fixed);
|
||||
else if (fixed instanceof Period)
|
||||
|
@ -1622,8 +1667,12 @@ public class InstanceValidator extends BaseValidator implements IResourceValidat
|
|||
}
|
||||
}
|
||||
|
||||
if (context.hasFixed())
|
||||
checkFixedValue(errors,path,e, context.getFixed(), context.getSliceName(), null);
|
||||
if (context.hasFixed()) {
|
||||
checkFixedValue(errors,path,e, context.getFixed(), context.getSliceName(), null, false);
|
||||
}
|
||||
if (context.hasPattern()) {
|
||||
checkFixedValue(errors, path, e, context.getPattern(), context.getSliceName(), null, true);
|
||||
}
|
||||
|
||||
// for nothing to check
|
||||
}
|
||||
|
@ -3819,6 +3868,9 @@ private boolean isAnswerRequirementFulfilled(QuestionnaireItemComponent qItem, L
|
|||
if (ei.definition.hasFixed()) {
|
||||
checkFixedValue(errors,ei.path, ei.element, ei.definition.getFixed(), ei.definition.getSliceName(), null);
|
||||
}
|
||||
if (ei.definition.hasPattern()) {
|
||||
checkFixedValue(errors,ei.path, ei.element, ei.definition.getPattern(), ei.definition.getSliceName(), null, true);
|
||||
}
|
||||
}
|
||||
if (type.equals("Identifier")) {
|
||||
checkIdentifier(errors, ei.path, ei.element, ei.definition);
|
||||
|
|
|
@ -484,11 +484,18 @@
|
|||
"errors": ["ERROR: Observation.code.coding.code: Value is '13457-7' but must be '35200-5'","ERROR: Observation.code.coding.display: Value is 'Cholesterol in LDL [Mass/volume] in Serum or Plasma by calculation' but must be 'Cholesterol [Moles/?volume] in Serum or Plasma'"]
|
||||
},
|
||||
"observation-triglyceride-good.xml" : {
|
||||
"errorCount": 0
|
||||
"warningCount": 1,
|
||||
"errorCount": 0,
|
||||
"warnings": ["WARNING: Observation.code.coding[1]: The display \"Triglyceride [Moles/volume] in Serum or Plasma\" is not a valid display for the code {http://loinc.org}35217-9 - should be one of [\"Triglyceride [Mass or Moles/volume] in Serum or Plasma\",\"Trigl SerPl-msCnc\""]
|
||||
},
|
||||
"observation-triglyceride-good2.xml" : {
|
||||
"warningCount": 1,
|
||||
"errorCount": 0,
|
||||
"warnings": ["WARNING: Observation.code.coding[2]: The display \"Triglyceride [Moles/volume] in Serum or Plasma\" is not a valid display for the code {http://loinc.org}35217-9 - should be one of [\"Triglyceride [Mass or Moles/volume] in Serum or Plasma\",\"Trigl SerPl-msCnc\""]
|
||||
},
|
||||
"observation-triglyceride-bad-wrongcode.xml" : {
|
||||
"errorCount": 1,
|
||||
"errors": ["ERROR: "]
|
||||
"errors": ["ERROR: Observation.code: Expected patternCodeableConcept not found for system: http://loinc.org code: 35217-9 display: Triglyceride [Moles/volume] in Serum or Plasma"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
<system value="http://loinc.org" />
|
||||
<code value="35217-9" />
|
||||
<display
|
||||
value="Triglyceride [Moles/​volume] in Serum or Plasma" />
|
||||
value="Triglyceride [Moles/​volume] in Serum or Plasma" />
|
||||
</coding>
|
||||
<coding>
|
||||
<system value="http://snomed.info/sct" />
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<Observation xmlns="http://hl7.org/fhir">
|
||||
<!-- extract from http://hl7.org/fhir/triglyceride-examples.html, changed
|
||||
id from triglyceride and added explicit profile reference to http://hl7.org/fhir/StructureDefinition/triglyceride
|
||||
and added snomed ct code for triglyceride -->
|
||||
<id value="observation-triglyceride-good2" />
|
||||
<meta>
|
||||
<profile
|
||||
value="http://hl7.org/fhir/StructureDefinition/triglyceride" />
|
||||
</meta>
|
||||
<text>
|
||||
<status value="generated" />
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>
|
||||
<b> Generated Narrative with Details</b>
|
||||
</p>
|
||||
<p>
|
||||
<b> id</b>
|
||||
: triglyceride
|
||||
</p>
|
||||
<p>
|
||||
<b> status</b>
|
||||
: final
|
||||
</p>
|
||||
<p>
|
||||
<b> code</b>
|
||||
: Triglyceride
|
||||
<span> (Details : {LOINC code '35217-9' = 'Triglyceride [Mass or
|
||||
Moles/volume] in Serum or Plasma',
|
||||
given as 'Triglyceride
|
||||
[Moles/​volume] in Serum or Plasma'})
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<b> subject</b>
|
||||
:
|
||||
<a> Patient/pat2</a>
|
||||
</p>
|
||||
<p>
|
||||
<b> performer</b>
|
||||
:
|
||||
<a> Acme Laboratory, Inc</a>
|
||||
</p>
|
||||
<p>
|
||||
<b> value</b>
|
||||
: 1.3 mmol/L
|
||||
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||
</p>
|
||||
<h3> ReferenceRanges</h3>
|
||||
<table>
|
||||
<tr>
|
||||
<td> -</td>
|
||||
<td>
|
||||
<b> High</b>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> *</td>
|
||||
<td>
|
||||
2.0 mmol/L
|
||||
<span> (Details: UCUM code mmol/L = 'mmol/L')</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</text>
|
||||
<status value="final" />
|
||||
<code>
|
||||
<coding>
|
||||
<system value="http://snomed.info/sct" />
|
||||
<code value="85600001" />
|
||||
<display value="Triacylglycerol" />
|
||||
</coding>
|
||||
<coding>
|
||||
<system value="http://loinc.org" />
|
||||
<code value="35217-9" />
|
||||
<display
|
||||
value="Triglyceride [Moles/​volume] in Serum or Plasma" />
|
||||
</coding>
|
||||
<coding>
|
||||
<system value="http://snomed.info/sct" />
|
||||
<code value="85600001" />
|
||||
<display value="Triacylglycerol" />
|
||||
</coding>
|
||||
<text value="Triglyceride" />
|
||||
</code>
|
||||
<subject>
|
||||
<reference value="Patient/pat2" />
|
||||
</subject>
|
||||
<performer>
|
||||
<reference
|
||||
value="Organization/1832473e-2fe0-452d-abe9-3cdb9879522f" />
|
||||
<display value="Acme Laboratory, Inc" />
|
||||
</performer>
|
||||
<valueQuantity>
|
||||
<value value="1.3" />
|
||||
<unit value="mmol/L" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mmol/L" />
|
||||
</valueQuantity>
|
||||
<referenceRange>
|
||||
<high>
|
||||
<value value="2.0" />
|
||||
<unit value="mmol/L" />
|
||||
<system value="http://unitsofmeasure.org" />
|
||||
<code value="mmol/L" />
|
||||
</high>
|
||||
</referenceRange>
|
||||
</Observation>
|
Loading…
Reference in New Issue