mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-02-16 18:05:19 +00:00
More terminology service work
This commit is contained in:
parent
c318d1a040
commit
32cebb2a9f
168
examples/src/main/java/example/ValidateDirectory.java
Normal file
168
examples/src/main/java/example/ValidateDirectory.java
Normal file
@ -0,0 +1,168 @@
|
||||
package example;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.FhirInstanceValidator;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.ValidationSupportChain;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetExpansionComponent;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationResult;
|
||||
|
||||
public class ValidateDirectory {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidateDirectory.class);
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Load all profiles in this directory
|
||||
File profileDirectory = new File("/tmp/directory/with/profiles");
|
||||
|
||||
// Validate resources in this directory
|
||||
File resourceDirectory = new File("/tmp/directory/with/resources/to/validate");
|
||||
|
||||
FhirContext ctx = FhirContext.forDstu3();
|
||||
IParser xmlParser = ctx.newXmlParser();
|
||||
IParser jsonParser = ctx.newJsonParser();
|
||||
|
||||
Map<String, StructureDefinition> structureDefinitions = new HashMap<String, StructureDefinition>();
|
||||
Map<String, CodeSystem> codeSystems = new HashMap<String, CodeSystem>();
|
||||
Map<String, ValueSet> valueSets = new HashMap<String, ValueSet>();
|
||||
|
||||
// Load all profile files
|
||||
for (File nextFile : profileDirectory.listFiles()) {
|
||||
|
||||
IBaseResource parsedRes = null;
|
||||
if (nextFile.getAbsolutePath().toLowerCase().endsWith(".xml")) {
|
||||
parsedRes = xmlParser.parseResource(new FileReader(nextFile));
|
||||
} else if (nextFile.getAbsolutePath().toLowerCase().endsWith(".json")) {
|
||||
parsedRes = jsonParser.parseResource(new FileReader(nextFile));
|
||||
} else {
|
||||
ourLog.info("Ignoring file: {}", nextFile.getName());
|
||||
}
|
||||
|
||||
if (parsedRes instanceof StructureDefinition) {
|
||||
StructureDefinition res = (StructureDefinition) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
structureDefinitions.put(res.getUrl(), res);
|
||||
}
|
||||
} else if (parsedRes instanceof ValueSet) {
|
||||
ValueSet res = (ValueSet) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
valueSets.put(res.getUrl(), res);
|
||||
}
|
||||
} else if (parsedRes instanceof CodeSystem) {
|
||||
CodeSystem res = (CodeSystem) parsedRes;
|
||||
if (isNotBlank(res.getUrl())) {
|
||||
codeSystems.put(res.getUrl(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FhirInstanceValidator instanceValidator = new FhirInstanceValidator();
|
||||
|
||||
ValidationSupportChain validationSupportChain = new ValidationSupportChain();
|
||||
validationSupportChain.addValidationSupport(new DefaultProfileValidationSupport());
|
||||
validationSupportChain.addValidationSupport(new PrePopulatedValidationSupport(structureDefinitions, valueSets, codeSystems));
|
||||
|
||||
instanceValidator.setValidationSupport(validationSupportChain);
|
||||
|
||||
FhirValidator val = ctx.newValidator();
|
||||
val.registerValidatorModule(instanceValidator);
|
||||
|
||||
// Loop through the files in the validation directory and validate each one
|
||||
for (File nextFile : resourceDirectory.listFiles()) {
|
||||
|
||||
if (nextFile.getAbsolutePath().toLowerCase().endsWith(".xml")) {
|
||||
ourLog.info("Going to validate: {}", nextFile.getName());
|
||||
} else if (nextFile.getAbsolutePath().toLowerCase().endsWith(".json")) {
|
||||
ourLog.info("Going to validate: {}", nextFile.getName());
|
||||
} else {
|
||||
ourLog.info("Ignoring file: {}", nextFile.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
String input = IOUtils.toString(new FileReader(nextFile));
|
||||
ValidationResult result = val.validateWithResult(input);
|
||||
IBaseOperationOutcome oo = result.toOperationOutcome();
|
||||
ourLog.info("Result:\n{}", xmlParser.setPrettyPrint(true).encodeResourceToString(oo));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PrePopulatedValidationSupport implements IValidationSupport {
|
||||
|
||||
private Map<String, StructureDefinition> myStructureDefinitions;
|
||||
private Map<String, ValueSet> myValueSets;
|
||||
private Map<String, CodeSystem> myCodeSystems;
|
||||
|
||||
public PrePopulatedValidationSupport(Map<String, StructureDefinition> theStructureDefinitions, Map<String, ValueSet> theValueSets, Map<String, CodeSystem> theCodeSystems) {
|
||||
myStructureDefinitions = theStructureDefinitions;
|
||||
myValueSets = theValueSets;
|
||||
myCodeSystems = theCodeSystems;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueSetExpansionComponent expandValueSet(FhirContext theContext, ConceptSetComponent theInclude) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return new ArrayList<StructureDefinition>(myStructureDefinitions.values());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
return myCodeSystems.get(theSystem);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T extends IBaseResource> T fetchResource(FhirContext theContext, Class<T> theClass, String theUri) {
|
||||
if (theClass.equals(StructureDefinition.class)) {
|
||||
return (T) myStructureDefinitions.get(theUri);
|
||||
}
|
||||
if (theClass.equals(ValueSet.class)) {
|
||||
return (T) myValueSets.get(theUri);
|
||||
}
|
||||
if (theClass.equals(CodeSystem.class)) {
|
||||
return (T) myCodeSystems.get(theUri);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StructureDefinition fetchStructureDefinition(FhirContext theCtx, String theUrl) {
|
||||
return myStructureDefinitions.get(theUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCodeSystemSupported(FhirContext theContext, String theSystem) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeValidationResult validateCode(FhirContext theContext, String theCodeSystem, String theCode, String theDisplay) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.codec.binary.StringUtils;
|
||||
import org.hl7.fhir.dstu3.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
@ -75,7 +76,7 @@ public class FhirResourceDaoValueSetDstu3 extends FhirResourceDaoDstu3<ValueSet>
|
||||
String filterLc = theFilter != null ? theFilter.toLowerCase() : null;
|
||||
|
||||
ValueSetExpansionOutcome outcome = workerContext.expand(source);
|
||||
ValueSetExpansionComponent expansion = outcome.getValueset().getExpansion();
|
||||
ValueSetExpansionComponent expansion = outcome.getValueset().getExpansion();
|
||||
if (isNotBlank(theFilter)) {
|
||||
for (Iterator<ValueSetExpansionContainsComponent> containsIter = expansion.getContains().iterator(); containsIter.hasNext();) {
|
||||
ValueSetExpansionContainsComponent nextContains = containsIter.next();
|
||||
|
@ -207,11 +207,12 @@ public class TermConcept implements Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public void setDisplay(String theDisplay) {
|
||||
public TermConcept setDisplay(String theDisplay) {
|
||||
myDisplay = theDisplay;
|
||||
if (isNotBlank(theDisplay) && theDisplay.length() > MAX_DESC_LENGTH) {
|
||||
myDisplay = myDisplay.substring(0, MAX_DESC_LENGTH);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setParentPids(Set<Long> theParentPids) {
|
||||
|
@ -66,27 +66,18 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
@Autowired
|
||||
protected ITermConceptDao myConceptDao;
|
||||
|
||||
@Autowired
|
||||
private DaoConfig myDaoConfig;
|
||||
|
||||
@Autowired
|
||||
private ITermConceptParentChildLinkDao myConceptParentChildLinkDao;
|
||||
|
||||
@Autowired
|
||||
protected FhirContext myContext;
|
||||
|
||||
@Autowired
|
||||
private DaoConfig myDaoConfig;
|
||||
|
||||
@PersistenceContext(type = PersistenceContextType.TRANSACTION)
|
||||
protected EntityManager myEntityManager;
|
||||
|
||||
private void fetchChildren(TermConcept theConcept, Set<TermConcept> theSetToPopulate) {
|
||||
for (TermConceptParentChildLink nextChildLink : theConcept.getChildren()) {
|
||||
TermConcept nextChild = nextChildLink.getChild();
|
||||
if (addToSet(theSetToPopulate, nextChild)) {
|
||||
fetchChildren(nextChild, theSetToPopulate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addToSet(Set<TermConcept> theSetToPopulate, TermConcept theConcept) {
|
||||
boolean retVal = theSetToPopulate.add(theConcept);
|
||||
if (retVal) {
|
||||
@ -98,6 +89,15 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private void fetchChildren(TermConcept theConcept, Set<TermConcept> theSetToPopulate) {
|
||||
for (TermConceptParentChildLink nextChildLink : theConcept.getChildren()) {
|
||||
TermConcept nextChild = nextChildLink.getChild();
|
||||
if (addToSet(theSetToPopulate, nextChild)) {
|
||||
fetchChildren(nextChild, theSetToPopulate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private TermConcept fetchLoadedCode(Long theCodeSystemResourcePid, Long theCodeSystemVersionPid, String theCode) {
|
||||
TermCodeSystemVersion codeSystem = myCodeSystemVersionDao.findByCodeSystemResourceAndVersion(theCodeSystemResourcePid, theCodeSystemVersionPid);
|
||||
TermConcept concept = myConceptDao.findByCodeSystemAndCode(codeSystem, theCode);
|
||||
@ -113,6 +113,17 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
}
|
||||
}
|
||||
|
||||
public TermConcept findCode(String theCodeSystem, String theCode) {
|
||||
TermCodeSystemVersion csv = findCurrentCodeSystemVersionForSystem(theCodeSystem);
|
||||
|
||||
return myConceptDao.findByCodeSystemAndCode(csv, theCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TermConcept> findCodes(String theSystem) {
|
||||
return myConceptDao.findByCodeSystemVersion(findCurrentCodeSystemVersionForSystem(theSystem));
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.REQUIRED)
|
||||
@Override
|
||||
public Set<TermConcept> findCodesAbove(Long theCodeSystemResourcePid, Long theCodeSystemVersionPid, String theCode) {
|
||||
@ -177,6 +188,20 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private TermCodeSystemVersion findCurrentCodeSystemVersionForSystem(String theCodeSystem) {
|
||||
TermCodeSystem cs = getCodeSystem(theCodeSystem);
|
||||
if (cs == null || cs.getCurrentVersion() == null) {
|
||||
return null;
|
||||
}
|
||||
TermCodeSystemVersion csv = cs.getCurrentVersion();
|
||||
return csv;
|
||||
}
|
||||
|
||||
private TermCodeSystem getCodeSystem(String theSystem) {
|
||||
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
||||
return cs;
|
||||
}
|
||||
|
||||
private void persistChildren(TermConcept theConcept, TermCodeSystemVersion theCodeSystem, IdentityHashMap<TermConcept, Object> theConceptsStack, HashSet<Long> thePidsInHierarchy) {
|
||||
if (theConceptsStack.put(theConcept, PLACEHOLDER_OBJECT) != null) {
|
||||
return;
|
||||
@ -277,11 +302,6 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
return cs != null;
|
||||
}
|
||||
|
||||
private TermCodeSystem getCodeSystem(String theSystem) {
|
||||
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(theSystem);
|
||||
return cs;
|
||||
}
|
||||
|
||||
private ArrayList<VersionIndependentConcept> toVersionIndependentConcepts(String theSystem, Set<TermConcept> codes) {
|
||||
ArrayList<VersionIndependentConcept> retVal = new ArrayList<VersionIndependentConcept>(codes.size());
|
||||
for (TermConcept next : codes) {
|
||||
@ -309,14 +329,4 @@ public abstract class BaseHapiTerminologySvc implements IHapiTerminologySvc {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public TermConcept findCode(String theCodeSystem, String theCode) {
|
||||
TermCodeSystem cs = getCodeSystem(theCodeSystem);
|
||||
if (cs == null || cs.getCurrentVersion() == null) {
|
||||
return null;
|
||||
}
|
||||
TermCodeSystemVersion csv = cs.getCurrentVersion();
|
||||
|
||||
return myConceptDao.findByCodeSystemAndCode(csv, theCode);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -121,60 +121,82 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||
TermCodeSystem cs = myCodeSystemDao.findByCodeSystemUri(system);
|
||||
TermCodeSystemVersion csv = cs.getCurrentVersion();
|
||||
|
||||
FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager);
|
||||
QueryBuilder qb = em.getSearchFactory().buildQueryBuilder().forEntity(TermConcept.class).get();
|
||||
BooleanJunction<?> bool = qb.bool();
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
Set<String> addedCodes = new HashSet<String>();
|
||||
boolean haveIncludeCriteria = false;
|
||||
|
||||
bool.must(qb.keyword().onField("myCodeSystemVersionPid").matching(csv.getPid()).createQuery());
|
||||
|
||||
Set<String> wantCodes = new HashSet<String>();
|
||||
/*
|
||||
* Include Concepts
|
||||
*/
|
||||
for (ConceptReferenceComponent next : theInclude.getConcept()) {
|
||||
String nextCode = next.getCode();
|
||||
if (isNotBlank(nextCode)) {
|
||||
wantCodes.add(nextCode);
|
||||
bool.should(qb.keyword().onField("myCode").matching(nextCode).createQuery());
|
||||
if (isNotBlank(nextCode) && !addedCodes.contains(nextCode)) {
|
||||
haveIncludeCriteria = true;
|
||||
TermConcept code = super.findCode(system, nextCode);
|
||||
if (code != null) {
|
||||
addedCodes.add(nextCode);
|
||||
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
||||
contains.setCode(nextCode);
|
||||
contains.setSystem(system);
|
||||
contains.setDisplay(code.getDisplay());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
|
||||
if (nextFilter.getProperty().equals("display") && nextFilter.getOp() == FilterOperator.EQUAL) {
|
||||
if (isNotBlank(nextFilter.getValue())) {
|
||||
bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
|
||||
/*
|
||||
* Filters
|
||||
*/
|
||||
|
||||
if (theInclude.getFilter().size() > 0) {
|
||||
haveIncludeCriteria = true;
|
||||
|
||||
FullTextEntityManager em = org.hibernate.search.jpa.Search.getFullTextEntityManager(myEntityManager);
|
||||
QueryBuilder qb = em.getSearchFactory().buildQueryBuilder().forEntity(TermConcept.class).get();
|
||||
BooleanJunction<?> bool = qb.bool();
|
||||
|
||||
bool.must(qb.keyword().onField("myCodeSystemVersionPid").matching(csv.getPid()).createQuery());
|
||||
|
||||
for (ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
|
||||
if (nextFilter.getProperty().equals("display") && nextFilter.getOp() == FilterOperator.EQUAL) {
|
||||
if (isNotBlank(nextFilter.getValue())) {
|
||||
bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
|
||||
}
|
||||
} else if (nextFilter.getOp() == FilterOperator.ISA) {
|
||||
if (isNotBlank(nextFilter.getValue())) {
|
||||
TermConcept code = super.findCode(system, nextFilter.getValue());
|
||||
bool.must(qb.keyword().onField("myParentPids").matching(code.getId()).createQuery());
|
||||
}
|
||||
} else {
|
||||
throw new InvalidRequestException("Unknown filter property[" + nextFilter + "] + op[" + nextFilter.getOpElement().getValueAsString() + "]");
|
||||
}
|
||||
} else if (nextFilter.getOp() == FilterOperator.ISA) {
|
||||
if (isNotBlank(nextFilter.getValue())) {
|
||||
TermConcept code = super.findCode(system, nextFilter.getValue());
|
||||
bool.must(qb.keyword().onField("myParentPids").matching(code.getId()).createQuery());
|
||||
}
|
||||
} else {
|
||||
throw new InvalidRequestException("Unknown filter property[" + nextFilter + "] + op[" + nextFilter.getOpElement().getValueAsString() + "]");
|
||||
}
|
||||
|
||||
Query luceneQuery = bool.createQuery();
|
||||
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TermConcept> result = jpaQuery.getResultList();
|
||||
for (TermConcept nextConcept : result) {
|
||||
addCodeIfNotAlreadyAdded(system, retVal, addedCodes, nextConcept);
|
||||
}
|
||||
}
|
||||
|
||||
ValueSetExpansionComponent retVal = new ValueSetExpansionComponent();
|
||||
|
||||
Query luceneQuery = bool.createQuery();
|
||||
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TermConcept> result = jpaQuery.getResultList();
|
||||
for (TermConcept nextConcept : result) {
|
||||
if (!wantCodes.isEmpty() && !wantCodes.contains(nextConcept.getCode())) {
|
||||
continue;
|
||||
|
||||
if (!haveIncludeCriteria) {
|
||||
List<TermConcept> allCodes = super.findCodes(system);
|
||||
for (TermConcept nextConcept : allCodes) {
|
||||
addCodeIfNotAlreadyAdded(system, retVal, addedCodes, nextConcept);
|
||||
}
|
||||
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
||||
contains.setCode(nextConcept.getCode());
|
||||
contains.setSystem(system);
|
||||
contains.setDisplay(nextConcept.getDisplay());
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private void addCodeIfFilterMatches(ValueSetExpansionComponent retVal, TermConcept termCode, List<ConceptSetFilterComponent> theFilters, String theSystem) {
|
||||
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
||||
contains.setSystem(theSystem);
|
||||
contains.setCode(termCode.getCode());
|
||||
contains.setDisplay(termCode.getDisplay());
|
||||
private void addCodeIfNotAlreadyAdded(String system, ValueSetExpansionComponent retVal, Set<String> addedCodes, TermConcept nextConcept) {
|
||||
if (addedCodes.add(nextConcept.getCode())) {
|
||||
ValueSetExpansionContainsComponent contains = retVal.addContains();
|
||||
contains.setCode(nextConcept.getCode());
|
||||
contains.setSystem(system);
|
||||
contains.setDisplay(nextConcept.getDisplay());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -185,7 +207,7 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
||||
@CoverageIgnore
|
||||
@Override
|
||||
public CodeSystem fetchCodeSystem(FhirContext theContext, String theSystem) {
|
||||
throw new UnsupportedOperationException();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,4 +46,6 @@ public interface IHapiTerminologySvc {
|
||||
|
||||
void storeNewCodeSystemVersion(String theSystem, TermCodeSystemVersion theCodeSystemVersion, RequestDetails theRequestDetails);
|
||||
|
||||
List<TermConcept> findCodes(String theSystem);
|
||||
|
||||
}
|
||||
|
@ -132,38 +132,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||
|
||||
@Test
|
||||
public void testSearchCodeInExternalCodesystem() {
|
||||
CodeSystem codeSystem = new CodeSystem();
|
||||
codeSystem.setUrl(URL_MY_CODE_SYSTEM);
|
||||
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
|
||||
IIdType id = myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();
|
||||
|
||||
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
|
||||
|
||||
TermCodeSystemVersion cs = new TermCodeSystemVersion();
|
||||
cs.setResource(table);
|
||||
cs.setResourceVersionId(table.getVersion());
|
||||
|
||||
TermConcept parentA = new TermConcept(cs, "ParentA");
|
||||
cs.getConcepts().add(parentA);
|
||||
|
||||
TermConcept childAA = new TermConcept(cs, "childAA");
|
||||
parentA.addChild(childAA, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAAA = new TermConcept(cs, "childAAA");
|
||||
childAA.addChild(childAAA, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAAB = new TermConcept(cs, "childAAB");
|
||||
childAA.addChild(childAAB, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAB = new TermConcept(cs, "childAB");
|
||||
parentA.addChild(childAB, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept parentB = new TermConcept(cs, "ParentB");
|
||||
cs.getConcepts().add(parentB);
|
||||
|
||||
myTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs);
|
||||
|
||||
createLocalVs(codeSystem);
|
||||
createExternalCsAndLocalVs();
|
||||
|
||||
Observation obsPA = new Observation();
|
||||
obsPA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("ParentA");
|
||||
@ -195,6 +164,48 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void createExternalCsAndLocalVs() {
|
||||
CodeSystem codeSystem = createExternalCs();
|
||||
|
||||
createLocalVs(codeSystem);
|
||||
}
|
||||
|
||||
|
||||
private CodeSystem createExternalCs() {
|
||||
CodeSystem codeSystem = new CodeSystem();
|
||||
codeSystem.setUrl(URL_MY_CODE_SYSTEM);
|
||||
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
|
||||
IIdType id = myCodeSystemDao.create(codeSystem, new ServletRequestDetails()).getId().toUnqualified();
|
||||
|
||||
ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
|
||||
|
||||
TermCodeSystemVersion cs = new TermCodeSystemVersion();
|
||||
cs.setResource(table);
|
||||
cs.setResourceVersionId(table.getVersion());
|
||||
|
||||
TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
|
||||
cs.getConcepts().add(parentA);
|
||||
|
||||
TermConcept childAA = new TermConcept(cs, "childAA").setDisplay("Child AA");
|
||||
parentA.addChild(childAA, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAAA = new TermConcept(cs, "childAAA").setDisplay("Child AAA");
|
||||
childAA.addChild(childAAA, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAAB = new TermConcept(cs, "childAAB").setDisplay("Child AAB");
|
||||
childAA.addChild(childAAB, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept childAB = new TermConcept(cs, "childAB").setDisplay("Child AB");
|
||||
parentA.addChild(childAB, RelationshipTypeEnum.ISA);
|
||||
|
||||
TermConcept parentB = new TermConcept(cs, "ParentB").setDisplay("Parent B");
|
||||
cs.getConcepts().add(parentB);
|
||||
|
||||
myTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs);
|
||||
return codeSystem;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchCodeBelowAndAboveUnknownCodeSystem() {
|
||||
|
||||
@ -299,19 +310,48 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||
//
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testExpandWithSystemAndCodesAndFilterInLocalValueSet() {
|
||||
public void testExpandWithSystemAndCodesAndFilterInExternalValueSet() {
|
||||
createExternalCsAndLocalVs();
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||
include.addConcept().setCode("ParentA");
|
||||
include.addConcept().setCode("childAA");
|
||||
include.addConcept().setCode("childAAA");
|
||||
|
||||
include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue("Parent B");
|
||||
|
||||
ValueSet result = myValueSetDao.expand(vs, null);
|
||||
|
||||
String encoded = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result);
|
||||
ourLog.info(encoded);
|
||||
|
||||
ArrayList<String> codes = toCodesContains(result.getExpansion().getContains());
|
||||
assertThat(codes, containsInAnyOrder("ParentA", "childAA", "childAAA", "ParentB"));
|
||||
|
||||
int idx = codes.indexOf("childAA");
|
||||
assertEquals("childAA", result.getExpansion().getContains().get(idx).getCode());
|
||||
assertEquals("Child AA", result.getExpansion().getContains().get(idx).getDisplay());
|
||||
assertEquals(URL_MY_CODE_SYSTEM, result.getExpansion().getContains().get(idx).getSystem());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithSystemAndCodesAndFilterKeywordInLocalValueSet() {
|
||||
createLocalCsAndVs();
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||
include.addConcept().setCode("A");
|
||||
include.addConcept().setCode("AA");
|
||||
include.addConcept().setCode("AAA");
|
||||
include.addConcept().setCode("AB");
|
||||
// include.addConcept().setCode("A");
|
||||
// include.addConcept().setCode("AA");
|
||||
// include.addConcept().setCode("AAA");
|
||||
// include.addConcept().setCode("AB");
|
||||
|
||||
include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue("Code AAA");
|
||||
include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue("AAA");
|
||||
|
||||
ValueSet result = myValueSetDao.expand(vs, null);
|
||||
|
||||
@ -324,11 +364,44 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
|
||||
assertEquals("AAA", result.getExpansion().getContains().get(0).getCode());
|
||||
assertEquals("Code AAA", result.getExpansion().getContains().get(0).getDisplay());
|
||||
assertEquals(URL_MY_CODE_SYSTEM, result.getExpansion().getContains().get(0).getSystem());
|
||||
// ValueSet expansion = myValueSetDao.expandByIdentifier(URL_MY_VALUE_SET, "cervical");
|
||||
// ValueSet expansion = myValueSetDao.expandByIdentifier(URL_MY_VALUE_SET, "cervical");
|
||||
//
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithNoResultsInLocalValueSet1() {
|
||||
createLocalCsAndVs();
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||
include.setSystem(URL_MY_CODE_SYSTEM);
|
||||
include.addConcept().setCode("ZZZZ");
|
||||
|
||||
try {
|
||||
myValueSetDao.expand(vs, null);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("Unable to find code 'ZZZZ' in code system http://example.com/my_code_system", e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExpandWithNoResultsInLocalValueSet2() {
|
||||
createLocalCsAndVs();
|
||||
|
||||
ValueSet vs = new ValueSet();
|
||||
ConceptSetComponent include = vs.getCompose().addInclude();
|
||||
include.setSystem(URL_MY_CODE_SYSTEM + "AA");
|
||||
include.addConcept().setCode("A");
|
||||
|
||||
try {
|
||||
myValueSetDao.expand(vs, null);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertEquals("unable to find code system http://example.com/my_code_systemAA", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private ArrayList<String> toCodesContains(List<ValueSetExpansionContainsComponent> theContains) {
|
||||
ArrayList<String> retVal = new ArrayList<String>();
|
||||
for (ValueSetExpansionContainsComponent next : theContains) {
|
||||
|
@ -158,23 +158,19 @@ public class FhirResourceDaoDstu3ValueSetTest extends BaseJpaDstu3Test {
|
||||
ValueSet expanded = myValueSetDao.expand(myExtensionalVsId, null);
|
||||
resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
// @formatter:off
|
||||
assertThat(resp,
|
||||
stringContainsInOrder("<ValueSet xmlns=\"http://hl7.org/fhir\">",
|
||||
"<expansion>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"8450-9\"/>",
|
||||
"<display value=\"Systolic blood pressure--expiration\"/>",
|
||||
"</contains>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>",
|
||||
"</contains>",
|
||||
"</expansion>"
|
||||
));
|
||||
//@formatter:on
|
||||
assertThat(resp, containsString("<ValueSet xmlns=\"http://hl7.org/fhir\">"));
|
||||
assertThat(resp, containsString("<expansion>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"8450-9\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure--expiration\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"11378-7\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("</expansion>"));
|
||||
|
||||
/*
|
||||
* Filter with display name
|
||||
|
@ -2830,23 +2830,19 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||
String resp = IOUtils.toString(response.getEntity().getContent());
|
||||
ourLog.info(resp);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
// @formatter:off
|
||||
assertThat(resp,
|
||||
stringContainsInOrder("<ValueSet xmlns=\"http://hl7.org/fhir\">",
|
||||
"<expansion>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"8450-9\"/>",
|
||||
"<display value=\"Systolic blood pressure--expiration\"/>",
|
||||
"</contains>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>",
|
||||
"</contains>",
|
||||
"</expansion>"
|
||||
));
|
||||
//@formatter:on
|
||||
assertThat(resp, containsString("<ValueSet xmlns=\"http://hl7.org/fhir\">"));
|
||||
assertThat(resp, containsString("<expansion>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"8450-9\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure--expiration\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"11378-7\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("</expansion>"));
|
||||
} finally {
|
||||
IOUtils.closeQuietly(response.getEntity().getContent());
|
||||
response.close();
|
||||
|
@ -62,23 +62,19 @@ public class ResourceProviderDstu3ValueSetTest extends BaseResourceProviderDstu3
|
||||
|
||||
String resp = myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(expanded);
|
||||
ourLog.info(resp);
|
||||
// @formatter:off
|
||||
assertThat(resp,
|
||||
stringContainsInOrder("<ValueSet xmlns=\"http://hl7.org/fhir\">",
|
||||
"<expansion>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"8450-9\"/>",
|
||||
"<display value=\"Systolic blood pressure--expiration\"/>",
|
||||
"</contains>",
|
||||
"<contains>",
|
||||
"<system value=\"http://acme.org\"/>",
|
||||
"<code value=\"11378-7\"/>",
|
||||
"<display value=\"Systolic blood pressure at First encounter\"/>",
|
||||
"</contains>",
|
||||
"</expansion>"
|
||||
));
|
||||
//@formatter:on
|
||||
assertThat(resp, containsString("<ValueSet xmlns=\"http://hl7.org/fhir\">"));
|
||||
assertThat(resp, containsString("<expansion>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"8450-9\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure--expiration\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("<contains>"));
|
||||
assertThat(resp, containsString("<system value=\"http://acme.org\"/>"));
|
||||
assertThat(resp, containsString("<code value=\"11378-7\"/>"));
|
||||
assertThat(resp, containsString("<display value=\"Systolic blood pressure at First encounter\"/>"));
|
||||
assertThat(resp, containsString("</contains>"));
|
||||
assertThat(resp, containsString("</expansion>"));
|
||||
|
||||
/*
|
||||
* Filter with display name
|
||||
|
10
hapi-fhir-jpaserver-base/src/test/resources/loinc/loinc.csv
Normal file
10
hapi-fhir-jpaserver-base/src/test/resources/loinc/loinc.csv
Normal file
@ -0,0 +1,10 @@
|
||||
"LOINC_NUM","COMPONENT","PROPERTY","TIME_ASPCT","SYSTEM","SCALE_TYP","METHOD_TYP","CLASS","SOURCE","VersionLastChanged","CHNG_TYPE","DefinitionDescription","STATUS","CONSUMER_NAME","CLASSTYPE","FORMULA","SPECIES","EXMPL_ANSWERS","SURVEY_QUEST_TEXT","SURVEY_QUEST_SRC","UNITSREQUIRED","SUBMITTED_UNITS","RELATEDNAMES2","SHORTNAME","ORDER_OBS","CDISC_COMMON_TESTS","HL7_FIELD_SUBFIELD_ID","EXTERNAL_COPYRIGHT_NOTICE","EXAMPLE_UNITS","LONG_COMMON_NAME","UnitsAndRange","DOCUMENT_SECTION","EXAMPLE_UCUM_UNITS","EXAMPLE_SI_UCUM_UNITS","STATUS_REASON","STATUS_TEXT","CHANGE_REASON_PUBLIC","COMMON_TEST_RANK","COMMON_ORDER_RANK","COMMON_SI_TEST_RANK","HL7_ATTACHMENT_STRUCTURE","EXTERNAL_COPYRIGHT_LINK","PanelType","AskAtOrderEntry","AssociatedObservations"
|
||||
"10013-1","R' wave amplitude.lead I","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-I; R wave Amp L-I; Random; Right; Voltage","R' wave Amp L-I","Observation",,,,"mV","R' wave amplitude in lead I",,,"mV",,,,,0,0,0,,,,,
|
||||
"10014-9","R' wave amplitude.lead II","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"2; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-II; R wave Amp L-II; Random; Right; Voltage","R' wave Amp L-II","Observation",,,,"mV","R' wave amplitude in lead II",,,"mV",,,,,0,0,0,,,,,
|
||||
"10015-6","R' wave amplitude.lead III","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"3; Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-III; R wave Amp L-III; Random; Right; Voltage","R' wave Amp L-III","Observation",,,,"mV","R' wave amplitude in lead III",,,"mV",,,,,0,0,0,,,,,
|
||||
"10016-4","R' wave amplitude.lead V1","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V1; R wave Amp L-V1; Random; Right; Voltage","R' wave Amp L-V1","Observation",,,,"mV","R' wave amplitude in lead V1",,,"mV",,,,,0,0,0,,,,,
|
||||
"1001-7","DBG Ab","Pr","Pt","Ser/Plas^donor","Ord",,"BLDBK","FS","2.44","MIN",,"ACTIVE",,1,,,,,,,,"ABS; Aby; Antby; Anti; Antibodies; Antibody; Autoantibodies; Autoantibody; BLOOD BANK; Donna Bennett-Goodspeed; Donr; Ordinal; Pl; Plasma; Plsm; Point in time; QL; Qual; Qualitative; Random; Screen; SerP; SerPl; SerPl^donor; SerPlas; Serum; Serum or plasma; SR","DBG Ab SerPl Donr Ql","Observation",,,,,"DBG Ab [Presence] in Serum or Plasma from donor",,,,,,,"The Property has been changed from ACnc to Pr (Presence) to reflect the new model for ordinal terms where results are based on presence or absence.",0,0,0,,,,,
|
||||
"10017-2","R' wave amplitude.lead V2","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V2; R wave Amp L-V2; Random; Right; Voltage","R' wave Amp L-V2","Observation",,,,"mV","R' wave amplitude in lead V2",,,"mV",,,,,0,0,0,,,,,
|
||||
"10018-0","R' wave amplitude.lead V3","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V3; R wave Amp L-V3; Random; Right; Voltage","R' wave Amp L-V3","Observation",,,,"mV","R' wave amplitude in lead V3",,,"mV",,,,,0,0,0,,,,,
|
||||
"10019-8","R' wave amplitude.lead V4","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V4; R wave Amp L-V4; Random; Right; Voltage","R' wave Amp L-V4","Observation",,,,"mV","R' wave amplitude in lead V4",,,"mV",,,,,0,0,0,,,,,
|
||||
"10020-6","R' wave amplitude.lead V5","Elpot","Pt","Heart","Qn","EKG","EKG.MEAS","CH","2.48","MIN",,"ACTIVE",,2,,,,,,"Y",,"Cardiac; ECG; EKG.MEASUREMENTS; Electrical potential; Electrocardiogram; Electrocardiograph; Hrt; Painter's colic; PB; Plumbism; Point in time; QNT; Quan; Quant; Quantitative; R prime; R' wave Amp L-V5; R wave Amp L-V5; Random; Right; Voltage","R' wave Amp L-V5","Observation",,,,"mV","R' wave amplitude in lead V5",,,"mV",,,,,0,0,0,,,,,
|
|
@ -11,6 +11,7 @@ import java.util.Set;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.hl7.fhir.dstu3.exceptions.TerminologyServiceException;
|
||||
import org.hl7.fhir.dstu3.formats.IParser;
|
||||
import org.hl7.fhir.dstu3.formats.ParserType;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport.CodeValidationResult;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package org.hl7.fhir.dstu3.terminologies;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
@ -46,6 +48,7 @@ import org.hl7.fhir.dstu3.model.Type;
|
||||
import org.hl7.fhir.dstu3.model.UriType;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent;
|
||||
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
|
||||
@ -144,20 +147,16 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
||||
}
|
||||
|
||||
private void includeCodes(ConceptSetComponent inc, List<ValueSetExpansionParameterComponent> params) throws TerminologyServiceException, ETooCostly {
|
||||
if (context.supportsSystem(inc.getSystem())) {
|
||||
try {
|
||||
int i = codes.size();
|
||||
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
|
||||
if ((cs == null || cs.getContent() != CodeSystemContentMode.COMPLETE) && context.supportsSystem(inc.getSystem())) {
|
||||
addCodes(context.expandVS(inc), params);
|
||||
if (codes.size() > i)
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// ok, we'll try locally
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CodeSystem cs = context.fetchCodeSystem(inc.getSystem());
|
||||
if (cs == null)
|
||||
throw new TerminologyServiceException("unable to find code system "+inc.getSystem().toString());
|
||||
if (cs == null)
|
||||
throw new TerminologyServiceException("unable to find code system "+inc.getSystem().toString());
|
||||
if (cs.getContent() != CodeSystemContentMode.COMPLETE)
|
||||
throw new TerminologyServiceException("Code system "+inc.getSystem().toString()+" is incomplete");
|
||||
if (cs.hasVersion())
|
||||
if (!existsInParams(params, "version", new UriType(cs.getUrl()+"?version="+cs.getVersion())))
|
||||
params.add(new ValueSetExpansionParameterComponent().setName("version").setValue(new UriType(cs.getUrl()+"?version="+cs.getVersion())));
|
||||
@ -181,8 +180,17 @@ public class ValueSetExpanderSimple implements ValueSetExpander {
|
||||
if (def == null)
|
||||
throw new TerminologyServiceException("Code '"+fc.getValue()+"' not found in system '"+inc.getSystem()+"'");
|
||||
addCodeAndDescendents(cs, inc.getSystem(), def);
|
||||
} else if ("display".equals(fc.getProperty()) && fc.getOp() == FilterOperator.EQUAL) {
|
||||
ConceptDefinitionComponent def = getConceptForCode(cs.getConcept(), fc.getValue());
|
||||
if (def != null) {
|
||||
if (isNotBlank(def.getDisplay()) && isNotBlank(fc.getValue())) {
|
||||
if (def.getDisplay().contains(fc.getValue())) {
|
||||
addCode(inc.getSystem(), def.getCode(), def.getDisplay());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
throw new NotImplementedException("not done yet");
|
||||
throw new NotImplementedException("Search by property[" + fc.getProperty() + "] and op[" + fc.getOp() + "] is not supported yet");
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user