Documentation fixes
This commit is contained in:
parent
862b1bd79d
commit
a1aedf2f31
|
@ -97,7 +97,7 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
if (myIgnoreMissingTemplates) {
|
if (myIgnoreMissingTemplates) {
|
||||||
ourLog.debug("No narrative template available for profile: {}", theProfile);
|
ourLog.debug("No narrative template available for profile: {}", theProfile);
|
||||||
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
|
return new NarrativeDt(new XhtmlDt("<div>No narrative template available for resource profile: " + theProfile + "</div>"), NarrativeStatusEnum.EMPTY);
|
||||||
} else {
|
} else {
|
||||||
throw new DataFormatException("No narrative template for class " + theResource.getClass().getCanonicalName());
|
throw new DataFormatException("No narrative template for class " + theResource.getClass().getCanonicalName());
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,7 @@ public abstract class BaseThymeleafNarrativeGenerator implements INarrativeGener
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (myIgnoreFailures) {
|
if (myIgnoreFailures) {
|
||||||
ourLog.error("Failed to generate narrative", e);
|
ourLog.error("Failed to generate narrative", e);
|
||||||
return new NarrativeDt(new XhtmlDt("<div>No narrative available</div>"), NarrativeStatusEnum.EMPTY);
|
return new NarrativeDt(new XhtmlDt("<div>No narrative available - Error: " + e.getMessage() + "</div>"), NarrativeStatusEnum.EMPTY);
|
||||||
} else {
|
} else {
|
||||||
throw new DataFormatException(e);
|
throw new DataFormatException(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.param;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -31,6 +32,59 @@ public class CodingListParam implements IQueryParameterOr, Iterable<CodingDt> {
|
||||||
|
|
||||||
private List<CodingDt> myCodings = new ArrayList<CodingDt>();
|
private List<CodingDt> myCodings = new ArrayList<CodingDt>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. Codings should be added, e.g. using {@link #add(CodingDt)}
|
||||||
|
*/
|
||||||
|
public CodingListParam() {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which accepts an array of codings
|
||||||
|
*
|
||||||
|
* @param theCodings
|
||||||
|
* The codings
|
||||||
|
*/
|
||||||
|
public CodingListParam(CodingDt... theCodings) {
|
||||||
|
if (theCodings != null) {
|
||||||
|
for (CodingDt next : theCodings) {
|
||||||
|
add(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which accepts a code system and an array of codes in that system
|
||||||
|
*
|
||||||
|
* @param theSystem
|
||||||
|
* The code system
|
||||||
|
* @param theCodings
|
||||||
|
* The codes
|
||||||
|
*/
|
||||||
|
public CodingListParam(String theSystem, String... theCodes) {
|
||||||
|
if (theCodes != null) {
|
||||||
|
for (String next : theCodes) {
|
||||||
|
add(new CodingDt(theSystem, next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which accepts a code system and a collection of codes in that system
|
||||||
|
*
|
||||||
|
* @param theSystem
|
||||||
|
* The code system
|
||||||
|
* @param theCodings
|
||||||
|
* The codes
|
||||||
|
*/
|
||||||
|
public CodingListParam(String theSystem, Collection<String> theCodes) {
|
||||||
|
if (theCodes != null) {
|
||||||
|
for (String next : theCodes) {
|
||||||
|
add(new CodingDt(theSystem, next));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all Codings associated with this list
|
* Returns all Codings associated with this list
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -26,6 +26,8 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||||
|
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||||
|
|
||||||
public class DateRangeParam implements IQueryParameterAnd {
|
public class DateRangeParam implements IQueryParameterAnd {
|
||||||
|
@ -33,6 +35,83 @@ public class DateRangeParam implements IQueryParameterAnd {
|
||||||
private QualifiedDateParam myLowerBound;
|
private QualifiedDateParam myLowerBound;
|
||||||
private QualifiedDateParam myUpperBound;
|
private QualifiedDateParam myUpperBound;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic constructor. Values must be supplied by calling {@link #setLowerBound(QualifiedDateParam)} and {@link #setUpperBound(QualifiedDateParam)}
|
||||||
|
*/
|
||||||
|
public DateRangeParam() {
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which takes two strings representing the lower and upper bounds of the range
|
||||||
|
*
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the lower date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the upper date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
|
*/
|
||||||
|
public DateRangeParam(String theLowerBound, String theUpperBound) {
|
||||||
|
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
||||||
|
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor which takes two Dates representing the lower and upper bounds of the range
|
||||||
|
*
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the lower date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
|
* @param theLowerBound
|
||||||
|
* A qualified date param representing the upper date bound (optionally may include time), e.g. "2011-02-22" or "2011-02-22T13:12:00"
|
||||||
|
*/
|
||||||
|
public DateRangeParam(Date theLowerBound, Date theUpperBound) {
|
||||||
|
myLowerBound = new QualifiedDateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theLowerBound);
|
||||||
|
myUpperBound = new QualifiedDateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theUpperBound);
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void validateAndThrowDataFormatExceptionIfInvalid() {
|
||||||
|
boolean haveLowerBound = myLowerBound != null && myLowerBound.isEmpty() == false;
|
||||||
|
boolean haveUpperBound = myUpperBound != null && myUpperBound.isEmpty() == false;
|
||||||
|
if (haveLowerBound && haveUpperBound) {
|
||||||
|
if (myLowerBound.getValue().after(myUpperBound.getValue())) {
|
||||||
|
throw new DataFormatException("Lower bound of " + myLowerBound.getValueAsString() + " is after upper bound of " + myUpperBound.getValueAsString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (haveLowerBound) {
|
||||||
|
if (myLowerBound.getComparator() == null) {
|
||||||
|
myLowerBound.setComparator(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS);
|
||||||
|
}
|
||||||
|
switch (myLowerBound.getComparator()) {
|
||||||
|
case GREATERTHAN:
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
throw new DataFormatException("Lower bound comparator must be > or >=, can not be " + myLowerBound.getComparator().getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (haveUpperBound) {
|
||||||
|
if (myUpperBound.getComparator() == null) {
|
||||||
|
myUpperBound.setComparator(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS);
|
||||||
|
}
|
||||||
|
switch (myUpperBound.getComparator()) {
|
||||||
|
case LESSTHAN:
|
||||||
|
case LESSTHAN_OR_EQUALS:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
case GREATERTHAN:
|
||||||
|
case GREATERTHAN_OR_EQUALS:
|
||||||
|
throw new DataFormatException("Upper bound comparator must be < or <=, can not be " + myUpperBound.getComparator().getCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void addParam(QualifiedDateParam theParsed) throws InvalidRequestException {
|
private void addParam(QualifiedDateParam theParsed) throws InvalidRequestException {
|
||||||
if (theParsed.getComparator() == null) {
|
if (theParsed.getComparator() == null) {
|
||||||
if (myLowerBound != null || myUpperBound != null) {
|
if (myLowerBound != null || myUpperBound != null) {
|
||||||
|
@ -88,10 +167,12 @@ public class DateRangeParam implements IQueryParameterAnd {
|
||||||
|
|
||||||
public void setLowerBound(QualifiedDateParam theLowerBound) {
|
public void setLowerBound(QualifiedDateParam theLowerBound) {
|
||||||
myLowerBound = theLowerBound;
|
myLowerBound = theLowerBound;
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpperBound(QualifiedDateParam theUpperBound) {
|
public void setUpperBound(QualifiedDateParam theUpperBound) {
|
||||||
myUpperBound = theUpperBound;
|
myUpperBound = theUpperBound;
|
||||||
|
validateAndThrowDataFormatExceptionIfInvalid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -20,7 +20,6 @@ package ca.uhn.fhir.rest.param;
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -28,6 +27,7 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
import ca.uhn.fhir.context.ConfigurationException;
|
||||||
import ca.uhn.fhir.model.api.PathSpecification;
|
import ca.uhn.fhir.model.api.PathSpecification;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||||
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||||
|
@ -38,8 +38,9 @@ public class IncludeParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
private Class<? extends Collection<PathSpecification>> myInstantiableCollectionType;
|
private Class<? extends Collection<PathSpecification>> myInstantiableCollectionType;
|
||||||
private HashSet<String> myAllow;
|
private HashSet<String> myAllow;
|
||||||
|
private Class<?> mySpecType;
|
||||||
|
|
||||||
public IncludeParameter(IncludeParam theAnnotation, Class<? extends Collection<PathSpecification>> theInstantiableCollectionType) {
|
public IncludeParameter(IncludeParam theAnnotation, Class<? extends Collection<PathSpecification>> theInstantiableCollectionType, Class<?> theSpecType) {
|
||||||
myInstantiableCollectionType = theInstantiableCollectionType;
|
myInstantiableCollectionType = theInstantiableCollectionType;
|
||||||
if (theAnnotation.allow().length > 0) {
|
if (theAnnotation.allow().length > 0) {
|
||||||
myAllow = new HashSet<String>();
|
myAllow = new HashSet<String>();
|
||||||
|
@ -47,6 +48,12 @@ public class IncludeParameter extends BaseQueryParameter {
|
||||||
myAllow.add(next);
|
myAllow.add(next);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mySpecType = theSpecType;
|
||||||
|
if (mySpecType != PathSpecification.class && mySpecType != String.class) {
|
||||||
|
throw new ConfigurationException("Invalid @" + IncludeParam.class.getSimpleName() + " parameter type: " + mySpecType);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -54,10 +61,18 @@ public class IncludeParameter extends BaseQueryParameter {
|
||||||
public List<List<String>> encode(Object theObject) throws InternalErrorException {
|
public List<List<String>> encode(Object theObject) throws InternalErrorException {
|
||||||
ArrayList<List<String>> retVal = new ArrayList<List<String>>();
|
ArrayList<List<String>> retVal = new ArrayList<List<String>>();
|
||||||
|
|
||||||
|
if (myInstantiableCollectionType == null) {
|
||||||
|
if (mySpecType == PathSpecification.class) {
|
||||||
|
retVal.add(Collections.singletonList(((PathSpecification)theObject).getValue()));
|
||||||
|
} else {
|
||||||
|
retVal.add(Collections.singletonList(((String)theObject)));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
Collection<PathSpecification> val = (Collection<PathSpecification>) theObject;
|
Collection<PathSpecification> val = (Collection<PathSpecification>) theObject;
|
||||||
for (PathSpecification pathSpec : val) {
|
for (PathSpecification pathSpec : val) {
|
||||||
retVal.add(Collections.singletonList(pathSpec.getValue()));
|
retVal.add(Collections.singletonList(pathSpec.getValue()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
@ -69,12 +84,14 @@ public class IncludeParameter extends BaseQueryParameter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object parse(List<List<String>> theString) throws InternalErrorException, InvalidRequestException {
|
public Object parse(List<List<String>> theString) throws InternalErrorException, InvalidRequestException {
|
||||||
Collection<PathSpecification> retVal;
|
Collection<PathSpecification> retValCollection = null;
|
||||||
|
if (myInstantiableCollectionType!=null) {
|
||||||
try {
|
try {
|
||||||
retVal = myInstantiableCollectionType.newInstance();
|
retValCollection = myInstantiableCollectionType.newInstance();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InternalErrorException("Failed to instantiate " + myInstantiableCollectionType.getName(), e);
|
throw new InternalErrorException("Failed to instantiate " + myInstantiableCollectionType.getName(), e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (List<String> nextParamList : theString) {
|
for (List<String> nextParamList : theString) {
|
||||||
if (nextParamList.isEmpty()) {
|
if (nextParamList.isEmpty()) {
|
||||||
|
@ -90,10 +107,18 @@ public class IncludeParameter extends BaseQueryParameter {
|
||||||
throw new InvalidRequestException("Invalid _include parameter value: '" + value + "'. Valid values are: " + new TreeSet<String>(myAllow));
|
throw new InvalidRequestException("Invalid _include parameter value: '" + value + "'. Valid values are: " + new TreeSet<String>(myAllow));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
retVal.add(new PathSpecification(value));
|
if (retValCollection == null) {
|
||||||
|
if (mySpecType == String.class) {
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
return new PathSpecification(value);
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
retValCollection.add(new PathSpecification(value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return retVal;
|
return retValCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -106,12 +106,20 @@ public class ParameterUtil {
|
||||||
extractDescription(parameter, annotations);
|
extractDescription(parameter, annotations);
|
||||||
param = parameter;
|
param = parameter;
|
||||||
} else if (nextAnnotation instanceof IncludeParam) {
|
} else if (nextAnnotation instanceof IncludeParam) {
|
||||||
if (parameterType != PathSpecification.class || innerCollectionType == null || outerCollectionType != null) {
|
Class<? extends Collection<PathSpecification>> instantiableCollectionType;
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<" + PathSpecification.class.getSimpleName() + ">");
|
Class<?> specType;
|
||||||
}
|
|
||||||
Class<? extends Collection<PathSpecification>> instantiableCollectionType = (Class<? extends Collection<PathSpecification>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName() + "'");
|
|
||||||
|
|
||||||
param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType);
|
if (parameterType == String.class) {
|
||||||
|
instantiableCollectionType=null;
|
||||||
|
specType=String.class;
|
||||||
|
}else if (parameterType != PathSpecification.class || innerCollectionType == null || outerCollectionType != null) {
|
||||||
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<" + PathSpecification.class.getSimpleName() + ">");
|
||||||
|
} else {
|
||||||
|
instantiableCollectionType = (Class<? extends Collection<PathSpecification>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName() + "'");
|
||||||
|
specType = PathSpecification.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType, specType);
|
||||||
} else if (nextAnnotation instanceof ResourceParam) {
|
} else if (nextAnnotation instanceof ResourceParam) {
|
||||||
if (!IResource.class.isAssignableFrom(parameterType)) {
|
if (!IResource.class.isAssignableFrom(parameterType)) {
|
||||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName() + " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
|
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName() + " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.util.Date;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||||
|
import ca.uhn.fhir.parser.DataFormatException;
|
||||||
|
|
||||||
public class QualifiedDateParam extends DateTimeDt implements IQueryParameterType {
|
public class QualifiedDateParam extends DateTimeDt implements IQueryParameterType {
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@ public class QualifiedDateParam extends DateTimeDt implements IQueryParameterTyp
|
||||||
@Override
|
@Override
|
||||||
public void setValueAsQueryToken(String theParameter) {
|
public void setValueAsQueryToken(String theParameter) {
|
||||||
if (theParameter.length() < 2) {
|
if (theParameter.length() < 2) {
|
||||||
throw new IllegalArgumentException("Invalid qualified date parameter: "+theParameter);
|
throw new DataFormatException("Invalid qualified date parameter: "+theParameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
char char0 = theParameter.charAt(0);
|
char char0 = theParameter.charAt(0);
|
||||||
|
@ -92,7 +93,7 @@ public class QualifiedDateParam extends DateTimeDt implements IQueryParameterTyp
|
||||||
String comparatorString = theParameter.substring(0, dateStart);
|
String comparatorString = theParameter.substring(0, dateStart);
|
||||||
QuantityCompararatorEnum comparator = QuantityCompararatorEnum.VALUESET_BINDER.fromCodeString(comparatorString);
|
QuantityCompararatorEnum comparator = QuantityCompararatorEnum.VALUESET_BINDER.fromCodeString(comparatorString);
|
||||||
if (comparator==null) {
|
if (comparator==null) {
|
||||||
throw new IllegalArgumentException("Invalid date qualifier: "+comparatorString);
|
throw new DataFormatException("Invalid date qualifier: "+comparatorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
String dateString = theParameter.substring(dateStart);
|
String dateString = theParameter.substring(dateStart);
|
||||||
|
|
|
@ -49,16 +49,15 @@ import org.thymeleaf.templateresolver.TemplateResolver;
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||||
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.primitive.IdDt;
|
import ca.uhn.fhir.model.primitive.IdDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||||
import ca.uhn.fhir.rest.client.GenericClient;
|
import ca.uhn.fhir.rest.client.GenericClient;
|
||||||
import ca.uhn.fhir.rest.client.IGenericClient;
|
|
||||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||||
import ca.uhn.fhir.rest.server.Constants;
|
import ca.uhn.fhir.rest.server.Constants;
|
||||||
import ca.uhn.fhir.rest.server.EncodingUtil;
|
import ca.uhn.fhir.rest.server.EncodingUtil;
|
||||||
import ca.uhn.fhir.testmodel.IdentifierDt;
|
|
||||||
|
|
||||||
public class PublicTesterServlet extends HttpServlet {
|
public class PublicTesterServlet extends HttpServlet {
|
||||||
|
|
||||||
|
|
|
@ -250,6 +250,36 @@ public List<DiagnosticReport> getDiagnosticReport(
|
||||||
}
|
}
|
||||||
//END SNIPPET: pathSpec
|
//END SNIPPET: pathSpec
|
||||||
|
|
||||||
|
|
||||||
|
//START SNIPPET: pathSpecSimple
|
||||||
|
@Search()
|
||||||
|
public List<DiagnosticReport> getDiagnosticReport(
|
||||||
|
@RequiredParam(name=DiagnosticReport.SP_IDENTIFIER)
|
||||||
|
IdentifierDt theIdentifier,
|
||||||
|
@IncludeParam(allow= {"DiagnosticReport.subject"})
|
||||||
|
String theInclude ) {
|
||||||
|
List<DiagnosticReport> retVal = new ArrayList<DiagnosticReport>();
|
||||||
|
|
||||||
|
// Assume this method exists and loads the report from the DB
|
||||||
|
DiagnosticReport report = loadSomeDiagnosticReportFromDatabase(theIdentifier);
|
||||||
|
|
||||||
|
// If the client has asked for the subject to be included:
|
||||||
|
if ("DiagnosticReport.subject".equals(theInclude)) {
|
||||||
|
|
||||||
|
// The resource reference should contain the ID of the patient
|
||||||
|
IdDt subjectId = report.getSubject().getId();
|
||||||
|
|
||||||
|
// So load the patient ID and return it
|
||||||
|
Patient subject = loadSomePatientFromDatabase(subjectId);
|
||||||
|
report.getSubject().setResource(subject);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
retVal.add(report);
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
//END SNIPPET: pathSpecSimple
|
||||||
|
|
||||||
//START SNIPPET: dateRange
|
//START SNIPPET: dateRange
|
||||||
@Search()
|
@Search()
|
||||||
public List<Observation> getObservationsByDateRange(@RequiredParam(name="subject.identifier") IdentifierDt theSubjectId,
|
public List<Observation> getObservationsByDateRange(@RequiredParam(name="subject.identifier") IdentifierDt theSubjectId,
|
||||||
|
|
|
@ -729,6 +729,17 @@
|
||||||
<code>http://fhir.example.com/DiagnosticReport?subject.identifier=7000135&_include=DiagnosticReport.subject</code>
|
<code>http://fhir.example.com/DiagnosticReport?subject.identifier=7000135&_include=DiagnosticReport.subject</code>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
It is also possible to use a String type for the include parameter,
|
||||||
|
which is more convenient if only a single include (or null for none)
|
||||||
|
is all that is required.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<macro name="snippet">
|
||||||
|
<param name="id" value="pathSpecSimple" />
|
||||||
|
<param name="file" value="src/site/example/java/example/RestfulPatientResourceProviderMore.java" />
|
||||||
|
</macro>
|
||||||
|
|
||||||
</subsection>
|
</subsection>
|
||||||
|
|
||||||
<subsection name="Named Queries (_query)">
|
<subsection name="Named Queries (_query)">
|
||||||
|
|
|
@ -48,6 +48,7 @@ import ca.uhn.fhir.model.primitive.InstantDt;
|
||||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||||
import ca.uhn.fhir.model.primitive.StringDt;
|
import ca.uhn.fhir.model.primitive.StringDt;
|
||||||
import ca.uhn.fhir.rest.annotation.Create;
|
import ca.uhn.fhir.rest.annotation.Create;
|
||||||
|
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||||
import ca.uhn.fhir.rest.annotation.Search;
|
import ca.uhn.fhir.rest.annotation.Search;
|
||||||
|
@ -637,6 +638,29 @@ public class ClientTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSearchWithStringIncludes() throws Exception {
|
||||||
|
|
||||||
|
String msg = getPatientFeedWithOneResult();
|
||||||
|
|
||||||
|
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||||
|
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||||
|
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||||
|
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||||
|
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||||
|
|
||||||
|
ITestClientWithStringIncludes client = ctx.newRestfulClient(ITestClientWithStringIncludes.class, "http://foo");
|
||||||
|
client.getPatientWithIncludes(new StringDt("aaa"), "inc1");
|
||||||
|
|
||||||
|
assertEquals("http://foo/Patient?withIncludes=aaa&_include=inc1", capt.getValue().getURI().toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITestClientWithStringIncludes extends IBasicClient {
|
||||||
|
@Search()
|
||||||
|
public Patient getPatientWithIncludes(@RequiredParam(name = "withIncludes") StringDt theString, @IncludeParam String theInclude);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchWithOptionalParam() throws Exception {
|
public void testSearchWithOptionalParam() throws Exception {
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||||
|
import ca.uhn.fhir.model.dstu.resource.AdverseReaction;
|
||||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticOrder;
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticOrder;
|
||||||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||||
|
@ -531,6 +532,20 @@ public class ResfulServerMethodTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadOnTypeThatDoesntSupportRead() throws Exception {
|
||||||
|
|
||||||
|
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/AdverseReaction/223");
|
||||||
|
HttpResponse status = ourClient.execute(httpGet);
|
||||||
|
|
||||||
|
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||||
|
ourLog.info("Response was:\n{}", responseContent);
|
||||||
|
|
||||||
|
assertEquals(Constants.STATUS_HTTP_404_NOT_FOUND, status.getStatusLine().getStatusCode());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSearchAllProfiles() throws Exception {
|
public void testSearchAllProfiles() throws Exception {
|
||||||
|
|
||||||
|
@ -999,9 +1014,10 @@ public class ResfulServerMethodTest {
|
||||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||||
ServerProfileProvider profProvider = new ServerProfileProvider(ourCtx);
|
ServerProfileProvider profProvider = new ServerProfileProvider(ourCtx);
|
||||||
DummyDiagnosticReportResourceProvider reportProvider = new DummyDiagnosticReportResourceProvider();
|
DummyDiagnosticReportResourceProvider reportProvider = new DummyDiagnosticReportResourceProvider();
|
||||||
|
DummyAdverseReactionResourceProvider adv = new DummyAdverseReactionResourceProvider();
|
||||||
|
|
||||||
ServletHandler proxyHandler = new ServletHandler();
|
ServletHandler proxyHandler = new ServletHandler();
|
||||||
DummyRestfulServer servlet = new DummyRestfulServer(patientProvider, profProvider, reportProvider);
|
DummyRestfulServer servlet = new DummyRestfulServer(patientProvider, profProvider, reportProvider, adv);
|
||||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||||
ourServer.setHandler(proxyHandler);
|
ourServer.setHandler(proxyHandler);
|
||||||
|
@ -1061,6 +1077,31 @@ public class ResfulServerMethodTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by dsotnikov on 2/25/2014.
|
||||||
|
*/
|
||||||
|
public static class DummyAdverseReactionResourceProvider implements IResourceProvider {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* *********************
|
||||||
|
* NO NEW METHODS
|
||||||
|
* *********************
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends IResource> getResourceType() {
|
||||||
|
return AdverseReaction.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Create()
|
||||||
|
public MethodOutcome create(@ResourceParam AdverseReaction thePatient) {
|
||||||
|
IdDt id = new IdDt(thePatient.getIdentifier().get(0).getValue().getValue());
|
||||||
|
IdDt version = new IdDt(thePatient.getIdentifier().get(1).getValue().getValue());
|
||||||
|
return new MethodOutcome(id, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by dsotnikov on 2/25/2014.
|
* Created by dsotnikov on 2/25/2014.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue