Correctly index reference paths with multiple paths, and don't store duplicate indexes in JPA

This commit is contained in:
jamesagnew 2015-09-20 08:23:03 -04:00
parent 70e942e9f8
commit d59c0ff404
18 changed files with 748 additions and 224 deletions

View File

@ -166,8 +166,8 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
return InstantDt.withCurrentTime();
}
protected List<ResourceLink> extractResourceLinks(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceLink> retVal = new ArrayList<ResourceLink>();
protected Set<ResourceLink> extractResourceLinks(ResourceTable theEntity, IResource theResource) {
Set<ResourceLink> retVal = new HashSet<ResourceLink>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -185,73 +185,76 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> 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<? extends IBaseResource> 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<? extends IBaseResource> 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<T extends IBaseResource> implements IDao {
return retVal;
}
protected List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamDates(theEntity, theResource);
}
protected List<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamNumber(theEntity, theResource);
}
protected List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamUri(theEntity, theResource);
}
protected List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamCoords(theEntity, theResource);
}
protected List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamQuantity(theEntity, theResource);
}
protected List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
protected Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamStrings(theEntity, theResource);
}
protected List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
protected Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
return mySearchParamExtractor.extractSearchParamTokens(theEntity, theResource);
}
private List<Object> extractValues(String thePaths, IResource theResource) {
private List<Object> extractValues(String thePath, IResource theResource) {
List<Object> values = new ArrayList<Object>();
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<T extends IBaseResource> implements IDao {
Collection<ResourceIndexedSearchParamCoords> paramsCoords = new ArrayList<ResourceIndexedSearchParamCoords>(theEntity.getParamsCoords());
Collection<ResourceLink> resourceLinks = new ArrayList<ResourceLink>(theEntity.getResourceLinks());
List<ResourceIndexedSearchParamString> stringParams = null;
List<ResourceIndexedSearchParamToken> tokenParams = null;
List<ResourceIndexedSearchParamNumber> numberParams = null;
List<ResourceIndexedSearchParamQuantity> quantityParams = null;
List<ResourceIndexedSearchParamDate> dateParams = null;
List<ResourceIndexedSearchParamUri> uriParams = null;
List<ResourceIndexedSearchParamCoords> coordsParams = null;
List<ResourceLink> links = null;
Set<ResourceIndexedSearchParamString> stringParams = null;
Set<ResourceIndexedSearchParamToken> tokenParams = null;
Set<ResourceIndexedSearchParamNumber> numberParams = null;
Set<ResourceIndexedSearchParamQuantity> quantityParams = null;
Set<ResourceIndexedSearchParamDate> dateParams = null;
Set<ResourceIndexedSearchParamUri> uriParams = null;
Set<ResourceIndexedSearchParamCoords> coordsParams = null;
Set<ResourceLink> 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<T extends IBaseResource> implements IDao {
// ourLog.info("Indexing resource: {}", entity.getId());
ourLog.trace("Storing string indexes: {}", stringParams);
tokenParams = new ArrayList<ResourceIndexedSearchParamToken>();
tokenParams = new HashSet<ResourceIndexedSearchParamToken>();
for (BaseResourceIndexedSearchParam next : extractSearchParamTokens(theEntity, theResource)) {
if (next instanceof ResourceIndexedSearchParamToken) {
tokenParams.add((ResourceIndexedSearchParamToken) next);

View File

@ -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

View File

@ -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<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource);
public abstract List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource);
public abstract ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource);
public abstract List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource);
public abstract List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource);
public abstract List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource);
public abstract Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource);
public abstract List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource);
public abstract Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource);
}

View File

@ -75,13 +75,13 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public List<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
return Collections.emptyList();
public Set<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
return Collections.emptySet();
}
@Override
public List<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<ResourceIndexedSearchParamDate>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -135,8 +135,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public ArrayList<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamNumber> retVal = new HashSet<ResourceIndexedSearchParamNumber>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -230,8 +230,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public List<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamQuantity> retVal = new ArrayList<ResourceIndexedSearchParamQuantity>();
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamQuantity> retVal = new HashSet<ResourceIndexedSearchParamQuantity>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -278,8 +278,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public List<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamString> retVal = new HashSet<ResourceIndexedSearchParamString>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -364,8 +364,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public List<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
ArrayList<BaseResourceIndexedSearchParam> retVal = new ArrayList<BaseResourceIndexedSearchParam>();
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
HashSet<BaseResourceIndexedSearchParam> retVal = new HashSet<BaseResourceIndexedSearchParam>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -472,8 +472,8 @@ public class SearchParamExtractorDstu1 extends BaseSearchParamExtractor implemen
}
@Override
public List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
return Collections.emptyList();
public Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
return Collections.emptySet();
}
}

View File

@ -84,7 +84,7 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
super(theContext);
}
private void addSearchTerm(ResourceTable theEntity, ArrayList<ResourceIndexedSearchParamString> retVal, String resourceName, String searchTerm) {
private void addSearchTerm(ResourceTable theEntity, Set<ResourceIndexedSearchParamString> 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<BaseResourceIndexedSearchParam> retVal, RuntimeSearchParam nextSpDef, String value) {
private void addStringParam(ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> 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<ResourceIndexedSearchParamCoords> extractSearchParamCoords(ResourceTable theEntity, IResource theResource) {
public Set<ResourceIndexedSearchParamCoords> 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<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamDate> retVal = new ArrayList<ResourceIndexedSearchParamDate>();
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamDate> retVal = new HashSet<ResourceIndexedSearchParamDate>();
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<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamNumber> retVal = new ArrayList<ResourceIndexedSearchParamNumber>();
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamNumber> retVal = new HashSet<ResourceIndexedSearchParamNumber>();
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<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamQuantity> retVal = new ArrayList<ResourceIndexedSearchParamQuantity>();
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamQuantity> retVal = new HashSet<ResourceIndexedSearchParamQuantity>();
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<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamString> retVal = new ArrayList<ResourceIndexedSearchParamString>();
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamString> retVal = new HashSet<ResourceIndexedSearchParamString>();
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<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
ArrayList<BaseResourceIndexedSearchParam> retVal = new ArrayList<BaseResourceIndexedSearchParam>();
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IResource theResource) {
HashSet<BaseResourceIndexedSearchParam> retVal = new HashSet<BaseResourceIndexedSearchParam>();
String useSystem = null;
if (theResource instanceof ValueSet) {
@ -556,8 +556,8 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
}
@Override
public List<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
ArrayList<ResourceIndexedSearchParamUri> retVal = new ArrayList<ResourceIndexedSearchParamUri>();
public Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IResource theResource) {
HashSet<ResourceIndexedSearchParamUri> retVal = new HashSet<ResourceIndexedSearchParamUri>();
RuntimeResourceDefinition def = getContext().getResourceDefinition(theResource);
for (RuntimeSearchParam nextSpDef : def.getSearchParams()) {
@ -608,13 +608,13 @@ public class SearchParamExtractorDstu2 extends BaseSearchParamExtractor implemen
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConceptDt theCodeableConcept, ResourceTable theEntity,
ArrayList<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
for (CodingDt nextCoding : theCodeableConcept.getCoding()) {
extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding);
}
}
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, ArrayList<BaseResourceIndexedSearchParam> theListToPopulate,
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate,
RuntimeSearchParam theParameterDef, CodingDt nextCoding) {
if (nextCoding != null && !nextCoding.isEmpty()) {

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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<ResourceIndexedSearchParamNumber> theNumberParams) {
public void setParamsNumber(Collection<ResourceIndexedSearchParamNumber> theNumberParams) {
if (!isParamsNumberPopulated() && theNumberParams.isEmpty()) {
return;
}
@ -396,7 +394,7 @@ public class ResourceTable extends BaseHasResource implements Serializable {
myProfile = theProfile;
}
public void setResourceLinks(List<ResourceLink> theLinks) {
public void setResourceLinks(Collection<ResourceLink> theLinks) {
if (!isHasLinks() && theLinks.isEmpty()) {
return;
}

View File

@ -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<ConceptMap> myConceptMapDao;
@Autowired
@Qualifier("mySubstanceDaoDstu2")
protected IFhirResourceDao<Substance> mySubstanceDao;
@Autowired
protected DaoConfig myDaoConfig;
@Autowired
@Qualifier("myDeviceDaoDstu2")
protected IFhirResourceDao<Device> myDeviceDao;
@Autowired
@Qualifier("myDiagnosticOrderDaoDstu2")
protected IFhirResourceDao<DiagnosticOrder> myDiagnosticOrderDao;
@Autowired
@Qualifier("myDiagnosticReportDaoDstu2")
protected IFhirResourceDao<DiagnosticReport> myDiagnosticReportDao;
@Autowired
@ -82,6 +94,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
protected EntityManager myEntityManager;
@Autowired
protected FhirContext myFhirCtx;
@Autowired
@Qualifier("myImmunizationDaoDstu2")
protected IFhirResourceDao<Immunization> myImmunizationDao;
protected IServerInterceptor myInterceptor;
@Autowired
@Qualifier("myLocationDaoDstu2")

View File

@ -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<ResourceIndexedSearchParamString> type = ResourceIndexedSearchParamString.class;
List<ResourceIndexedSearchParamString> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
assertEquals(2, results.size());
List<IIdType> 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<IIdType> actual = toUnqualifiedVersionlessIds(myDiagnosticOrderDao.search(DiagnosticOrder.SP_ITEM_DATE, new DateParam("2011-12-12T11:12:12Z")));
assertThat(actual, contains(id));
Class<ResourceIndexedSearchParamDate> 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<IIdType> actual = toUnqualifiedVersionlessIds(myImmunizationDao.search(Immunization.SP_DOSE_SEQUENCE, new NumberParam("1")));
assertThat(actual, contains(id));
Class<ResourceIndexedSearchParamNumber> 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<ResourceIndexedSearchParamUri> type = ResourceIndexedSearchParamUri.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
assertEquals(2, results.size());
List<IIdType> 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<ResourceIndexedSearchParamQuantity> type = ResourceIndexedSearchParamQuantity.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
assertEquals(2, results.size());
List<IIdType> 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<ResourceIndexedSearchParamToken> type = ResourceIndexedSearchParamToken.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
assertEquals(2, results.size());
List<IIdType> 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<ResourceLink> type = ResourceLink.class;
List<?> results = myEntityManager.createQuery("SELECT i FROM " + type.getSimpleName() + " i", type).getResultList();
ourLog.info(toStringMultiline(results));
assertEquals(2, results.size());
List<IIdType> 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() {
{

View File

@ -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<Patient> searchNoList(
@RequiredParam(name = "ref") ReferenceParam theParam) {
ourLastMethod = "searchNoList";
ourLastRef = theParam;
return Collections.emptyList();
}
//@formatter:on
//@formatter:off
@Search()
public List<Patient> searchDateAndList(

View File

@ -6,6 +6,17 @@
<title>HAPI FHIR Changelog</title>
</properties>
<body>
<release version="1.3" date="TBD">
<action type="add">
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)
</action>
<action type="fix">
JPA server did not correctly index search parameters of type "reference" where the
path had multiple entries (i.e. "Resource.path1 | Resource.path2")
</action>
</release>
<release version="1.2" date="2015-09-18">
<action type="add">
JPA server now validates QuestionnaireAnswers for conformance to their respective Questionnaire