infer system when value set has includes

This commit is contained in:
Grahame Grieve 2022-03-11 10:37:10 +11:00
parent 56c52ab7dd
commit 6b3d7d4eaa
1 changed files with 63 additions and 40 deletions

View File

@ -33,8 +33,10 @@ package org.hl7.fhir.r5.terminologies;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hl7.fhir.exceptions.FHIRException;
import org.hl7.fhir.exceptions.NoTerminologyServiceException;
@ -544,71 +546,92 @@ public class ValueSetCheckerSimple extends ValueSetWorker implements ValueSetChe
private String systemForCodeInValueSet(String code) {
String sys = null;
Set<String> sys = new HashSet<>();
if (!scanForCodeInValueSet(code, sys)) {
return null;
}
if (sys.size() != 1) {
return null;
} else {
return sys.iterator().next();
}
}
private boolean scanForCodeInValueSet(String code, Set<String> sys) {
if (valueset.hasCompose()) {
if (valueset.getCompose().hasExclude()) {
return null;
}
// not sure what to do with the
// if (valueset.getCompose().hasExclude()) {
// return false;
// }
for (ConceptSetComponent vsi : valueset.getCompose().getInclude()) {
if (vsi.hasValueSet()) {
return null;
}
if (!vsi.hasSystem()) {
return null;
}
if (vsi.hasFilter()) {
return null;
}
CodeSystem cs = resolveCodeSystem(vsi.getSystem());
if (cs == null) {
return null;
}
if (vsi.hasConcept()) {
for (ConceptReferenceComponent cc : vsi.getConcept()) {
boolean match = cs.getCaseSensitive() ? cc.getCode().equals(code) : cc.getCode().equalsIgnoreCase(code);
if (match) {
if (sys == null) {
sys = vsi.getSystem();
} else if (!sys.equals(vsi.getSystem())) {
return null;
}
for (CanonicalType u : vsi.getValueSet()) {
if (!checkForCodeInValueSet(code, u.getValue(), sys)) {
return false;
}
}
} else {
ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code);
if (cc != null) {
if (sys == null) {
sys = vsi.getSystem();
} else if (!sys.equals(vsi.getSystem())) {
return null;
} else if (!vsi.hasSystem()) {
return false;
}
if (vsi.hasSystem()) {
if (vsi.hasFilter()) {
return false;
}
CodeSystem cs = resolveCodeSystem(vsi.getSystem());
if (cs != null) {
if (vsi.hasConcept()) {
for (ConceptReferenceComponent cc : vsi.getConcept()) {
boolean match = cs.getCaseSensitive() ? cc.getCode().equals(code) : cc.getCode().equalsIgnoreCase(code);
if (match) {
sys.add(vsi.getSystem());
}
}
} else {
ConceptDefinitionComponent cc = findCodeInConcept(cs.getConcept(), code);
if (cc != null) {
sys.add(vsi.getSystem());
}
}
} else {
if (vsi.hasConcept()) {
for (ConceptReferenceComponent cc : vsi.getConcept()) {
boolean match = cc.getCode().equals(code);
if (match) {
sys.add(vsi.getSystem());
}
}
}
}
}
}
} else if (valueset.hasExpansion()) {
// Retrieve a list of all systems associated with this code in the expansion
List<String> systems = new ArrayList<String>();
checkSystems(valueset.getExpansion().getContains(), code, systems);
if (systems.size()==1)
sys = systems.get(0);
if (!checkSystems(valueset.getExpansion().getContains(), code, sys)) {
return false;
}
}
return true;
}
return sys;
private boolean checkForCodeInValueSet(String code, String uri, Set<String> sys) {
ValueSetCheckerSimple vs = getVs(uri);
return vs.scanForCodeInValueSet(code, sys);
}
/*
* Recursively go through all codes in the expansion and for any coding that matches the specified code, add the system for that coding
* to the passed list.
*/
private void checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, List<String> systems) {
private boolean checkSystems(List<ValueSetExpansionContainsComponent> contains, String code, Set<String> systems) {
for (ValueSetExpansionContainsComponent c: contains) {
if (c.getCode().equals(code)) {
if (!systems.contains(c.getSystem()))
systems.add(c.getSystem());
systems.add(c.getSystem());
}
if (c.hasContains())
checkSystems(c.getContains(), code, systems);
}
return true;
}
@Override