diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java index 952362ae003..f0c4503a175 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java @@ -166,8 +166,8 @@ public abstract class BaseHapiFhirDao implements IDao { return InstantDt.withCurrentTime(); } - protected List extractResourceLinks(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + protected Set extractResourceLinks(ResourceTable theEntity, IResource theResource) { + Set retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -185,73 +185,76 @@ public abstract class BaseHapiFhirDao implements IDao { multiType = true; } - for (Object nextObject : extractValues(nextPathsUnsplit, theResource)) { - if (nextObject == null) { - continue; - } - - ResourceLink nextEntity; - if (nextObject instanceof BaseResourceReferenceDt) { - BaseResourceReferenceDt nextValue = (BaseResourceReferenceDt) nextObject; - if (nextValue.isEmpty()) { - continue; - } - if (nextValue.getReference().isEmpty() || nextValue.getReference().getValue().startsWith("#")) { - // This is a blank or contained resource reference + String[] nextPathsSplit = nextPathsUnsplit.split("\\|"); + for (String nextPath : nextPathsSplit) { + for (Object nextObject : extractValues(nextPath, theResource)) { + if (nextObject == null) { continue; } - String typeString = nextValue.getReference().getResourceType(); - if (isBlank(typeString)) { - throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue()); - } - RuntimeResourceDefinition resourceDefinition; - try { - resourceDefinition = getContext().getResourceDefinition(typeString); - } catch (DataFormatException e) { - throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue()); - } + ResourceLink nextEntity; + if (nextObject instanceof BaseResourceReferenceDt) { + BaseResourceReferenceDt nextValue = (BaseResourceReferenceDt) nextObject; + if (nextValue.isEmpty()) { + continue; + } + if (nextValue.getReference().isEmpty() || nextValue.getReference().getValue().startsWith("#")) { + // This is a blank or contained resource reference + continue; + } - Class type = resourceDefinition.getImplementingClass(); - String id = nextValue.getReference().getIdPart(); - if (StringUtils.isBlank(id)) { - throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReference().getValue()); - } + String typeString = nextValue.getReference().getResourceType(); + if (isBlank(typeString)) { + throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReference().getValue()); + } + RuntimeResourceDefinition resourceDefinition; + try { + resourceDefinition = getContext().getResourceDefinition(typeString); + } catch (DataFormatException e) { + throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Resource type is unknown or not supported on this server - " + nextValue.getReference().getValue()); + } - IFhirResourceDao dao = getDao(type); - if (dao == null) { - StringBuilder b = new StringBuilder(); - b.append("This server (version "); - b.append(myContext.getVersion().getVersion()); - b.append(") is not able to handle resources of type["); - b.append(nextValue.getReference().getResourceType()); - b.append("] - Valid resource types for this server: "); - b.append(myResourceTypeToDao.keySet().toString()); + Class type = resourceDefinition.getImplementingClass(); + String id = nextValue.getReference().getIdPart(); + if (StringUtils.isBlank(id)) { + throw new InvalidRequestException("Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReference().getValue()); + } - throw new InvalidRequestException(b.toString()); - } - Long valueOf; - try { - valueOf = translateForcedIdToPid(nextValue.getReference()); - } catch (ResourceNotFoundException e) { - String resName = getContext().getResourceDefinition(type).getName(); - throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit); - } - ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf); - if (target == null) { - String resName = getContext().getResourceDefinition(type).getName(); - throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit); - } - nextEntity = new ResourceLink(nextPathsUnsplit, theEntity, target); - } else { - if (!multiType) { - throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass()); + IFhirResourceDao dao = getDao(type); + if (dao == null) { + StringBuilder b = new StringBuilder(); + b.append("This server (version "); + b.append(myContext.getVersion().getVersion()); + b.append(") is not able to handle resources of type["); + b.append(nextValue.getReference().getResourceType()); + b.append("] - Valid resource types for this server: "); + b.append(myResourceTypeToDao.keySet().toString()); + + throw new InvalidRequestException(b.toString()); + } + Long valueOf; + try { + valueOf = translateForcedIdToPid(nextValue.getReference()); + } catch (ResourceNotFoundException e) { + String resName = getContext().getResourceDefinition(type).getName(); + throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit); + } + ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf); + if (target == null) { + String resName = getContext().getResourceDefinition(type).getName(); + throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit); + } + nextEntity = new ResourceLink(nextPath, theEntity, target); } else { - continue; + if (!multiType) { + throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass()); + } else { + continue; + } + } + if (nextEntity != null) { + retVal.add(nextEntity); } - } - if (nextEntity != null) { - retVal.add(nextEntity); } } } @@ -261,46 +264,43 @@ public abstract class BaseHapiFhirDao implements IDao { return retVal; } - protected List extractSearchParamDates(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamDates(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamDates(theEntity, theResource); } - protected List extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamNumber(theEntity, theResource); } - protected List extractSearchParamUri(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamUri(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamUri(theEntity, theResource); } - protected List extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource); } - protected List extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamQuantity(theEntity, theResource); } - protected List extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamStrings(theEntity, theResource); } - protected List extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { + protected Set extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { return mySearchParamExtractor.extractSearchParamTokens(theEntity, theResource); } - private List extractValues(String thePaths, IResource theResource) { + private List extractValues(String thePath, IResource theResource) { List values = new ArrayList(); - String[] nextPathsSplit = thePaths.split("\\|"); FhirTerser t = getContext().newTerser(); - for (String nextPath : nextPathsSplit) { - String nextPathTrimmed = nextPath.trim(); - try { - values.addAll(t.getValues(theResource, nextPathTrimmed)); - } catch (Exception e) { - RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); - ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() }); - } + String nextPathTrimmed = thePath.trim(); + try { + values.addAll(t.getValues(theResource, nextPathTrimmed)); + } catch (Exception e) { + RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); + ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() }); } return values; } @@ -1109,25 +1109,25 @@ public abstract class BaseHapiFhirDao implements IDao { Collection paramsCoords = new ArrayList(theEntity.getParamsCoords()); Collection resourceLinks = new ArrayList(theEntity.getResourceLinks()); - List stringParams = null; - List tokenParams = null; - List numberParams = null; - List quantityParams = null; - List dateParams = null; - List uriParams = null; - List coordsParams = null; - List links = null; + Set stringParams = null; + Set tokenParams = null; + Set numberParams = null; + Set quantityParams = null; + Set dateParams = null; + Set uriParams = null; + Set coordsParams = null; + Set links = null; if (theDeletedTimestampOrNull != null) { - stringParams = Collections.emptyList(); - tokenParams = Collections.emptyList(); - numberParams = Collections.emptyList(); - quantityParams = Collections.emptyList(); - dateParams = Collections.emptyList(); - uriParams = Collections.emptyList(); - coordsParams = Collections.emptyList(); - links = Collections.emptyList(); + stringParams = Collections.emptySet(); + tokenParams = Collections.emptySet(); + numberParams = Collections.emptySet(); + quantityParams = Collections.emptySet(); + dateParams = Collections.emptySet(); + uriParams = Collections.emptySet(); + coordsParams = Collections.emptySet(); + links = Collections.emptySet(); theEntity.setDeleted(theDeletedTimestampOrNull); theEntity.setUpdated(theDeletedTimestampOrNull); @@ -1147,7 +1147,7 @@ public abstract class BaseHapiFhirDao implements IDao { // ourLog.info("Indexing resource: {}", entity.getId()); ourLog.trace("Storing string indexes: {}", stringParams); - tokenParams = new ArrayList(); + tokenParams = new HashSet(); for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(theEntity, theResource)) { if (next instanceof ResourceIndexedSearchParamToken) { tokenParams.add((ResourceIndexedSearchParamToken) next); diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java index 916c4358a9d..bd9977b30e4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java @@ -1,6 +1,5 @@ package ca.uhn.fhir.jpa.dao; -import static org.apache.commons.lang3.StringUtils.INDEX_NOT_FOUND; /* * #%L * HAPI FHIR JPA Server diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamExtractor.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamExtractor.java index 58799408638..a072560042a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamExtractor.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamExtractor.java @@ -1,27 +1,6 @@ package ca.uhn.fhir.jpa.dao; -/* - * #%L - * HAPI FHIR JPA Server - * %% - * Copyright (C) 2014 - 2015 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% - */ - -import java.util.ArrayList; -import java.util.List; +import java.util.Set; import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam; import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords; @@ -35,18 +14,18 @@ import ca.uhn.fhir.model.api.IResource; interface ISearchParamExtractor { - public abstract List extractSearchParamCoords(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamCoords(ResourceTable theEntity, IResource theResource); - public abstract List extractSearchParamDates(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamDates(ResourceTable theEntity, IResource theResource); - public abstract ArrayList extractSearchParamNumber(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamNumber(ResourceTable theEntity, IResource theResource); - public abstract List extractSearchParamQuantity(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamQuantity(ResourceTable theEntity, IResource theResource); - public abstract List extractSearchParamStrings(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamStrings(ResourceTable theEntity, IResource theResource); - public abstract List extractSearchParamTokens(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamTokens(ResourceTable theEntity, IResource theResource); - public abstract List extractSearchParamUri(ResourceTable theEntity, IResource theResource); + public abstract Set extractSearchParamUri(ResourceTable theEntity, IResource theResource); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu1.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu1.java index 6bced7ae6e3..ceff8c5756c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu1.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu1.java @@ -75,13 +75,13 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { - return Collections.emptyList(); + public Set extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { + return Collections.emptySet(); } @Override - public List extractSearchParamDates(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamDates(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -135,8 +135,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public ArrayList extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public HashSet extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -230,8 +230,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -278,8 +278,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -364,8 +364,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -472,8 +472,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamUri(ResourceTable theEntity, IResource theResource) { - return Collections.emptyList(); + public Set extractSearchParamUri(ResourceTable theEntity, IResource theResource) { + return Collections.emptySet(); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu2.java index a23641d9ba5..b8bede8cb10 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu2.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchParamExtractorDstu2.java @@ -84,7 +84,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen super(theContext); } - private void addSearchTerm(ResourceTable theEntity, ArrayList retVal, String resourceName, String searchTerm) { + private void addSearchTerm(ResourceTable theEntity, Set retVal, String resourceName, String searchTerm) { if (isBlank(searchTerm)) { return; } @@ -97,7 +97,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen retVal.add(nextEntity); } - private void addStringParam(ResourceTable theEntity, ArrayList retVal, RuntimeSearchParam nextSpDef, String value) { + private void addStringParam(ResourceTable theEntity, Set retVal, RuntimeSearchParam nextSpDef, String value) { if (value.length() > ResourceIndexedSearchParamString.MAX_LENGTH) { value = value.substring(0, ResourceIndexedSearchParamString.MAX_LENGTH); } @@ -107,9 +107,9 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { + public Set extractSearchParamCoords(ResourceTable theEntity, IResource theResource) { // TODO: implement - return Collections.emptyList(); + return Collections.emptySet(); } /* @@ -118,8 +118,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen * @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource) */ @Override - public List extractSearchParamDates(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamDates(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -178,8 +178,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen * @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource) */ @Override - public ArrayList extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public HashSet extractSearchParamNumber(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -272,8 +272,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen * @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource) */ @Override - public List extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -326,8 +326,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen * @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource) */ @Override - public List extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamStrings(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -407,8 +407,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen * @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IResource) */ @Override - public List extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamTokens(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); String useSystem = null; if (theResource instanceof ValueSet) { @@ -556,8 +556,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen } @Override - public List extractSearchParamUri(ResourceTable theEntity, IResource theResource) { - ArrayList retVal = new ArrayList(); + public Set extractSearchParamUri(ResourceTable theEntity, IResource theResource) { + HashSet retVal = new HashSet(); RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource); for (RuntimeSearchParam nextSpDef : def.getSearchParams()) { @@ -608,13 +608,13 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen private void extractTokensFromCodeableConcept(List theSystems, List theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity, - ArrayList theListToPopulate, RuntimeSearchParam theParameterDef) { + Set theListToPopulate, RuntimeSearchParam theParameterDef) { for (CodingDt nextCoding : theCodeableConcept.getCoding()) { extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding); } } - private void extractTokensFromCoding(List theSystems, List theCodes, ResourceTable theEntity, ArrayList theListToPopulate, + private void extractTokensFromCoding(List theSystems, List theCodes, ResourceTable theEntity, Set theListToPopulate, RuntimeSearchParam theParameterDef, CodingDt nextCoding) { if (nextCoding != null && !nextCoding.isEmpty()) { diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamCoords.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamCoords.java index 7e6e4e88c8c..2f89be47f57 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamCoords.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamCoords.java @@ -24,6 +24,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + //@formatter:off @Entity @Table(name = "HFJ_SPIDX_COORDS" /* , indexes = { @Index(name = "IDX_SP_TOKEN", columnList = "SP_SYSTEM,SP_VALUE") } */) @@ -52,20 +57,59 @@ public class ResourceIndexedSearchParamCoords extends BaseResourceIndexedSearchP setLongitude(theLongitude); } - public double getLatitude() { - return myLatitude; + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamCoords)) { + return false; + } + ResourceIndexedSearchParamCoords obj = (ResourceIndexedSearchParamCoords) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getLatitude(), obj.getLatitude()); + b.append(getLongitude(), obj.getLongitude()); + return b.isEquals(); } - public void setLatitude(double theLatitude) { - myLatitude = theLatitude; + public double getLatitude() { + return myLatitude; } public double getLongitude() { return myLongitude; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getLatitude()); + b.append(getLongitude()); + return b.toHashCode(); + } + + public void setLatitude(double theLatitude) { + myLatitude = theLatitude; + } + public void setLongitude(double theLongitude) { myLongitude = theLongitude; } - + + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + b.append("paramName", getParamName()); + b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this + b.append("lat", getLatitude()); + b.append("lon", getLongitude()); + return b.build(); + } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamDate.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamDate.java index 303a2797089..140951b433a 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamDate.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamDate.java @@ -28,6 +28,11 @@ import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + //@formatter:off @Entity @Table(name = "HFJ_SPIDX_DATE" /*, indexes= {@Index(name="IDX_SP_DATE", columnList= "SP_VALUE_LOW,SP_VALUE_HIGH")}*/) @@ -47,18 +52,34 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar @Temporal(TemporalType.TIMESTAMP) public Date myValueLow; - - public ResourceIndexedSearchParamDate() { } - + public ResourceIndexedSearchParamDate(String theName, Date theLow, Date theHigh) { setParamName(theName); setValueLow(theLow); setValueHigh(theHigh); } - + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamDate)) { + return false; + } + ResourceIndexedSearchParamDate obj = (ResourceIndexedSearchParamDate) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getValueHigh(), obj.getValueHigh()); + b.append(getValueLow(), obj.getValueLow()); + return b.isEquals(); + } public Date getValueHigh() { return myValueHigh; @@ -68,6 +89,16 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar return myValueLow; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getValueHigh()); + b.append(getValueLow()); + return b.toHashCode(); + } + public void setValueHigh(Date theValueHigh) { myValueHigh = theValueHigh; } @@ -76,6 +107,13 @@ public class ResourceIndexedSearchParamDate extends BaseResourceIndexedSearchPar myValueLow = theValueLow; } - - + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + b.append("paramName", getParamName()); + b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this + b.append("valueLow", getValueLow()); + b.append("valueHigh", getValueHigh()); + return b.build(); + } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamNumber.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamNumber.java index 405f778fae8..50d9dafabc2 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamNumber.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamNumber.java @@ -26,6 +26,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + //@formatter:off @Entity @Table(name = "HFJ_SPIDX_NUMBER" /*, indexes= {@Index(name="IDX_SP_NUMBER", columnList="SP_VALUE")}*/ ) @@ -39,21 +44,57 @@ public class ResourceIndexedSearchParamNumber extends BaseResourceIndexedSearchP @Column(name = "SP_VALUE", nullable = true) public BigDecimal myValue; - + public ResourceIndexedSearchParamNumber() { } - + public ResourceIndexedSearchParamNumber(String theParamName, BigDecimal theValue) { setParamName(theParamName); setValue(theValue); } + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamNumber)) { + return false; + } + ResourceIndexedSearchParamNumber obj = (ResourceIndexedSearchParamNumber) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getValue(), obj.getValue()); + return b.isEquals(); + } + public BigDecimal getValue() { return myValue; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getValue()); + return b.toHashCode(); + } + public void setValue(BigDecimal theValue) { myValue = theValue; } + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + b.append("paramName", getParamName()); + b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this + b.append("value", getValue()); + return b.build(); + } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamQuantity.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamQuantity.java index 71e4356dbb9..ab824f7d109 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamQuantity.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamQuantity.java @@ -26,6 +26,11 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Table; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + //@formatter:off @Entity @Table(name = "HFJ_SPIDX_QUANTITY" /*, indexes= {@Index(name="IDX_SP_NUMBER", columnList="SP_VALUE")}*/ ) @@ -47,9 +52,9 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc public BigDecimal myValue; public ResourceIndexedSearchParamQuantity() { - //nothing + // nothing } - + public ResourceIndexedSearchParamQuantity(String theParamName, BigDecimal theValue, String theSystem, String theUnits) { setParamName(theParamName); setSystem(theSystem); @@ -57,6 +62,27 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc setUnits(theUnits); } + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamQuantity)) { + return false; + } + ResourceIndexedSearchParamQuantity obj = (ResourceIndexedSearchParamQuantity) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getSystem(), obj.getSystem()); + b.append(getUnits(), obj.getUnits()); + b.append(getValue(), obj.getValue()); + return b.isEquals(); + } + public String getSystem() { return mySystem; } @@ -69,6 +95,16 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc return myValue; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getSystem()); + b.append(getUnits()); + b.append(getValue()); + return b.toHashCode(); + } public void setSystem(String theSystem) { mySystem = theSystem; @@ -82,4 +118,15 @@ public class ResourceIndexedSearchParamQuantity extends BaseResourceIndexedSearc myValue = theValue; } + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + b.append("paramName", getParamName()); + b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this + b.append("system", getSystem()); + b.append("units", getUnits()); + b.append("value", getValue()); + return b.build(); + } + } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java index 493d1b08756..2e6b3860855 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamString.java @@ -25,25 +25,26 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; @Entity -@Table(name = "HFJ_SPIDX_STRING"/*, indexes= {@Index(name="IDX_SP_STRING", columnList="SP_VALUE_NORMALIZED")}*/) -@org.hibernate.annotations.Table(appliesTo="HFJ_SPIDX_STRING",indexes= { - @org.hibernate.annotations.Index(name="IDX_SP_STRING", columnNames= {"RES_TYPE", "SP_NAME", "SP_VALUE_NORMALIZED"})}) +@Table(name = "HFJ_SPIDX_STRING"/* , indexes= {@Index(name="IDX_SP_STRING", columnList="SP_VALUE_NORMALIZED")} */) +@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_STRING", indexes = { @org.hibernate.annotations.Index(name = "IDX_SP_STRING", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE_NORMALIZED" }) }) public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchParam { public static final int MAX_LENGTH = 100; private static final long serialVersionUID = 1L; + @Column(name = "SP_VALUE_EXACT", length = 100, nullable = true) + public String myValueExact; + @Column(name = "SP_VALUE_NORMALIZED", length = MAX_LENGTH, nullable = true) public String myValueNormalized; - @Column(name="SP_VALUE_EXACT",length=100,nullable=true) - public String myValueExact; - public ResourceIndexedSearchParamString() { } @@ -53,21 +54,42 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP setValueExact(theValueExact); } - public String getValueNormalized() { - return myValueNormalized; - } - - public void setValueNormalized(String theValueNormalized) { - if (StringUtils.defaultString(theValueNormalized).length() > MAX_LENGTH) { - throw new IllegalArgumentException("Value is too long: " + theValueNormalized.length()); + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; } - myValueNormalized = theValueNormalized; + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamString)) { + return false; + } + ResourceIndexedSearchParamString obj = (ResourceIndexedSearchParamString) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getValueExact(), obj.getValueExact()); + return b.isEquals(); } public String getValueExact() { return myValueExact; } + public String getValueNormalized() { + return myValueNormalized; + } + + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getValueExact()); + return b.toHashCode(); + } + public void setValueExact(String theValueExact) { if (StringUtils.defaultString(theValueExact).length() > MAX_LENGTH) { throw new IllegalArgumentException("Value is too long: " + theValueExact.length()); @@ -75,6 +97,13 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP myValueExact = theValueExact; } + public void setValueNormalized(String theValueNormalized) { + if (StringUtils.defaultString(theValueNormalized).length() > MAX_LENGTH) { + throw new IllegalArgumentException("Value is too long: " + theValueNormalized.length()); + } + myValueNormalized = theValueNormalized; + } + @Override public String toString() { ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); @@ -83,5 +112,4 @@ public class ResourceIndexedSearchParamString extends BaseResourceIndexedSearchP b.append("value", getValueNormalized()); return b.build(); } - } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamToken.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamToken.java index 7f84b351e67..c22dd0ec877 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamToken.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamToken.java @@ -25,13 +25,15 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; @Entity @Table(name = "HFJ_SPIDX_TOKEN" /* , indexes = { @Index(name = "IDX_SP_TOKEN", columnList = "SP_SYSTEM,SP_VALUE") } */) -@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_TOKEN", indexes = { - @org.hibernate.annotations.Index(name = "IDX_SP_TOKEN", columnNames = { "RES_TYPE", "SP_NAME", "SP_SYSTEM", "SP_VALUE" }), - @org.hibernate.annotations.Index(name = "IDX_SP_TOKEN_UNQUAL", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE" }) -}) +@org.hibernate.annotations.Table(appliesTo = "HFJ_SPIDX_TOKEN", indexes = { @org.hibernate.annotations.Index(name = "IDX_SP_TOKEN", columnNames = { "RES_TYPE", "SP_NAME", "SP_SYSTEM", "SP_VALUE" }), + @org.hibernate.annotations.Index(name = "IDX_SP_TOKEN_UNQUAL", columnNames = { "RES_TYPE", "SP_NAME", "SP_VALUE" }) }) public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchParam { public static final int MAX_LENGTH = 100; @@ -53,6 +55,26 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa setValue(theValue); } + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamToken)) { + return false; + } + ResourceIndexedSearchParamToken obj = (ResourceIndexedSearchParamToken) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getSystem(), obj.getSystem()); + b.append(getValue(), obj.getValue()); + return b.isEquals(); + } + public String getSystem() { return mySystem; } @@ -61,6 +83,16 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa return myValue; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getSystem()); + b.append(getValue()); + return b.toHashCode(); + } + public void setSystem(String theSystem) { mySystem = StringUtils.defaultIfBlank(theSystem, null); } @@ -69,4 +101,13 @@ public class ResourceIndexedSearchParamToken extends BaseResourceIndexedSearchPa myValue = StringUtils.defaultIfBlank(theValue, null); } + @Override + public String toString() { + ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE); + b.append("paramName", getParamName()); + b.append("resourceId", getResource().getId()); // TODO: add a field so we don't need to resolve this + b.append("system", getSystem()); + b.append("value", getValue()); + return b.build(); + } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamUri.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamUri.java index 3309724dfe3..2a2370fcc8c 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamUri.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceIndexedSearchParamUri.java @@ -25,6 +25,8 @@ import javax.persistence.Entity; import javax.persistence.Table; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; //@formatter:off @@ -51,10 +53,38 @@ public class ResourceIndexedSearchParamUri extends BaseResourceIndexedSearchPara setUri(theUri); } + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceIndexedSearchParamUri)) { + return false; + } + ResourceIndexedSearchParamUri obj = (ResourceIndexedSearchParamUri) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(getParamName(), obj.getParamName()); + b.append(getResource(), obj.getResource()); + b.append(getUri(), obj.getUri()); + return b.isEquals(); + } + public String getUri() { return myUri; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(getParamName()); + b.append(getResource()); + b.append(getUri()); + return b.toHashCode(); + } + public void setUri(String theUri) { myUri = StringUtils.defaultIfBlank(theUri, null); } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java index 519088cf4c0..27e3aa2e9dd 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceLink.java @@ -32,11 +32,12 @@ import javax.persistence.ManyToOne; import javax.persistence.Table; import org.apache.commons.lang3.Validate; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; @Entity -@Table(name = "HFJ_RES_LINK"/*, indexes= {@Index(name="IDX_RL_TPATHRES", columnList= "SRC_PATH,TARGET_RESOURCE_ID")}*/) -@org.hibernate.annotations.Table(appliesTo="HFJ_RES_LINK",indexes= { - @org.hibernate.annotations.Index(name="IDX_RL_TPATHRES", columnNames= {"SRC_PATH", "TARGET_RESOURCE_ID"})}) +@Table(name = "HFJ_RES_LINK"/* , indexes= {@Index(name="IDX_RL_TPATHRES", columnList= "SRC_PATH,TARGET_RESOURCE_ID")} */) +@org.hibernate.annotations.Table(appliesTo = "HFJ_RES_LINK", indexes = { @org.hibernate.annotations.Index(name = "IDX_RL_TPATHRES", columnNames = { "SRC_PATH", "TARGET_RESOURCE_ID" }) }) public class ResourceLink implements Serializable { private static final long serialVersionUID = 1L; @@ -50,33 +51,21 @@ public class ResourceLink implements Serializable { private String mySourcePath; @ManyToOne(optional = false) - @JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName="RES_ID", nullable=false) + @JoinColumn(name = "SRC_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false) private ResourceTable mySourceResource; - @Column(name = "SRC_RESOURCE_ID", insertable = false, updatable = false, nullable=false) + @Column(name = "SRC_RESOURCE_ID", insertable = false, updatable = false, nullable = false) private Long mySourceResourcePid; @ManyToOne(optional = false) - @JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName="RES_ID", nullable=false) + @JoinColumn(name = "TARGET_RESOURCE_ID", referencedColumnName = "RES_ID", nullable = false) private ResourceTable myTargetResource; - @Column(name = "TARGET_RESOURCE_ID", insertable = false, updatable = false,nullable=false) + @Column(name = "TARGET_RESOURCE_ID", insertable = false, updatable = false, nullable = false) private Long myTargetResourcePid; public ResourceLink() { - //nothing - } - - @Override - public String toString() { - StringBuilder b = new StringBuilder(); - b.append("ResourceLink["); - b.append("path=").append(mySourcePath); - b.append(", src=").append(mySourceResource.getId()); - b.append(", target=").append(myTargetResource.getId()); - - b.append("]"); - return b.toString(); + // nothing } public ResourceLink(String theSourcePath, ResourceTable theSourceResource, ResourceTable theTargetResource) { @@ -86,6 +75,25 @@ public class ResourceLink implements Serializable { myTargetResource = theTargetResource; } + @Override + public boolean equals(Object theObj) { + if (this == theObj) { + return true; + } + if (theObj == null) { + return false; + } + if (!(theObj instanceof ResourceLink)) { + return false; + } + ResourceLink obj = (ResourceLink) theObj; + EqualsBuilder b = new EqualsBuilder(); + b.append(mySourcePath, obj.mySourcePath); + b.append(mySourceResource, obj.mySourceResource); + b.append(myTargetResource, obj.myTargetResource); + return b.isEquals(); + } + public String getSourcePath() { return mySourcePath; } @@ -106,6 +114,15 @@ public class ResourceLink implements Serializable { return myTargetResourcePid; } + @Override + public int hashCode() { + HashCodeBuilder b = new HashCodeBuilder(); + b.append(mySourcePath); + b.append(mySourceResource); + b.append(myTargetResource); + return b.toHashCode(); + } + public void setSourcePath(String theSourcePath) { mySourcePath = theSourcePath; } @@ -114,17 +131,21 @@ public class ResourceLink implements Serializable { mySourceResource = theSourceResource; } - public void setSourceResourcePid(Long theSourceResourcePid) { - mySourceResourcePid = theSourceResourcePid; - } - public void setTargetResource(ResourceTable theTargetResource) { Validate.notNull(theTargetResource); myTargetResource = theTargetResource; } - public void setTargetResourcePid(Long theTargetResourcePid) { - myTargetResourcePid = theTargetResourcePid; + @Override + public String toString() { + StringBuilder b = new StringBuilder(); + b.append("ResourceLink["); + b.append("path=").append(mySourcePath); + b.append(", src=").append(mySourceResource.getId()); + b.append(", target=").append(myTargetResource.getId()); + + b.append("]"); + return b.toString(); } } diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTable.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTable.java index 45e9bd316ac..2dc12fabdc4 100644 --- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTable.java +++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/ResourceTable.java @@ -19,14 +19,12 @@ package ca.uhn.fhir.jpa.entity; * limitations under the License. * #L% */ - -import static org.apache.commons.lang3.StringUtils.*; +import static org.apache.commons.lang3.StringUtils.defaultString; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.persistence.CascadeType; @@ -329,7 +327,7 @@ public class ResourceTable extends BaseHasResource implements Serializable { myParamsDatePopulated = theParamsDatePopulated; } - public void setParamsNumber(List theNumberParams) { + public void setParamsNumber(Collection theNumberParams) { if (!isParamsNumberPopulated() && theNumberParams.isEmpty()) { return; } @@ -396,7 +394,7 @@ public class ResourceTable extends BaseHasResource implements Serializable { myProfile = theProfile; } - public void setResourceLinks(List theLinks) { + public void setResourceLinks(Collection theLinks) { if (!isHasLinks() && theLinks.isEmpty()) { return; } diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java index 3143be96d85..e72f4ce64ea 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/BaseJpaDstu2Test.java @@ -12,7 +12,6 @@ import javax.persistence.PersistenceContext; import org.apache.commons.io.IOUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.junit.Before; -import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -42,9 +41,12 @@ import ca.uhn.fhir.jpa.entity.ResourceTag; import ca.uhn.fhir.jpa.entity.TagDefinition; import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2; import ca.uhn.fhir.model.dstu2.resource.Bundle; +import ca.uhn.fhir.model.dstu2.resource.ConceptMap; import ca.uhn.fhir.model.dstu2.resource.Device; +import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder; import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport; import ca.uhn.fhir.model.dstu2.resource.Encounter; +import ca.uhn.fhir.model.dstu2.resource.Immunization; import ca.uhn.fhir.model.dstu2.resource.Location; import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.dstu2.resource.Organization; @@ -53,6 +55,7 @@ import ca.uhn.fhir.model.dstu2.resource.Practitioner; import ca.uhn.fhir.model.dstu2.resource.Questionnaire; import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse; import ca.uhn.fhir.model.dstu2.resource.StructureDefinition; +import ca.uhn.fhir.model.dstu2.resource.Substance; import ca.uhn.fhir.model.dstu2.resource.ValueSet; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.method.MethodUtil; @@ -67,12 +70,21 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; //@formatter:on public abstract class BaseJpaDstu2Test extends BaseJpaTest { + @Autowired + @Qualifier("myConceptMapDaoDstu2") + protected IFhirResourceDao myConceptMapDao; + @Autowired + @Qualifier("mySubstanceDaoDstu2") + protected IFhirResourceDao mySubstanceDao; @Autowired protected DaoConfig myDaoConfig; @Autowired @Qualifier("myDeviceDaoDstu2") protected IFhirResourceDao myDeviceDao; @Autowired + @Qualifier("myDiagnosticOrderDaoDstu2") + protected IFhirResourceDao myDiagnosticOrderDao; + @Autowired @Qualifier("myDiagnosticReportDaoDstu2") protected IFhirResourceDao myDiagnosticReportDao; @Autowired @@ -82,6 +94,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest { protected EntityManager myEntityManager; @Autowired protected FhirContext myFhirCtx; + @Autowired + @Qualifier("myImmunizationDaoDstu2") + protected IFhirResourceDao myImmunizationDao; protected IServerInterceptor myInterceptor; @Autowired @Qualifier("myLocationDaoDstu2") diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java index 78ba3c9ca45..51b0a3eb090 100644 --- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java +++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2SearchTest.java @@ -24,7 +24,13 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import org.junit.Test; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity; import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken; +import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamUri; +import ca.uhn.fhir.jpa.entity.ResourceLink; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.Include; @@ -38,14 +44,18 @@ import ca.uhn.fhir.model.dstu2.composite.IdentifierDt; import ca.uhn.fhir.model.dstu2.composite.PeriodDt; import ca.uhn.fhir.model.dstu2.composite.QuantityDt; import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt; +import ca.uhn.fhir.model.dstu2.resource.ConceptMap; import ca.uhn.fhir.model.dstu2.resource.Device; +import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder; import ca.uhn.fhir.model.dstu2.resource.DiagnosticReport; import ca.uhn.fhir.model.dstu2.resource.Encounter; +import ca.uhn.fhir.model.dstu2.resource.Immunization; import ca.uhn.fhir.model.dstu2.resource.Location; import ca.uhn.fhir.model.dstu2.resource.Observation; import ca.uhn.fhir.model.dstu2.resource.Organization; import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.dstu2.resource.Practitioner; +import ca.uhn.fhir.model.dstu2.resource.Substance; import ca.uhn.fhir.model.dstu2.resource.ValueSet; import ca.uhn.fhir.model.dstu2.valueset.ContactPointSystemEnum; import ca.uhn.fhir.model.primitive.DateDt; @@ -70,6 +80,163 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; public class FhirResourceDaoDstu2SearchTest extends BaseJpaDstu2Test { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu2SearchTest.class); + @Test + public void testIndexNoDuplicatesString() { + Patient p = new Patient(); + p.addAddress().addLine("123 Fake Street"); + p.addAddress().addLine("123 Fake Street"); + p.addAddress().addLine("123 Fake Street"); + p.addAddress().addLine("456 Fake Street"); + p.addAddress().addLine("456 Fake Street"); + p.addAddress().addLine("456 Fake Street"); + + IIdType id = myPatientDao.create(p).getId().toUnqualifiedVersionless(); + + Class type = ResourceIndexedSearchParamString.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + + List actual = toUnqualifiedVersionlessIds(myPatientDao.search(Patient.SP_ADDRESS, new StringParam("123 Fake Street"))); + assertThat(actual, contains(id)); + } + + @Test + public void testIndexNoDuplicatesDate() { + DiagnosticOrder order = new DiagnosticOrder(); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z")); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z")); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-11T11:12:12Z")); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z")); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z")); + order.addItem().addEvent().setDateTime(new DateTimeDt("2011-12-12T11:12:12Z")); + + IIdType id = myDiagnosticOrderDao.create(order).getId().toUnqualifiedVersionless(); + + List actual = toUnqualifiedVersionlessIds(myDiagnosticOrderDao.search(DiagnosticOrder.SP_ITEM_DATE, new DateParam("2011-12-12T11:12:12Z"))); + assertThat(actual, contains(id)); + + Class type = ResourceIndexedSearchParamDate.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + } + + @Test + public void testIndexNoDuplicatesNumber() { + Immunization res = new Immunization(); + res.addVaccinationProtocol().setDoseSequence(1); + res.addVaccinationProtocol().setDoseSequence(1); + res.addVaccinationProtocol().setDoseSequence(1); + res.addVaccinationProtocol().setDoseSequence(2); + res.addVaccinationProtocol().setDoseSequence(2); + res.addVaccinationProtocol().setDoseSequence(2); + + IIdType id = myImmunizationDao.create(res).getId().toUnqualifiedVersionless(); + + List actual = toUnqualifiedVersionlessIds(myImmunizationDao.search(Immunization.SP_DOSE_SEQUENCE, new NumberParam("1"))); + assertThat(actual, contains(id)); + + Class type = ResourceIndexedSearchParamNumber.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + } + + @Test + public void testIndexNoDuplicatesUri() { + ConceptMap res = new ConceptMap(); + res.addElement().addTarget().addDependsOn().setElement("http://foo"); + res.addElement().addTarget().addDependsOn().setElement("http://foo"); + res.addElement().addTarget().addDependsOn().setElement("http://bar"); + res.addElement().addTarget().addDependsOn().setElement("http://bar"); + + IIdType id = myConceptMapDao.create(res).getId().toUnqualifiedVersionless(); + + Class type = ResourceIndexedSearchParamUri.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + + List actual = toUnqualifiedVersionlessIds(myConceptMapDao.search(ConceptMap.SP_DEPENDSON, new UriParam("http://foo"))); + assertThat(actual, contains(id)); + } + + @Test + public void testIndexNoDuplicatesQuantity() { + Substance res = new Substance(); + res.addInstance().getQuantity().setSystem("http://foo").setCode("UNIT").setValue(123); + res.addInstance().getQuantity().setSystem("http://foo").setCode("UNIT").setValue(123); + res.addInstance().getQuantity().setSystem("http://foo2").setCode("UNIT2").setValue(1232); + res.addInstance().getQuantity().setSystem("http://foo2").setCode("UNIT2").setValue(1232); + + IIdType id = mySubstanceDao.create(res).getId().toUnqualifiedVersionless(); + + Class type = ResourceIndexedSearchParamQuantity.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + + List actual = toUnqualifiedVersionlessIds(mySubstanceDao.search(Substance.SP_QUANTITY, new QuantityParam(null, 123, "http://foo", "UNIT"))); + assertThat(actual, contains(id)); + } + + @Test + public void testIndexNoDuplicatesToken() { + Patient res = new Patient(); + res.addIdentifier().setSystem("http://foo1").setValue("123"); + res.addIdentifier().setSystem("http://foo1").setValue("123"); + res.addIdentifier().setSystem("http://foo2").setValue("1234"); + res.addIdentifier().setSystem("http://foo2").setValue("1234"); + + IIdType id = myPatientDao.create(res).getId().toUnqualifiedVersionless(); + + Class type = ResourceIndexedSearchParamToken.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + + List actual = toUnqualifiedVersionlessIds(myPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("http://foo1", "123"))); + assertThat(actual, contains(id)); + } + + @Test + public void testIndexNoDuplicatesReference() { + Practitioner pract =new Practitioner(); + pract.setId("Practitioner/somepract"); + pract.getName().addFamily("SOME PRACT"); + myPractitionerDao.update(pract); + Practitioner pract2 =new Practitioner(); + pract2.setId("Practitioner/somepract2"); + pract2.getName().addFamily("SOME PRACT2"); + myPractitionerDao.update(pract2); + + DiagnosticOrder res = new DiagnosticOrder(); + res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract")); + res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract")); + res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract2")); + res.addEvent().setActor(new ResourceReferenceDt("Practitioner/somepract2")); + + IIdType id = myDiagnosticOrderDao.create(res).getId().toUnqualifiedVersionless(); + + Class type = ResourceLink.class; + List results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList(); + ourLog.info(toStringMultiline(results)); + assertEquals(2, results.size()); + + List actual = toUnqualifiedVersionlessIds(myDiagnosticOrderDao.search(DiagnosticOrder.SP_ACTOR, new ReferenceParam("Practitioner/somepract"))); + assertThat(actual, contains(id)); + } + + private String toStringMultiline(List theResults) { + StringBuilder b = new StringBuilder(); + for (Object next : theResults) { + b.append('\n'); + b.append(" * ").append(next.toString()); + } + return b.toString(); + } + @Test public void testSearchAll() { { diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java index 534060da738..e481fc4b9c2 100644 --- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java +++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java @@ -51,11 +51,13 @@ public class SearchDstu2Test { private static Server ourServer; private static String ourLastMethod; private static DateAndListParam ourLastDateAndList; + private static ReferenceParam ourLastRef; @Before public void before() { ourLastMethod = null; ourLastDateAndList = null; + ourLastRef = null; } @Test @@ -68,6 +70,59 @@ public class SearchDstu2Test { assertEquals(400, status.getStatusLine().getStatusCode()); } + + @Test + public void testSearchReferenceParams01() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref=123"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("123", ourLastRef.getIdPart()); + assertEquals(null, ourLastRef.getResourceType()); + } + + @Test + public void testSearchReferenceParams02() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref=Patient/123"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("123", ourLastRef.getIdPart()); + assertEquals("Patient", ourLastRef.getResourceType()); + } + + @Test + public void testSearchReferenceParams03() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref:Patient=Patient/123"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("123", ourLastRef.getIdPart()); + assertEquals("Patient", ourLastRef.getResourceType()); + } + + @Test + public void testSearchReferenceParams04() throws Exception { + HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=searchNoList&ref:Patient=123"); + HttpResponse status = ourClient.execute(httpGet); + String responseContent = IOUtils.toString(status.getEntity().getContent()); + IOUtils.closeQuietly(status.getEntity().getContent()); + ourLog.info(responseContent); + assertEquals(200, status.getStatusLine().getStatusCode()); + + assertEquals("123", ourLastRef.getIdPart()); + assertEquals("Patient", ourLastRef.getResourceType()); + } + @Test public void testSearchDateAndList() throws Exception { HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?searchDateAndList=2001,2002&searchDateAndList=2003,2004"); @@ -220,7 +275,17 @@ public class SearchDstu2Test { return Collections.emptyList(); } //@formatter:on - + + //@formatter:off + @Search(queryName="searchNoList") + public List searchNoList( + @RequiredParam(name = "ref") ReferenceParam theParam) { + ourLastMethod = "searchNoList"; + ourLastRef = theParam; + return Collections.emptyList(); + } + //@formatter:on + //@formatter:off @Search() public List searchDateAndList( diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 349eaa2d071..5de0f193023 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -6,6 +6,17 @@ HAPI FHIR Changelog + + + JPA server removes duplicate resource index entries before storing them + (e.g. if a patient has the same name twice, only one index entry is created + for that name) + + + JPA server did not correctly index search parameters of type "reference" where the + path had multiple entries (i.e. "Resource.path1 | Resource.path2") + + JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire