Support extensions pointing to references for JPA custom search params
This commit is contained in:
parent
bf94d78872
commit
54055f5bfb
|
@ -195,6 +195,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
if (myLowerBound.getPrefix() != null) {
|
if (myLowerBound.getPrefix() != null) {
|
||||||
switch (myLowerBound.getPrefix()) {
|
switch (myLowerBound.getPrefix()) {
|
||||||
case GREATERTHAN:
|
case GREATERTHAN:
|
||||||
|
case STARTS_AFTER:
|
||||||
retVal = myLowerBound.getPrecision().add(retVal, 1);
|
retVal = myLowerBound.getPrecision().add(retVal, 1);
|
||||||
break;
|
break;
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
|
@ -205,7 +206,6 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
case LESSTHAN_OR_EQUALS:
|
case LESSTHAN_OR_EQUALS:
|
||||||
case ENDS_BEFORE:
|
case ENDS_BEFORE:
|
||||||
case NOT_EQUAL:
|
case NOT_EQUAL:
|
||||||
case STARTS_AFTER:
|
|
||||||
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix());
|
throw new IllegalStateException("Unvalid lower bound comparator: " + myLowerBound.getPrefix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,6 +224,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
if (myUpperBound.getPrefix() != null) {
|
if (myUpperBound.getPrefix() != null) {
|
||||||
switch (myUpperBound.getPrefix()) {
|
switch (myUpperBound.getPrefix()) {
|
||||||
case LESSTHAN:
|
case LESSTHAN:
|
||||||
|
case ENDS_BEFORE:
|
||||||
retVal = new Date(retVal.getTime() - 1L);
|
retVal = new Date(retVal.getTime() - 1L);
|
||||||
break;
|
break;
|
||||||
case EQUAL:
|
case EQUAL:
|
||||||
|
@ -234,7 +235,6 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
||||||
case GREATERTHAN_OR_EQUALS:
|
case GREATERTHAN_OR_EQUALS:
|
||||||
case GREATERTHAN:
|
case GREATERTHAN:
|
||||||
case APPROXIMATE:
|
case APPROXIMATE:
|
||||||
case ENDS_BEFORE:
|
|
||||||
case NOT_EQUAL:
|
case NOT_EQUAL:
|
||||||
case STARTS_AFTER:
|
case STARTS_AFTER:
|
||||||
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix());
|
throw new IllegalStateException("Unvalid upper bound comparator: " + myUpperBound.getPrefix());
|
||||||
|
|
|
@ -59,16 +59,7 @@ import org.apache.http.client.utils.URLEncodedUtils;
|
||||||
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
|
import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
|
||||||
import org.hl7.fhir.dstu3.model.IdType;
|
import org.hl7.fhir.dstu3.model.IdType;
|
||||||
import org.hl7.fhir.dstu3.model.StringType;
|
import org.hl7.fhir.dstu3.model.StringType;
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IDomainResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IIdType;
|
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
|
@ -262,8 +253,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
Map<String, RuntimeSearchParam> searchParams = mySearchParamRegistry.getActiveSearchParams(toResourceName(theResource.getClass()));
|
||||||
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
|
for (RuntimeSearchParam nextSpDef : searchParams.values()) {
|
||||||
|
|
||||||
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
|
if (nextSpDef.getParamType() != RestSearchParameterTypeEnum.REFERENCE) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -283,6 +274,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||||
for (PathAndRef nextPathAndRef : refs) {
|
for (PathAndRef nextPathAndRef : refs) {
|
||||||
Object nextObject = nextPathAndRef.getRef();
|
Object nextObject = nextPathAndRef.getRef();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A search parameter on an extension field that contains
|
||||||
|
* references should index those references
|
||||||
|
*/
|
||||||
|
if (nextObject instanceof IBaseExtension<?, ?>) {
|
||||||
|
nextObject = ((IBaseExtension<?, ?>) nextObject).getValue();
|
||||||
|
}
|
||||||
|
|
||||||
IIdType nextId;
|
IIdType nextId;
|
||||||
if (nextObject instanceof IBaseReference) {
|
if (nextObject instanceof IBaseReference) {
|
||||||
IBaseReference nextValue = (IBaseReference) nextObject;
|
IBaseReference nextValue = (IBaseReference) nextObject;
|
||||||
|
|
|
@ -93,7 +93,7 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor
|
||||||
return myContext;
|
return myContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
|
public Collection<RuntimeSearchParam> getSearchParams(IBaseResource theResource) {
|
||||||
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
|
||||||
Collection<RuntimeSearchParam> retVal = mySearchParamRegistry.getActiveSearchParams(def.getName()).values();
|
Collection<RuntimeSearchParam> retVal = mySearchParamRegistry.getActiveSearchParams(def.getName()).values();
|
||||||
List<RuntimeSearchParam> defaultList= Collections.emptyList();
|
List<RuntimeSearchParam> defaultList= Collections.emptyList();
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.hl7.fhir.dstu3.model.CodeType;
|
import org.hl7.fhir.dstu3.model.CodeType;
|
||||||
|
@ -18,6 +19,9 @@ import org.junit.AfterClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.Practitioner;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
import ca.uhn.fhir.rest.param.TokenParam;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||||
|
@ -284,6 +288,34 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
||||||
assertThat(foundResources, contains(patId.getValue()));
|
assertThat(foundResources, contains(patId.getValue()));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCustomReferenceParameter() throws Exception {
|
||||||
|
SearchParameter sp = new SearchParameter();
|
||||||
|
sp.addBase("Patient");
|
||||||
|
sp.setCode("myDoctor");
|
||||||
|
sp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE);
|
||||||
|
sp.setTitle("My Doctor");
|
||||||
|
sp.setExpression("Patient.extension('http://fmcna.com/myDoctor')");
|
||||||
|
sp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
|
sp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
mySearchParameterDao.create(sp);
|
||||||
|
|
||||||
|
org.hl7.fhir.dstu3.model.Practitioner pract = new org.hl7.fhir.dstu3.model.Practitioner();
|
||||||
|
pract.setId("A");
|
||||||
|
pract.addName().setFamily("PRACT");
|
||||||
|
myPractitionerDao.update(pract);
|
||||||
|
|
||||||
|
Patient pat = myFhirCtx.newJsonParser().parseResource(Patient.class, loadClasspath("/dstu3_custom_resource_patient.json"));
|
||||||
|
IIdType pid = myPatientDao.create(pat, mySrd).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
SearchParameterMap params = new SearchParameterMap();
|
||||||
|
params.add("myDoctor", new ReferenceParam("A"));
|
||||||
|
IBundleProvider outcome = myPatientDao.search(params);
|
||||||
|
List<String> ids = toUnqualifiedVersionlessIdValues(outcome);
|
||||||
|
ourLog.info("IDS: " + ids);
|
||||||
|
assertThat(ids, contains(pid.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void afterClassClearContext() {
|
public static void afterClassClearContext() {
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"resourceType": "Patient",
|
||||||
|
"extension": [
|
||||||
|
{
|
||||||
|
"url": "http://fmcna.com/myDoctor",
|
||||||
|
"valueReference": {
|
||||||
|
"reference": "Practitioner/A"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"identifier": [{
|
||||||
|
"type": {
|
||||||
|
"coding": [{
|
||||||
|
"system": "http://hl7.org/fhir/v2/0203",
|
||||||
|
"code": "MR"
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
"system": "http://hl7.org/fhir/v2/0203",
|
||||||
|
"value": "5000077430"
|
||||||
|
}],
|
||||||
|
"name": [{
|
||||||
|
"use": "official",
|
||||||
|
"family": "Ravi",
|
||||||
|
"given": [
|
||||||
|
"Kuchi"
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
|
@ -68,6 +68,11 @@
|
||||||
<![CDATA[<code>IFhirResourceDao#removeTag(IIdType, TagTypeEnum, String, String)</code>]]>. This allows client code to remove tags
|
<![CDATA[<code>IFhirResourceDao#removeTag(IIdType, TagTypeEnum, String, String)</code>]]>. This allows client code to remove tags
|
||||||
from a resource without having a servlet request object in context.
|
from a resource without having a servlet request object in context.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
JPA server was unable to process custom search parameters where
|
||||||
|
the path pointed to an extension containing a reference. Thanks
|
||||||
|
to Ravi Kuchi for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.3" date="2017-03-18">
|
<release version="2.3" date="2017-03-18">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
|
Loading…
Reference in New Issue