From 43f17534bb1297b1affa263eb2e8b25d5162ac80 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 16:40:53 -0400 Subject: [PATCH 1/7] commiting with FIXMEs so James can review --- .../rest/api/RestSearchParameterTypeEnum.java | 9 +- .../ca/uhn/fhir/rest/param/ParameterUtil.java | 116 +++++++++--------- .../fhir/rest/param/SourceAndListParam.java | 41 +++++++ .../fhir/rest/param/SourceOrListParam.java | 41 +++++++ .../ca/uhn/fhir/rest/param/SourceParam.java | 83 +++++++++++++ .../uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java | 2 +- .../ca/uhn/fhir/jpa/dao/SearchBuilder.java | 22 ++-- .../fhir/jpa/searchparam/MatchUrlService.java | 18 +-- .../matcher/InMemoryResourceMatcher.java | 1 + .../InMemoryResourceMatcherR5Test.java | 10 ++ 10 files changed, 259 insertions(+), 84 deletions(-) create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java create mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java index 0bcce616947..0c7a715904e 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java @@ -89,13 +89,18 @@ public enum RestSearchParameterTypeEnum { */ HAS("string", "http://hl7.org/fhir/search-param-type"), - /** + /** * Code Value: number * * Search parameter SHALL be a number (a whole number, or a decimal). */ SPECIAL("special", "http://hl7.org/fhir/search-param-type"), + /** + * _has parameter + */ + SOURCE("string", "http://hl7.org/fhir/search-param-type"), + ; @@ -119,7 +124,7 @@ public enum RestSearchParameterTypeEnum { static { for (RestSearchParameterTypeEnum next : RestSearchParameterTypeEnum.values()) { - if (next == HAS) { + if (next == HAS || next == SOURCE) { continue; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java index d58758f9133..5d56f3abdd3 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java @@ -61,43 +61,47 @@ public class ParameterUtil { * This is a utility method intended provided to help the JPA module. */ public static IQueryParameterAnd parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType, - String theUnqualifiedParamName, List theParameters) { + String theUnqualifiedParamName, List theParameters) { QueryParameterAndBinder binder = null; switch (paramType) { - case COMPOSITE: - throw new UnsupportedOperationException(); - case DATE: - binder = new QueryParameterAndBinder(DateAndListParam.class, - Collections.> emptyList()); - break; - case NUMBER: - binder = new QueryParameterAndBinder(NumberAndListParam.class, - Collections.> emptyList()); - break; - case QUANTITY: - binder = new QueryParameterAndBinder(QuantityAndListParam.class, - Collections.> emptyList()); - break; - case REFERENCE: - binder = new QueryParameterAndBinder(ReferenceAndListParam.class, - Collections.> emptyList()); - break; - case STRING: - binder = new QueryParameterAndBinder(StringAndListParam.class, - Collections.> emptyList()); - break; - case TOKEN: - binder = new QueryParameterAndBinder(TokenAndListParam.class, - Collections.> emptyList()); - break; - case URI: - binder = new QueryParameterAndBinder(UriAndListParam.class, - Collections.> emptyList()); - break; - case HAS: - binder = new QueryParameterAndBinder(HasAndListParam.class, - Collections.> emptyList()); - break; + case COMPOSITE: + throw new UnsupportedOperationException(); + case DATE: + binder = new QueryParameterAndBinder(DateAndListParam.class, + Collections.>emptyList()); + break; + case NUMBER: + binder = new QueryParameterAndBinder(NumberAndListParam.class, + Collections.>emptyList()); + break; + case QUANTITY: + binder = new QueryParameterAndBinder(QuantityAndListParam.class, + Collections.>emptyList()); + break; + case REFERENCE: + binder = new QueryParameterAndBinder(ReferenceAndListParam.class, + Collections.>emptyList()); + break; + case STRING: + binder = new QueryParameterAndBinder(StringAndListParam.class, + Collections.>emptyList()); + break; + case TOKEN: + binder = new QueryParameterAndBinder(TokenAndListParam.class, + Collections.>emptyList()); + break; + case URI: + binder = new QueryParameterAndBinder(UriAndListParam.class, + Collections.>emptyList()); + break; + case HAS: + binder = new QueryParameterAndBinder(HasAndListParam.class, + Collections.>emptyList()); + break; + case SOURCE: + binder = new QueryParameterAndBinder(SourceAndListParam.class, + Collections.>emptyList()); + break; } // FIXME null access @@ -108,7 +112,7 @@ public class ParameterUtil { * This is a utility method intended provided to help the JPA module. */ public static IQueryParameterAnd parseQueryParams(FhirContext theContext, RuntimeSearchParam theParamDef, - String theUnqualifiedParamName, List theParameters) { + String theUnqualifiedParamName, List theParameters) { RestSearchParameterTypeEnum paramType = theParamDef.getParamType(); return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters); } @@ -126,14 +130,14 @@ public class ParameterUtil { for (int i = 0; i < theValue.length(); i++) { char next = theValue.charAt(i); switch (next) { - case '$': - case ',': - case '|': - case '\\': - b.append('\\'); - break; - default: - break; + case '$': + case ',': + case '|': + case '\\': + b.append('\\'); + break; + default: + break; } b.append(next); } @@ -207,7 +211,7 @@ public class ParameterUtil { public static boolean isBindableIntegerType(Class theClass) { return Integer.class.isAssignableFrom(theClass) - || IPrimitiveType.class.isAssignableFrom(theClass); + || IPrimitiveType.class.isAssignableFrom(theClass); } public static String escapeAndJoinOrList(Collection theValues) { @@ -236,7 +240,7 @@ public class ParameterUtil { if (value.charAt(0) == '"') { eTagVersion = value.substring(1, value.length() - 1); } else if (value.length() > 3 && value.charAt(0) == 'W' && value.charAt(1) == '/' - && value.charAt(2) == '"') { + && value.charAt(2) == '"') { eTagVersion = value.substring(3, value.length() - 1); } else { eTagVersion = value; @@ -262,16 +266,16 @@ public class ParameterUtil { @Override public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, - QualifiedParamList theParameters) { + QualifiedParamList theParameters) { if (theParameters.isEmpty()) { return; } if (theParameters.size() > 1) { throw new IllegalArgumentException( - "Type " + theParam.getClass().getCanonicalName() + " does not support multiple values"); + "Type " + theParam.getClass().getCanonicalName() + " does not support multiple values"); } theParam.setValueAsQueryToken(theContext, theParamName, theParameters.getQualifier(), - theParameters.get(0)); + theParameters.get(0)); } }; } @@ -351,13 +355,13 @@ public class ParameterUtil { b.append(next); } else { switch (theValue.charAt(i + 1)) { - case '$': - case ',': - case '|': - case '\\': - continue; - default: - b.append(next); + case '$': + case ',': + case '|': + case '\\': + continue; + default: + b.append(next); } } } else { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java new file mode 100644 index 00000000000..b0314f79a33 --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java @@ -0,0 +1,41 @@ +package ca.uhn.fhir.rest.param; + +import ca.uhn.fhir.util.CoverageIgnore; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2019 University Health Network + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +public class SourceAndListParam extends BaseAndListParam { + + @Override + SourceOrListParam newInstance() { + return new SourceOrListParam(); + } + + @CoverageIgnore + @Override + public SourceAndListParam addAnd(SourceOrListParam theValue) { + addValue(theValue); + return this; + } + + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java new file mode 100644 index 00000000000..262a8af7c1c --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java @@ -0,0 +1,41 @@ +package ca.uhn.fhir.rest.param; + +import ca.uhn.fhir.util.CoverageIgnore; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2019 University Health Network + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + + +public class SourceOrListParam extends BaseOrListParam { + + @CoverageIgnore + @Override + SourceParam newInstance() { + return new SourceParam(); + } + + @CoverageIgnore + @Override + public SourceOrListParam addOr(SourceParam theParameter) { + add(theParameter); + return this; + } + +} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java new file mode 100644 index 00000000000..88e82cbd4eb --- /dev/null +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java @@ -0,0 +1,83 @@ +package ca.uhn.fhir.rest.param; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; + +import static org.apache.commons.lang3.StringUtils.defaultString; +import static org.apache.commons.lang3.StringUtils.left; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2019 University Health Network + * %% + * 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. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/** + * Implementation of the _has method parameter + */ +public class SourceParam extends BaseParam implements IQueryParameterType { + + private static final long serialVersionUID = 1L; + private String myParameterValue; + private String mySourceUri; + private String myRequestId; + + public SourceParam() {} + + public SourceParam(String theParameterValue) { + setValue(theParameterValue); + } + + private void setValue(String theParameterValue) { + myParameterValue = theParameterValue; + String requestId; + int lastHashValueIndex = theParameterValue.lastIndexOf('#'); + if (lastHashValueIndex == -1) { + mySourceUri = theParameterValue; + requestId = null; + } else { + mySourceUri = theParameterValue.substring(0, lastHashValueIndex); + requestId = theParameterValue.substring(lastHashValueIndex + 1); + } + myRequestId = left(requestId, Constants.REQUEST_ID_LENGTH); + } + + @Override + String doGetQueryParameterQualifier() { + return myParameterValue; + } + + @Override + String doGetValueAsQueryToken(FhirContext theContext) { + return myParameterValue; + } + + @Override + void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) { + setValue(theValue); + } + + public String getSourceUri() { + return mySourceUri; + } + + public String getRequestId() { + return myRequestId; + } +} diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java index 34d98c5de73..5381eaf475f 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java @@ -243,7 +243,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao { int qIndex = url.indexOf('?'); ArrayListMultimap paramValues = ArrayListMultimap.create(); - requestDetails.setParameters(new HashMap()); + requestDetails.setParameters(new HashMap<>()); if (qIndex != -1) { String params = url.substring(qIndex); List parameters = myMatchUrlService.translateMatchUrl(params); 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 b3ccb922442..e0f7bce418f 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 @@ -861,19 +861,10 @@ public class SearchBuilder implements ISearchBuilder { List codePredicates = new ArrayList<>(); for (IQueryParameterType nextParameter : theList) { - String nextParamValue = nextParameter.getValueAsQueryToken(myContext); - int lastHashValueIndex = nextParamValue.lastIndexOf('#'); - String sourceUri; - String requestId; - if (lastHashValueIndex == -1) { - sourceUri = nextParamValue; - requestId = null; - } else { - sourceUri = nextParamValue.substring(0, lastHashValueIndex); - requestId = nextParamValue.substring(lastHashValueIndex + 1); - } - requestId = left(requestId, Constants.REQUEST_ID_LENGTH); - + // FIXME KHS this works, but is it right? + SourceParam sourceParameter = new SourceParam(nextParameter.getValueAsQueryToken(myContext)); + String sourceUri = sourceParameter.getSourceUri(); + String requestId = sourceParameter.getRequestId(); Predicate sourceUriPredicate = myBuilder.equal(join.get("mySourceUri"), sourceUri); Predicate requestIdPredicate = myBuilder.equal(join.get("myRequestId"), requestId); if (isNotBlank(sourceUri) && isNotBlank(requestId)) { @@ -1280,6 +1271,7 @@ public class SearchBuilder implements ISearchBuilder { retVal = createPredicateQuantity(leftValue, theResourceName, theParam.getName(), myBuilder, dateJoin); break; } + case SOURCE: case COMPOSITE: case HAS: case NUMBER: @@ -2747,6 +2739,7 @@ public class SearchBuilder implements ISearchBuilder { throw new InvalidRequestException("Unexpected search parameter type encountered, expected string type for language search"); } } else if (searchParam.getName().equals(Constants.PARAM_SOURCE)) { + // FIXME KHS remove this if (searchParam.getParamType() == RestSearchParameterTypeEnum.TOKEN) { TokenParam param = new TokenParam(); param.setValueAsQueryToken(null, null, null, theFilter.getValue()); @@ -3008,6 +3001,9 @@ public class SearchBuilder implements ISearchBuilder { case REFERENCE: qp = new ReferenceParam(); break; + case SOURCE: + qp = new SourceParam(); + break; case SPECIAL: case URI: case HAS: diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java index be810cca188..75956967d75 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java @@ -93,16 +93,10 @@ public class MatchUrlService { paramMap.setLastUpdated(p1); } } - continue; - } - - if (Constants.PARAM_HAS.equals(nextParamName)) { + } else if (Constants.PARAM_HAS.equals(nextParamName)) { IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.HAS, nextParamName, paramList); paramMap.add(nextParamName, param); - continue; - } - - if (Constants.PARAM_COUNT.equals(nextParamName)) { + } else if (Constants.PARAM_COUNT.equals(nextParamName)) { if (paramList.size() > 0 && paramList.get(0).size() > 0) { String intString = paramList.get(0).get(0); try { @@ -111,16 +105,16 @@ public class MatchUrlService { throw new InvalidRequestException("Invalid " + Constants.PARAM_COUNT + " value: " + intString); } } - continue; - } - - if (ResourceMetaParams.RESOURCE_META_PARAMS.containsKey(nextParamName)) { + } else if (ResourceMetaParams.RESOURCE_META_PARAMS.containsKey(nextParamName)) { if (isNotBlank(paramList.get(0).getQualifier()) && paramList.get(0).getQualifier().startsWith(".")) { throw new InvalidRequestException("Invalid parameter chain: " + nextParamName + paramList.get(0).getQualifier()); } IQueryParameterAnd type = newInstanceAnd(nextParamName); type.setValuesAsQueryTokens(myContext, nextParamName, (paramList)); paramMap.add(nextParamName, type); + } else if (Constants.PARAM_SOURCE.equals(nextParamName)) { + IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.SOURCE, nextParamName, paramList); + paramMap.add(nextParamName, param); } else if (nextParamName.startsWith("_")) { // ignore these since they aren't search params (e.g. _sort) } else { diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index 5454a44bba7..6be8b90e511 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -179,6 +179,7 @@ public class InMemoryResourceMatcher { case COMPOSITE: case HAS: case SPECIAL: + case SOURCE: default: return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName, InMemoryMatchResult.PARAM); } diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java index 58f0cd714ef..ff8595b8e81 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java @@ -7,6 +7,7 @@ import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.model.primitive.BaseDateTimeDt; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.TokenParamModifier; @@ -15,6 +16,7 @@ import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.Observation; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -88,6 +90,14 @@ public class InMemoryResourceMatcherR5Test { mySearchParams = extractDateSearchParam(myObservation); } + // FIXME KHS get this test to work + @Ignore + @Test + public void testSupportedSource() { + InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=FOO", myObservation, mySearchParams); + assertTrue(result.supported()); + } + @Test public void testUnsupportedChained() { InMemoryMatchResult result = myInMemoryResourceMatcher.match("encounter.class=FOO", myObservation, mySearchParams); From 4fa849a3e58774d1aa1f79fcf54b43a96354b93c Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 16:43:47 -0400 Subject: [PATCH 2/7] pre-review cleanup --- .../src/main/java/ca/uhn/fhir/rest/param/SourceParam.java | 2 -- .../src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java | 1 - .../fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java | 3 ++- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java index 88e82cbd4eb..34da9d85af9 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java @@ -3,9 +3,7 @@ package ca.uhn.fhir.rest.param; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import static org.apache.commons.lang3.StringUtils.defaultString; import static org.apache.commons.lang3.StringUtils.left; /* 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 e0f7bce418f..f5a1e122699 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 @@ -2739,7 +2739,6 @@ public class SearchBuilder implements ISearchBuilder { throw new InvalidRequestException("Unexpected search parameter type encountered, expected string type for language search"); } } else if (searchParam.getName().equals(Constants.PARAM_SOURCE)) { - // FIXME KHS remove this if (searchParam.getParamType() == RestSearchParameterTypeEnum.TOKEN) { TokenParam param = new TokenParam(); param.setValueAsQueryToken(null, null, null, theFilter.getValue()); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index 6be8b90e511..4f1522a3f94 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -176,10 +176,11 @@ public class InMemoryResourceMatcher { } else { return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theResourceName, theParamName, theParamDef, nextAnd, theSearchParams))); } + case SOURCE: + // FIXME KHS implement case COMPOSITE: case HAS: case SPECIAL: - case SOURCE: default: return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName, InMemoryMatchResult.PARAM); } From b7aa32711850d5d44d05156778660191d154d227 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 16:47:43 -0400 Subject: [PATCH 3/7] pre-review cleanup --- .../java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java index 0c7a715904e..78ba8ef5dd4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java @@ -97,7 +97,7 @@ public enum RestSearchParameterTypeEnum { SPECIAL("special", "http://hl7.org/fhir/search-param-type"), /** - * _has parameter + * _source parameter */ SOURCE("string", "http://hl7.org/fhir/search-param-type"), From 5379ab8c2c23bb92554022a7fa97ef09d9a61e69 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 17:53:02 -0400 Subject: [PATCH 4/7] implement in-memory match --- .../ca/uhn/fhir/rest/param/SourceParam.java | 8 +++- .../matcher/InMemoryResourceMatcher.java | 43 +++++++++++++------ .../InMemoryResourceMatcherR5Test.java | 27 ++++++++++-- 3 files changed, 58 insertions(+), 20 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java index 34da9d85af9..66c2b0ed285 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java @@ -3,6 +3,8 @@ package ca.uhn.fhir.rest.param; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import static org.apache.commons.lang3.StringUtils.left; @@ -50,7 +52,9 @@ public class SourceParam extends BaseParam implements IQueryParameterType { mySourceUri = theParameterValue; requestId = null; } else { - mySourceUri = theParameterValue.substring(0, lastHashValueIndex); + if (lastHashValueIndex != 0) { + mySourceUri = theParameterValue.substring(0, lastHashValueIndex); + } requestId = theParameterValue.substring(lastHashValueIndex + 1); } myRequestId = left(requestId, Constants.REQUEST_ID_LENGTH); @@ -58,7 +62,7 @@ public class SourceParam extends BaseParam implements IQueryParameterType { @Override String doGetQueryParameterQualifier() { - return myParameterValue; + return null; } @Override diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index 4f1522a3f94..bf6539fd251 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -30,11 +30,9 @@ import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; -import ca.uhn.fhir.rest.param.BaseParamWithPrefix; -import ca.uhn.fhir.rest.param.ParamPrefixEnum; -import ca.uhn.fhir.rest.param.ReferenceParam; -import ca.uhn.fhir.rest.param.StringParam; +import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; +import ca.uhn.fhir.util.MetaUtil; import ca.uhn.fhir.util.UrlUtil; import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -125,7 +123,6 @@ public class InMemoryResourceMatcher { switch (theParamName) { case IAnyResource.SP_RES_ID: - return InMemoryMatchResult.fromBoolean(matchIdsAndOr(theAndOrParams, theResource)); case IAnyResource.SP_RES_LANGUAGE: @@ -133,16 +130,39 @@ public class InMemoryResourceMatcher { case Constants.PARAM_TAG: case Constants.PARAM_PROFILE: case Constants.PARAM_SECURITY: - return InMemoryMatchResult.unsupportedFromParameterAndReason(theParamName, InMemoryMatchResult.PARAM); - + case Constants.PARAM_SOURCE: + return InMemoryMatchResult.fromBoolean(matchSourcesAndOr(theAndOrParams, theResource)); default: - - return matchResourceParam(theParamName, theAndOrParams, theSearchParams, resourceName, paramDef); } } + // FIXME KHS move these clustered methods out + private boolean matchSourcesAndOr(List> theAndOrParams, IBaseResource theResource) { + if (theResource == null) { + return true; + } + return theAndOrParams.stream().allMatch(nextAnd -> matchSourcesOr(nextAnd, theResource)); + } + + private boolean matchSourcesOr(List theOrParams, IBaseResource theResource) { + return theOrParams.stream().anyMatch(param -> matchSource(param, theResource)); + } + + private boolean matchSource(IQueryParameterType theSourceParam, IBaseResource theResource) { + SourceParam paramSource = new SourceParam(theSourceParam.getValueAsQueryToken(myFhirContext)); + SourceParam resourceSource = new SourceParam(MetaUtil.getSource(myFhirContext, theResource.getMeta())); + boolean matches = true; + if (paramSource.getSourceUri() != null) { + matches = paramSource.getSourceUri().equals(resourceSource.getSourceUri()); + } + if (paramSource.getRequestId() != null) { + matches &= paramSource.getRequestId().equals(resourceSource.getRequestId()); + } + return matches; + } + private boolean matchIdsAndOr(List> theAndOrParams, IBaseResource theResource) { if (theResource == null) { return true; @@ -151,9 +171,6 @@ public class InMemoryResourceMatcher { } private boolean matchIdsOr(List theOrParams, IBaseResource theResource) { - if (theResource == null) { - return true; - } return theOrParams.stream().anyMatch(param -> param instanceof StringParam && matchId(((StringParam) param).getValue(), theResource.getIdElement())); } @@ -176,8 +193,6 @@ public class InMemoryResourceMatcher { } else { return InMemoryMatchResult.fromBoolean(theAndOrParams.stream().anyMatch(nextAnd -> matchParams(theResourceName, theParamName, theParamDef, nextAnd, theSearchParams))); } - case SOURCE: - // FIXME KHS implement case COMPOSITE: case HAS: case SPECIAL: diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java index ff8595b8e81..a5bdb00a346 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java @@ -11,6 +11,9 @@ import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.TokenParamModifier; +import org.hl7.fhir.dstu3.model.Patient; +import org.hl7.fhir.dstu3.model.StringType; +import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.DateTimeType; @@ -40,6 +43,9 @@ public class InMemoryResourceMatcherR5Test { private static final String EARLY_DATE = "1965-08-09"; private static final String LATE_DATE = "2000-06-29"; public static final String OBSERVATION_CODE = "MATCH"; + private static final String SOURCE_URI = "urn:source:0"; + private static final String REQUEST_ID = "a_request_id"; + private static final String TEST_SOURCE = SOURCE_URI + "#" + REQUEST_ID; @Autowired private @@ -83,6 +89,7 @@ public class InMemoryResourceMatcherR5Test { when(mySearchParamRegistry.getActiveSearchParam("Observation", "encounter")).thenReturn(encSearchParam); myObservation = new Observation(); + myObservation.getMeta().setSource(TEST_SOURCE); myObservation.setEffective(new DateTimeType(OBSERVATION_DATE)); CodeableConcept codeableConcept = new CodeableConcept(); codeableConcept.addCoding().setCode(OBSERVATION_CODE); @@ -90,12 +97,24 @@ public class InMemoryResourceMatcherR5Test { mySearchParams = extractDateSearchParam(myObservation); } - // FIXME KHS get this test to work - @Ignore @Test public void testSupportedSource() { - InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=FOO", myObservation, mySearchParams); - assertTrue(result.supported()); + { + InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=" + TEST_SOURCE, myObservation, mySearchParams); + assertTrue(result.matched()); + } + { + InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=" + SOURCE_URI, myObservation, mySearchParams); + assertTrue(result.matched()); + } + { + InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=" + REQUEST_ID, myObservation, mySearchParams); + assertFalse(result.matched()); + } + { + InMemoryMatchResult result = myInMemoryResourceMatcher.match(Constants.PARAM_SOURCE + "=#" + REQUEST_ID, myObservation, mySearchParams); + assertTrue(result.matched()); + } } @Test From 08472c1e3faa7f868c049ade2ecced0211971943 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 17:56:15 -0400 Subject: [PATCH 5/7] ready to merge --- .../ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java | 4 ++-- .../src/main/java/ca/uhn/fhir/rest/param/SourceParam.java | 2 -- .../src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java | 2 +- .../src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java | 3 +-- .../fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java | 1 - .../searchparam/matcher/InMemoryResourceMatcherR5Test.java | 4 ---- 6 files changed, 4 insertions(+), 12 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java index 78ba8ef5dd4..ab4528944cd 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java @@ -21,11 +21,11 @@ package ca.uhn.fhir.rest.api; * #L% */ +import ca.uhn.fhir.model.api.IValueSetEnumBinder; + import java.util.HashMap; import java.util.Map; -import ca.uhn.fhir.model.api.IValueSetEnumBinder; - public enum RestSearchParameterTypeEnum { /** diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java index 66c2b0ed285..b576c1291bb 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java @@ -3,8 +3,6 @@ package ca.uhn.fhir.rest.param; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; -import org.apache.commons.lang3.builder.EqualsBuilder; -import org.apache.commons.lang3.builder.HashCodeBuilder; import static org.apache.commons.lang3.StringUtils.left; diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java index 5381eaf475f..fed33cf2b44 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java @@ -24,7 +24,6 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.jpa.delete.DeleteConflictList; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.TagDefinition; -import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; @@ -55,6 +54,7 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetai import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; +import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil.UrlParts; 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 f5a1e122699..0821490dca7 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 @@ -39,8 +39,8 @@ import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; -import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.term.VersionIndependentConcept; +import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.util.*; import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.base.composite.BaseCodingDt; @@ -861,7 +861,6 @@ public class SearchBuilder implements ISearchBuilder { List codePredicates = new ArrayList<>(); for (IQueryParameterType nextParameter : theList) { - // FIXME KHS this works, but is it right? SourceParam sourceParameter = new SourceParam(nextParameter.getValueAsQueryToken(myContext)); String sourceUri = sourceParameter.getSourceUri(); String requestId = sourceParameter.getRequestId(); diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index bf6539fd251..b01366f932a 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -138,7 +138,6 @@ public class InMemoryResourceMatcher { } } - // FIXME KHS move these clustered methods out private boolean matchSourcesAndOr(List> theAndOrParams, IBaseResource theResource) { if (theResource == null) { return true; diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java index a5bdb00a346..89a4ca82534 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java @@ -11,15 +11,11 @@ import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.ParamPrefixEnum; import ca.uhn.fhir.rest.param.TokenParamModifier; -import org.hl7.fhir.dstu3.model.Patient; -import org.hl7.fhir.dstu3.model.StringType; -import org.hl7.fhir.instance.model.api.IIdType; import org.hl7.fhir.r5.model.BaseDateTimeType; import org.hl7.fhir.r5.model.CodeableConcept; import org.hl7.fhir.r5.model.DateTimeType; import org.hl7.fhir.r5.model.Observation; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; From 4a2ed62357353392e3b25254928e886567eb951e Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 20:25:16 -0400 Subject: [PATCH 6/7] review feedback --- .../rest/api/RestSearchParameterTypeEnum.java | 7 +--- .../ca/uhn/fhir/rest/param/ParameterUtil.java | 4 -- .../fhir/rest/param/SourceAndListParam.java | 41 ------------------- .../fhir/rest/param/SourceOrListParam.java | 41 ------------------- .../ca/uhn/fhir/jpa/dao/SearchBuilder.java | 5 +-- .../fhir/jpa/searchparam/MatchUrlService.java | 2 +- .../matcher/InMemoryResourceMatcher.java | 6 ++- .../jpa/searchparam/util}/SourceParam.java | 39 ++++-------------- .../InMemoryResourceMatcherR5Test.java | 3 +- 9 files changed, 18 insertions(+), 130 deletions(-) delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java delete mode 100644 hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java rename {hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param => hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util}/SourceParam.java (64%) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java index ab4528944cd..0a8fd6b3bb4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java @@ -96,11 +96,6 @@ public enum RestSearchParameterTypeEnum { */ SPECIAL("special", "http://hl7.org/fhir/search-param-type"), - /** - * _source parameter - */ - SOURCE("string", "http://hl7.org/fhir/search-param-type"), - ; @@ -124,7 +119,7 @@ public enum RestSearchParameterTypeEnum { static { for (RestSearchParameterTypeEnum next : RestSearchParameterTypeEnum.values()) { - if (next == HAS || next == SOURCE) { + if (next == HAS) { continue; } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java index 5d56f3abdd3..19b825ddca4 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ParameterUtil.java @@ -98,10 +98,6 @@ public class ParameterUtil { binder = new QueryParameterAndBinder(HasAndListParam.class, Collections.>emptyList()); break; - case SOURCE: - binder = new QueryParameterAndBinder(SourceAndListParam.class, - Collections.>emptyList()); - break; } // FIXME null access diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java deleted file mode 100644 index b0314f79a33..00000000000 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceAndListParam.java +++ /dev/null @@ -1,41 +0,0 @@ -package ca.uhn.fhir.rest.param; - -import ca.uhn.fhir.util.CoverageIgnore; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2019 University Health Network - * %% - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - - -public class SourceAndListParam extends BaseAndListParam { - - @Override - SourceOrListParam newInstance() { - return new SourceOrListParam(); - } - - @CoverageIgnore - @Override - public SourceAndListParam addAnd(SourceOrListParam theValue) { - addValue(theValue); - return this; - } - - -} diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java deleted file mode 100644 index 262a8af7c1c..00000000000 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceOrListParam.java +++ /dev/null @@ -1,41 +0,0 @@ -package ca.uhn.fhir.rest.param; - -import ca.uhn.fhir.util.CoverageIgnore; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2019 University Health Network - * %% - * 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. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - - -public class SourceOrListParam extends BaseOrListParam { - - @CoverageIgnore - @Override - SourceParam newInstance() { - return new SourceParam(); - } - - @CoverageIgnore - @Override - public SourceOrListParam addOr(SourceParam theParameter) { - add(theParameter); - return this; - } - -} 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 0821490dca7..8175c58323e 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 @@ -39,6 +39,7 @@ import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.jpa.term.VersionIndependentConcept; import ca.uhn.fhir.jpa.term.api.ITermReadSvc; import ca.uhn.fhir.jpa.util.*; @@ -1270,7 +1271,6 @@ public class SearchBuilder implements ISearchBuilder { retVal = createPredicateQuantity(leftValue, theResourceName, theParam.getName(), myBuilder, dateJoin); break; } - case SOURCE: case COMPOSITE: case HAS: case NUMBER: @@ -2999,9 +2999,6 @@ public class SearchBuilder implements ISearchBuilder { case REFERENCE: qp = new ReferenceParam(); break; - case SOURCE: - qp = new SourceParam(); - break; case SPECIAL: case URI: case HAS: diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java index 75956967d75..09a260d5f4d 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/MatchUrlService.java @@ -113,7 +113,7 @@ public class MatchUrlService { type.setValuesAsQueryTokens(myContext, nextParamName, (paramList)); paramMap.add(nextParamName, type); } else if (Constants.PARAM_SOURCE.equals(nextParamName)) { - IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.SOURCE, nextParamName, paramList); + IQueryParameterAnd param = ParameterUtil.parseQueryParams(myContext, RestSearchParameterTypeEnum.TOKEN, nextParamName, paramList); paramMap.add(nextParamName, param); } else if (nextParamName.startsWith("_")) { // ignore these since they aren't search params (e.g. _sort) diff --git a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java index b01366f932a..e7c509de7eb 100644 --- a/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcher.java @@ -27,10 +27,14 @@ import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.extractor.ResourceIndexedSearchParams; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; +import ca.uhn.fhir.jpa.searchparam.util.SourceParam; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; -import ca.uhn.fhir.rest.param.*; +import ca.uhn.fhir.rest.param.BaseParamWithPrefix; +import ca.uhn.fhir.rest.param.ParamPrefixEnum; +import ca.uhn.fhir.rest.param.ReferenceParam; +import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.util.MetaUtil; import ca.uhn.fhir.util.UrlUtil; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/SourceParam.java similarity index 64% rename from hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java rename to hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/SourceParam.java index b576c1291bb..61c082df9b6 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/SourceParam.java +++ b/hapi-fhir-jpaserver-searchparam/src/main/java/ca/uhn/fhir/jpa/searchparam/util/SourceParam.java @@ -1,7 +1,5 @@ -package ca.uhn.fhir.rest.param; +package ca.uhn.fhir.jpa.searchparam.util; -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.api.Constants; import static org.apache.commons.lang3.StringUtils.left; @@ -27,22 +25,16 @@ import static org.apache.commons.lang3.StringUtils.left; */ /** - * Implementation of the _has method parameter + * Model of the _source parameter */ -public class SourceParam extends BaseParam implements IQueryParameterType { +public class SourceParam { private static final long serialVersionUID = 1L; - private String myParameterValue; - private String mySourceUri; - private String myRequestId; - - public SourceParam() {} + private final String myParameterValue; + private final String mySourceUri; + private final String myRequestId; public SourceParam(String theParameterValue) { - setValue(theParameterValue); - } - - private void setValue(String theParameterValue) { myParameterValue = theParameterValue; String requestId; int lastHashValueIndex = theParameterValue.lastIndexOf('#'); @@ -50,7 +42,9 @@ public class SourceParam extends BaseParam implements IQueryParameterType { mySourceUri = theParameterValue; requestId = null; } else { - if (lastHashValueIndex != 0) { + if (lastHashValueIndex == 0) { + mySourceUri = null; + } else { mySourceUri = theParameterValue.substring(0, lastHashValueIndex); } requestId = theParameterValue.substring(lastHashValueIndex + 1); @@ -58,21 +52,6 @@ public class SourceParam extends BaseParam implements IQueryParameterType { myRequestId = left(requestId, Constants.REQUEST_ID_LENGTH); } - @Override - String doGetQueryParameterQualifier() { - return null; - } - - @Override - String doGetValueAsQueryToken(FhirContext theContext) { - return myParameterValue; - } - - @Override - void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) { - setValue(theValue); - } - public String getSourceUri() { return mySourceUri; } diff --git a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java index 89a4ca82534..b151af6232c 100644 --- a/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java +++ b/hapi-fhir-jpaserver-searchparam/src/test/java/ca/uhn/fhir/jpa/searchparam/matcher/InMemoryResourceMatcherR5Test.java @@ -44,8 +44,7 @@ public class InMemoryResourceMatcherR5Test { private static final String TEST_SOURCE = SOURCE_URI + "#" + REQUEST_ID; @Autowired - private - InMemoryResourceMatcher myInMemoryResourceMatcher; + private InMemoryResourceMatcher myInMemoryResourceMatcher; @MockBean ISearchParamRegistry mySearchParamRegistry; From f19100cbb3bbf0b73baf93764f62e10190c80a66 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Thu, 24 Oct 2019 20:29:45 -0400 Subject: [PATCH 7/7] final cleanup --- .../ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java | 4 ++-- .../src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java | 4 ++-- .../src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java index 0a8fd6b3bb4..1da52a194c6 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/RestSearchParameterTypeEnum.java @@ -21,11 +21,11 @@ package ca.uhn.fhir.rest.api; * #L% */ -import ca.uhn.fhir.model.api.IValueSetEnumBinder; - import java.util.HashMap; import java.util.Map; +import ca.uhn.fhir.model.api.IValueSetEnumBinder; + public enum RestSearchParameterTypeEnum { /** diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java index fed33cf2b44..34d98c5de73 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java @@ -24,6 +24,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.jpa.delete.DeleteConflictList; import ca.uhn.fhir.jpa.model.entity.ResourceTable; import ca.uhn.fhir.jpa.model.entity.TagDefinition; +import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.jpa.searchparam.MatchUrlService; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; @@ -54,7 +55,6 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetai import ca.uhn.fhir.rest.server.method.BaseMethodBinding; import ca.uhn.fhir.rest.server.method.BaseResourceReturningMethodBinding; import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; -import ca.uhn.fhir.rest.server.servlet.ServletSubRequestDetails; import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.UrlUtil; import ca.uhn.fhir.util.UrlUtil.UrlParts; @@ -243,7 +243,7 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao { int qIndex = url.indexOf('?'); ArrayListMultimap paramValues = ArrayListMultimap.create(); - requestDetails.setParameters(new HashMap<>()); + requestDetails.setParameters(new HashMap()); if (qIndex != -1) { String params = url.substring(qIndex); List parameters = myMatchUrlService.translateMatchUrl(params); 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 8175c58323e..1e3f16fcfd6 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 @@ -40,8 +40,8 @@ import ca.uhn.fhir.jpa.searchparam.ResourceMetaParams; import ca.uhn.fhir.jpa.searchparam.SearchParameterMap; import ca.uhn.fhir.jpa.searchparam.registry.ISearchParamRegistry; import ca.uhn.fhir.jpa.searchparam.util.SourceParam; -import ca.uhn.fhir.jpa.term.VersionIndependentConcept; import ca.uhn.fhir.jpa.term.api.ITermReadSvc; +import ca.uhn.fhir.jpa.term.VersionIndependentConcept; import ca.uhn.fhir.jpa.util.*; import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.base.composite.BaseCodingDt;