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;
|
||||
|
@ -259,15 +260,10 @@ 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 (Object nextObject : extractValues(nextPath, theResource)) {
|
||||
if (nextObject == null) {
|
||||
continue;
|
||||
}
|
||||
for (PathAndRef nextPathAndRef : refs) {
|
||||
Object nextObject = nextPathAndRef.getRef();
|
||||
|
||||
ResourceLink nextEntity;
|
||||
if (nextObject instanceof IBaseReference) {
|
||||
|
@ -331,34 +327,39 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
+ 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);
|
||||
}
|
||||
if (nextSpDef.getTargets() != null && !nextSpDef.getTargets().contains(typeString)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean acceptableLink = false;
|
||||
for (Class<? extends IBaseResource> next : allowedTypesInField) {
|
||||
if (next.isAssignableFrom(targetResourceDef.getImplementingClass())) {
|
||||
acceptableLink = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// /*
|
||||
// * 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");
|
||||
// }
|
||||
|
||||
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);
|
||||
nextEntity = new ResourceLink(nextPathAndRef.getPath(), theEntity, target);
|
||||
} else {
|
||||
if (!multiType) {
|
||||
if (nextSpDef.getName().equals("sourceuri")) {
|
||||
|
@ -373,7 +374,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
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;
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
|
@ -680,6 +673,23 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
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