Implement the parent and child filters for LOINC. #1453

This commit is contained in:
Diederik Muylwyk 2019-09-15 21:52:33 -04:00
parent 9b1af6b207
commit b05c5f3f71
2 changed files with 597 additions and 121 deletions

View File

@ -199,20 +199,6 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
}
}
private void addCopyrightFilter3rdParty(BooleanJunction<?> bool) {
// FIXME: DM 2019-09-13 - This feels hacky but it works until we have a better way for filtering TermConcept based on TermConceptProperty.
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + "EXTERNAL_COPYRIGHT_NOTICE", ".*");
RegexpQuery query = new RegexpQuery(term);
bool.must(query);
}
private void addCopyrightFilterLoinc(BooleanJunction<?> bool) {
// FIXME: DM 2019-09-13 - This feels hacky but it works until we have a better way for filtering TermConcept based on TermConceptProperty.
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + "EXTERNAL_COPYRIGHT_NOTICE", ".*");
RegexpQuery query = new RegexpQuery(term);
bool.must(query).not();
}
private void addDisplayFilterExact(QueryBuilder qb, BooleanJunction<?> bool, ValueSet.ConceptSetFilterComponent nextFilter) {
bool.must(qb.phrase().onField("myDisplay").sentence(nextFilter.getValue()).createQuery());
}
@ -705,11 +691,11 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
/**
* @return Returns true if there are potentially more results to process.
*/
private Boolean expandValueSetHandleIncludeOrExclude(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theInclude, boolean theAdd, AtomicInteger theCodeCounter, int theQueryIndex) {
private Boolean expandValueSetHandleIncludeOrExclude(IValueSetConceptAccumulator theValueSetCodeAccumulator, Set<String> theAddedCodes, ValueSet.ConceptSetComponent theIncludeOrExclude, boolean theAdd, AtomicInteger theCodeCounter, int theQueryIndex) {
String system = theInclude.getSystem();
String system = theIncludeOrExclude.getSystem();
boolean hasSystem = isNotBlank(system);
boolean hasValueSet = theInclude.getValueSet().size() > 0;
boolean hasValueSet = theIncludeOrExclude.getValueSet().size() > 0;
if (hasSystem) {
ourLog.info("Starting {} expansion around CodeSystem: {}", (theAdd ? "inclusion" : "exclusion"), system);
@ -725,7 +711,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
* since we're going to do it without the database.
*/
if (myFulltextSearchSvc == null) {
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theInclude, system, theAdd, theCodeCounter);
expandWithoutHibernateSearch(theValueSetCodeAccumulator, theAddedCodes, theIncludeOrExclude, system, theAdd, theCodeCounter);
return false;
}
@ -740,20 +726,14 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
/*
* Filters
*/
if (theInclude.getFilter().size() > 0) {
for (ValueSet.ConceptSetFilterComponent nextFilter : theInclude.getFilter()) {
handleFilter(system, qb, bool, nextFilter);
}
}
handleFilters(bool, system, qb, theIncludeOrExclude);
Query luceneQuery = bool.createQuery();
/*
* Include Concepts
* Include/Exclude Concepts
*/
List<Term> codes = theInclude
List<Term> codes = theIncludeOrExclude
.getConcept()
.stream()
.filter(Objects::nonNull)
@ -773,8 +753,8 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
/*
* Execute the query
*/
FullTextQuery jpaQuery = em.createFullTextQuery(luceneQuery, TermConcept.class);
/*
* DM 2019-08-21 - Processing slows after any ValueSets with many codes explicitly identified. This might
* be due to the dark arts that is memory management. Will monitor but not do anything about this right now.
@ -813,15 +793,15 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
}
} else {
// No codesystem matching the URL found in the database
// No CodeSystem matching the URL found in the database.
CodeSystem codeSystemFromContext = getCodeSystemFromContext(system);
if (codeSystemFromContext == null) {
throw new InvalidRequestException("Unknown code system: " + system);
}
if (!theInclude.getConcept().isEmpty()) {
for (ValueSet.ConceptReferenceComponent next : theInclude.getConcept()) {
if (!theIncludeOrExclude.getConcept().isEmpty()) {
for (ValueSet.ConceptReferenceComponent next : theIncludeOrExclude.getConcept()) {
String nextCode = next.getCode();
if (isNoneBlank(system, nextCode) && !theAddedCodes.contains(system + "|" + nextCode)) {
CodeSystem.ConceptDefinitionComponent code = findCode(codeSystemFromContext.getConcept(), nextCode);
@ -844,7 +824,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
}
} else if (hasValueSet) {
for (CanonicalType nextValueSet : theInclude.getValueSet()) {
for (CanonicalType nextValueSet : theIncludeOrExclude.getValueSet()) {
ourLog.info("Starting {} expansion around ValueSet: {}", (theAdd ? "inclusion" : "exclusion"), nextValueSet.getValueAsString());
List<VersionIndependentConcept> expanded = expandValueSet(nextValueSet.getValueAsString());
@ -874,74 +854,163 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
}
private void handleFilter(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent nextFilter) {
if (isBlank(nextFilter.getValue()) && nextFilter.getOp() == null && isBlank(nextFilter.getProperty())) {
private void handleFilters(BooleanJunction<?> theBool, String theSystem, QueryBuilder theQb, ValueSet.ConceptSetComponent theIncludeOrExclude) {
if (theIncludeOrExclude.getFilter().size() > 0) {
for (ValueSet.ConceptSetFilterComponent nextFilter : theIncludeOrExclude.getFilter()) {
handleFilter(theSystem, theQb, theBool, nextFilter);
}
}
}
private void handleFilter(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
if (isBlank(theFilter.getValue()) && theFilter.getOp() == null && isBlank(theFilter.getProperty())) {
return;
}
if (isBlank(nextFilter.getValue()) || nextFilter.getOp() == null || isBlank(nextFilter.getProperty())) {
if (isBlank(theFilter.getValue()) || theFilter.getOp() == null || isBlank(theFilter.getProperty())) {
throw new InvalidRequestException("Invalid filter, must have fields populated: property op value");
}
if (nextFilter.getProperty().equals("display:exact") || nextFilter.getProperty().equals("display")) {
handleDisplayFilter(theQb, theBool, nextFilter);
} else if (nextFilter.getProperty().equals("concept") || nextFilter.getProperty().equals("code")) {
handleConceptAndCodeFilter(theSystem, theQb, theBool, nextFilter);
} else if (nextFilter.getProperty().equals("copyright")) {
handleLoincCopyrightFilter(theQb, theBool, nextFilter);
switch (theFilter.getProperty()) {
case "display:exact":
case "display":
handleFilterDisplay(theQb, theBool, theFilter);
break;
case "concept":
case "code":
handleFilterConceptAndCode(theSystem, theQb, theBool, theFilter);
break;
case "parent":
case "child":
handleFilterLoincParentChild(theSystem, theQb, theBool, theFilter);
break;
case "copyright":
handleFilterLoincCopyright(theSystem, theQb, theBool, theFilter);
break;
default:
handleFilterRegex(theBool, theFilter);
break;
}
}
private void handleFilterDisplay(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
if (theFilter.getProperty().equals("display:exact") && theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
addDisplayFilterExact(theQb, theBool, theFilter);
} else if (theFilter.getProperty().equals("display") && theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
if (theFilter.getValue().trim().contains(" ")) {
addDisplayFilterExact(theQb, theBool, theFilter);
} else {
handleRegexFilter(theBool, nextFilter);
}
}
private void handleDisplayFilter(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent nextFilter) {
if (nextFilter.getProperty().equals("display:exact") && nextFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
addDisplayFilterExact(theQb, theBool, nextFilter);
} else if (nextFilter.getProperty().equals("display") && nextFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
if (nextFilter.getValue().trim().contains(" ")) {
addDisplayFilterExact(theQb, theBool, nextFilter);
} else {
addDisplayFilterInexact(theQb, theBool, nextFilter);
addDisplayFilterInexact(theQb, theBool, theFilter);
}
}
}
private void handleConceptAndCodeFilter(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent nextFilter) {
TermConcept code = findCode(theSystem, nextFilter.getValue())
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + theSystem + "}" + nextFilter.getValue()));
private void handleFilterConceptAndCode(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
TermConcept code = findCode(theSystem, theFilter.getValue())
.orElseThrow(() -> new InvalidRequestException("Invalid filter criteria - code does not exist: {" + theSystem + "}" + theFilter.getValue()));
if (nextFilter.getOp() == ValueSet.FilterOperator.ISA) {
if (theFilter.getOp() == ValueSet.FilterOperator.ISA) {
ourLog.info(" * Filtering on codes with a parent of {}/{}/{}", code.getId(), code.getCode(), code.getDisplay());
theBool.must(theQb.keyword().onField("myParentPids").matching("" + code.getId()).createQuery());
} else {
throw new InvalidRequestException("Don't know how to handle op=" + nextFilter.getOp() + " on property " + nextFilter.getProperty());
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
}
}
private void handleLoincCopyrightFilter(QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent nextFilter) {
if (nextFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
private void handleFilterLoincParentChild(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
if (isNotCodeSystemLoinc(theSystem)) {
return;
}
String copyrightFilterValue = defaultString(nextFilter.getValue()).toLowerCase();
if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
addLoincFilterParentChildEqual(theBool, theFilter.getProperty(), theFilter.getValue());
} else if (theFilter.getOp() == ValueSet.FilterOperator.IN) {
addLoincFilterParentChildIn(theBool, theFilter);
} else {
throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty());
}
}
private boolean isCodeSystemLoinc(String theSystem) {
return IHapiTerminologyLoaderSvc.LOINC_URI.equals(theSystem);
}
private boolean isNotCodeSystemLoinc(String theSystem) {
return !isCodeSystemLoinc(theSystem);
}
private void addLoincFilterParentChildEqual(BooleanJunction<?> theBool, String theProperty, String theValue) {
logFilteringValueOnProperty(theValue, theProperty);
theBool.must(new TermsQuery(getPropertyTerm(theProperty, theValue)));
}
private void addLoincFilterParentChildIn(BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
String[] values = theFilter.getValue().split(",");
List<Term> terms = new ArrayList<>();
for (String value : values) {
logFilteringValueOnProperty(value, theFilter.getProperty());
terms.add(getPropertyTerm(theFilter.getProperty(), value));
}
theBool.must(new TermsQuery(terms));
}
private Term getPropertyTerm(String theProperty, String theValue) {
return new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theProperty, theValue);
}
private void handleFilterLoincCopyright(String theSystem, QueryBuilder theQb, BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
if (isNotCodeSystemLoinc(theSystem)) {
return;
}
if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {
String copyrightFilterValue = defaultString(theFilter.getValue()).toLowerCase();
switch (copyrightFilterValue) {
case "loinc":
ourLog.info(" * Filtering with value=" + nextFilter.getValue() + " on property " + nextFilter.getProperty());
addCopyrightFilterLoinc(theBool);
break;
case "3rdparty":
ourLog.info(" * Filtering with value=" + nextFilter.getValue() + " on property " + nextFilter.getProperty());
addCopyrightFilter3rdParty(theBool);
logFilteringValueOnProperty(theFilter.getValue(), theFilter.getProperty());
addFilterLoincCopyright3rdParty(theBool);
break;
case "loinc":
logFilteringValueOnProperty(theFilter.getValue(), theFilter.getProperty());
addFilterLoincCopyrightLoinc(theBool);
break;
default:
throw new InvalidRequestException("Don't know how to handle value=" + nextFilter.getValue() + " on property " + nextFilter.getProperty());
throwInvalidRequestForValueOnProperty(theFilter.getValue(), theFilter.getProperty());
}
} else {
throw new InvalidRequestException("Don't know how to handle op=" + nextFilter.getOp() + " on property " + nextFilter.getProperty());
throwInvalidRequestForOpOnProperty(theFilter.getOp(), theFilter.getProperty());
}
}
private void handleRegexFilter(BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent nextFilter) {
if (nextFilter.getOp() == ValueSet.FilterOperator.REGEX) {
private void addFilterLoincCopyright3rdParty(BooleanJunction<?> theBool) {
theBool.must(getRegexQueryForFilterLoincCopyright());
}
private void addFilterLoincCopyrightLoinc(BooleanJunction<?> theBool) {
theBool.must(getRegexQueryForFilterLoincCopyright()).not();
}
private RegexpQuery getRegexQueryForFilterLoincCopyright() {
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + "EXTERNAL_COPYRIGHT_NOTICE", ".*");
return new RegexpQuery(term);
}
private void logFilteringValueOnProperty(String theValue, String theProperty) {
ourLog.info(" * Filtering with value={} on property {}", theValue, theProperty);
}
private void throwInvalidRequestForOpOnProperty(ValueSet.FilterOperator theOp, String theProperty) {
throw new InvalidRequestException("Don't know how to handle op=" + theOp + " on property " + theProperty);
}
private void throwInvalidRequestForValueOnProperty(String theValue, String theProperty) {
throw new InvalidRequestException("Don't know how to handle value=" + theValue + " on property " + theProperty);
}
private void handleFilterRegex(BooleanJunction<?> theBool, ValueSet.ConceptSetFilterComponent theFilter) {
if (theFilter.getOp() == ValueSet.FilterOperator.REGEX) {
/*
* We treat the regex filter as a match on the regex
@ -949,7 +1018,7 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
* say whether or not this is the right behaviour, but
* there are examples that seem to suggest that it is.
*/
String value = nextFilter.getValue();
String value = theFilter.getValue();
if (value.endsWith("$")) {
value = value.substring(0, value.length() - 1);
} else if (!value.endsWith(".*")) {
@ -961,14 +1030,14 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc,
value = value.substring(1);
}
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + nextFilter.getProperty(), value);
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theFilter.getProperty(), value);
RegexpQuery query = new RegexpQuery(term);
theBool.must(query);
} else {
String value = nextFilter.getValue();
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + nextFilter.getProperty(), value);
String value = theFilter.getValue();
Term term = new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theFilter.getProperty(), value);
theBool.must(new TermsQuery(term));
}

View File

@ -31,6 +31,7 @@ import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import static ca.uhn.fhir.jpa.term.IHapiTerminologyLoaderSvc.LOINC_URI;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
@ -124,7 +125,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
public void createLoincSystemWithSomeCodes() {
runInTransaction(() -> {
CodeSystem codeSystem = new CodeSystem();
codeSystem.setUrl(CS_URL);
codeSystem.setUrl(LOINC_URI);
codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
@ -133,27 +134,57 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
TermCodeSystemVersion cs = new TermCodeSystemVersion();
cs.setResource(table);
TermConcept code;
code = new TermConcept(cs, "50015-7");
code.addPropertyString("SYSTEM", "Bld/Bone mar^Donor");
cs.getConcepts().add(code);
TermConcept code1 = new TermConcept(cs, "50015-7");
TermConcept code2 = new TermConcept(cs, "43343-3");
TermConcept code3 = new TermConcept(cs, "43343-4");
TermConcept code4 = new TermConcept(cs, "47239-9");
code = new TermConcept(cs, "43343-3");
code.addPropertyString("SYSTEM", "Ser");
code.addPropertyString("HELLO", "12345-1");
cs.getConcepts().add(code);
code1.addPropertyString("SYSTEM", "Bld/Bone mar^Donor");
code1.addPropertyCoding(
"child",
LOINC_URI,
code2.getCode(),
code2.getDisplay());
cs.getConcepts().add(code1);
code = new TermConcept(cs, "43343-4");
code.addPropertyString("SYSTEM", "Ser");
code.addPropertyString("HELLO", "12345-2");
cs.getConcepts().add(code);
code2.addPropertyString("SYSTEM", "Ser");
code2.addPropertyString("HELLO", "12345-1");
code2.addPropertyCoding(
"parent",
LOINC_URI,
code1.getCode(),
code1.getDisplay());
code2.addPropertyCoding(
"child",
LOINC_URI,
code3.getCode(),
code3.getDisplay());
code2.addPropertyCoding(
"child",
LOINC_URI,
code4.getCode(),
code4.getDisplay());
cs.getConcepts().add(code2);
code = new TermConcept(cs, "47239-9");
code.addPropertyString("SYSTEM", "^Patient");
code.addPropertyString("EXTERNAL_COPYRIGHT_NOTICE", "Copyright © 2006 World Health Organization...");
cs.getConcepts().add(code);
code3.addPropertyString("SYSTEM", "Ser");
code3.addPropertyString("HELLO", "12345-2");
code3.addPropertyCoding(
"parent",
LOINC_URI,
code2.getCode(),
code2.getDisplay());
cs.getConcepts().add(code3);
myTermSvc.storeNewCodeSystemVersion(table.getId(), CS_URL, "SYSTEM NAME", "SYSTEM VERSION" , cs);
code4.addPropertyString("SYSTEM", "^Patient");
code4.addPropertyString("EXTERNAL_COPYRIGHT_NOTICE", "Copyright © 2006 World Health Organization...");
code4.addPropertyCoding(
"parent",
LOINC_URI,
code2.getCode(),
code2.getDisplay());
cs.getConcepts().add(code4);
myTermSvc.storeNewCodeSystemVersion(table.getId(), LOINC_URI, "SYSTEM NAME", "SYSTEM VERSION" , cs);
});
}
@ -279,7 +310,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithExclude3rdParty() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithExclude3rdParty() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -291,10 +322,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("copyright")
@ -308,10 +339,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("copyright")
@ -323,7 +354,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithExcludeLoinc() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithExcludeLoinc() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -335,10 +366,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("copyright")
@ -352,10 +383,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("copyright")
@ -367,7 +398,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithInclude3rdParty() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithInclude3rdParty() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -378,7 +409,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -391,7 +422,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -403,7 +434,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithIncludeLoinc() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithIncludeLoinc() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -414,7 +445,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -427,7 +458,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -439,7 +470,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithUnsupportedOp() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithUnsupportedOp() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -450,7 +481,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -465,7 +496,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
@Test
public void testExpandValueSetPropertyFilterCopyrightWithUnsupportedValue() {
public void testExpandValueSetPropertyFilterLoincCopyrightWithUnsupportedValue() {
createLoincSystemWithSomeCodes();
List<String> codes;
@ -476,7 +507,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("copyright")
@ -490,6 +521,383 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
}
}
@Test
public void testExpandValueSetPropertyFilterLoincChildWithExcludeAndEqual() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent exclude;
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("50015-7");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-3");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-3", "43343-4", "47239-9"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-4");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
}
@Test
public void testExpandValueSetPropertyFilterLoincChildWithExcludeAndIn() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent exclude;
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.IN)
.setValue("50015-7,43343-3,43343-4,47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-4", "47239-9"));
}
@Test
public void testExpandValueSetPropertyFilterLoincChildWithIncludeAndEqual() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent include;
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("50015-7");
outcome = myTermSvc.expandValueSet(vs);
assertEquals(0, outcome.getExpansion().getContains().size());
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-3");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7"));
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-4");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-3"));
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-3"));
}
@Test
public void testExpandValueSetPropertyFilterLoincChildWithIncludeAndIn() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent include;
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("child")
.setOp(ValueSet.FilterOperator.IN)
.setValue("50015-7,43343-3,43343-4,47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3"));
}
@Test
public void testExpandValueSetPropertyFilterLoincParentWithExcludeAndEqual() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent exclude;
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("50015-7");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-4", "47239-9"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-3");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-4");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7", "43343-3", "43343-4", "47239-9"));
}
@Test
public void testExpandValueSetPropertyFilterLoincParentWithExcludeAndIn() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent exclude;
// Include
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(LOINC_URI);
// Exclude
exclude = vs.getCompose().addExclude();
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.IN)
.setValue("50015-7,43343-3,43343-4,47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("50015-7"));
}
@Test
public void testExpandValueSetPropertyFilterLoincParentWithIncludeAndEqual() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent include;
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("50015-7");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-3"));
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-3");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-4", "47239-9"));
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("43343-4");
outcome = myTermSvc.expandValueSet(vs);
assertEquals(0, outcome.getExpansion().getContains().size());
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.EQUAL)
.setValue("47239-9");
outcome = myTermSvc.expandValueSet(vs);
assertEquals(0, outcome.getExpansion().getContains().size());
}
@Test
public void testExpandValueSetPropertyFilterLoincParentWithIncludeAndIn() {
createLoincSystemWithSomeCodes();
List<String> codes;
ValueSet vs;
ValueSet outcome;
ValueSet.ConceptSetComponent include;
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("parent")
.setOp(ValueSet.FilterOperator.IN)
.setValue("50015-7,43343-3,43343-4,47239-9");
outcome = myTermSvc.expandValueSet(vs);
codes = toCodesContains(outcome.getExpansion().getContains());
assertThat(codes, containsInAnyOrder("43343-3", "43343-4", "47239-9"));
}
@Test
public void testExpandValueSetPropertySearchWithRegexExclude() {
createLoincSystemWithSomeCodes();
@ -503,10 +911,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("SYSTEM")
@ -530,10 +938,10 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
vs = new ValueSet();
vs.getCompose()
.addInclude()
.setSystem(CS_URL);
.setSystem(LOINC_URI);
exclude = vs.getCompose().addExclude();
exclude.setSystem(CS_URL);
exclude.setSystem(LOINC_URI);
exclude
.addFilter()
.setProperty("HELLO")
@ -546,7 +954,6 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
@Test
public void testExpandValueSetPropertySearchWithRegexInclude() {
// create codes with "SYSTEM" property "Bld/Bone mar^Donor" and "Ser"
createLoincSystemWithSomeCodes();
List<String> codes;
@ -557,7 +964,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")
@ -570,7 +977,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")
@ -583,7 +990,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")
@ -596,7 +1003,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")
@ -609,7 +1016,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")
@ -622,7 +1029,7 @@ public class TerminologySvcImplDstu3Test extends BaseJpaDstu3Test {
// Include
vs = new ValueSet();
include = vs.getCompose().addInclude();
include.setSystem(CS_URL);
include.setSystem(LOINC_URI);
include
.addFilter()
.setProperty("SYSTEM")