From 7c5cf9f1f44f0e4478b3954c467ae15dd25f270c Mon Sep 17 00:00:00 2001 From: Diederik Muylwyk Date: Wed, 25 Sep 2019 17:33:45 -0400 Subject: [PATCH] Incremental progress for ancestor/descendant filters. --- .../jpa/term/BaseHapiTerminologySvcImpl.java | 51 +++++++++++++++---- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java index a88c8c4a3bd..017fbb6a329 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/term/BaseHapiTerminologySvcImpl.java @@ -872,19 +872,17 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, break; case "parent": case "child": - if (isCodeSystemLoinc(theSystem)) { - handleFilterLoincParentChild(theQb, theBool, theFilter); - } else { - throw new InvalidRequestException("Invalid filter, property " + theFilter.getProperty() + " is LOINC-specific and cannot be used with system: " + theSystem); - } + isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); + handleFilterLoincParentChild(theQb, theBool, theFilter); + break; + case "ancestor": + case "descendant": + isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); + handleFilterLoincAncestorDescendant(theQb, theBool, theFilter); break; - // FIXME: DM 2019-09-24 - Need to implement LOINC-specific filters for "ancestor" and "descendant". case "copyright": - if (isCodeSystemLoinc(theSystem)) { - handleFilterLoincCopyright(theQb, theBool, theFilter); - } else { - throw new InvalidRequestException("Invalid filter, property " + theFilter.getProperty() + " is LOINC-specific and cannot be used with system: " + theSystem); - } + isCodeSystemLoingOrThrowInvalidRequestException(theSystem, theFilter.getProperty()); + handleFilterLoincCopyright(theQb, theBool, theFilter); break; default: handleFilterRegex(theBool, theFilter); @@ -892,6 +890,13 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, } } + private boolean isCodeSystemLoingOrThrowInvalidRequestException(String theSystem, String theProperty) { + if (!isCodeSystemLoinc(theSystem)) { + throw new InvalidRequestException("Invalid filter, property " + theProperty + " is LOINC-specific and cannot be used with system: " + theSystem); + } + return true; + } + private boolean isCodeSystemLoinc(String theSystem) { return IHapiTerminologyLoaderSvc.LOINC_URI.equals(theSystem); } @@ -965,6 +970,30 @@ public abstract class BaseHapiTerminologySvcImpl implements IHapiTerminologySvc, return new Term(TermConceptPropertyFieldBridge.CONCEPT_FIELD_PROPERTY_PREFIX + theProperty, theValue); } + private void handleFilterLoincAncestorDescendant(QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) { + addLoincFilterAncestorDescendantEqual(theBool, theFilter.getProperty(), theFilter.getValue()); + } else if (theFilter.getOp() == ValueSet.FilterOperator.IN) { + addLoincFilterAncestorDescendantIn(theBool, theFilter); + } else { + throw new InvalidRequestException("Don't know how to handle op=" + theFilter.getOp() + " on property " + theFilter.getProperty()); + } + } + + private void addLoincFilterAncestorDescendantEqual(BooleanJunction theBool, String theProperty, String theValue) { + logFilteringValueOnProperty(theValue, theProperty); + // FIXME: DM 2019-09-25 - Filter with op=EQUAL on ancestor/descendant + } + + private void addLoincFilterAncestorDescendantIn(BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { + String[] values = theFilter.getValue().split(","); + List terms = new ArrayList<>(); + for (String value : values) { + logFilteringValueOnProperty(value, theFilter.getProperty()); + // FIXME: DM 2019-09-25 - Filter with op=IN on ancestor/descendant + } + } + private void handleFilterLoincCopyright(QueryBuilder theQb, BooleanJunction theBool, ValueSet.ConceptSetFilterComponent theFilter) { if (theFilter.getOp() == ValueSet.FilterOperator.EQUAL) {