diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
index 9f6491c6b86..4a9fb531754 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/DaoConfig.java
@@ -17,9 +17,9 @@ import java.util.*;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -60,6 +60,9 @@ public class DaoConfig {
* update setter javadoc if default changes
*/
private boolean myAllowExternalReferences = false;
+ /**
+ * update setter javadoc if default changes
+ */
private boolean myAllowContainsSearches = true;
/**
@@ -137,6 +140,7 @@ public class DaoConfig {
myTreatReferencesAsLogical.add(theTreatReferencesAsLogical);
}
+
/**
* Specifies the highest number that a client is permitted to use in a
* Cache-Control: nostore, max-results=NNN
@@ -376,9 +380,9 @@ public class DaoConfig {
* of higher importance than raw write performance
*
- * Note that this setting also has an impact on sorting (i.e. using the
- * _sort
parameter on searches): If the server is configured
- * to not index missing field.
+ * Note that this setting also has an impact on sorting (i.e. using the
+ * _sort
parameter on searches): If the server is configured
+ * to not index missing field.
*
true
+ */
+ public boolean isAllowContainsSearches() {
+ return myAllowContainsSearches;
+ }
+
+ /**
+ * If enabled, the server will support the use of :contains searches,
+ * which are helpful but can have adverse effects on performance.
+ *
+ * Default is true
+ */
+ public void setAllowContainsSearches(boolean theAllowContainsSearches) {
+ this.myAllowContainsSearches = theAllowContainsSearches;
+ }
+
/**
* If set to true
(default is false
) the server will allow
* resources to have references to external servers. For example if this server is
@@ -1099,16 +1123,6 @@ public class DaoConfig {
}
- public boolean allowContainsSearches() {
-
- return myAllowContainsSearches;
- }
-
- public void setAllowContainsSearches(boolean myAllowContainsSearches) {
-
- this.myAllowContainsSearches = myAllowContainsSearches;
- }
-
public enum IndexEnabledEnum {
ENABLED,
DISABLED
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index 293514954fa..7f9a004a4c9 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -9,9 +9,9 @@ package ca.uhn.fhir.jpa.dao;
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -28,8 +28,6 @@ import ca.uhn.fhir.jpa.search.JpaRuntimeSearchParam;
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
import ca.uhn.fhir.jpa.util.BaseIterator;
-import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
-import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
@@ -45,7 +43,9 @@ import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
+import ca.uhn.fhir.util.StopWatch;
import ca.uhn.fhir.util.UrlUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
@@ -1091,10 +1091,10 @@ public class SearchBuilder implements ISearchBuilder {
} else if (theParameter instanceof StringParam) {
StringParam id = (StringParam) theParameter;
rawSearchTerm = id.getValue();
- if ((id.isContains()) &&
- (!myCallingDao.getConfig().allowContainsSearches()))
- {
- throw new MethodNotAllowedException(":contains modifier is disabled on this server");
+ if (id.isContains()) {
+ if (!myCallingDao.getConfig().isAllowContainsSearches()) {
+ throw new MethodNotAllowedException(":contains modifier is disabled on this server");
+ }
}
} else if (theParameter instanceof IPrimitiveDatatype>) {
IPrimitiveDatatype> id = (IPrimitiveDatatype>) theParameter;
@@ -1109,18 +1109,11 @@ public class SearchBuilder implements ISearchBuilder {
}
String likeExpression = BaseHapiFhirDao.normalizeString(rawSearchTerm);
- if (myCallingDao.getConfig().allowContainsSearches()) {
- if (theParameter instanceof StringParam) {
- if (((StringParam) theParameter).isContains()) {
- likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
- } else {
- likeExpression = createLeftMatchLikeExpression(likeExpression);
- }
- } else {
- likeExpression = createLeftMatchLikeExpression(likeExpression);
- }
- }
- else {
+ if (theParameter instanceof StringParam &&
+ ((StringParam) theParameter).isContains() &&
+ myCallingDao.getConfig().isAllowContainsSearches()) {
+ likeExpression = createLeftAndRightMatchLikeExpression(likeExpression);
+ } else {
likeExpression = createLeftMatchLikeExpression(likeExpression);
}
@@ -2020,14 +2013,14 @@ public class SearchBuilder implements ISearchBuilder {
return lastUpdatedPredicates;
}
- private static String createLeftMatchLikeExpression(String likeExpression) {
- return likeExpression.replace("%", "[%]") + "%";
- }
-
private static String createLeftAndRightMatchLikeExpression(String likeExpression) {
return "%" + likeExpression.replace("%", "[%]") + "%";
}
+ private static String createLeftMatchLikeExpression(String likeExpression) {
+ return likeExpression.replace("%", "[%]") + "%";
+ }
+
private static Predicate createResourceLinkPathPredicate(IDao theCallingDao, FhirContext theContext, String theParamName, From, ? extends ResourceLink> theFrom,
String theResourceType) {
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
index 05185a32150..514a71d2b5a 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/r4/FhirResourceDaoR4SearchNoFtTest.java
@@ -11,6 +11,7 @@ import ca.uhn.fhir.rest.api.Constants;
import ca.uhn.fhir.rest.api.server.IBundleProvider;
import ca.uhn.fhir.rest.param.*;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.util.TestUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
@@ -54,6 +55,7 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
public void afterResetSearchSize() {
myDaoConfig.setReuseCachedSearchResultsForMillis(new DaoConfig().getReuseCachedSearchResultsForMillis());
myDaoConfig.setFetchSizeDefaultMaximum(new DaoConfig().getFetchSizeDefaultMaximum());
+ myDaoConfig.setAllowContainsSearches(new DaoConfig().isAllowContainsSearches());
}
@Before
@@ -1404,43 +1406,6 @@ public class FhirResourceDaoR4SearchNoFtTest extends BaseJpaR4Test {
}
}
- /**
- * See #819
- */
- @Test
- public void testSearchTokenWithNotModifier() {
- String male, female;
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("001");
- patient.addName().setFamily("Tester").addGiven("Joe");
- patient.setGender(AdministrativeGender.MALE);
- male = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
- }
- {
- Patient patient = new Patient();
- patient.addIdentifier().setSystem("urn:system").setValue("002");
- patient.addName().setFamily("Tester").addGiven("Jane");
- patient.setGender(AdministrativeGender.FEMALE);
- female = myPatientDao.create(patient, mySrd).getId().toUnqualifiedVersionless().getValue();
- }
-
- List