Work on getting tests passing
This commit is contained in:
parent
c90795ccef
commit
804149205a
|
@ -769,7 +769,7 @@ class ModelScanner {
|
|||
}
|
||||
|
||||
|
||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments);
|
||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), paramType, providesMembershipInCompartments, toTargetList(searchParam.target()));
|
||||
theResourceDef.addSearchParam(param);
|
||||
nameToParam.put(param.getName(), param);
|
||||
}
|
||||
|
@ -789,11 +789,24 @@ class ModelScanner {
|
|||
compositeOf.add(param);
|
||||
}
|
||||
|
||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf, null);
|
||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), RestSearchParameterTypeEnum.COMPOSITE, compositeOf, null, toTargetList(searchParam.target()));
|
||||
theResourceDef.addSearchParam(param);
|
||||
}
|
||||
}
|
||||
|
||||
private Set<String> toTargetList(Class<? extends IBaseResource>[] theTarget) {
|
||||
HashSet<String> retVal = new HashSet<String>();
|
||||
|
||||
for (Class<? extends IBaseResource> nextType : theTarget) {
|
||||
ResourceDef resourceDef = nextType.getAnnotation(ResourceDef.class);
|
||||
if (resourceDef != null) {
|
||||
retVal.add(resourceDef.name());
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static Class<?> getGenericCollectionTypeOfCodedField(Field next) {
|
||||
Class<?> type;
|
||||
ParameterizedType collectionType = (ParameterizedType) next.getGenericType();
|
||||
|
|
|
@ -30,15 +30,16 @@ import ca.uhn.fhir.rest.method.RestSearchParameterTypeEnum;
|
|||
|
||||
public class RuntimeSearchParam {
|
||||
|
||||
private List<RuntimeSearchParam> myCompositeOf;
|
||||
private String myDescription;
|
||||
private String myName;
|
||||
private RestSearchParameterTypeEnum myParamType;
|
||||
private String myPath;
|
||||
private Set<String> myProvidesMembershipInCompartments;
|
||||
private final List<RuntimeSearchParam> myCompositeOf;
|
||||
private final String myDescription;
|
||||
private final String myName;
|
||||
private final RestSearchParameterTypeEnum myParamType;
|
||||
private final String myPath;
|
||||
private final Set<String> myTargets;
|
||||
private final Set<String> myProvidesMembershipInCompartments;
|
||||
|
||||
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, List<RuntimeSearchParam> theCompositeOf,
|
||||
Set<String> theProvidesMembershipInCompartments) {
|
||||
Set<String> theProvidesMembershipInCompartments, Set<String> theTargets) {
|
||||
super();
|
||||
myName = theName;
|
||||
myDescription = theDescription;
|
||||
|
@ -50,10 +51,19 @@ public class RuntimeSearchParam {
|
|||
} else {
|
||||
myProvidesMembershipInCompartments = null;
|
||||
}
|
||||
if (theTargets != null && theTargets.isEmpty() == false) {
|
||||
myTargets = Collections.unmodifiableSet(theTargets);
|
||||
} else {
|
||||
myTargets = null;
|
||||
}
|
||||
}
|
||||
|
||||
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments) {
|
||||
this(theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments);
|
||||
public Set<String> getTargets() {
|
||||
return myTargets;
|
||||
}
|
||||
|
||||
public RuntimeSearchParam(String theName, String theDescription, String thePath, RestSearchParameterTypeEnum theParamType, Set<String> theProvidesMembershipInCompartments, Set<String> theTargets) {
|
||||
this(theName, theDescription, thePath, theParamType, null, theProvidesMembershipInCompartments, theTargets);
|
||||
}
|
||||
|
||||
public List<RuntimeSearchParam> getCompositeOf() {
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package ca.uhn.fhir.cli;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.hapi.validation.IValidationSupport;
|
||||
import org.hl7.fhir.dstu3.model.CodeSystem;
|
||||
import org.hl7.fhir.dstu3.model.StructureDefinition;
|
||||
|
@ -61,4 +64,9 @@ public class LoadingValidationSupportDstu3 implements IValidationSupport {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StructureDefinition> fetchAllStructureDefinitions(FhirContext theContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ import javax.persistence.Tuple;
|
|||
import javax.persistence.TypedQuery;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Expression;
|
||||
import javax.persistence.criteria.Predicate;
|
||||
import javax.persistence.criteria.Root;
|
||||
import javax.xml.stream.events.Characters;
|
||||
|
@ -60,6 +59,7 @@ import org.hl7.fhir.dstu3.model.Bundle.HTTPVerb;
|
|||
import org.hl7.fhir.dstu3.model.IdType;
|
||||
import org.hl7.fhir.dstu3.model.StringType;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBase;
|
||||
import org.hl7.fhir.instance.model.api.IBaseCoding;
|
||||
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
|
||||
import org.hl7.fhir.instance.model.api.IBaseReference;
|
||||
|
@ -74,6 +74,8 @@ import com.google.common.base.Charsets;
|
|||
import com.google.common.collect.ArrayListMultimap;
|
||||
|
||||
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
|
||||
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
|
@ -84,7 +86,6 @@ import ca.uhn.fhir.jpa.dao.data.IForcedIdDao;
|
|||
import ca.uhn.fhir.jpa.dao.data.IResourceHistoryTableDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
|
||||
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
|
||||
import ca.uhn.fhir.jpa.dao.dstu3.SearchParamExtractorDstu3;
|
||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.BaseTag;
|
||||
|
@ -224,7 +225,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
if (isValidPid(theId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
ForcedId fid = new ForcedId();
|
||||
fid.setResourceType(theEntity.getResourceType());
|
||||
fid.setForcedId(theId.getIdPart());
|
||||
|
@ -259,121 +260,121 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
multiType = true;
|
||||
}
|
||||
|
||||
String[] nextPathsSplit = nextPathsUnsplit.split("\\|");
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
nextPath = nextPath.trim();
|
||||
List<PathAndRef> refs = mySearchParamExtractor.extractResourceLinks(theResource, nextSpDef);
|
||||
List<Class<? extends IBaseResource>> allowedTypesInField = null;
|
||||
for (PathAndRef nextPathAndRef : refs) {
|
||||
Object nextObject = nextPathAndRef.getRef();
|
||||
|
||||
List<Class<? extends IBaseResource>> allowedTypesInField = null;
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject == null) {
|
||||
ResourceLink nextEntity;
|
||||
if (nextObject instanceof IBaseReference) {
|
||||
IBaseReference nextValue = (IBaseReference) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (nextValue.getReferenceElement().isEmpty() || nextValue.getReferenceElement().getValue().startsWith("#")) {
|
||||
// This is a blank or contained resource reference
|
||||
continue;
|
||||
}
|
||||
|
||||
ResourceLink nextEntity;
|
||||
if (nextObject instanceof IBaseReference) {
|
||||
IBaseReference nextValue = (IBaseReference) nextObject;
|
||||
if (nextValue.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
if (nextValue.getReferenceElement().isEmpty() || nextValue.getReferenceElement().getValue().startsWith("#")) {
|
||||
// This is a blank or contained resource reference
|
||||
continue;
|
||||
}
|
||||
|
||||
String typeString = nextValue.getReferenceElement().getResourceType();
|
||||
if (isBlank(typeString)) {
|
||||
throw new InvalidRequestException(
|
||||
"Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReferenceElement().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.getReferenceElement().getValue());
|
||||
}
|
||||
|
||||
Class<? extends IBaseResource> type = resourceDefinition.getImplementingClass();
|
||||
String id = nextValue.getReferenceElement().getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new InvalidRequestException(
|
||||
"Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReferenceElement().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.getReferenceElement().getResourceType());
|
||||
b.append("] - Valid resource types for this server: ");
|
||||
b.append(myResourceTypeToDao.keySet().toString());
|
||||
|
||||
throw new InvalidRequestException(b.toString());
|
||||
}
|
||||
Long valueOf;
|
||||
try {
|
||||
valueOf = translateForcedIdToPid(typeString, id);
|
||||
} 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);
|
||||
RuntimeResourceDefinition targetResourceDef = getContext().getResourceDefinition(type);
|
||||
if (target == null) {
|
||||
String resName = targetResourceDef.getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
|
||||
if (!typeString.equals(target.getResourceType())) {
|
||||
throw new UnprocessableEntityException("Resource contains reference to " + nextValue.getReferenceElement().getValue() + " but resource with ID "
|
||||
+ nextValue.getReferenceElement().getIdPart() + " is actually of type " + target.getResourceType());
|
||||
}
|
||||
|
||||
/*
|
||||
* Is the target type an allowable type of resource for the path where it is referenced?
|
||||
*/
|
||||
|
||||
if (allowedTypesInField == null) {
|
||||
BaseRuntimeChildDefinition childDef = getContext().newTerser().getDefinition(theResource.getClass(), nextPath);
|
||||
if (childDef instanceof RuntimeChildResourceDefinition) {
|
||||
RuntimeChildResourceDefinition resRefDef = (RuntimeChildResourceDefinition) childDef;
|
||||
allowedTypesInField = resRefDef.getResourceTypes();
|
||||
} else {
|
||||
allowedTypesInField = new ArrayList<Class<? extends IBaseResource>>();
|
||||
allowedTypesInField.add(IBaseResource.class);
|
||||
}
|
||||
}
|
||||
|
||||
boolean acceptableLink = false;
|
||||
for (Class<? extends IBaseResource> next : allowedTypesInField) {
|
||||
if (next.isAssignableFrom(targetResourceDef.getImplementingClass())) {
|
||||
acceptableLink = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!acceptableLink) {
|
||||
throw new UnprocessableEntityException("Invalid reference found at path '" + nextPath + "'. Resource type '" + targetResourceDef.getName() + "' is not valid for this path");
|
||||
}
|
||||
|
||||
nextEntity = new ResourceLink(nextPath, theEntity, target);
|
||||
} else {
|
||||
if (!multiType) {
|
||||
if (nextSpDef.getName().equals("sourceuri")) {
|
||||
continue; // TODO: disable this eventually - ConceptMap:sourceuri is of type reference but points to a URI
|
||||
}
|
||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
String typeString = nextValue.getReferenceElement().getResourceType();
|
||||
if (isBlank(typeString)) {
|
||||
throw new InvalidRequestException(
|
||||
"Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource type - " + nextValue.getReferenceElement().getValue());
|
||||
}
|
||||
if (nextEntity != null) {
|
||||
retVal.add(nextEntity);
|
||||
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.getReferenceElement().getValue());
|
||||
}
|
||||
|
||||
Class<? extends IBaseResource> type = resourceDefinition.getImplementingClass();
|
||||
String id = nextValue.getReferenceElement().getIdPart();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new InvalidRequestException(
|
||||
"Invalid resource reference found at path[" + nextPathsUnsplit + "] - Does not contain resource ID - " + nextValue.getReferenceElement().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.getReferenceElement().getResourceType());
|
||||
b.append("] - Valid resource types for this server: ");
|
||||
b.append(myResourceTypeToDao.keySet().toString());
|
||||
|
||||
throw new InvalidRequestException(b.toString());
|
||||
}
|
||||
Long valueOf;
|
||||
try {
|
||||
valueOf = translateForcedIdToPid(typeString, id);
|
||||
} 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);
|
||||
RuntimeResourceDefinition targetResourceDef = getContext().getResourceDefinition(type);
|
||||
if (target == null) {
|
||||
String resName = targetResourceDef.getName();
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
}
|
||||
|
||||
if (!typeString.equals(target.getResourceType())) {
|
||||
throw new UnprocessableEntityException("Resource contains reference to " + nextValue.getReferenceElement().getValue() + " but resource with ID "
|
||||
+ nextValue.getReferenceElement().getIdPart() + " is actually of type " + target.getResourceType());
|
||||
}
|
||||
|
||||
if (nextSpDef.getTargets() != null && !nextSpDef.getTargets().contains(typeString)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// /*
|
||||
// * Is the target type an allowable type of resource for the path where it is referenced?
|
||||
// */
|
||||
//
|
||||
// if (allowedTypesInField == null) {
|
||||
// BaseRuntimeChildDefinition childDef = getContext().newTerser().getDefinition(theResource.getClass(), nextPathAndRef.getPath());
|
||||
// if (childDef instanceof RuntimeChildResourceDefinition) {
|
||||
// RuntimeChildResourceDefinition resRefDef = (RuntimeChildResourceDefinition) childDef;
|
||||
// allowedTypesInField = resRefDef.getResourceTypes();
|
||||
// } else {
|
||||
// allowedTypesInField = new ArrayList<Class<? extends IBaseResource>>();
|
||||
// allowedTypesInField.add(IBaseResource.class);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// boolean acceptableLink = false;
|
||||
// for (Class<? extends IBaseResource> next : allowedTypesInField) {
|
||||
// if (next.isAssignableFrom(targetResourceDef.getImplementingClass())) {
|
||||
// acceptableLink = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!acceptableLink) {
|
||||
// throw new UnprocessableEntityException(
|
||||
// "Invalid reference found at path '" + nextPathAndRef.getPath() + "'. Resource type '" + targetResourceDef.getName() + "' is not valid for this path");
|
||||
// }
|
||||
|
||||
nextEntity = new ResourceLink(nextPathAndRef.getPath(), theEntity, target);
|
||||
} else {
|
||||
if (!multiType) {
|
||||
if (nextSpDef.getName().equals("sourceuri")) {
|
||||
continue; // TODO: disable this eventually - ConceptMap:sourceuri is of type reference but points to a URI
|
||||
}
|
||||
throw new ConfigurationException("Search param " + nextSpDef.getName() + " is of unexpected datatype: " + nextObject.getClass());
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nextEntity != null) {
|
||||
retVal.add(nextEntity);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
theEntity.setHasLinks(retVal.size() > 0);
|
||||
|
@ -518,7 +519,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return myConfig;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public FhirContext getContext() {
|
||||
return myContext;
|
||||
|
@ -655,7 +655,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
search.setTotalCount(myResourceHistoryTableDao.countForResourceInstance(theId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
search = mySearchDao.save(search);
|
||||
|
||||
return new PersistedJpaBundleProvider(search.getUuid(), this);
|
||||
|
@ -679,7 +679,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
requestDetails.notifyIncomingRequestPreHandled(theOperationType);
|
||||
|
||||
|
||||
List<IServerInterceptor> interceptors = getConfig().getInterceptors();
|
||||
if (interceptors == null) {
|
||||
return;
|
||||
|
@ -877,7 +877,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
IDao.RESOURCE_PID.put(res, theEntity.getId());
|
||||
|
||||
Collection<? extends BaseTag> tags = theEntity.getTags();
|
||||
|
||||
|
||||
if (theEntity.isHasTags()) {
|
||||
for (BaseTag next : tags) {
|
||||
switch (next.getTag().getTagType()) {
|
||||
|
@ -977,7 +977,6 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
myContext = theContext;
|
||||
}
|
||||
|
||||
|
||||
public void setEntityManager(EntityManager theEntityManager) {
|
||||
myEntityManager = theEntityManager;
|
||||
}
|
||||
|
@ -1458,6 +1457,63 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
if (tag != null) {
|
||||
throw new UnprocessableEntityException("Resource contains the 'subsetted' tag, and must not be stored as it may contain a subset of available data");
|
||||
}
|
||||
|
||||
String resName = getContext().getResourceDefinition(theResource).getName();
|
||||
validateChildReferences(theResource, resName);
|
||||
|
||||
}
|
||||
|
||||
private void validateChildReferences(IBase theElement, String thePath) {
|
||||
if (theElement == null) {
|
||||
return;
|
||||
}
|
||||
BaseRuntimeElementDefinition<?> def = myContext.getElementDefinition(theElement.getClass());
|
||||
if (!(def instanceof BaseRuntimeElementCompositeDefinition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
BaseRuntimeElementCompositeDefinition<?> cdef = (BaseRuntimeElementCompositeDefinition<?>)def;
|
||||
for (BaseRuntimeChildDefinition nextChildDef : cdef.getChildren()) {
|
||||
|
||||
List<IBase> values = nextChildDef.getAccessor().getValues(theElement);
|
||||
if (values == null || values.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String newPath = thePath + "." + nextChildDef.getElementName();
|
||||
|
||||
for (IBase nextChild : values) {
|
||||
validateChildReferences(nextChild, newPath);
|
||||
}
|
||||
|
||||
if (nextChildDef instanceof RuntimeChildResourceDefinition) {
|
||||
RuntimeChildResourceDefinition nextChildDefRes = (RuntimeChildResourceDefinition)nextChildDef;
|
||||
Set<String> validTypes = new HashSet<String>();
|
||||
boolean allowAny = false;
|
||||
for (Class<? extends IBaseResource> nextValidType : nextChildDefRes.getResourceTypes()) {
|
||||
if (nextValidType.isInterface()) {
|
||||
allowAny = true;
|
||||
break;
|
||||
}
|
||||
validTypes.add(getContext().getResourceDefinition(nextValidType).getName());
|
||||
}
|
||||
|
||||
if (allowAny) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (IBase nextChild : values) {
|
||||
IBaseReference nextRef = (IBaseReference)nextChild;
|
||||
if (!isBlank(nextRef.getReferenceElement().getResourceType())) {
|
||||
if (!validTypes.contains(nextRef.getReferenceElement().getResourceType())) {
|
||||
throw new UnprocessableEntityException(
|
||||
"Invalid reference found at path '" + newPath + "'. Resource type '" + nextRef.getReferenceElement().getResourceType() + "' is not valid for this path");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean isValidPid(IIdType theId) {
|
||||
|
@ -1561,7 +1617,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
|
||||
static List<Long> translateForcedIdToPids(IIdType theId, IForcedIdDao theForcedIdDao) {
|
||||
Validate.isTrue(theId.hasIdPart());
|
||||
|
||||
|
||||
if (isValidPid(theId)) {
|
||||
return Collections.singletonList(theId.getIdPartAsLong());
|
||||
} else {
|
||||
|
@ -1571,7 +1627,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
} else {
|
||||
forcedId = theForcedIdDao.findByForcedId(theId.getIdPart());
|
||||
}
|
||||
|
||||
|
||||
if (forcedId.isEmpty() == false) {
|
||||
List<Long> retVal = new ArrayList<Long>(forcedId.size());
|
||||
for (ForcedId next : forcedId) {
|
||||
|
|
|
@ -31,12 +31,13 @@ import com.google.common.annotations.VisibleForTesting;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
|
||||
public class BaseSearchParamExtractor {
|
||||
public abstract class BaseSearchParamExtractor implements ISearchParamExtractor {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseSearchParamExtractor.class);
|
||||
private static final Pattern SPLIT = Pattern.compile("\\||( or )");
|
||||
protected static final Pattern SPLIT = Pattern.compile("\\||( or )");
|
||||
|
||||
@Autowired
|
||||
private FhirContext myContext;
|
||||
|
@ -74,5 +75,21 @@ public class BaseSearchParamExtractor {
|
|||
myContext = theContext;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<PathAndRef> extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) {
|
||||
List<PathAndRef> refs = new ArrayList<PathAndRef>();
|
||||
String[] nextPathsSplit = theNextSpDef.getPath().split("\\|");
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
nextPath = nextPath.trim();
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject == null) {
|
||||
continue;
|
||||
}
|
||||
refs.add(new PathAndRef(nextPath, nextObject));
|
||||
}
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR JPA Server
|
||||
|
@ -24,6 +26,7 @@ import java.util.Set;
|
|||
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||
|
@ -49,4 +52,6 @@ public interface ISearchParamExtractor {
|
|||
|
||||
public abstract Set<ResourceIndexedSearchParamUri> extractSearchParamUri(ResourceTable theEntity, IBaseResource theResource);
|
||||
|
||||
public abstract List<PathAndRef> extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef);
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
public class PathAndRef {
|
||||
|
||||
private final String myPath;
|
||||
public String getPath() {
|
||||
return myPath;
|
||||
}
|
||||
public PathAndRef(String thePath, Object theRef) {
|
||||
super();
|
||||
myPath = thePath;
|
||||
myRef = theRef;
|
||||
}
|
||||
public Object getRef() {
|
||||
return myRef;
|
||||
}
|
||||
private final Object myRef;
|
||||
|
||||
}
|
|
@ -73,6 +73,7 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
|
|||
import ca.uhn.fhir.jpa.dao.BaseHapiFhirDao;
|
||||
import ca.uhn.fhir.jpa.dao.BaseSearchParamExtractor;
|
||||
import ca.uhn.fhir.jpa.dao.ISearchParamExtractor;
|
||||
import ca.uhn.fhir.jpa.dao.PathAndRef;
|
||||
import ca.uhn.fhir.jpa.entity.BaseResourceIndexedSearchParam;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords;
|
||||
import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
|
||||
|
@ -88,17 +89,17 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implements ISearchParamExtractor {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamExtractorDstu3.class);
|
||||
|
||||
|
||||
@Autowired
|
||||
private org.hl7.fhir.dstu3.hapi.validation.IValidationSupport myValidationSupport;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SearchParamExtractorDstu3() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public SearchParamExtractorDstu3(FhirContext theCtx, IValidationSupport theValidationSupport) {
|
||||
super(theCtx);
|
||||
myValidationSupport = theValidationSupport;
|
||||
|
@ -135,8 +136,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IBaseResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamDates(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IBaseResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamDate> extractSearchParamDates(ResourceTable theEntity, IBaseResource theResource) {
|
||||
|
@ -196,8 +196,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IBaseResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamNumber(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IBaseResource)
|
||||
*/
|
||||
@Override
|
||||
public HashSet<ResourceIndexedSearchParamNumber> extractSearchParamNumber(ResourceTable theEntity, IBaseResource theResource) {
|
||||
|
@ -244,17 +243,12 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
nextValue = newValue;
|
||||
|
||||
/*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends
|
||||
* org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if
|
||||
* (unit.isCompatible(UCUM.DAY)) {
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>> unit = (PhysicsUnit<? extends org.unitsofmeasurement.quantity.Quantity<?>>)
|
||||
* UCUMFormat.getCaseInsensitiveInstance().parse(nextValue.getCode().getValue(), null); if (unit.isCompatible(UCUM.DAY)) {
|
||||
*
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit =
|
||||
* (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY); double
|
||||
* dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); Duration newValue =
|
||||
* new Duration(); newValue.setSystem(UCUM_NS); newValue.setCode(UCUM.DAY.getSymbol());
|
||||
* newValue.setValue(dayValue); nextValue=newValue; }
|
||||
* @SuppressWarnings("unchecked") PhysicsUnit<org.unitsofmeasurement.quantity.Time> timeUnit = (PhysicsUnit<Time>) unit; UnitConverter conv = timeUnit.getConverterTo(UCUM.DAY);
|
||||
* double dayValue = conv.convert(nextValue.getValue().getValue().doubleValue()); Duration newValue = new Duration(); newValue.setSystem(UCUM_NS);
|
||||
* newValue.setCode(UCUM.DAY.getSymbol()); newValue.setValue(dayValue); nextValue=newValue; }
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -296,8 +290,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IBaseResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamQuantity(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IBaseResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamQuantity> extractSearchParamQuantity(ResourceTable theEntity, IBaseResource theResource) {
|
||||
|
@ -331,7 +324,8 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
continue;
|
||||
}
|
||||
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(), nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
ResourceIndexedSearchParamQuantity nextEntity = new ResourceIndexedSearchParamQuantity(resourceName, nextValue.getValueElement().getValue(),
|
||||
nextValue.getSystemElement().getValueAsString(), nextValue.getCode());
|
||||
nextEntity.setResource(theEntity);
|
||||
retVal.add(nextEntity);
|
||||
} else {
|
||||
|
@ -350,8 +344,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IBaseResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamStrings(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IBaseResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<ResourceIndexedSearchParamString> extractSearchParamStrings(ResourceTable theEntity, IBaseResource theResource) {
|
||||
|
@ -372,7 +365,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
|
||||
if ("Questionnaire".equals(def.getName()) && nextSpDef.getName().equals("title")) {
|
||||
Questionnaire q = (Questionnaire) theResource;
|
||||
String title = "";//q.getGroup().getTitle();
|
||||
String title = "";// q.getGroup().getTitle();
|
||||
addSearchTerm(theEntity, retVal, resourceName, title);
|
||||
}
|
||||
continue;
|
||||
|
@ -432,8 +425,7 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable,
|
||||
* ca.uhn.fhir.model.api.IBaseResource)
|
||||
* @see ca.uhn.fhir.jpa.dao.ISearchParamExtractor#extractSearchParamTokens(ca.uhn.fhir.jpa.entity.ResourceTable, ca.uhn.fhir.model.api.IBaseResource)
|
||||
*/
|
||||
@Override
|
||||
public Set<BaseResourceIndexedSearchParam> extractSearchParamTokens(ResourceTable theEntity, IBaseResource theResource) {
|
||||
|
@ -464,15 +456,15 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
List<String> systems = new ArrayList<String>();
|
||||
List<String> codes = new ArrayList<String>();
|
||||
|
||||
// String needContactPointSystem = null;
|
||||
// if (nextPath.contains(".where(system='phone')")) {
|
||||
// nextPath = nextPath.replace(".where(system='phone')", "");
|
||||
// needContactPointSystem = "phone";
|
||||
// }
|
||||
// if (nextPath.contains(".where(system='email')")) {
|
||||
// nextPath = nextPath.replace(".where(system='email')", "");
|
||||
// needContactPointSystem = "email";
|
||||
// }
|
||||
// String needContactPointSystem = null;
|
||||
// if (nextPath.contains(".where(system='phone')")) {
|
||||
// nextPath = nextPath.replace(".where(system='phone')", "");
|
||||
// needContactPointSystem = "phone";
|
||||
// }
|
||||
// if (nextPath.contains(".where(system='email')")) {
|
||||
// nextPath = nextPath.replace(".where(system='email')", "");
|
||||
// needContactPointSystem = "email";
|
||||
// }
|
||||
|
||||
for (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
|
||||
|
@ -639,14 +631,15 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConcept theCodeableConcept, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
private void extractTokensFromCodeableConcept(List<String> theSystems, List<String> theCodes, CodeableConcept theCodeableConcept, ResourceTable theEntity,
|
||||
Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef) {
|
||||
for (Coding nextCoding : theCodeableConcept.getCoding()) {
|
||||
extractTokensFromCoding(theSystems, theCodes, theEntity, theListToPopulate, theParameterDef, nextCoding);
|
||||
}
|
||||
}
|
||||
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate, RuntimeSearchParam theParameterDef, Coding nextCoding) {
|
||||
private void extractTokensFromCoding(List<String> theSystems, List<String> theCodes, ResourceTable theEntity, Set<BaseResourceIndexedSearchParam> theListToPopulate,
|
||||
RuntimeSearchParam theParameterDef, Coding nextCoding) {
|
||||
if (nextCoding != null && !nextCoding.isEmpty()) {
|
||||
|
||||
String nextSystem = nextCoding.getSystemElement().getValueAsString();
|
||||
|
@ -670,16 +663,33 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
protected List<Object> extractValues(String thePaths, IBaseResource theResource) {
|
||||
IWorkerContext worker = new org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext(getContext(), myValidationSupport);
|
||||
FHIRPathEngine fp = new FHIRPathEngine(worker);
|
||||
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
try {
|
||||
values.addAll(fp.evaluate((Base)theResource, thePaths));
|
||||
values.addAll(fp.evaluate((Base) theResource, thePaths));
|
||||
} catch (FHIRException e) {
|
||||
throw new InternalErrorException(e);
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PathAndRef> extractResourceLinks(IBaseResource theResource, RuntimeSearchParam theNextSpDef) {
|
||||
ArrayList<PathAndRef> retVal = new ArrayList<PathAndRef>();
|
||||
|
||||
String[] nextPathsSplit = SPLIT.split(theNextSpDef.getPath());
|
||||
for (String path : nextPathsSplit) {
|
||||
path = path.trim();
|
||||
if (isNotBlank(path)) {
|
||||
for (Object next : extractValues(path, theResource)) {
|
||||
retVal.add(new PathAndRef(path, next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void setValidationSupportForTesting(org.hl7.fhir.dstu3.hapi.validation.IValidationSupport theValidationSupport) {
|
||||
myValidationSupport = theValidationSupport;
|
||||
|
|
|
@ -83,7 +83,7 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
|
|||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||
patient.setManagingOrganization(new ResourceReferenceDt("Patient/99999999"));
|
||||
patient.setManagingOrganization(new ResourceReferenceDt("Organization/99999999"));
|
||||
try {
|
||||
ourPatientDao.create(patient, mySrd);
|
||||
fail();
|
||||
|
|
|
@ -593,7 +593,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||
patient.setManagingOrganization(new ResourceReferenceDt("Patient/99999999"));
|
||||
patient.setManagingOrganization(new ResourceReferenceDt("Organization/99999999"));
|
||||
try {
|
||||
myPatientDao.create(patient, mySrd);
|
||||
fail();
|
||||
|
@ -626,8 +626,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
try {
|
||||
myPatientDao.create(p, mySrd);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid resource reference"));
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Blah' is not valid for this path"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -278,7 +278,10 @@ public class FhirResourceDaoDstu3SearchNoFtTest extends BaseJpaDstu3Test {
|
|||
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());
|
||||
|
||||
// This is 3 for now because the FluentPath for Patient:deceased adds a value.. this should
|
||||
// be corrected at some point, and we'll then drop back down to 2
|
||||
assertEquals(3, results.size());
|
||||
|
||||
List<IIdType> actual = toUnqualifiedVersionlessIds(myPatientDao.search(Patient.SP_IDENTIFIER, new TokenParam("http://foo1", "123")));
|
||||
assertThat(actual, contains(id));
|
||||
|
|
|
@ -715,7 +715,7 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
public void testCreateWithInvalidReferenceFailsGracefully() {
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
|
||||
patient.setManagingOrganization(new Reference("Patient/99999999"));
|
||||
patient.setManagingOrganization(new Reference("Organization/99999999"));
|
||||
try {
|
||||
myPatientDao.create(patient, mySrd);
|
||||
fail();
|
||||
|
@ -748,8 +748,8 @@ public class FhirResourceDaoDstu3Test extends BaseJpaDstu3Test {
|
|||
try {
|
||||
myPatientDao.create(p, mySrd);
|
||||
fail();
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid resource reference"));
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertThat(e.getMessage(), containsString("Invalid reference found at path 'Patient.managingOrganization'. Resource type 'Blah' is not valid for this path"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,8 +175,8 @@ public class DynamicSearchTest {
|
|||
@Override
|
||||
public List<RuntimeSearchParam> getSearchParameters() {
|
||||
ArrayList<RuntimeSearchParam> retVal = new ArrayList<RuntimeSearchParam>();
|
||||
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", RestSearchParameterTypeEnum.STRING, null));
|
||||
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", RestSearchParameterTypeEnum.DATE, null));
|
||||
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", RestSearchParameterTypeEnum.STRING, null, null));
|
||||
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", RestSearchParameterTypeEnum.DATE, null, null));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.dstu2.composite.CodeableConceptDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.CodingDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Claim;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Practitioner;
|
||||
|
@ -23,11 +24,6 @@ public class ModelDstu2Test {
|
|||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu2();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompositeNames() {
|
||||
assertEquals(MetaDt.class, ourCtx.getElementDefinition("meta").getImplementingClass());
|
||||
|
|
|
@ -50,6 +50,8 @@ import org.hl7.fhir.utilities.Table;
|
|||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.hl7.fhir.utilities.ucum.Decimal;
|
||||
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Grahame Grieve
|
||||
|
@ -2239,7 +2241,7 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcExists(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
result.add(new BooleanType(!focus.isEmpty()));
|
||||
result.add(new BooleanType(!ElementUtil.isEmpty(focus)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2441,7 +2443,7 @@ public class FHIRPathEngine {
|
|||
|
||||
private List<Base> funcEmpty(ExecutionContext context, List<Base> focus, ExpressionNode exp) {
|
||||
List<Base> result = new ArrayList<Base>();
|
||||
result.add(new BooleanType(focus.isEmpty()));
|
||||
result.add(new BooleanType(ElementUtil.isEmpty(focus)));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
package org.hl7.fhir.dstu3.utils;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.exceptions.FHIRException;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
|
||||
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
|
||||
import org.hl7.fhir.dstu3.model.Base;
|
||||
import org.hl7.fhir.dstu3.model.BooleanType;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class FhirPathEngineTest {
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static FHIRPathEngine ourEngine;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirPathEngineTest.class);
|
||||
|
||||
@Test
|
||||
public void testExistsWithNoValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType());
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertFalse(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExistsWithValue() throws FHIRException {
|
||||
Patient patient = new Patient();
|
||||
patient.setDeceased(new BooleanType(false));
|
||||
List<Base> eval = ourEngine.evaluate(patient, "Patient.deceased.exists()");
|
||||
ourLog.info(eval.toString());
|
||||
assertTrue(((BooleanType)eval.get(0)).getValue());
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() {
|
||||
ourEngine = new FHIRPathEngine(new HapiWorkerContext(ourCtx, new DefaultProfileValidationSupport()));
|
||||
}
|
||||
|
||||
}
|
|
@ -79,6 +79,11 @@
|
|||
DSTU2 structures. Thanks to Rahul Somasunderam and
|
||||
Claude Nanjo for the suggestions!
|
||||
</action>
|
||||
<action type="add">
|
||||
JPA server has now been refactored to use the
|
||||
new FluentPath search parameter definitions
|
||||
for DSTU3 resources.
|
||||
</action>
|
||||
</release>
|
||||
<release version="1.5" date="2016-04-20">
|
||||
<action type="fix" issue="339">
|
||||
|
|
Loading…
Reference in New Issue