Fix #441: Correctly handle search with chains across a field with choice
type
This commit is contained in:
parent
8b80d932da
commit
ff4755fbf3
|
@ -21,20 +21,10 @@ package ca.uhn.fhir.context;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.hl7.fhir.instance.model.api.IBase;
|
import org.hl7.fhir.instance.model.api.*;
|
||||||
import org.hl7.fhir.instance.model.api.IBaseDatatype;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.annotation.Child;
|
import ca.uhn.fhir.model.api.annotation.Child;
|
||||||
import ca.uhn.fhir.model.api.annotation.Description;
|
import ca.uhn.fhir.model.api.annotation.Description;
|
||||||
|
@ -46,6 +36,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
private Map<Class<? extends IBase>, String> myDatatypeToElementName;
|
private Map<Class<? extends IBase>, String> myDatatypeToElementName;
|
||||||
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
|
private Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> myDatatypeToElementDefinition;
|
||||||
private String myReferenceSuffix;
|
private String myReferenceSuffix;
|
||||||
|
private List<Class<? extends IBaseResource>> myResourceTypes;
|
||||||
|
|
||||||
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IBase>> theChoiceTypes) {
|
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IBase>> theChoiceTypes) {
|
||||||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||||
|
@ -86,6 +77,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
myNameToChildDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
myNameToChildDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||||
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
myDatatypeToElementName = new HashMap<Class<? extends IBase>, String>();
|
||||||
myDatatypeToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
myDatatypeToElementDefinition = new HashMap<Class<? extends IBase>, BaseRuntimeElementDefinition<?>>();
|
||||||
|
myResourceTypes = new ArrayList<Class<? extends IBaseResource>>();
|
||||||
|
|
||||||
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
if (theContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
|
||||||
myReferenceSuffix = "Resource";
|
myReferenceSuffix = "Resource";
|
||||||
|
@ -107,6 +99,8 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
|
myNameToChildDefinition.put(getElementName() + "Reference", nextDef);
|
||||||
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
|
myNameToChildDefinition.put(getElementName() + "Resource", nextDef);
|
||||||
|
|
||||||
|
myResourceTypes.add((Class<? extends IBaseResource>) next);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
nextDef = theClassToElementDefinitions.get(next);
|
nextDef = theClassToElementDefinitions.get(next);
|
||||||
BaseRuntimeElementDefinition<?> nextDefForChoice = nextDef;
|
BaseRuntimeElementDefinition<?> nextDefForChoice = nextDef;
|
||||||
|
@ -166,10 +160,14 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
||||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||||
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
||||||
myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
||||||
|
myResourceTypes = Collections.unmodifiableList(myResourceTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List<Class<? extends IBaseResource>> getResourceTypes() {
|
||||||
|
return myResourceTypes;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
public String getChildNameByDatatype(Class<? extends IBase> theDatatype) {
|
||||||
String retVal = myDatatypeToElementName.get(theDatatype);
|
String retVal = myDatatypeToElementName.get(theDatatype);
|
||||||
|
|
|
@ -27,34 +27,13 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.MathContext;
|
import java.math.MathContext;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.Tuple;
|
import javax.persistence.Tuple;
|
||||||
import javax.persistence.TypedQuery;
|
import javax.persistence.TypedQuery;
|
||||||
import javax.persistence.criteria.CriteriaBuilder;
|
import javax.persistence.criteria.*;
|
||||||
import javax.persistence.criteria.CriteriaQuery;
|
|
||||||
import javax.persistence.criteria.Expression;
|
|
||||||
import javax.persistence.criteria.From;
|
|
||||||
import javax.persistence.criteria.Join;
|
|
||||||
import javax.persistence.criteria.JoinType;
|
|
||||||
import javax.persistence.criteria.Order;
|
|
||||||
import javax.persistence.criteria.Path;
|
|
||||||
import javax.persistence.criteria.Predicate;
|
|
||||||
import javax.persistence.criteria.Root;
|
|
||||||
import javax.persistence.criteria.Subquery;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.ObjectUtils;
|
import org.apache.commons.lang3.ObjectUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -70,45 +49,16 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.common.collect.Sets;
|
import com.google.common.collect.Sets;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
import ca.uhn.fhir.context.*;
|
||||||
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
|
|
||||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
|
||||||
import ca.uhn.fhir.context.ConfigurationException;
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
|
||||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
|
||||||
import ca.uhn.fhir.context.RuntimeChildResourceDefinition;
|
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceIndexedSearchParamUriDao;
|
||||||
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
|
||||||
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.jpa.entity.ResourceTable;
|
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTag;
|
|
||||||
import ca.uhn.fhir.jpa.entity.Search;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SearchInclude;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SearchResult;
|
|
||||||
import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagDefinition;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
|
|
||||||
import ca.uhn.fhir.jpa.entity.TermConcept;
|
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
import ca.uhn.fhir.jpa.term.IHapiTerminologySvc;
|
||||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||||
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
|
import ca.uhn.fhir.model.api.*;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
|
||||||
import ca.uhn.fhir.model.api.IResource;
|
|
||||||
import ca.uhn.fhir.model.api.Include;
|
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
import ca.uhn.fhir.model.base.composite.BaseIdentifierDt;
|
||||||
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
|
import ca.uhn.fhir.model.base.composite.BaseQuantityDt;
|
||||||
|
@ -120,19 +70,7 @@ import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||||
import ca.uhn.fhir.rest.api.SortSpec;
|
import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
||||||
import ca.uhn.fhir.rest.param.CompositeParam;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
import ca.uhn.fhir.rest.param.DateParam;
|
|
||||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
|
||||||
import ca.uhn.fhir.rest.param.HasParam;
|
|
||||||
import ca.uhn.fhir.rest.param.NumberParam;
|
|
||||||
import ca.uhn.fhir.rest.param.ParamPrefixEnum;
|
|
||||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
|
||||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
|
||||||
import ca.uhn.fhir.rest.param.StringParam;
|
|
||||||
import ca.uhn.fhir.rest.param.TokenParam;
|
|
||||||
import ca.uhn.fhir.rest.param.TokenParamModifier;
|
|
||||||
import ca.uhn.fhir.rest.param.UriParam;
|
|
||||||
import ca.uhn.fhir.rest.param.UriParamQualifierEnum;
|
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||||
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
import ca.uhn.fhir.rest.server.SimpleBundleProvider;
|
||||||
|
@ -606,21 +544,31 @@ public class SearchBuilder {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
String paramPath = myContext.getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
|
||||||
BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, paramPath);
|
|
||||||
if (!(def instanceof RuntimeChildResourceDefinition)) {
|
|
||||||
throw new ConfigurationException("Property " + paramPath + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
|
||||||
}
|
|
||||||
List<Class<? extends IBaseResource>> resourceTypes;
|
List<Class<? extends IBaseResource>> resourceTypes;
|
||||||
|
|
||||||
String resourceId;
|
String resourceId;
|
||||||
if (!ref.getValue().matches("[a-zA-Z]+\\/.*")) {
|
if (!ref.getValue().matches("[a-zA-Z]+\\/.*")) {
|
||||||
|
|
||||||
|
String paramPath = myContext.getResourceDefinition(myResourceType).getSearchParam(theParamName).getPath();
|
||||||
|
if (paramPath.endsWith(".as(Reference)")) {
|
||||||
|
paramPath = paramPath.substring(0, paramPath.length() - ".as(Reference)".length()) + "Reference";
|
||||||
|
}
|
||||||
|
|
||||||
|
BaseRuntimeChildDefinition def = myContext.newTerser().getDefinition(myResourceType, paramPath);
|
||||||
|
if (def instanceof RuntimeChildChoiceDefinition) {
|
||||||
|
RuntimeChildChoiceDefinition choiceDef = (RuntimeChildChoiceDefinition)def;
|
||||||
|
resourceTypes = choiceDef.getResourceTypes();
|
||||||
|
} else if (def instanceof RuntimeChildResourceDefinition) {
|
||||||
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
|
RuntimeChildResourceDefinition resDef = (RuntimeChildResourceDefinition) def;
|
||||||
resourceTypes = resDef.getResourceTypes();
|
resourceTypes = resDef.getResourceTypes();
|
||||||
resourceId = ref.getValue();
|
|
||||||
} else {
|
} else {
|
||||||
resourceTypes = new ArrayList<Class<? extends IBaseResource>>();
|
throw new ConfigurationException("Property " + paramPath + " of type " + myResourceName + " is not a resource: " + def.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
resourceId = ref.getValue();
|
||||||
|
|
||||||
|
} else {
|
||||||
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(ref.getResourceType());
|
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(ref.getResourceType());
|
||||||
|
resourceTypes = new ArrayList<Class<? extends IBaseResource>>(1);
|
||||||
resourceTypes.add(resDef.getImplementingClass());
|
resourceTypes.add(resDef.getImplementingClass());
|
||||||
resourceId = ref.getIdPart();
|
resourceId = ref.getIdPart();
|
||||||
}
|
}
|
||||||
|
@ -2011,16 +1959,6 @@ public class SearchBuilder {
|
||||||
myResourceName = theResourceName;
|
myResourceName = theResourceName;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Long> toList(Collection<Long> theLoadPids) {
|
|
||||||
final List<Long> pids;
|
|
||||||
if (theLoadPids instanceof List) {
|
|
||||||
pids = (List<Long>) theLoadPids;
|
|
||||||
} else {
|
|
||||||
pids = new ArrayList<Long>(theLoadPids);
|
|
||||||
}
|
|
||||||
return pids;
|
|
||||||
}
|
|
||||||
|
|
||||||
private IQueryParameterType toParameterType(RuntimeSearchParam theParam) {
|
private IQueryParameterType toParameterType(RuntimeSearchParam theParam) {
|
||||||
IQueryParameterType qp;
|
IQueryParameterType qp;
|
||||||
switch (theParam.getParamType()) {
|
switch (theParam.getParamType()) {
|
||||||
|
|
|
@ -682,7 +682,10 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
||||||
try {
|
try {
|
||||||
String[] nextPathsSplit = SPLIT.split(thePaths);
|
String[] nextPathsSplit = SPLIT.split(thePaths);
|
||||||
for (String nextPath : nextPathsSplit) {
|
for (String nextPath : nextPathsSplit) {
|
||||||
values.addAll(fp.evaluate((Base) theResource, nextPath));
|
List<Base> allValues = fp.evaluate((Base) theResource, nextPath);
|
||||||
|
if (allValues.isEmpty() == false) {
|
||||||
|
values.addAll(allValues);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (FHIRException e) {
|
} catch (FHIRException e) {
|
||||||
throw new InternalErrorException(e);
|
throw new InternalErrorException(e);
|
||||||
|
|
|
@ -40,28 +40,7 @@ import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Appointment;
|
import ca.uhn.fhir.model.dstu2.resource.*;
|
||||||
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.Media;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.MedicationOrder;
|
|
||||||
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.Questionnaire;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireResponse;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Subscription;
|
|
||||||
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.parser.IParser;
|
||||||
import ca.uhn.fhir.rest.method.MethodUtil;
|
import ca.uhn.fhir.rest.method.MethodUtil;
|
||||||
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
||||||
|
@ -120,6 +99,9 @@ public abstract class BaseJpaDstu2Test extends BaseJpaTest {
|
||||||
@Qualifier("myMedicationDaoDstu2")
|
@Qualifier("myMedicationDaoDstu2")
|
||||||
protected IFhirResourceDao<Medication> myMedicationDao;
|
protected IFhirResourceDao<Medication> myMedicationDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("myMedicationAdministrationDaoDstu2")
|
||||||
|
protected IFhirResourceDao<MedicationAdministration> myMedicationAdministrationDao;
|
||||||
|
@Autowired
|
||||||
@Qualifier("myMedicationOrderDaoDstu2")
|
@Qualifier("myMedicationOrderDaoDstu2")
|
||||||
protected IFhirResourceDao<MedicationOrder> myMedicationOrderDao;
|
protected IFhirResourceDao<MedicationOrder> myMedicationOrderDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -11,41 +11,8 @@ import javax.persistence.EntityManager;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.hibernate.search.jpa.FullTextEntityManager;
|
import org.hibernate.search.jpa.FullTextEntityManager;
|
||||||
import org.hibernate.search.jpa.Search;
|
import org.hibernate.search.jpa.Search;
|
||||||
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
|
|
||||||
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
|
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
|
||||||
import org.hl7.fhir.dstu3.model.AllergyIntolerance;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.dstu3.model.Appointment;
|
|
||||||
import org.hl7.fhir.dstu3.model.AuditEvent;
|
|
||||||
import org.hl7.fhir.dstu3.model.Bundle;
|
|
||||||
import org.hl7.fhir.dstu3.model.CarePlan;
|
|
||||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
|
||||||
import org.hl7.fhir.dstu3.model.CodeableConcept;
|
|
||||||
import org.hl7.fhir.dstu3.model.Coding;
|
|
||||||
import org.hl7.fhir.dstu3.model.CompartmentDefinition;
|
|
||||||
import org.hl7.fhir.dstu3.model.ConceptMap;
|
|
||||||
import org.hl7.fhir.dstu3.model.Condition;
|
|
||||||
import org.hl7.fhir.dstu3.model.Device;
|
|
||||||
import org.hl7.fhir.dstu3.model.DiagnosticRequest;
|
|
||||||
import org.hl7.fhir.dstu3.model.DiagnosticReport;
|
|
||||||
import org.hl7.fhir.dstu3.model.Encounter;
|
|
||||||
import org.hl7.fhir.dstu3.model.Immunization;
|
|
||||||
import org.hl7.fhir.dstu3.model.Location;
|
|
||||||
import org.hl7.fhir.dstu3.model.Media;
|
|
||||||
import org.hl7.fhir.dstu3.model.Medication;
|
|
||||||
import org.hl7.fhir.dstu3.model.MedicationOrder;
|
|
||||||
import org.hl7.fhir.dstu3.model.Meta;
|
|
||||||
import org.hl7.fhir.dstu3.model.NamingSystem;
|
|
||||||
import org.hl7.fhir.dstu3.model.Observation;
|
|
||||||
import org.hl7.fhir.dstu3.model.OperationDefinition;
|
|
||||||
import org.hl7.fhir.dstu3.model.Organization;
|
|
||||||
import org.hl7.fhir.dstu3.model.Patient;
|
|
||||||
import org.hl7.fhir.dstu3.model.Practitioner;
|
|
||||||
import org.hl7.fhir.dstu3.model.Questionnaire;
|
|
||||||
import org.hl7.fhir.dstu3.model.QuestionnaireResponse;
|
|
||||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
|
||||||
import org.hl7.fhir.dstu3.model.Subscription;
|
|
||||||
import org.hl7.fhir.dstu3.model.Substance;
|
|
||||||
import org.hl7.fhir.dstu3.model.ValueSet;
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
|
@ -63,14 +30,7 @@ import org.springframework.transaction.support.TransactionTemplate;
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.jpa.config.TestDstu3Config;
|
import ca.uhn.fhir.jpa.config.TestDstu3Config;
|
||||||
import ca.uhn.fhir.jpa.dao.BaseJpaTest;
|
import ca.uhn.fhir.jpa.dao.*;
|
||||||
import ca.uhn.fhir.jpa.dao.DaoConfig;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoPatient;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSubscription;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
|
|
||||||
import ca.uhn.fhir.jpa.dao.IFulltextSearchSvc;
|
|
||||||
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
import ca.uhn.fhir.jpa.dao.data.IResourceTableDao;
|
||||||
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
|
import ca.uhn.fhir.jpa.dao.dstu2.FhirResourceDaoDstu2SearchNoFtTest;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
|
||||||
|
@ -160,6 +120,9 @@ public abstract class BaseJpaDstu3Test extends BaseJpaTest {
|
||||||
@Qualifier("myMedicationDaoDstu3")
|
@Qualifier("myMedicationDaoDstu3")
|
||||||
protected IFhirResourceDao<Medication> myMedicationDao;
|
protected IFhirResourceDao<Medication> myMedicationDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@Qualifier("myMedicationAdministrationDaoDstu3")
|
||||||
|
protected IFhirResourceDao<MedicationAdministration> myMedicationAdministrationDao;
|
||||||
|
@Autowired
|
||||||
@Qualifier("myMedicationOrderDaoDstu3")
|
@Qualifier("myMedicationOrderDaoDstu3")
|
||||||
protected IFhirResourceDao<MedicationOrder> myMedicationOrderDao;
|
protected IFhirResourceDao<MedicationOrder> myMedicationOrderDao;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
|
||||||
import static org.hamcrest.Matchers.contains;
|
import static org.hamcrest.Matchers.contains;
|
||||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||||
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
import static org.hamcrest.Matchers.containsInRelativeOrder;
|
||||||
|
import static org.hamcrest.Matchers.containsString;
|
||||||
import static org.hamcrest.Matchers.empty;
|
import static org.hamcrest.Matchers.empty;
|
||||||
import static org.hamcrest.Matchers.endsWith;
|
import static org.hamcrest.Matchers.endsWith;
|
||||||
import static org.hamcrest.Matchers.hasItems;
|
import static org.hamcrest.Matchers.hasItems;
|
||||||
|
@ -22,6 +23,7 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hibernate.boot.model.source.spi.IdentifierSourceSimple;
|
||||||
import org.hl7.fhir.dstu3.model.*;
|
import org.hl7.fhir.dstu3.model.*;
|
||||||
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
import org.hl7.fhir.dstu3.model.ContactPoint.ContactPointSystem;
|
||||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||||
|
@ -42,7 +44,10 @@ import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||||
import ca.uhn.fhir.jpa.entity.*;
|
import ca.uhn.fhir.jpa.entity.*;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.api.Include;
|
import ca.uhn.fhir.model.api.Include;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.MedicationPrescription;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
import ca.uhn.fhir.rest.api.SortOrderEnum;
|
||||||
import ca.uhn.fhir.rest.api.SortSpec;
|
import ca.uhn.fhir.rest.api.SortSpec;
|
||||||
import ca.uhn.fhir.rest.param.*;
|
import ca.uhn.fhir.rest.param.*;
|
||||||
|
@ -96,6 +101,26 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
||||||
myCodeSystemDao.create(cs);
|
myCodeSystemDao.create(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #441
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testChainedMedication() {
|
||||||
|
Medication medication = new Medication();
|
||||||
|
medication.getCode().addCoding().setSystem("SYSTEM").setCode("04823543");
|
||||||
|
IIdType medId = myMedicationDao.create(medication).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
MedicationAdministration ma = new MedicationAdministration();
|
||||||
|
ma.setMedication(new Reference(medId));
|
||||||
|
IIdType moId = myMedicationAdministrationDao.create(ma).getId().toUnqualified();
|
||||||
|
|
||||||
|
SearchParameterMap map = new SearchParameterMap();
|
||||||
|
map.add(MedicationAdministration.SP_MEDICATION, new ReferenceAndListParam().addAnd(new ReferenceOrListParam().add(new ReferenceParam("code", "04823543"))));
|
||||||
|
IBundleProvider results = myMedicationAdministrationDao.search(map);
|
||||||
|
List<String> ids = toUnqualifiedIdValues(results);
|
||||||
|
|
||||||
|
assertThat(ids, contains(moId.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCodeSearch() {
|
public void testCodeSearch() {
|
||||||
|
|
|
@ -54,28 +54,8 @@ import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
import ca.uhn.fhir.model.dstu2.composite.PeriodDt;
|
||||||
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
import ca.uhn.fhir.model.dstu2.composite.ResourceReferenceDt;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.BaseResource;
|
import ca.uhn.fhir.model.dstu2.resource.*;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Condition;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Device;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.DiagnosticOrder;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.DocumentManifest;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.DocumentReference;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Encounter;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.ImagingStudy;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Location;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Medication;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.MedicationOrder;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Organization;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Parameters;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
|
||||||
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.Subscription;
|
|
||||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.AnswerFormatEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.AnswerFormatEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.EncounterClassEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.EncounterClassEnum;
|
||||||
import ca.uhn.fhir.model.dstu2.valueset.EncounterStateEnum;
|
import ca.uhn.fhir.model.dstu2.valueset.EncounterStateEnum;
|
||||||
|
@ -131,6 +111,33 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
||||||
assertEquals(200, resp.getStatusLine().getStatusCode());
|
assertEquals(200, resp.getStatusLine().getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #441
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchMedicationChain() throws Exception {
|
||||||
|
Medication medication = new Medication();
|
||||||
|
medication.getCode().addCoding().setSystem("SYSTEM").setCode("04823543");
|
||||||
|
IIdType medId = myMedicationDao.create(medication).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
MedicationAdministration ma = new MedicationAdministration();
|
||||||
|
ma.setMedication(new ResourceReferenceDt(medId));
|
||||||
|
IIdType moId = myMedicationAdministrationDao.create(ma).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
HttpGet get = new HttpGet(ourServerBase + "/MedicationAdministration?medication.code=04823543");
|
||||||
|
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||||
|
try {
|
||||||
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
|
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
assertThat(responseString, containsString(moId.getIdPart()));
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEverythingInstanceWithContentFilter() {
|
public void testEverythingInstanceWithContentFilter() {
|
||||||
Patient pt1 = new Patient();
|
Patient pt1 = new Patient();
|
||||||
|
|
|
@ -86,6 +86,31 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
||||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See #441
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSearchMedicationChain() throws Exception {
|
||||||
|
Medication medication = new Medication();
|
||||||
|
medication.getCode().addCoding().setSystem("SYSTEM").setCode("04823543");
|
||||||
|
IIdType medId = myMedicationDao.create(medication).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
MedicationAdministration ma = new MedicationAdministration();
|
||||||
|
ma.setMedication(new Reference(medId));
|
||||||
|
IIdType moId = myMedicationAdministrationDao.create(ma).getId().toUnqualifiedVersionless();
|
||||||
|
|
||||||
|
HttpGet get = new HttpGet(ourServerBase + "/MedicationAdministration?medication.code=04823543");
|
||||||
|
CloseableHttpResponse response = ourHttpClient.execute(get);
|
||||||
|
try {
|
||||||
|
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||||
|
String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||||
|
assertThat(responseString, containsString(moId.getIdPart()));
|
||||||
|
} finally {
|
||||||
|
response.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchPagingKeepsOldSearches() throws Exception {
|
public void testSearchPagingKeepsOldSearches() throws Exception {
|
||||||
String methodName = "testSearchPagingKeepsOldSearches";
|
String methodName = "testSearchPagingKeepsOldSearches";
|
||||||
|
|
|
@ -121,6 +121,13 @@
|
||||||
<![CDATA[<code>Resource#equalsDeep()</code>]]>. Thanks to
|
<![CDATA[<code>Resource#equalsDeep()</code>]]>. Thanks to
|
||||||
GitHub user @XcrigX for reporting!
|
GitHub user @XcrigX for reporting!
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix" issue="441">
|
||||||
|
JPA server did not correctly process searches for chained parameters
|
||||||
|
where the chain passed across a field that was a choice between a
|
||||||
|
reference and a non-reference type (e.g.
|
||||||
|
<![CDATA[<code>MedicationAdministration.medication[x]</code>]]>.
|
||||||
|
Thanks to GitHub user @Crudelus for reporting!
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="2.0" date="2016-08-30">
|
<release version="2.0" date="2016-08-30">
|
||||||
<action type="fix">
|
<action type="fix">
|
||||||
|
|
Loading…
Reference in New Issue