diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java index 77d74a2a638..550350b6383 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/BaseSearchParamExtractor.java @@ -23,7 +23,11 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam; import ca.uhn.fhir.jpa.model.entity.ModelConfig; +import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; +import ca.uhn.fhir.jpa.model.entity.ResourceTable; +import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import com.google.common.annotations.VisibleForTesting; import org.apache.commons.lang3.ObjectUtils; @@ -34,8 +38,11 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.regex.Pattern; +import static org.apache.commons.lang3.StringUtils.isBlank; + public abstract class BaseSearchParamExtractor implements ISearchParamExtractor { public static final Pattern SPLIT = Pattern.compile("\\||( or )"); @@ -58,6 +65,36 @@ public abstract class BaseSearchParamExtractor implements ISearchParamExtractor mySearchParamRegistry = theSearchParamRegistry; } + protected void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { + if (isBlank(searchTerm)) { + return; + } + if (searchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + searchTerm = searchTerm.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + String normalizedString = StringNormalizer.normalizeString(searchTerm); + if (normalizedString.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + normalizedString = normalizedString.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + + ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), resourceName, normalizedString, searchTerm); + nextEntity.setResource(theEntity); + retVal.add(nextEntity); + } + + protected void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { + if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + String normalizedValue = StringNormalizer.normalizeString(value); + if (normalizedValue.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { + normalizedValue = normalizedValue.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); + } + ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), nextSpDef.getName(), normalizedValue, value); + nextEntity.setResource(theEntity); + retVal.add(nextEntity); + } + @Override public List extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) { List refs = new ArrayList(); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java index d2a0a6810f9..a089d91440f 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu2.java @@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.entity.*; -import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IPrimitiveDatatype; @@ -60,28 +59,6 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorDstu2.class); - private void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { - if (isBlank(searchTerm)) { - return; - } - if (searchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - searchTerm = searchTerm.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), resourceName, StringNormalizer.normalizeString(searchTerm), searchTerm); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - - private void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { - if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), nextSpDef.getName(), StringNormalizer.normalizeString(value), value); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - @Override public Set extractSearchParamCoords(ResourceTable theEntity, IBaseResource theResource) { // TODO: implement diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java index 10d06426030..68ec34e83f5 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.entity.*; -import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; @@ -88,28 +87,6 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen } } - private void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { - if (isBlank(searchTerm)) { - return; - } - if (searchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - searchTerm = searchTerm.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), resourceName, StringNormalizer.normalizeString(searchTerm), searchTerm); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - - private void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { - if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), nextSpDef.getName(), StringNormalizer.normalizeString(value), value); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - @Override public List extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) { ArrayList retVal = new ArrayList(); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java index d424d63e1b5..e2c86121fdf 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR4.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.entity.*; -import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; @@ -127,28 +126,6 @@ public class SearchParamExtractorR4 extends BaseSearchParamExtractor implements } } - private void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { - if (isBlank(searchTerm)) { - return; - } - if (searchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - searchTerm = searchTerm.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), resourceName, StringNormalizer.normalizeString(searchTerm), searchTerm); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - - private void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { - if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), nextSpDef.getName(), StringNormalizer.normalizeString(value), value); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - @Override public List extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) { ArrayList retVal = new ArrayList<>(); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java index c50383d8dd7..9964a5c5d37 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorR5.java @@ -23,7 +23,6 @@ package ca.uhn.fhir.jpa.searchparam.extractor; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.entity.*; -import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.SearchParamConstants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; @@ -116,28 +115,6 @@ public class SearchParamExtractorR5 extends BaseSearchParamExtractor implements } } - private void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { - if (isBlank(searchTerm)) { - return; - } - if (searchTerm.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - searchTerm = searchTerm.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), resourceName, StringNormalizer.normalizeString(searchTerm), searchTerm); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - - private void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { - if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { - value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); - } - ResourceIndexedSearchParamString nextEntity = new ResourceIndexedSearchParamString(getModelConfig(), nextSpDef.getName(), StringNormalizer.normalizeString(value), value); - nextEntity.setResource(theEntity); - retVal.add(nextEntity); - } - @Override public List extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) { ArrayList retVal = new ArrayList<>(); diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java index af4793b6ec3..56876b42106 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/extractor/SearchParamExtractorDstu3Test.java @@ -5,19 +5,25 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeSearchParam; import ca.uhn.fhir.jpa.model.entity.BaseResourceIndexedSearchParam; import ca.uhn.fhir.jpa.model.entity.ModelConfig; +import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamString; import ca.uhn.fhir.jpa.model.entity.ResourceIndexedSearchParamToken; import ca.uhn.fhir.jpa.model.entity.ResourceTable; +import ca.uhn.fhir.jpa.model.util.StringNormalizer; import ca.uhn.fhir.jpa.searchparam.JpaRuntimeSearchParam; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.util.TestUtil; import org.hl7.fhir.dstu3.hapi.ctx.DefaultProfileValidationSupport; import org.hl7.fhir.dstu3.hapi.ctx.IValidationSupport; import org.hl7.fhir.dstu3.model.Observation; +import org.hl7.fhir.dstu3.model.Questionnaire; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; +import java.text.Normalizer; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import static org.junit.Assert.assertEquals; @@ -99,6 +105,81 @@ public class SearchParamExtractorDstu3Test { assertEquals("CODE", token.getValue()); } + @Test + public void testNormalizedStringIsShortened() { + // String with character that will change it's length on normalization + String value = IntStream.range(1, 200).mapToObj(v -> "a").collect(Collectors.joining()) + "ئ"; + assertEquals(value.length(), 200); + assertEquals(Normalizer.normalize(value, Normalizer.Form.NFD).length(), 201); + assertEquals(StringNormalizer.normalizeString(value).length(), 201); + + Questionnaire questionnaire = new Questionnaire(); + questionnaire.setDescription(value); + + ISearchParamRegistry searchParamRegistry = new ISearchParamRegistry() { + @Override + public void forceRefresh() { + // nothing + } + + @Override + public RuntimeSearchParam getActiveSearchParam(String theResourceName, String theParamName) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean refreshCacheIfNecessary() { + // nothing + return false; + } + + @Override + public Map> getActiveSearchParams() { + throw new UnsupportedOperationException(); + } + + @Override + public Map getActiveSearchParams(String theResourceName) { + RuntimeResourceDefinition nextResDef = ourCtx.getResourceDefinition(theResourceName); + Map sps = new HashMap<>(); + for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) { + sps.put(nextSp.getName(), nextSp); + } + return sps; + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName, Set theParamNames) { + throw new UnsupportedOperationException(); + } + + @Override + public List getActiveUniqueSearchParams(String theResourceName) { + throw new UnsupportedOperationException(); + } + + @Override + public void requestRefresh() { + // nothing + } + + @Override + public RuntimeSearchParam getSearchParamByName(RuntimeResourceDefinition theResourceDef, String theParamName) { + return null; + } + + @Override + public Collection getSearchParamsByResourceType(RuntimeResourceDefinition theResourceDef) { + return null; + } + }; + + SearchParamExtractorDstu3 extractor = new SearchParamExtractorDstu3(new ModelConfig(), ourCtx, ourValidationSupport, searchParamRegistry); + extractor.start(); + Set params = extractor.extractSearchParamStrings(new ResourceTable(), questionnaire); + assertEquals(1, params.size()); + } + @AfterClass public static void afterClassClearContext() { TestUtil.clearAllStaticFieldsForUnitTest();