all but unit tests

This commit is contained in:
Ken Stevens 2020-03-02 21:27:50 -05:00
parent 24acb57f3b
commit 27dcafe4f2
10 changed files with 513 additions and 474 deletions

View File

@ -39,6 +39,7 @@ import ca.uhn.fhir.jpa.model.search.StorageProcessingMessage;
import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry;
import ca.uhn.fhir.jpa.searchparam.util.DistanceHelper;
import ca.uhn.fhir.jpa.util.*; import ca.uhn.fhir.jpa.util.*;
import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
@ -160,7 +161,7 @@ public class SearchBuilder implements ISearchBuilder {
theParams.clean(); theParams.clean();
// Pull out near-distance first so when it comes time to evaluate near, we already know the distance // Pull out near-distance first so when it comes time to evaluate near, we already know the distance
theParams.setNearDistance(myResourceType); DistanceHelper.setNearDistance(myResourceType, theParams);
/* /*
* Check if there is a unique key associated with the set * Check if there is a unique key associated with the set

View File

@ -0,0 +1,134 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import ca.uhn.fhir.rest.param.TokenParam;
import org.hl7.fhir.dstu3.model.Location;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import java.util.List;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
public class FhirResourceDaoDstu3SearchDistanceTest extends BaseJpaDstu3Test {
@Autowired
MatchUrlService myMatchUrlService;
@Before
public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@Test
public void testNearSearchDistanceNoDistance() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + ":" + longitude,
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchDistanceZero() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + ":" + longitude +
"&" +
Location.SP_NEAR_DISTANCE + "=0||",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
@Test
public void testBadCoordsFormat() {
assertInvalidNearFormat("1:2:3");
assertInvalidNearFormat("1:");
assertInvalidNearFormat(":");
assertInvalidNearFormat("");
}
private void assertInvalidNearFormat(String theCoords) {
SearchParameterMap map = new SearchParameterMap();
map.add(Location.SP_NEAR, new TokenParam(theCoords));
map.setLoadSynchronous(true);
try {
myLocationDao.search(map);
fail();
} catch (InvalidDataAccessApiUsageException e) {
assertEquals("Invalid position format '" + theCoords + "'. Required format is 'latitude:longitude'", e.getCause().getMessage());
}
}
@Test
public void testNearMissingLat() {
SearchParameterMap map = new SearchParameterMap();
map.add(Location.SP_NEAR, new TokenParam(":2"));
map.setLoadSynchronous(true);
try {
myLocationDao.search(map);
fail();
} catch (InvalidDataAccessApiUsageException e) {
assertEquals("Invalid position format ':2'. Both latitude and longitude must be provided.", e.getCause().getMessage());
}
}
}

View File

@ -2,11 +2,9 @@ package ca.uhn.fhir.jpa.dao.dstu3;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.model.entity.*; import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
@ -36,8 +34,6 @@ import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore; import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate; import org.springframework.transaction.support.TransactionTemplate;
@ -59,9 +55,6 @@ import static org.mockito.Mockito.mock;
public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test { public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchNoFtTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchNoFtTest.class);
@Autowired
MatchUrlService myMatchUrlService;
@Before @Before
public void beforeDisableResultReuse() { public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null); myDaoConfig.setReuseCachedSearchResultsForMillis(null);
@ -3473,112 +3466,6 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
assertThat(ids.toString(), ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB")); assertThat(ids.toString(), ids, contains("Patient/AA", "Patient/AB", "Patient/BA", "Patient/BB"));
} }
@Test
public void testNearSearchDistanceNoDistance() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + ":" + longitude,
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchDistanceZero() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + ":" + longitude +
"&" +
Location.SP_NEAR_DISTANCE + "=0||",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + ":" + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + "|http://unitsofmeasure.org|km", myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
@Test
public void testBadCoordsFormat() {
assertInvalidNearFormat("1:2:3");
assertInvalidNearFormat("1:");
assertInvalidNearFormat(":");
assertInvalidNearFormat("");
}
private void assertInvalidNearFormat(String theCoords) {
SearchParameterMap map = new SearchParameterMap();
map.add(Location.SP_NEAR, new TokenParam(theCoords));
map.setLoadSynchronous(true);
try {
myLocationDao.search(map);
fail();
} catch (InvalidDataAccessApiUsageException e) {
assertEquals("Invalid position format '" + theCoords + "'. Required format is 'latitude:longitude'", e.getCause().getMessage());
}
}
@Test
public void testNearMissingLat() {
SearchParameterMap map = new SearchParameterMap();
map.add(Location.SP_NEAR, new TokenParam(":2"));
map.setLoadSynchronous(true);
try {
myLocationDao.search(map);
fail();
} catch (InvalidDataAccessApiUsageException e) {
assertEquals("Invalid position format ':2'. Both latitude and longitude must be provided.", e.getCause().getMessage());
}
}
private String toStringMultiline(List<?> theResults) { private String toStringMultiline(List<?> theResults) {
StringBuilder b = new StringBuilder(); StringBuilder b = new StringBuilder();
for (Object next : theResults) { for (Object next : theResults) {

View File

@ -0,0 +1,140 @@
package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import org.hl7.fhir.r4.model.Location;
import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
public class FhirResourceDaoR4SearchDistanceTest extends BaseJpaR4Test {
@Before
public void beforeDisableResultReuse() {
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@Autowired
MatchUrlService myMatchUrlService;
@Test
public void testNearSearchDistanceNoDistance() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LATITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude,
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchDistanceZero() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LATITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude + "|0",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude + "|0.0",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
}
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
bigEnoughDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
tooSmallDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
@Test
public void testNearSearchApproximateNearAntiMeridian() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_TAVEUNI;
double longitude = CoordCalculatorTest.LONGITIDE_TAVEUNI;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // We match even when the box crosses the anti-meridian
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_TAVEUNI;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_TAVEUNI + "|"
+ CoordCalculatorTest.LONGITIDE_TAVEUNI + "|" +
bigEnoughDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // We don't match outside a box that crosses the anti-meridian
double tooSmallDistance = CoordCalculatorTest.DISTANCE_TAVEUNI;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
tooSmallDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
}

View File

@ -3,18 +3,10 @@ package ca.uhn.fhir.jpa.dao.r4;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.jpa.dao.DaoConfig; import ca.uhn.fhir.jpa.dao.DaoConfig;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamDate; import ca.uhn.fhir.jpa.model.entity.*;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamNumber;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamQuantity;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken;
import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamUri;
import ca.uhn.fhir.jpa.model.entity.ResourceLink;
import ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.MatchUrlService;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap.EverythingModeEnum;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import ca.uhn.fhir.jpa.util.TestUtil; import ca.uhn.fhir.jpa.util.TestUtil;
import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
@ -40,11 +32,7 @@ import org.hl7.fhir.r4.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.r4.model.Observation.ObservationStatus; import org.hl7.fhir.r4.model.Observation.ObservationStatus;
import org.hl7.fhir.r4.model.Subscription.SubscriptionChannelType; import org.hl7.fhir.r4.model.Subscription.SubscriptionChannelType;
import org.hl7.fhir.r4.model.Subscription.SubscriptionStatus; import org.hl7.fhir.r4.model.Subscription.SubscriptionStatus;
import org.junit.After; import org.junit.*;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionCallback;
@ -55,30 +43,11 @@ import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collections; import java.util.*;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.Matchers.*;
import static org.hamcrest.Matchers.contains; import static org.junit.Assert.*;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
@SuppressWarnings({"unchecked", "Duplicates"}) @SuppressWarnings({"unchecked", "Duplicates"})
@ -4264,120 +4233,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
assertThat(toUnqualifiedVersionlessIdValues(outcome), contains(crId)); assertThat(toUnqualifiedVersionlessIdValues(outcome), contains(crId));
} }
@Test
public void testNearSearchDistanceNoDistance() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LATITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude,
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
@Test
public void testNearSearchDistanceZero() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LATITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude + "|0",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + latitude + "|" + longitude + "|0.0",
myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
}
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
bigEnoughDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
tooSmallDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
@Test
public void testNearSearchApproximateNearAntiMeridian() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_TAVEUNI;
double longitude = CoordCalculatorTest.LONGITIDE_TAVEUNI;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
String locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless().getValue();
{ // We match even when the box crosses the anti-meridian
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_TAVEUNI;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_TAVEUNI + "|"
+ CoordCalculatorTest.LONGITIDE_TAVEUNI + "|" +
bigEnoughDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids, contains(locId));
}
{ // We don't match outside a box that crosses the anti-meridian
double tooSmallDistance = CoordCalculatorTest.DISTANCE_TAVEUNI;
SearchParameterMap map = myMatchUrlService.translateMatchUrl(
"Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + "|"
+ CoordCalculatorTest.LONGITUDE_CHIN + "|" +
tooSmallDistance, myFhirCtx.getResourceDefinition("Location"));
List<String> ids = toUnqualifiedVersionlessIdValues(myLocationDao.search(map));
assertThat(ids.size(), is(0));
}
}
@Test @Test
public void testCircularReferencesDontBreakRevIncludes() { public void testCircularReferencesDontBreakRevIncludes() {

View File

@ -0,0 +1,153 @@
package ca.uhn.fhir.jpa.provider.dstu3;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.dstu3.model.PractitionerRole;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.Test;
import java.net.URLEncoder;
import static org.junit.Assert.assertEquals;
public class ResourceProviderDstu3DistanceTest extends BaseResourceProviderDstu3Test {
@Override
public void before() throws Exception {
super.before();
myDaoConfig.setReuseCachedSearchResultsForMillis(null);
}
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
String url = "/Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
assertEquals(1, actual.getEntry().size());
assertEquals(locId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
String url = "/Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(0, actual.getEntry().size());
}
}
@Test
public void testNearSearchDistanceNoDistanceChained() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
PractitionerRole pr = new PractitionerRole();
pr.addLocation().setReference(locId.getValue());
IIdType prId = ourClient.create().resource(pr).execute().getId().toUnqualifiedVersionless();
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + latitude + URLEncoder.encode(":") + longitude;
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
assertEquals(1, actual.getEntry().size());
assertEquals(prId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
@Test
public void testNearSearchApproximateChained() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
myCaptureQueriesListener.clear();
IIdType locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless();
myCaptureQueriesListener.logInsertQueries();
PractitionerRole pr = new PractitionerRole();
pr.addLocation().setReference(locId.getValue());
IIdType prId = myPractitionerRoleDao.create(pr).getId().toUnqualifiedVersionless();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
"location." + Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(1, actual.getEntry().size());
assertEquals(prId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
"location." + Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(0, actual.getEntry().size());
}
}
}

View File

@ -5,7 +5,6 @@ import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.entity.Search; import ca.uhn.fhir.jpa.entity.Search;
import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test; import ca.uhn.fhir.jpa.provider.r4.ResourceProviderR4Test;
import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl; import ca.uhn.fhir.jpa.search.SearchCoordinatorSvcImpl;
import ca.uhn.fhir.jpa.util.CoordCalculatorTest;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum; import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.model.primitive.UriDt;
@ -66,7 +65,6 @@ import java.math.BigDecimal;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Socket; import java.net.Socket;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -4280,141 +4278,6 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
} }
// FIXME KHS move distance tests to distance test class
@Test
public void testNearSearchApproximate() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
String url = "/Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
assertEquals(1, actual.getEntry().size());
assertEquals(locId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
String url = "/Location?" +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(0, actual.getEntry().size());
}
}
@Test
public void testNearSearchDistanceNoDistanceChained() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_CHIN;
double longitude = CoordCalculatorTest.LONGITUDE_CHIN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
IIdType locId = ourClient.create().resource(loc).execute().getId().toUnqualifiedVersionless();
PractitionerRole pr = new PractitionerRole();
pr.addLocation().setReference(locId.getValue());
IIdType prId = ourClient.create().resource(pr).execute().getId().toUnqualifiedVersionless();
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + latitude + URLEncoder.encode(":") + longitude;
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
assertEquals(1, actual.getEntry().size());
assertEquals(prId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
@Test
public void testNearSearchApproximateChained() {
Location loc = new Location();
double latitude = CoordCalculatorTest.LATITUDE_UHN;
double longitude = CoordCalculatorTest.LONGITUDE_UHN;
Location.LocationPositionComponent position = new Location.LocationPositionComponent().setLatitude(latitude).setLongitude(longitude);
loc.setPosition(position);
myCaptureQueriesListener.clear();
IIdType locId = myLocationDao.create(loc).getId().toUnqualifiedVersionless();
myCaptureQueriesListener.logInsertQueries();
PractitionerRole pr = new PractitionerRole();
pr.addLocation().setReference(locId.getValue());
IIdType prId = myPractitionerRoleDao.create(pr).getId().toUnqualifiedVersionless();
{ // In the box
double bigEnoughDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN * 2;
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
"location." + Location.SP_NEAR_DISTANCE + "=" + bigEnoughDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(1, actual.getEntry().size());
assertEquals(prId.getIdPart(), actual.getEntry().get(0).getResource().getIdElement().getIdPart());
}
{ // Outside the box
double tooSmallDistance = CoordCalculatorTest.DISTANCE_KM_CHIN_TO_UHN / 2;
String url = "PractitionerRole?location." +
Location.SP_NEAR + "=" + CoordCalculatorTest.LATITUDE_CHIN + URLEncoder.encode(":") + CoordCalculatorTest.LONGITUDE_CHIN +
"&" +
"location." + Location.SP_NEAR_DISTANCE + "=" + tooSmallDistance + URLEncoder.encode("|http://unitsofmeasure.org|km");
myCaptureQueriesListener.clear();
Bundle actual = ourClient
.search()
.byUrl(ourServerBase + "/" + url)
.encodedJson()
.prettyPrint()
.returnBundle(Bundle.class)
.execute();
myCaptureQueriesListener.logSelectQueries();
assertEquals(0, actual.getEntry().size());
}
}
private String toStr(Date theDate) { private String toStr(Date theDate) {
return new InstantDt(theDate).getValueAsString(); return new InstantDt(theDate).getValueAsString();
} }

View File

@ -58,7 +58,6 @@ public class MatchUrlServiceTest extends BaseJpaTest {
Location.SP_NEAR + "=1000.0:2000.0" + Location.SP_NEAR + "=1000.0:2000.0" +
"&" + "&" +
Location.SP_NEAR_DISTANCE + "=" + kmDistance + "|http://unitsofmeasure.org|km", ourCtx.getResourceDefinition("Location")); Location.SP_NEAR_DISTANCE + "=" + kmDistance + "|http://unitsofmeasure.org|km", ourCtx.getResourceDefinition("Location"));
map.setNearDistance(Location.class);
QuantityParam nearDistanceParam = map.getNearDistanceParam(); QuantityParam nearDistanceParam = map.getNearDistanceParam();
assertEquals(1, map.size()); assertEquals(1, map.size());
@ -75,7 +74,6 @@ public class MatchUrlServiceTest extends BaseJpaTest {
"&" + "&" +
Location.SP_NEAR_DISTANCE + "=2|http://unitsofmeasure.org|km", Location.SP_NEAR_DISTANCE + "=2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location")); ourCtx.getResourceDefinition("Location"));
map.setNearDistance(Location.class);
fail(); fail();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -92,7 +90,6 @@ public class MatchUrlServiceTest extends BaseJpaTest {
"," + "," +
"2|http://unitsofmeasure.org|km", "2|http://unitsofmeasure.org|km",
ourCtx.getResourceDefinition("Location")); ourCtx.getResourceDefinition("Location"));
map.setNearDistance(Location.class);
fail(); fail();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {

View File

@ -9,15 +9,12 @@ import ca.uhn.fhir.rest.api.*;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QuantityParam; import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.util.ObjectUtil; import ca.uhn.fhir.util.ObjectUtil;
import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.io.Serializable; import java.io.Serializable;
import java.util.*; import java.util.*;
@ -507,73 +504,6 @@ public class SearchParameterMap implements Serializable {
return myNearDistanceParam; return myNearDistanceParam;
} }
// FIXME KHS extract to helper class
public void setNearDistance(Class<? extends IBaseResource> theResourceType) {
if (theResourceType == Location.class && containsKey(Location.SP_NEAR_DISTANCE)) {
List<List<IQueryParameterType>> paramAndList = get(Location.SP_NEAR_DISTANCE);
QuantityParam quantityParam = getNearDistanceParam(paramAndList);
setNearDistanceParam(quantityParam);
// Need to remove near-distance or it we'll get a hashcode predicate for it
remove(Location.SP_NEAR_DISTANCE);
} else if (containsKey("location")) {
List<List<IQueryParameterType>> paramAndList = get("location");
ReferenceParam referenceParam = getChainedLocationNearDistanceParam(paramAndList);
if (referenceParam != null) {
QuantityParam quantityParam = new QuantityParam(referenceParam.getValue());
setNearDistanceParam(quantityParam);
}
}
}
private ReferenceParam getChainedLocationNearDistanceParam(List<List<IQueryParameterType>> theParamAndList) {
ReferenceParam retval = null;
List<IQueryParameterType> andParamToRemove = null;
for (List<IQueryParameterType> paramOrList : theParamAndList) {
IQueryParameterType orParamToRemove = null;
for (IQueryParameterType param : paramOrList) {
if (param instanceof ReferenceParam) {
ReferenceParam referenceParam = (ReferenceParam) param;
if (Location.SP_NEAR_DISTANCE.equals(referenceParam.getChain())) {
if (retval != null) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
} else {
retval = referenceParam;
orParamToRemove = param;
}
}
}
}
if (orParamToRemove != null) {
paramOrList.remove(orParamToRemove);
if (paramOrList.isEmpty()) {
andParamToRemove = paramOrList;
}
}
}
if (andParamToRemove != null) {
theParamAndList.remove(andParamToRemove);
}
return retval;
}
private QuantityParam getNearDistanceParam(List<List<IQueryParameterType>> theParamAndList) {
if (theParamAndList.isEmpty()) {
return null;
}
if (theParamAndList.size() > 1) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
}
List<IQueryParameterType> paramOrList = theParamAndList.get(0);
if (paramOrList.isEmpty()) {
return null;
}
if (paramOrList.size() > 1) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
}
return (QuantityParam) paramOrList.get(0);
}
public enum EverythingModeEnum { public enum EverythingModeEnum {
/* /*
* Don't reorder! We rely on the ordinals * Don't reorder! We rely on the ordinals

View File

@ -0,0 +1,79 @@
package ca.uhn.fhir.jpa.searchparam.util;
import ca.uhn.fhir.jpa.searchparam.SearchParameterMap;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import org.hl7.fhir.dstu3.model.Location;
import org.hl7.fhir.instance.model.api.IBaseResource;
import java.util.List;
// FIXME KHS write unit test
public class DistanceHelper {
public static void setNearDistance(Class<? extends IBaseResource> theResourceType, SearchParameterMap theParams) {
if (theResourceType == Location.class && theParams.containsKey(Location.SP_NEAR_DISTANCE)) {
List<List<IQueryParameterType>> paramAndList = theParams.get(Location.SP_NEAR_DISTANCE);
QuantityParam quantityParam = getNearDistanceParam(paramAndList);
theParams.setNearDistanceParam(quantityParam);
// Need to remove near-distance or it we'll get a hashcode predicate for it
theParams.remove(Location.SP_NEAR_DISTANCE);
} else if (theParams.containsKey("location")) {
List<List<IQueryParameterType>> paramAndList = theParams.get("location");
ReferenceParam referenceParam = getChainedLocationNearDistanceParam(paramAndList);
if (referenceParam != null) {
QuantityParam quantityParam = new QuantityParam(referenceParam.getValue());
theParams.setNearDistanceParam(quantityParam);
}
}
}
private static ReferenceParam getChainedLocationNearDistanceParam(List<List<IQueryParameterType>> theParamAndList) {
ReferenceParam retval = null;
List<IQueryParameterType> andParamToRemove = null;
for (List<IQueryParameterType> paramOrList : theParamAndList) {
IQueryParameterType orParamToRemove = null;
for (IQueryParameterType param : paramOrList) {
if (param instanceof ReferenceParam) {
ReferenceParam referenceParam = (ReferenceParam) param;
if (Location.SP_NEAR_DISTANCE.equals(referenceParam.getChain())) {
if (retval != null) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
} else {
retval = referenceParam;
orParamToRemove = param;
}
}
}
}
if (orParamToRemove != null) {
paramOrList.remove(orParamToRemove);
if (paramOrList.isEmpty()) {
andParamToRemove = paramOrList;
}
}
}
if (andParamToRemove != null) {
theParamAndList.remove(andParamToRemove);
}
return retval;
}
private static QuantityParam getNearDistanceParam(List<List<IQueryParameterType>> theParamAndList) {
if (theParamAndList.isEmpty()) {
return null;
}
if (theParamAndList.size() > 1) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
}
List<IQueryParameterType> paramOrList = theParamAndList.get(0);
if (paramOrList.isEmpty()) {
return null;
}
if (paramOrList.size() > 1) {
throw new IllegalArgumentException("Only one " + ca.uhn.fhir.model.dstu2.resource.Location.SP_NEAR_DISTANCE + " parameter may be present");
}
return (QuantityParam) paramOrList.get(0);
}
}