This commit is contained in:
James Agnew 2019-12-19 14:58:32 -05:00
parent 0e1f03b999
commit 28fba9734b
3 changed files with 128 additions and 4 deletions

View File

@ -4,6 +4,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.Constants;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.r4.hapi.ctx.DefaultProfileValidationSupport;
import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext; import org.hl7.fhir.r4.hapi.ctx.HapiWorkerContext;
import org.hl7.fhir.r4.hapi.ctx.IValidationSupport; import org.hl7.fhir.r4.hapi.ctx.IValidationSupport;
import org.hl7.fhir.r4.model.CodeSystem; import org.hl7.fhir.r4.model.CodeSystem;
@ -11,6 +12,7 @@ import org.hl7.fhir.r4.model.CodeType;
import org.hl7.fhir.r4.model.MetadataResource; import org.hl7.fhir.r4.model.MetadataResource;
import org.hl7.fhir.r4.model.Parameters; import org.hl7.fhir.r4.model.Parameters;
import org.hl7.fhir.r4.model.StructureDefinition; import org.hl7.fhir.r4.model.StructureDefinition;
import org.hl7.fhir.r4.model.UriType;
import org.hl7.fhir.r4.model.ValueSet; import org.hl7.fhir.r4.model.ValueSet;
import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent; import org.hl7.fhir.r4.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.r4.terminologies.ValueSetExpander; import org.hl7.fhir.r4.terminologies.ValueSetExpander;
@ -18,9 +20,12 @@ import org.hl7.fhir.r4.terminologies.ValueSetExpanderSimple;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isNotBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank;
/** /**
@ -32,6 +37,7 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
private Map<String, CodeSystem> myCodeSystems; private Map<String, CodeSystem> myCodeSystems;
private Map<String, StructureDefinition> myStructureDefinitions; private Map<String, StructureDefinition> myStructureDefinitions;
private Map<String, ValueSet> myValueSets; private Map<String, ValueSet> myValueSets;
private DefaultProfileValidationSupport myDefaultProfileValidationSupport = new DefaultProfileValidationSupport();
/** /**
* Constructor * Constructor
@ -134,7 +140,43 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
@Override @Override
public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) { public ValueSetExpander.ValueSetExpansionOutcome expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
return null; ValueSetExpander.ValueSetExpansionOutcome retVal = new ValueSetExpander.ValueSetExpansionOutcome(new ValueSet());
Set<String> wantCodes = new HashSet<>();
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
wantCodes.add(next.getCode());
}
CodeSystem system = fetchCodeSystem(theContext, theInclude.getSystem());
if (system != null) {
List<CodeSystem.ConceptDefinitionComponent> concepts = system.getConcept();
addConcepts(theInclude, retVal.getValueset().getExpansion(), wantCodes, concepts);
}
for (UriType next : theInclude.getValueSet()) {
ValueSet vs = myValueSets.get(defaultString(next.getValueAsString()));
if (vs != null) {
for (ConceptSetComponent nextInclude : vs.getCompose().getInclude()) {
ValueSetExpander.ValueSetExpansionOutcome contents = expandValueSet(theContext, nextInclude);
retVal.getValueset().getExpansion().getContains().addAll(contents.getValueset().getExpansion().getContains());
}
}
}
return retVal;
}
private void addConcepts(ConceptSetComponent theInclude, ValueSet.ValueSetExpansionComponent theRetVal, Set<String> theWantCodes, List<CodeSystem.ConceptDefinitionComponent> theConcepts) {
for (CodeSystem.ConceptDefinitionComponent next : theConcepts) {
if (theWantCodes.isEmpty() || theWantCodes.contains(next.getCode())) {
theRetVal
.addContains()
.setSystem(theInclude.getSystem())
.setCode(next.getCode())
.setDisplay(next.getDisplay());
}
addConcepts(theInclude, theRetVal, theWantCodes, next.getConcept());
}
} }
@Override @Override
@ -210,7 +252,8 @@ public class PrePopulatedValidationSupport implements IValidationSupport {
vs.getCompose().addInclude().setSystem(theCodeSystem); vs.getCompose().addInclude().setSystem(theCodeSystem);
} }
ValueSetExpanderSimple expander = new ValueSetExpanderSimple(new HapiWorkerContext(theContext, this)); IValidationSupport support = new ValidationSupportChain(this, myDefaultProfileValidationSupport);
ValueSetExpanderSimple expander = new ValueSetExpanderSimple(new HapiWorkerContext(theContext, support));
ValueSetExpander.ValueSetExpansionOutcome expansion = expander.expand(vs, new Parameters()); ValueSetExpander.ValueSetExpansionOutcome expansion = expander.expand(vs, new Parameters());
for (ValueSet.ValueSetExpansionContainsComponent nextExpansionCode : expansion.getValueset().getExpansion().getContains()) { for (ValueSet.ValueSetExpansionContainsComponent nextExpansionCode : expansion.getValueset().getExpansion().getContains()) {

View File

@ -53,8 +53,11 @@ public class HapiWorkerContextTest extends BaseTest {
HapiWorkerContext workerCtx = new HapiWorkerContext(ctx, validationSupportChain); HapiWorkerContext workerCtx = new HapiWorkerContext(ctx, validationSupportChain);
ValueSet vs = new ValueSet(); ValueSet vs = new ValueSet();
vs.setUrl("http://hl7.org/fhir/ValueSet/fm-status"); IWorkerContext.ValidationResult outcome;
// Built-in Codes
vs.setUrl("http://hl7.org/fhir/ValueSet/fm-status");
IWorkerContext.ValidationResult outcome = workerCtx.validateCode(new TerminologyServiceOptions(), "active", vs); IWorkerContext.ValidationResult outcome = workerCtx.validateCode(new TerminologyServiceOptions(), "active", vs);
assertEquals(outcome.getMessage(), true, outcome.isOk()); assertEquals(outcome.getMessage(), true, outcome.isOk());
@ -62,6 +65,16 @@ public class HapiWorkerContextTest extends BaseTest {
assertEquals(outcome.getMessage(), false, outcome.isOk()); assertEquals(outcome.getMessage(), false, outcome.isOk());
assertEquals("Unknown code[active2] in system[(none)]", outcome.getMessage()); assertEquals("Unknown code[active2] in system[(none)]", outcome.getMessage());
// PrePopulated codes
vs.setUrl("http://hl7.org/fhir/us/core/ValueSet/birthsex");
outcome = workerCtx.validateCode(new TerminologyServiceOptions(), "F", vs);
assertEquals(outcome.getMessage(), true, outcome.isOk());
outcome = workerCtx.validateCode(new TerminologyServiceOptions(), "F2", vs);
assertEquals(outcome.getMessage(), false, outcome.isOk());
assertEquals("Unknown code[F2] in system[(none)]", outcome.getMessage());
} }

View File

@ -1 +1,69 @@
{"resourceType":"ValueSet","id":"birthsex","text":{"status":"generated","div":"<div xmlns=\"http://www.w3.org/1999/xhtml\"><h2>Birth Sex</h2><div><p>Codes for assigning sex at birth as specified by the <a href=\"https://www.healthit.gov/newsroom/about-onc\">Office of the National Coordinator for Health IT (ONC)</a></p>\n</div><p>This value set includes codes from the following code systems:</p><ul><li>Include these codes as defined in <a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html\"><code>http://terminology.hl7.org/CodeSystem/v3-AdministrativeGender</code></a><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html#v3-AdministrativeGender-F\">F</a></td><td>Female</td><td>Female</td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html#v3-AdministrativeGender-M\">M</a></td><td>Male</td><td>Male</td></tr></table></li><li>Include these codes as defined in <a href=\"http://hl7.org/fhir/R4/v3/NullFlavor/cs.html\"><code>http://terminology.hl7.org/CodeSystem/v3-NullFlavor</code></a><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/NullFlavor/cs.html#v3-NullFlavor-UNK\">UNK</a></td><td>Unknown</td><td>Description:A proper value is applicable, but not known.<br/>\n \n Usage Notes: This means the actual value is not known. If the only thing that is unknown is how to properly express the value in the necessary constraints (value set, datatype, etc.), then the OTH or UNC flavor should be used. No properties should be included for a datatype with this property unless:<br/>\n \n Those properties themselves directly translate to a semantic of &quot;unknown&quot;. (E.g. a local code sent as a translation that conveys 'unknown')\n Those properties further qualify the nature of what is unknown. (E.g. specifying a use code of &quot;H&quot; and a URL prefix of &quot;tel:&quot; to convey that it is the home phone number that is unknown.)</td></tr></table></li></ul></div>"},"url":"http://hl7.org/fhir/us/core/ValueSet/birthsex","identifier":[{"system":"urn:ietf:rfc:3986","value":"urn:oid:2.16.840.1.113762.1.4.1021.24"}],"version":"3.1.0","name":"BirthSex","title":"Birth Sex","status":"active","date":"2019-05-21T00:00:00+00:00","publisher":"HL7 US Realm Steering Committee","contact":[{"telecom":[{"system":"other","value":"http://hl7.org/fhir"}]}],"description":"Codes for assigning sex at birth as specified by the [Office of the National Coordinator for Health IT (ONC)](https://www.healthit.gov/newsroom/about-onc)","jurisdiction":[{"coding":[{"system":"urn:iso:std:iso:3166","code":"US","display":"United States of America"}]}],"compose":{"include":[{"system":"http://terminology.hl7.org/CodeSystem/v3-AdministrativeGender","concept":[{"code":"F","display":"Female"},{"code":"M","display":"Male"}]},{"system":"http://terminology.hl7.org/CodeSystem/v3-NullFlavor","concept":[{"code":"UNK","display":"Unknown"}]}]}} {
"resourceType": "ValueSet",
"id": "birthsex",
"text": {
"status": "generated",
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\"><h2>Birth Sex</h2><div><p>Codes for assigning sex at birth as specified by the <a href=\"https://www.healthit.gov/newsroom/about-onc\">Office of the National Coordinator for Health IT (ONC)</a></p>\n</div><p>This value set includes codes from the following code systems:</p><ul><li>Include these codes as defined in <a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html\"><code>http://terminology.hl7.org/CodeSystem/v3-AdministrativeGender</code></a><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html#v3-AdministrativeGender-F\">F</a></td><td>Female</td><td>Female</td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/AdministrativeGender/cs.html#v3-AdministrativeGender-M\">M</a></td><td>Male</td><td>Male</td></tr></table></li><li>Include these codes as defined in <a href=\"http://hl7.org/fhir/R4/v3/NullFlavor/cs.html\"><code>http://terminology.hl7.org/CodeSystem/v3-NullFlavor</code></a><table class=\"none\"><tr><td style=\"white-space:nowrap\"><b>Code</b></td><td><b>Display</b></td></tr><tr><td><a href=\"http://hl7.org/fhir/R4/v3/NullFlavor/cs.html#v3-NullFlavor-UNK\">UNK</a></td><td>Unknown</td><td>Description:A proper value is applicable, but not known.<br/>\n \n Usage Notes: This means the actual value is not known. If the only thing that is unknown is how to properly express the value in the necessary constraints (value set, datatype, etc.), then the OTH or UNC flavor should be used. No properties should be included for a datatype with this property unless:<br/>\n \n Those properties themselves directly translate to a semantic of &quot;unknown&quot;. (E.g. a local code sent as a translation that conveys 'unknown')\n Those properties further qualify the nature of what is unknown. (E.g. specifying a use code of &quot;H&quot; and a URL prefix of &quot;tel:&quot; to convey that it is the home phone number that is unknown.)</td></tr></table></li></ul></div>"
},
"url": "http://hl7.org/fhir/us/core/ValueSet/birthsex",
"identifier": [
{
"system": "urn:ietf:rfc:3986",
"value": "urn:oid:2.16.840.1.113762.1.4.1021.24"
}
],
"version": "3.1.0",
"name": "BirthSex",
"title": "Birth Sex",
"status": "active",
"date": "2019-05-21T00:00:00+00:00",
"publisher": "HL7 US Realm Steering Committee",
"contact": [
{
"telecom": [
{
"system": "other",
"value": "http://hl7.org/fhir"
}
]
}
],
"description": "Codes for assigning sex at birth as specified by the [Office of the National Coordinator for Health IT (ONC)](https://www.healthit.gov/newsroom/about-onc)",
"jurisdiction": [
{
"coding": [
{
"system": "urn:iso:std:iso:3166",
"code": "US",
"display": "United States of America"
}
]
}
],
"compose": {
"include": [
{
"system": "http://terminology.hl7.org/CodeSystem/v3-AdministrativeGender",
"concept": [
{
"code": "F",
"display": "Female"
},
{
"code": "M",
"display": "Male"
}
]
},
{
"system": "http://terminology.hl7.org/CodeSystem/v3-NullFlavor",
"concept": [
{
"code": "UNK",
"display": "Unknown"
}
]
}
]
}
}