diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java index 6991fcaeb57..2aee72ce568 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParameterMap.java @@ -1,5 +1,7 @@ package ca.uhn.fhir.jpa.dao; +import static java.util.Collections.newSetFromMap; + /* * #%L * HAPI FHIR JPA Server @@ -21,9 +23,11 @@ package ca.uhn.fhir.jpa.dao; */ import java.util.*; +import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; +import ca.uhn.fhir.jpa.dao.SearchParameterMap.QueryParameterTypeComparator; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; @@ -32,9 +36,31 @@ import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.util.ObjectUtil; public class SearchParameterMap extends LinkedHashMap>> { + public class QueryParameterTypeComparator implements Comparator { + + @Override + public int compare(IQueryParameterType theO1, IQueryParameterType theO2) { + int retVal = 0; + + if (theO1.getMissing() == null && theO2.getMissing() == null) { + // neither are missing + } else if (theO1.getMissing() == null) { + retVal = -1; + } else if (theO2.getMissing() == null) { + retVal = 1; + } else if (!ObjectUtil.equals(theO1.getMissing(), theO2.getMissing())) { + + } + + return retVal; + } + + } + private static final long serialVersionUID = 1L; private Integer myCount; @@ -279,4 +305,24 @@ public class SearchParameterMap extends LinkedHashMap keys = new ArrayList(keySet()); + Collections.sort(keys); + for (String nextKey : keys) { + + List> nextValuesAnds = get(nextKey); + for (List nextValuesAnd : nextValuesAnds) { + for (List nextValuesOrs : nextValuesAnds) { + + nextValuesOrs = new ArrayList(nextValuesOrs); + Collections.sort(nextValuesOrs, new QueryParameterTypeComparator()); + + } + } + + } + } + } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SearchParameterMapTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SearchParameterMapTest.java index f79bed8fc0f..e7217997ad7 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SearchParameterMapTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/SearchParameterMapTest.java @@ -1,11 +1,14 @@ package ca.uhn.fhir.jpa.provider; +import static java.util.Collections.addAll; import static org.junit.Assert.assertEquals; import org.junit.AfterClass; import org.junit.Test; +import ca.uhn.fhir.jpa.dao.SearchParameterMap; import ca.uhn.fhir.jpa.dao.SearchParameterMap.EverythingModeEnum; +import ca.uhn.fhir.rest.param.*; import ca.uhn.fhir.util.TestUtil; public class SearchParameterMapTest { @@ -16,6 +19,25 @@ public class SearchParameterMapTest { } + @Test + public void testToQueryString() { + SearchParameterMap map = new SearchParameterMap(); + + StringAndListParam familyAnd = new StringAndListParam() + .addAnd(new StringOrListParam().add(new StringParam("ZZZ?").setExact(true))) + .addAnd(new StringOrListParam().add(new StringParam("homer")).add(new StringParam("jay"))) + .addAnd(new StringOrListParam().add(new StringParam("simpson")).add(new StringParam("bouvier"))); + map.add("name", familyAnd); + + DateAndListParam birthdateAnd = new DateAndListParam() + .addAnd(new DateOrListParam().add(new DateParam(ParamPrefixEnum.GREATERTHAN_OR_EQUALS, "2001"))) + .addAnd(new DateOrListParam().add(new DateParam(ParamPrefixEnum.LESSTHAN, "2002"))); + map.add("birthdate", birthdateAnd); + + String queryString = map.toQueryString(); + } + + /** * {@link Search} uses these ordinals so they shouldn't get out of order */