Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
a4975887b8
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.model.api;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
|
@ -34,8 +35,10 @@ public interface IQueryParameterAnd<T extends IQueryParameterOr<?>> {
|
|||
* <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search SearchParameter Types</a>
|
||||
* for information on the <b>token</b> format
|
||||
* </p>
|
||||
* @param theContext TODO
|
||||
* @param theParamName TODO
|
||||
*/
|
||||
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException;
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, List<QualifiedParamList> theParameters) throws InvalidRequestException;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -22,11 +22,12 @@ package ca.uhn.fhir.model.api;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
||||
public interface IQueryParameterOr<T extends IQueryParameterType> {
|
||||
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters);
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters);
|
||||
|
||||
public List<T> getValuesAsQueryTokens();
|
||||
|
||||
|
|
|
@ -31,7 +31,8 @@ public interface IQueryParameterType {
|
|||
* See FHIR specification <a href="http://www.hl7.org/implement/standards/fhir/search.html#ptypes">2.2.2 Search
|
||||
* SearchParameter Types</a> for information on the <b>token</b> format
|
||||
* </p>
|
||||
*
|
||||
* @param theContext TODO
|
||||
* @param theParamName TODO
|
||||
* @param theQualifier
|
||||
* The parameter name qualifier that accompanied this value. For example, if the complete query was
|
||||
* <code>http://foo?name:exact=John</code>, qualifier would be ":exact"
|
||||
|
@ -39,7 +40,7 @@ public interface IQueryParameterType {
|
|||
* The actual parameter value. For example, if the complete query was
|
||||
* <code>http://foo?name:exact=John</code>, the value would be "John"
|
||||
*/
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue);
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue);
|
||||
|
||||
/**
|
||||
* Returns a representation of this parameter's value as it will be represented "over the wire". In other
|
||||
|
|
|
@ -94,7 +94,7 @@ public abstract class BaseCodingDt extends BaseIdentifiableElement implements IC
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theParameter) {
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) {
|
||||
int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
|
||||
if (barIndex != -1) {
|
||||
setSystem(theParameter.substring(0, barIndex));
|
||||
|
|
|
@ -104,7 +104,7 @@ public abstract class BaseIdentifierDt extends BaseIdentifiableElement implement
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theParameter) {
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) {
|
||||
int barIndex = ParameterUtil.nonEscapedIndexOf(theParameter, '|');
|
||||
if (barIndex != -1) {
|
||||
setSystem(theParameter.substring(0, barIndex));
|
||||
|
|
|
@ -51,7 +51,7 @@ public abstract class BaseQuantityDt extends BaseIdentifiableElement implements
|
|||
|
||||
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
getComparatorElement().setValue(null);
|
||||
setCode( null);
|
||||
setSystem(null);
|
||||
|
|
|
@ -88,7 +88,7 @@ public class StringDt extends BasePrimitive<String> implements IQueryParameterTy
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
setValue(theValue);
|
||||
}
|
||||
|
||||
|
|
|
@ -48,12 +48,12 @@ abstract class BaseJavaPrimitiveBinder<T>implements IParamBinder<T> {
|
|||
if (isBlank(retVal)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<?> retValList = Collections.singletonList(MethodUtil.singleton(new StringParam(retVal)));
|
||||
List<?> retValList = Collections.singletonList(MethodUtil.singleton(new StringParam(retVal), null));
|
||||
return (List<IQueryParameterOr<?>>) retValList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T parse(String theName, List<QualifiedParamList> theParams) throws InternalErrorException, InvalidRequestException {
|
||||
public T parse(FhirContext theContext, String theName, List<QualifiedParamList> theParams) throws InternalErrorException, InvalidRequestException {
|
||||
if (theParams.size() == 0 || theParams.get(0).size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ public class DynamicSearchParameter implements IParameter {
|
|||
for (String next : theRequest.getParameters().keySet()) {
|
||||
String qualifier = null;
|
||||
String qualifiedParamName = next;
|
||||
String unqualifiedParamName = next;
|
||||
RuntimeSearchParam param = myNameToParam.get(next);
|
||||
if (param == null) {
|
||||
int colonIndex = next.indexOf(':');
|
||||
|
@ -86,6 +87,7 @@ public class DynamicSearchParameter implements IParameter {
|
|||
}
|
||||
qualifier = next.substring(index);
|
||||
next = next.substring(0, index);
|
||||
unqualifiedParamName = next;
|
||||
param = myNameToParam.get(next);
|
||||
}
|
||||
}
|
||||
|
@ -95,48 +97,50 @@ public class DynamicSearchParameter implements IParameter {
|
|||
for (String nextValue : theRequest.getParameters().get(qualifiedParamName)) {
|
||||
QualifiedParamList paramList = QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifier, nextValue);
|
||||
|
||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||
|
||||
switch (param.getParamType()) {
|
||||
case COMPOSITE:
|
||||
Class<? extends IQueryParameterType> left = toParamType(param.getCompositeOf().get(0));
|
||||
Class<? extends IQueryParameterType> right = toParamType(param.getCompositeOf().get(0));
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
CompositeOrListParam compositeOrListParam = new CompositeOrListParam(left, right);
|
||||
compositeOrListParam.setValuesAsQueryTokens(paramList);
|
||||
compositeOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, compositeOrListParam);
|
||||
break;
|
||||
case DATE:
|
||||
DateOrListParam dateOrListParam = new DateOrListParam();
|
||||
dateOrListParam.setValuesAsQueryTokens(paramList);
|
||||
dateOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, dateOrListParam);
|
||||
break;
|
||||
case NUMBER:
|
||||
NumberOrListParam numberOrListParam = new NumberOrListParam();
|
||||
numberOrListParam.setValuesAsQueryTokens(paramList);
|
||||
numberOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, numberOrListParam);
|
||||
break;
|
||||
case QUANTITY:
|
||||
QuantityOrListParam quantityOrListParam = new QuantityOrListParam();
|
||||
quantityOrListParam.setValuesAsQueryTokens(paramList);
|
||||
quantityOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, quantityOrListParam);
|
||||
break;
|
||||
case REFERENCE:
|
||||
ReferenceOrListParam referenceOrListParam = new ReferenceOrListParam();
|
||||
referenceOrListParam.setValuesAsQueryTokens(paramList);
|
||||
referenceOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, referenceOrListParam);
|
||||
break;
|
||||
case STRING:
|
||||
StringOrListParam stringOrListParam = new StringOrListParam();
|
||||
stringOrListParam.setValuesAsQueryTokens(paramList);
|
||||
stringOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, stringOrListParam);
|
||||
break;
|
||||
case TOKEN:
|
||||
TokenOrListParam tokenOrListParam = new TokenOrListParam();
|
||||
tokenOrListParam.setValuesAsQueryTokens(paramList);
|
||||
tokenOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, tokenOrListParam);
|
||||
break;
|
||||
case URI:
|
||||
UriOrListParam uriOrListParam = new UriOrListParam();
|
||||
uriOrListParam.setValuesAsQueryTokens(paramList);
|
||||
uriOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList);
|
||||
retVal.add(next, uriOrListParam);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,6 @@ interface IParamBinder<T> {
|
|||
|
||||
List<IQueryParameterOr<?>> encode(FhirContext theContext, T theString) throws InternalErrorException;
|
||||
|
||||
T parse(String theName, List<QualifiedParamList> theList) throws InternalErrorException, InvalidRequestException;
|
||||
T parse(FhirContext theContext, String theName, List<QualifiedParamList> theList) throws InternalErrorException, InvalidRequestException;
|
||||
|
||||
}
|
||||
|
|
|
@ -608,16 +608,16 @@ public class MethodUtil {
|
|||
/**
|
||||
* This is a utility method intended provided to help the JPA module.
|
||||
*/
|
||||
public static IQueryParameterAnd<?> parseQueryParams(RuntimeSearchParam theParamDef, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
|
||||
public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RuntimeSearchParam theParamDef, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
|
||||
RestSearchParameterTypeEnum paramType = theParamDef.getParamType();
|
||||
return parseQueryParams(paramType, theUnqualifiedParamName, theParameters);
|
||||
return parseQueryParams(theContext, paramType, theUnqualifiedParamName, theParameters);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This is a utility method intended provided to help the JPA module.
|
||||
*/
|
||||
public static IQueryParameterAnd<?> parseQueryParams(RestSearchParameterTypeEnum paramType, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
|
||||
public static IQueryParameterAnd<?> parseQueryParams(FhirContext theContext, RestSearchParameterTypeEnum paramType, String theUnqualifiedParamName, List<QualifiedParamList> theParameters) {
|
||||
QueryParameterAndBinder binder = null;
|
||||
switch (paramType) {
|
||||
case COMPOSITE:
|
||||
|
@ -648,7 +648,7 @@ public class MethodUtil {
|
|||
break;
|
||||
}
|
||||
|
||||
return binder.parse(theUnqualifiedParamName, theParameters);
|
||||
return binder.parse(theContext, theUnqualifiedParamName, theParameters);
|
||||
}
|
||||
|
||||
public static void parseTagValue(TagList tagList, String nextTagComplete) {
|
||||
|
@ -779,7 +779,7 @@ public class MethodUtil {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public static IQueryParameterOr<?> singleton(final IQueryParameterType theParam) {
|
||||
public static IQueryParameterOr<?> singleton(final IQueryParameterType theParam, final String theParamName) {
|
||||
return new IQueryParameterOr<IQueryParameterType>() {
|
||||
|
||||
@Override
|
||||
|
@ -788,14 +788,14 @@ public class MethodUtil {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) {
|
||||
if (theParameters.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (theParameters.size() > 1) {
|
||||
throw new IllegalArgumentException("Type " + theParam.getClass().getCanonicalName() + " does not support multiple values");
|
||||
}
|
||||
theParam.setValueAsQueryToken(theParameters.getQualifier(), theParameters.get(0));
|
||||
theParam.setValueAsQueryToken(theContext, theParamName, theParameters.getQualifier(), theParameters.get(0));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -304,7 +304,8 @@ public class OperationParameter implements IParameter {
|
|||
parameters.add(QualifiedParamList.singleton(paramValues[1]));
|
||||
}
|
||||
DateRangeParam dateRangeParam = new DateRangeParam();
|
||||
dateRangeParam.setValuesAsQueryTokens(parameters);
|
||||
FhirContext ctx = theRequest.getServer().getFhirContext();
|
||||
dateRangeParam.setValuesAsQueryTokens(ctx, myName, parameters);
|
||||
matchingParamValues.add(dateRangeParam);
|
||||
} else if (String.class.isAssignableFrom(myParameterType)) {
|
||||
|
||||
|
|
|
@ -43,11 +43,11 @@ final class QueryParameterAndBinder extends BaseBinder<IQueryParameterAnd<?>> im
|
|||
}
|
||||
|
||||
@Override
|
||||
public IQueryParameterAnd<?> parse(String theName, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
|
||||
public IQueryParameterAnd<?> parse(FhirContext theContext, String theParamName, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
|
||||
IQueryParameterAnd<?> dt;
|
||||
try {
|
||||
dt = newInstance();
|
||||
dt.setValuesAsQueryTokens(theString);
|
||||
dt.setValuesAsQueryTokens(theContext, theParamName, theString);
|
||||
} catch (SecurityException e) {
|
||||
throw new InternalErrorException(e);
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ final class QueryParameterOrBinder extends BaseBinder<IQueryParameterOr<?>> impl
|
|||
}
|
||||
|
||||
@Override
|
||||
public IQueryParameterOr<?> parse(String theName, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
|
||||
public IQueryParameterOr<?> parse(FhirContext theContext, String theParamName, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
|
||||
IQueryParameterOr<?> dt;
|
||||
try {
|
||||
dt = newInstance();
|
||||
|
@ -52,10 +52,10 @@ final class QueryParameterOrBinder extends BaseBinder<IQueryParameterOr<?>> impl
|
|||
return dt;
|
||||
}
|
||||
if (theString.size() > 1) {
|
||||
throw new InvalidRequestException("Multiple values detected for non-repeatable parameter '" + theName + "'. This server is not configured to allow multiple (AND/OR) values for this param.");
|
||||
throw new InvalidRequestException("Multiple values detected for non-repeatable parameter '" + theParamName + "'. This server is not configured to allow multiple (AND/OR) values for this param.");
|
||||
}
|
||||
|
||||
dt.setValuesAsQueryTokens(theString.get(0));
|
||||
dt.setValuesAsQueryTokens(theContext, theParamName, theString.get(0));
|
||||
} catch (SecurityException e) {
|
||||
throw new InternalErrorException(e);
|
||||
}
|
||||
|
|
|
@ -41,12 +41,12 @@ final class QueryParameterTypeBinder extends BaseBinder<IQueryParameterType> imp
|
|||
@Override
|
||||
public List<IQueryParameterOr<?>> encode(FhirContext theContext, IQueryParameterType theValue) throws InternalErrorException {
|
||||
IQueryParameterType param = theValue;
|
||||
List<?> retVal = Collections.singletonList(MethodUtil.singleton(param));
|
||||
List<?> retVal = Collections.singletonList(MethodUtil.singleton(param, null));
|
||||
return (List<IQueryParameterOr<?>>) retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IQueryParameterType parse(String theName, List<QualifiedParamList> theParams) throws InternalErrorException, InvalidRequestException {
|
||||
public IQueryParameterType parse(FhirContext theContext, String theParamName, List<QualifiedParamList> theParams) throws InternalErrorException, InvalidRequestException {
|
||||
String value = theParams.get(0).get(0);
|
||||
if (StringUtils.isBlank(value)) {
|
||||
return null;
|
||||
|
@ -58,10 +58,10 @@ final class QueryParameterTypeBinder extends BaseBinder<IQueryParameterType> imp
|
|||
return dt;
|
||||
}
|
||||
if (theParams.size() > 1 || theParams.get(0).size() > 1) {
|
||||
throw new InvalidRequestException("Multiple values detected for non-repeatable parameter '" + theName + "'. This server is not configured to allow multiple (AND/OR) values for this param.");
|
||||
throw new InvalidRequestException("Multiple values detected for non-repeatable parameter '" + theParamName + "'. This server is not configured to allow multiple (AND/OR) values for this param.");
|
||||
}
|
||||
|
||||
dt.setValueAsQueryToken(theParams.get(0).getQualifier(), value);
|
||||
dt.setValueAsQueryToken(theContext, theParamName, theParams.get(0).getQualifier(), value);
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
*/
|
||||
@Override
|
||||
public Object parse(FhirContext theContext, List<QualifiedParamList> theString) throws InternalErrorException, InvalidRequestException {
|
||||
return myParamBinder.parse(getName(), theString);
|
||||
return myParamBinder.parse(theContext, getName(), theString);
|
||||
}
|
||||
|
||||
public void setChainlists(String[] theChainWhitelist, String[] theChainBlacklist) {
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.param;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
@ -40,11 +41,11 @@ public abstract class BaseAndListParam<T extends IQueryParameterOr<?>> implement
|
|||
public abstract BaseAndListParam<T> addAnd(T theValue);
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, List<QualifiedParamList> theParameters) throws InvalidRequestException {
|
||||
myValues.clear();
|
||||
for (QualifiedParamList nextParam : theParameters) {
|
||||
T nextList = newInstance();
|
||||
nextList.setValuesAsQueryTokens(nextParam);
|
||||
nextList.setValuesAsQueryTokens(theContext, theParamName, nextParam);
|
||||
myValues.add(nextList);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ package ca.uhn.fhir.rest.param;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
@ -37,11 +38,11 @@ abstract class BaseOrListParam<MT extends BaseOrListParam<?, ?>, PT extends IQue
|
|||
// }
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) {
|
||||
myList.clear();
|
||||
for (String next : theParameters) {
|
||||
PT nextParam = newInstance();
|
||||
nextParam.setValueAsQueryToken(theParameters.getQualifier(), next);
|
||||
nextParam.setValueAsQueryToken(theContext, theParamName, theParameters.getQualifier(), next);
|
||||
myList.add(nextParam);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
||||
/*
|
||||
|
@ -24,6 +26,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
/**
|
||||
* Base class for RESTful operation parameter types
|
||||
|
@ -32,6 +35,12 @@ abstract class BaseParam implements IQueryParameterType {
|
|||
|
||||
private Boolean myMissing;
|
||||
|
||||
abstract String doGetQueryParameterQualifier();
|
||||
|
||||
abstract String doGetValueAsQueryToken(FhirContext theContext);
|
||||
|
||||
abstract void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue);
|
||||
|
||||
/**
|
||||
* If set to non-null value, indicates that this parameter has been populated with a "[name]:missing=true" or "[name]:missing=false" vale instead of a normal value
|
||||
*/
|
||||
|
@ -39,7 +48,7 @@ abstract class BaseParam implements IQueryParameterType {
|
|||
public Boolean getMissing() {
|
||||
return myMissing;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final String getQueryParameterQualifier() {
|
||||
if (myMissing != null && myMissing.booleanValue()) {
|
||||
|
@ -48,10 +57,6 @@ abstract class BaseParam implements IQueryParameterType {
|
|||
return doGetQueryParameterQualifier();
|
||||
}
|
||||
|
||||
abstract String doGetQueryParameterQualifier();
|
||||
|
||||
abstract String doGetValueAsQueryToken(FhirContext theContext);
|
||||
|
||||
@Override
|
||||
public final String getValueAsQueryToken(FhirContext theContext) {
|
||||
if (myMissing != null) {
|
||||
|
@ -60,6 +65,13 @@ abstract class BaseParam implements IQueryParameterType {
|
|||
return doGetValueAsQueryToken(theContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this parameter type support chained parameters (only reference should return <code>true</code> for this)
|
||||
*/
|
||||
protected boolean isSupportsChain() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If set to non-null value, indicates that this parameter has been populated
|
||||
* with a "[name]:missing=true" or "[name]:missing=false" vale instead of a
|
||||
|
@ -74,17 +86,21 @@ abstract class BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
public final void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
public final void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
if (Constants.PARAMQUALIFIER_MISSING.equals(theQualifier)) {
|
||||
myMissing = "true".equals(theValue);
|
||||
doSetValueAsQueryToken(null, null);
|
||||
doSetValueAsQueryToken(theContext, theParamName, null, null);
|
||||
} else {
|
||||
if (isNotBlank(theQualifier) && theQualifier.charAt(0) == '.') {
|
||||
if (!isSupportsChain()) {
|
||||
String msg = theContext.getLocalizer().getMessage(BaseParam.class, "chainNotSupported", theParamName + theQualifier, theQualifier);
|
||||
throw new InvalidRequestException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
myMissing = null;
|
||||
doSetValueAsQueryToken(theQualifier, theValue);
|
||||
doSetValueAsQueryToken(theContext, theParamName, theQualifier, theValue);
|
||||
}
|
||||
}
|
||||
|
||||
abstract void doSetValueAsQueryToken(String theQualifier, String theValue);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -78,18 +78,18 @@ public class CompositeParam<A extends IQueryParameterType, B extends IQueryParam
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
if (isBlank(theValue)) {
|
||||
myLeftType.setValueAsQueryToken(theQualifier, "");
|
||||
myRightType.setValueAsQueryToken(theQualifier, "");
|
||||
myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, "");
|
||||
myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, "");
|
||||
} else {
|
||||
List<String> parts = ParameterUtil.splitParameterString(theValue, '$', false);
|
||||
if (parts.size() > 2) {
|
||||
throw new InvalidRequestException("Invalid value for composite parameter (only one '$' is valid for this parameter, others must be escaped). Value was: " + theValue);
|
||||
}
|
||||
myLeftType.setValueAsQueryToken(theQualifier, parts.get(0));
|
||||
myLeftType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(0));
|
||||
if (parts.size() > 1) {
|
||||
myRightType.setValueAsQueryToken(theQualifier, parts.get(1));
|
||||
myRightType.setValueAsQueryToken(theContext, theParamName, theQualifier, parts.get(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ public class DateParam extends BaseParamWithPrefix<DateParam> implements IQueryP
|
|||
* The string
|
||||
*/
|
||||
public DateParam(String theString) {
|
||||
setValueAsQueryToken(null, theString);
|
||||
setValueAsQueryToken(null, null, null, theString);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,7 +185,7 @@ public class DateParam extends BaseParamWithPrefix<DateParam> implements IQueryP
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
setValueAsString(theValue);
|
||||
}
|
||||
|
||||
|
@ -285,7 +285,7 @@ public class DateParam extends BaseParamWithPrefix<DateParam> implements IQueryP
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, QualifiedParamList theParameters) {
|
||||
setMissing(null);
|
||||
setPrefix(null);
|
||||
setValueAsString(null);
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.List;
|
|||
|
||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
@ -357,7 +358,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
|
||||
public void setValuesAsQueryTokens(FhirContext theContext, String theParamName, List<QualifiedParamList> theParameters) throws InvalidRequestException {
|
||||
|
||||
boolean haveHadUnqualifiedParameter = false;
|
||||
for (QualifiedParamList paramList : theParameters) {
|
||||
|
@ -376,7 +377,7 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
|
|||
param = param.replace(' ', '+');
|
||||
|
||||
DateParam parsed = new DateParam();
|
||||
parsed.setValueAsQueryToken(paramList.getQualifier(), param);
|
||||
parsed.setValueAsQueryToken(theContext, theParamName, paramList.getQualifier(), param);
|
||||
addParam(parsed);
|
||||
|
||||
if (parsed.getPrefix() == null) {
|
||||
|
|
|
@ -62,7 +62,7 @@ public class HasParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
String qualifier = defaultString(theQualifier);
|
||||
if (!qualifier.startsWith(":")) {
|
||||
throwInvalidSyntaxException(Constants.PARAM_HAS + qualifier);
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.apache.commons.lang3.builder.ToStringBuilder;
|
|||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
||||
public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQueryParameterType {
|
||||
|
@ -49,7 +48,7 @@ public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQu
|
|||
* A string value, e.g. ">5.0"
|
||||
*/
|
||||
public NumberParam(String theValue) {
|
||||
setValueAsQueryToken(null, theValue);
|
||||
setValueAsQueryToken(null, null, null, theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,7 +67,7 @@ public class NumberParam extends BaseParamWithPrefix<NumberParam> implements IQu
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
if (getMissing() != null && isBlank(theValue)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements
|
|||
* A quantity value (with no system or units), such as "100.0" or "gt4"
|
||||
*/
|
||||
public QuantityParam(String theQuantity) {
|
||||
setValueAsQueryToken(null, theQuantity);
|
||||
setValueAsQueryToken(null, null, null, theQuantity);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -193,7 +193,7 @@ public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements
|
|||
* A quantity value (with no system or units), such as <code>100</code>
|
||||
*/
|
||||
public QuantityParam(long theQuantity) {
|
||||
setValueAsQueryToken(null, Long.toString(theQuantity));
|
||||
setValueAsQueryToken(null, null, null, Long.toString(theQuantity));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -207,7 +207,7 @@ public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements
|
|||
* The unit code
|
||||
*/
|
||||
public QuantityParam(String theQuantity, String theSystem, String theUnits) {
|
||||
setValueAsQueryToken(null, theQuantity);
|
||||
setValueAsQueryToken(null, null, null, theQuantity);
|
||||
setSystem(theSystem);
|
||||
setUnits(theUnits);
|
||||
}
|
||||
|
@ -248,7 +248,7 @@ public class QuantityParam extends BaseParamWithPrefix<QuantityParam> implements
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
clear();
|
||||
|
||||
if (theValue == null) {
|
||||
|
|
|
@ -35,9 +35,9 @@ import ca.uhn.fhir.util.CoverageIgnore;
|
|||
|
||||
public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
||||
|
||||
private final IdDt myId = new IdDt();
|
||||
private String myChain;
|
||||
|
||||
private final IdDt myId = new IdDt();
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
|
@ -49,14 +49,14 @@ public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
|||
* Constructor
|
||||
*/
|
||||
public ReferenceParam(String theValue) {
|
||||
setValueAsQueryToken(null, theValue);
|
||||
setValueAsQueryToken(null, null, null, theValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ReferenceParam(String theChain, String theValue) {
|
||||
setValueAsQueryToken(null, theValue);
|
||||
setValueAsQueryToken(null, null, null, theValue);
|
||||
setChain(theChain);
|
||||
}
|
||||
|
||||
|
@ -72,118 +72,6 @@ public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
|||
setChain(theChain);
|
||||
}
|
||||
|
||||
public void setValue(String theValue) {
|
||||
myId.setValue(theValue);
|
||||
}
|
||||
|
||||
public String getChain() {
|
||||
return myChain;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Class<? extends IBaseResource> getResourceType(FhirContext theCtx) {
|
||||
if (isBlank(getResourceType())) {
|
||||
return null;
|
||||
}
|
||||
return theCtx.getResourceDefinition(getResourceType()).getImplementingClass();
|
||||
}
|
||||
|
||||
|
||||
public void setChain(String theChain) {
|
||||
myChain = theChain;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link DateParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public DateParam toDateParam(FhirContext theContext) {
|
||||
DateParam retVal = new DateParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link NumberParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public NumberParam toNumberParam(FhirContext theContext) {
|
||||
NumberParam retVal = new NumberParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link QuantityParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public QuantityParam toQuantityParam(FhirContext theContext) {
|
||||
QuantityParam retVal = new QuantityParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
if (isNotBlank(myChain)) {
|
||||
b.append("chain", myChain);
|
||||
}
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return myId.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link StringParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public StringParam toStringParam(FhirContext theContext) {
|
||||
StringParam retVal = new StringParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link TokenParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public TokenParam toTokenParam(FhirContext theContext) {
|
||||
TokenParam retVal = new TokenParam();
|
||||
retVal.setValueAsQueryToken(null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
String doGetQueryParameterQualifier() {
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
@ -201,10 +89,6 @@ public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
|||
return null;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myId.getResourceType();
|
||||
}
|
||||
|
||||
@Override
|
||||
String doGetValueAsQueryToken(FhirContext theContext) {
|
||||
if (isBlank(myId.getResourceType())) {
|
||||
|
@ -215,7 +99,7 @@ public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
String q = theQualifier;
|
||||
String resourceType = null;
|
||||
if (isNotBlank(q)) {
|
||||
|
@ -239,27 +123,148 @@ public class ReferenceParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public String getIdPart() {
|
||||
return myId.getIdPart();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public Long getIdPartAsLong() {
|
||||
return myId.getIdPartAsLong();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public BigDecimal getIdPartAsBigDecimal() {
|
||||
return myId.getIdPartAsBigDecimal();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public String getBaseUrl() {
|
||||
return myId.getBaseUrl();
|
||||
}
|
||||
|
||||
|
||||
public String getChain() {
|
||||
return myChain;
|
||||
}
|
||||
|
||||
|
||||
@CoverageIgnore
|
||||
public String getIdPart() {
|
||||
return myId.getIdPart();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public BigDecimal getIdPartAsBigDecimal() {
|
||||
return myId.getIdPartAsBigDecimal();
|
||||
}
|
||||
|
||||
@CoverageIgnore
|
||||
public Long getIdPartAsLong() {
|
||||
return myId.getIdPartAsLong();
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myId.getResourceType();
|
||||
}
|
||||
|
||||
public Class<? extends IBaseResource> getResourceType(FhirContext theCtx) {
|
||||
if (isBlank(getResourceType())) {
|
||||
return null;
|
||||
}
|
||||
return theCtx.getResourceDefinition(getResourceType()).getImplementingClass();
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return myId.getValue();
|
||||
}
|
||||
|
||||
public boolean hasResourceType() {
|
||||
return myId.hasResourceType();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isSupportsChain() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setChain(String theChain) {
|
||||
myChain = theChain;
|
||||
}
|
||||
|
||||
public void setValue(String theValue) {
|
||||
myId.setValue(theValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link DateParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public DateParam toDateParam(FhirContext theContext) {
|
||||
DateParam retVal = new DateParam();
|
||||
retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link NumberParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public NumberParam toNumberParam(FhirContext theContext) {
|
||||
NumberParam retVal = new NumberParam();
|
||||
retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link QuantityParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public QuantityParam toQuantityParam(FhirContext theContext) {
|
||||
QuantityParam retVal = new QuantityParam();
|
||||
retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
if (isNotBlank(myChain)) {
|
||||
b.append("chain", myChain);
|
||||
}
|
||||
b.append("value", getValue());
|
||||
return b.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link StringParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public StringParam toStringParam(FhirContext theContext) {
|
||||
StringParam retVal = new StringParam();
|
||||
retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new param containing the same value as this param, but with the type copnverted
|
||||
* to {@link TokenParam}. This is useful if you are using reference parameters and want to handle
|
||||
* chained parameters of different types in a single method.
|
||||
* <p>
|
||||
* See <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_operations.html#dynamic_chains">Dynamic Chains</a>
|
||||
* in the HAPI FHIR documentation for an example of how to use this method.
|
||||
* </p>
|
||||
*/
|
||||
public TokenParam toTokenParam(FhirContext theContext) {
|
||||
TokenParam retVal = new TokenParam();
|
||||
retVal.setValueAsQueryToken(theContext, null, null, getValueAsQueryToken(theContext));
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ public class StringParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
if (Constants.PARAMQUALIFIER_STRING_EXACT.equals(theQualifier)) {
|
||||
setExact(true);
|
||||
} else {
|
||||
|
|
|
@ -107,7 +107,7 @@ public class TokenParam extends BaseParam implements IQueryParameterType {
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theParameter) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theParameter) {
|
||||
setModifier(null);
|
||||
if (theQualifier != null) {
|
||||
TokenParamModifier modifier = TokenParamModifier.forValue(theQualifier);
|
||||
|
|
|
@ -57,7 +57,7 @@ public class UriParam extends BaseParam implements IQueryParameterType {
|
|||
}
|
||||
|
||||
@Override
|
||||
void doSetValueAsQueryToken(String theQualifier, String theValue) {
|
||||
void doSetValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
myQualifier = UriParamQualifierEnum.forValue(theQualifier);
|
||||
myValue = ParameterUtil.unescape(theValue);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.rest.server;
|
|||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
|
@ -651,13 +652,15 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
* This is basically the end of processing for a successful request, since the
|
||||
* method binding replies to the client and closes the response.
|
||||
*/
|
||||
resourceMethod.invokeServer(this, requestDetails);
|
||||
Closeable outputStreamOrWriter = (Closeable) resourceMethod.invokeServer(this, requestDetails);
|
||||
|
||||
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
|
||||
IServerInterceptor next = getInterceptors().get(i);
|
||||
next.processingCompletedNormally(requestDetails);
|
||||
}
|
||||
|
||||
outputStreamOrWriter.close();
|
||||
|
||||
} catch (NotModifiedException e) {
|
||||
|
||||
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
|
||||
|
@ -1141,24 +1144,19 @@ public class RestfulServer extends HttpServlet implements IRestfulServer<Servlet
|
|||
if (allowPrefer) {
|
||||
addContentLocationHeaders(theRequest, servletResponse, response, resourceName);
|
||||
}
|
||||
Writer writer;
|
||||
if (outcome != null) {
|
||||
ResponseEncoding encoding = RestfulServerUtils.determineResponseEncodingWithDefault(theRequest);
|
||||
servletResponse.setContentType(encoding.getResourceContentType());
|
||||
Writer writer = servletResponse.getWriter();
|
||||
writer = servletResponse.getWriter();
|
||||
IParser parser = encoding.getEncoding().newParser(getFhirContext());
|
||||
parser.setPrettyPrint(RestfulServerUtils.prettyPrintResponse(this, theRequest));
|
||||
try {
|
||||
outcome.execute(parser, writer);
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
outcome.execute(parser, writer);
|
||||
} else {
|
||||
servletResponse.setContentType(Constants.CT_TEXT_WITH_UTF8);
|
||||
Writer writer = servletResponse.getWriter();
|
||||
writer.close();
|
||||
writer = servletResponse.getWriter();
|
||||
}
|
||||
// getMethod().in
|
||||
return null;
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.rest.server.interceptor;
|
|||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -51,7 +52,8 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
|
|||
|
||||
@Override
|
||||
public boolean handleException(RequestDetails theRequestDetails, BaseServerResponseException theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
|
||||
handleException(theRequestDetails, theException);
|
||||
Closeable writer = (Closeable) handleException(theRequestDetails, theException);
|
||||
writer.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package ca.uhn.fhir.rest.server.servlet;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -52,13 +50,12 @@ public class ServletRestfulResponse extends RestfulResponse<ServletRequestDetail
|
|||
theHttpResponse.setStatus(stausCode);
|
||||
theHttpResponse.setContentType(contentType);
|
||||
if (bin.getContent() == null || bin.getContent().length == 0) {
|
||||
return null;
|
||||
return theHttpResponse.getOutputStream();
|
||||
} else {
|
||||
theHttpResponse.setContentLength(bin.getContent().length);
|
||||
ServletOutputStream oos = theHttpResponse.getOutputStream();
|
||||
oos.write(bin.getContent());
|
||||
oos.close();
|
||||
return null;
|
||||
return oos;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,9 +83,8 @@ public class ServletRestfulResponse extends RestfulResponse<ServletRequestDetail
|
|||
}
|
||||
|
||||
@Override
|
||||
public final Object sendWriterResponse(int status, String contentType, String charset, Writer writer) throws IOException {
|
||||
writer.close();
|
||||
return null;
|
||||
public final Object sendWriterResponse(int theStatus, String theContentType, String theCharset, Writer theWriter) throws IOException {
|
||||
return theWriter;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -36,6 +36,8 @@ ca.uhn.fhir.rest.method.SearchMethodBinding.idNullForCompartmentSearch=ID parame
|
|||
|
||||
ca.uhn.fhir.rest.method.SummaryEnumParameter.cantCombineText=Can not combine _summary=text with other values for _summary
|
||||
|
||||
ca.uhn.fhir.rest.param.BaseParam.chainNotSupported=Invalid search parameter "{0}". Parameter contains a chain ({1}) and chains are not supported for this parameter (chaining is only allowed on reference parameters)
|
||||
|
||||
ca.uhn.fhir.rest.param.ResourceParameter.invalidContentTypeInRequest=Incorrect Content-Type header value of "{0}" was provided in the request. A FHIR Content-Type is required for "{1}" operation
|
||||
ca.uhn.fhir.rest.param.ResourceParameter.noContentTypeInRequest=No Content-Type header was provided in the request. This is required for "{0}" operation
|
||||
ca.uhn.fhir.rest.param.ResourceParameter.failedToParseRequest=Failed to parse request body as {0} resource. Error was: {1}
|
||||
|
|
|
@ -927,7 +927,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
public <R extends IBaseResource> Set<Long> processMatchUrl(String theMatchUrl, Class<R> theResourceType) {
|
||||
RuntimeResourceDefinition resourceDef = getContext().getResourceDefinition(theResourceType);
|
||||
|
||||
SearchParameterMap paramMap = translateMatchUrl(theMatchUrl, resourceDef);
|
||||
SearchParameterMap paramMap = translateMatchUrl(myContext, theMatchUrl, resourceDef);
|
||||
paramMap.setPersistResults(false);
|
||||
|
||||
if (paramMap.isEmpty() && paramMap.getLastUpdated() == null) {
|
||||
|
@ -1688,7 +1688,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
return parameters;
|
||||
}
|
||||
|
||||
public static SearchParameterMap translateMatchUrl(String theMatchUrl, RuntimeResourceDefinition resourceDef) {
|
||||
public static SearchParameterMap translateMatchUrl(FhirContext theContext, String theMatchUrl, RuntimeResourceDefinition resourceDef) {
|
||||
SearchParameterMap paramMap = new SearchParameterMap();
|
||||
List<NameValuePair> parameters = translateMatchUrl(theMatchUrl);
|
||||
|
||||
|
@ -1723,7 +1723,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Can not have more than 2 " + Constants.PARAM_LASTUPDATED + " parameter repetitions");
|
||||
} else {
|
||||
DateRangeParam p1 = new DateRangeParam();
|
||||
p1.setValuesAsQueryTokens(paramList);
|
||||
p1.setValuesAsQueryTokens(theContext, nextParamName, paramList);
|
||||
paramMap.setLastUpdated(p1);
|
||||
}
|
||||
}
|
||||
|
@ -1731,7 +1731,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
if (Constants.PARAM_HAS.equals(nextParamName)) {
|
||||
IQueryParameterAnd<?> param = MethodUtil.parseQueryParams(RestSearchParameterTypeEnum.HAS, nextParamName, paramList);
|
||||
IQueryParameterAnd<?> param = MethodUtil.parseQueryParams(theContext, RestSearchParameterTypeEnum.HAS, nextParamName, paramList);
|
||||
paramMap.add(nextParamName, param);
|
||||
continue;
|
||||
}
|
||||
|
@ -1753,7 +1753,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
throw new InvalidRequestException("Invalid parameter chain: " + nextParamName + paramList.get(0).getQualifier());
|
||||
}
|
||||
IQueryParameterAnd<?> type = newInstanceAnd(nextParamName);
|
||||
type.setValuesAsQueryTokens((paramList));
|
||||
type.setValuesAsQueryTokens(theContext, nextParamName, (paramList));
|
||||
paramMap.add(nextParamName, type);
|
||||
} else if (nextParamName.startsWith("_")) {
|
||||
// ignore these since they aren't search params (e.g. _sort)
|
||||
|
@ -1763,7 +1763,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
|
||||
}
|
||||
|
||||
IQueryParameterAnd<?> param = MethodUtil.parseQueryParams(paramDef, nextParamName, paramList);
|
||||
IQueryParameterAnd<?> param = MethodUtil.parseQueryParams(theContext, paramDef, nextParamName, paramList);
|
||||
paramMap.add(nextParamName, param);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ import ca.uhn.fhir.rest.param.ParamPrefixEnum;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
|
||||
public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subscription>implements IFhirResourceDaoSubscription<Subscription> {
|
||||
|
||||
|
@ -148,7 +147,7 @@ public class FhirResourceDaoSubscriptionDstu2 extends FhirResourceDaoDstu2<Subsc
|
|||
private int pollForNewUndeliveredResources(SubscriptionTable theSubscriptionTable) {
|
||||
Subscription subscription = toResource(Subscription.class, theSubscriptionTable.getSubscriptionResource(), false);
|
||||
RuntimeResourceDefinition resourceDef = validateCriteriaAndReturnResourceDefinition(subscription);
|
||||
SearchParameterMap criteriaUrl = translateMatchUrl(subscription.getCriteria(), resourceDef);
|
||||
SearchParameterMap criteriaUrl = translateMatchUrl(getContext(), subscription.getCriteria(), resourceDef);
|
||||
|
||||
criteriaUrl = new SearchParameterMap();
|
||||
long start = theSubscriptionTable.getMostRecentMatch().getTime();
|
||||
|
|
|
@ -617,11 +617,11 @@ public class SearchBuilder {
|
|||
}
|
||||
|
||||
chainValue = new ReferenceParam();
|
||||
chainValue.setValueAsQueryToken(qualifier, resourceId);
|
||||
chainValue.setValueAsQueryToken(myContext, theParamName, qualifier, resourceId);
|
||||
((ReferenceParam) chainValue).setChain(remainingChain);
|
||||
} else if (isMeta) {
|
||||
IQueryParameterType type = BaseHapiFhirDao.newInstanceType(chain);
|
||||
type.setValueAsQueryToken(qualifier, resourceId);
|
||||
type.setValueAsQueryToken(myContext, theParamName, qualifier, resourceId);
|
||||
chainValue = type;
|
||||
} else {
|
||||
chainValue = toParameterType(param, qualifier, resourceId);
|
||||
|
@ -1998,7 +1998,7 @@ public class SearchBuilder {
|
|||
private IQueryParameterType toParameterType(RuntimeSearchParam theParam, String theQualifier, String theValueAsQueryToken) {
|
||||
IQueryParameterType qp = toParameterType(theParam);
|
||||
|
||||
qp.setValueAsQueryToken(theQualifier, theValueAsQueryToken); // aaaa
|
||||
qp.setValueAsQueryToken(myContext, theParam.getName(), theQualifier, theValueAsQueryToken);
|
||||
return qp;
|
||||
}
|
||||
|
||||
|
|
|
@ -152,7 +152,7 @@ public class FhirResourceDaoSubscriptionDstu3 extends FhirResourceDaoDstu3<Subsc
|
|||
private int pollForNewUndeliveredResources(SubscriptionTable theSubscriptionTable) {
|
||||
Subscription subscription = toResource(Subscription.class, theSubscriptionTable.getSubscriptionResource(), false);
|
||||
RuntimeResourceDefinition resourceDef = validateCriteriaAndReturnResourceDefinition(subscription);
|
||||
SearchParameterMap criteriaUrl = translateMatchUrl(subscription.getCriteria(), resourceDef);
|
||||
SearchParameterMap criteriaUrl = translateMatchUrl(getContext(), subscription.getCriteria(), resourceDef);
|
||||
|
||||
criteriaUrl = new SearchParameterMap();
|
||||
long start = theSubscriptionTable.getMostRecentMatch().getTime();
|
||||
|
|
|
@ -27,7 +27,7 @@ public class BaseFhirDaoTest extends BaseJpaTest {
|
|||
|
||||
@Test
|
||||
public void testTranslateMatchUrl() {
|
||||
SearchParameterMap match = BaseHapiFhirDao.translateMatchUrl("Condition?patient=304&_lastUpdated=>2011-01-01T11:12:21.0000Z", ourCtx.getResourceDefinition(Condition.class));
|
||||
SearchParameterMap match = BaseHapiFhirDao.translateMatchUrl(ourCtx, "Condition?patient=304&_lastUpdated=>2011-01-01T11:12:21.0000Z", ourCtx.getResourceDefinition(Condition.class));
|
||||
assertEquals("2011-01-01T11:12:21.0000Z", match.getLastUpdated().getLowerBound().getValueAsString());
|
||||
assertEquals(ReferenceParam.class, match.get("patient").get(0).get(0).getClass());
|
||||
assertEquals("304", ((ReferenceParam)match.get("patient").get(0).get(0)).getIdPart());
|
||||
|
|
|
@ -16,7 +16,7 @@ public class CodingDtTest {
|
|||
@Test
|
||||
public void testTokenNoSystem() {
|
||||
CodingDt dt = new CodingDt();
|
||||
dt.setValueAsQueryToken(null, "c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "c");
|
||||
|
||||
assertEquals(null, dt.getSystem().getValueAsString());
|
||||
assertEquals("c", dt.getCode().getValue());
|
||||
|
@ -26,7 +26,7 @@ public class CodingDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValue() {
|
||||
CodingDt dt = new CodingDt();
|
||||
dt.setValueAsQueryToken(null, "a|b|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "a|b|c");
|
||||
|
||||
assertEquals("a", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getCode().getValue());
|
||||
|
@ -36,7 +36,7 @@ public class CodingDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValueAndNoSystem() {
|
||||
CodingDt dt = new CodingDt();
|
||||
dt.setValueAsQueryToken(null, "|b\\|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "|b\\|c");
|
||||
|
||||
assertEquals("", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getCode().getValue());
|
||||
|
@ -50,7 +50,7 @@ public class CodingDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValueAndNoSystemAndBeLenient() {
|
||||
CodingDt dt = new CodingDt();
|
||||
dt.setValueAsQueryToken(null, "|b|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "|b|c");
|
||||
|
||||
assertEquals("", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getCode().getValue());
|
||||
|
|
|
@ -15,7 +15,7 @@ public class IdentifierDtTest {
|
|||
@Test
|
||||
public void testTokenNoSystem() {
|
||||
IdentifierDt dt = new IdentifierDt();
|
||||
dt.setValueAsQueryToken(null, "c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "c");
|
||||
|
||||
assertEquals(null, dt.getSystem().getValueAsString());
|
||||
assertEquals("c", dt.getValue().getValue());
|
||||
|
@ -25,7 +25,7 @@ public class IdentifierDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValue() {
|
||||
IdentifierDt dt = new IdentifierDt();
|
||||
dt.setValueAsQueryToken(null, "a|b|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "a|b|c");
|
||||
|
||||
assertEquals("a", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getValue().getValue());
|
||||
|
@ -35,7 +35,7 @@ public class IdentifierDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValueAndNoSystem() {
|
||||
IdentifierDt dt = new IdentifierDt();
|
||||
dt.setValueAsQueryToken(null, "|b\\|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "|b\\|c");
|
||||
|
||||
assertEquals("", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getValue().getValue());
|
||||
|
@ -49,7 +49,7 @@ public class IdentifierDtTest {
|
|||
@Test
|
||||
public void testTokenWithPipeInValueAndNoSystemAndBeLenient() {
|
||||
IdentifierDt dt = new IdentifierDt();
|
||||
dt.setValueAsQueryToken(null, "|b|c");
|
||||
dt.setValueAsQueryToken(ourCtx, null, null, "|b|c");
|
||||
|
||||
assertEquals("", dt.getSystem().getValueAsString());
|
||||
assertEquals("b|c", dt.getValue().getValue());
|
||||
|
|
|
@ -13,6 +13,7 @@ import java.util.TimeZone;
|
|||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
|
@ -183,10 +184,12 @@ public class DateRangeParamTest {
|
|||
if (theUpper != null) {
|
||||
tokens.add(QualifiedParamList.singleton(null, theUpper));
|
||||
}
|
||||
p.setValuesAsQueryTokens(tokens);
|
||||
p.setValuesAsQueryTokens(ourCtx, null, tokens);
|
||||
return p;
|
||||
}
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu1();
|
||||
|
||||
public static Date parse(String theString) throws ParseException {
|
||||
return ourFmt.parse(theString);
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ public class QuantityParamTest {
|
|||
@Test
|
||||
public void testFull() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "<5.4|http://unitsofmeasure.org|mg");
|
||||
p.setValueAsQueryToken(ourCtx, null, null, "<5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(QuantityCompararatorEnum.LESSTHAN,p.getComparator());
|
||||
assertEquals("5.4", p.getValue().toPlainString());
|
||||
assertEquals("http://unitsofmeasure.org", p.getSystem());
|
||||
|
@ -26,7 +26,7 @@ public class QuantityParamTest {
|
|||
@Test
|
||||
public void testApproximate() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "~5.4|http://unitsofmeasure.org|mg");
|
||||
p.setValueAsQueryToken(ourCtx, null, null, "~5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(null,p.getComparator());
|
||||
assertEquals(true, p.isApproximate());
|
||||
assertEquals("5.4", p.getValue().toPlainString());
|
||||
|
@ -39,7 +39,7 @@ public class QuantityParamTest {
|
|||
@Test
|
||||
public void testNoQualifier() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "5.4|http://unitsofmeasure.org|mg");
|
||||
p.setValueAsQueryToken(ourCtx, null, null, "5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(null, p.getComparator());
|
||||
assertEquals("5.4", p.getValue().toPlainString());
|
||||
assertEquals("http://unitsofmeasure.org", p.getSystem());
|
||||
|
@ -51,7 +51,7 @@ public class QuantityParamTest {
|
|||
@Test
|
||||
public void testNoUnits() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "5.4");
|
||||
p.setValueAsQueryToken(ourCtx, null, null, "5.4");
|
||||
assertEquals(null, p.getComparator());
|
||||
assertEquals("5.4", p.getValue().toPlainString());
|
||||
assertEquals(null, p.getSystem());
|
||||
|
|
|
@ -5,6 +5,7 @@ import static org.junit.Assert.*;
|
|||
import org.junit.AfterClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class ReferenceParamTest {
|
||||
|
@ -13,7 +14,7 @@ public class ReferenceParamTest {
|
|||
public void testWithResourceTypeAsQualifier() {
|
||||
|
||||
ReferenceParam rp = new ReferenceParam();
|
||||
rp.setValueAsQueryToken(":Location", "123");
|
||||
rp.setValueAsQueryToken(ourCtx, null, ":Location", "123");
|
||||
assertEquals("Location", rp.getResourceType());
|
||||
assertEquals("123", rp.getIdPart());
|
||||
|
||||
|
@ -23,12 +24,13 @@ public class ReferenceParamTest {
|
|||
public void testWithResourceType() {
|
||||
|
||||
ReferenceParam rp = new ReferenceParam();
|
||||
rp.setValueAsQueryToken(null, "Location/123");
|
||||
rp.setValueAsQueryToken(ourCtx, null, null, "Location/123");
|
||||
assertEquals("Location", rp.getResourceType());
|
||||
assertEquals("123", rp.getIdPart());
|
||||
|
||||
}
|
||||
|
||||
private FhirContext ourCtx = FhirContext.forDstu1();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
@ -57,7 +59,7 @@ public class TokenOrListParamTest {
|
|||
@Test
|
||||
public void testParseExcaped() {
|
||||
TokenOrListParam params = new TokenOrListParam();
|
||||
params.setValuesAsQueryTokens(QualifiedParamList.singleton("system|code-include-but-not-end-with-comma\\,suffix"));
|
||||
params.setValuesAsQueryTokens(ourCtx, null, QualifiedParamList.singleton("system|code-include-but-not-end-with-comma\\,suffix"));
|
||||
|
||||
assertEquals(1, params.getListAsCodings().size());
|
||||
assertEquals("system", params.getListAsCodings().get(0).getSystemElement().getValue());
|
||||
|
@ -65,6 +67,8 @@ public class TokenOrListParamTest {
|
|||
}
|
||||
|
||||
|
||||
private static FhirContext ourCtx = FhirContext.forDstu1();
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() {
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.rest.server;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -44,7 +45,7 @@ public class StringParameterTest {
|
|||
assertEquals(":contains", sp.getQueryParameterQualifier());
|
||||
|
||||
sp = new StringParam("VAL");
|
||||
sp.setValueAsQueryToken(":contains", "VAL");
|
||||
sp.setValueAsQueryToken(ourCtx, null, ":contains", "VAL");
|
||||
assertEquals(true, sp.isContains());
|
||||
assertEquals("VAL", sp.getValue());
|
||||
}
|
||||
|
@ -54,7 +55,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?plain=aaa");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -63,7 +64,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?plain=BBB");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -76,7 +77,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=aaa");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -85,7 +86,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=AAA");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -94,7 +95,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str:exact=BBB");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -107,7 +108,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?ccc:exact=aaa");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -120,7 +121,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=aaa");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
|
@ -130,7 +131,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=AAA");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
|
@ -140,7 +141,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=BBB");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -153,7 +154,7 @@ public class StringParameterTest {
|
|||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?str=aaa&_format=xml&_pretty=true");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
|
|
@ -389,7 +389,7 @@ public class IdentifierDt
|
|||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public void setValueAsQueryToken(String theQualifier, String theValue) {
|
||||
public void setValueAsQueryToken(FhirContext theContext, String theParamName, String theQualifier, String theValue) {
|
||||
int barIndex = theValue.indexOf('|');
|
||||
if (barIndex != -1) {
|
||||
setSystem(new UriDt(theValue.substring(0, barIndex)));
|
||||
|
|
|
@ -0,0 +1,142 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.hl7.fhir.dstu3.model.HumanName;
|
||||
import org.hl7.fhir.dstu3.model.OperationOutcome;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
|
||||
public class SearchDstu3Test {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static FhirContext ourCtx = FhirContext.forDstu3();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchDstu3Test.class);
|
||||
private static int ourPort;
|
||||
private static Server ourServer;
|
||||
private static String ourLastMethod;
|
||||
private static TokenAndListParam ourIdentifiers;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourLastMethod = null;
|
||||
ourIdentifiers = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchNormal() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("search", ourLastMethod);
|
||||
|
||||
assertEquals("foo", ourIdentifiers.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0).getSystem());
|
||||
assertEquals("bar", ourIdentifiers.getValuesAsQueryTokens().get(0).getValuesAsQueryTokens().get(0).getValue());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithInvalidChain() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier.chain=foo%7Cbar");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
ourLog.info(responseContent);
|
||||
assertEquals(400, status.getStatusLine().getStatusCode());
|
||||
|
||||
OperationOutcome oo = (OperationOutcome) ourCtx.newXmlParser().parseResource(responseContent);
|
||||
assertEquals("Invalid search parameter \"identifier.chain\". Parameter contains a chain (.chain) and chains are not supported for this parameter (chaining is only allowed on reference parameters)", oo.getIssueFirstRep().getDiagnostics());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClassClearContext() throws Exception {
|
||||
ourServer.stop();
|
||||
TestUtil.clearAllStaticFieldsForUnitTest();
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer(ourCtx);
|
||||
servlet.setPagingProvider(new FifoMemoryPagingProvider(10));
|
||||
|
||||
servlet.setResourceProviders(patientProvider);
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
ourServer.start();
|
||||
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
builder.setConnectionManager(connectionManager);
|
||||
ourClient = builder.build();
|
||||
|
||||
}
|
||||
|
||||
public static class DummyPatientResourceProvider implements IResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IBaseResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Search()
|
||||
public List search(
|
||||
@OptionalParam(name=Patient.SP_IDENTIFIER) TokenAndListParam theIdentifiers
|
||||
) {
|
||||
ourLastMethod = "search";
|
||||
ourIdentifiers = theIdentifiers;
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
retVal.add((Patient) new Patient().addName(new HumanName().addFamily("FAMILY")).setId("1"));
|
||||
return retVal;
|
||||
}
|
||||
//@formatter:on
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -147,6 +147,16 @@
|
|||
a NullPointerException to be thrown. Now it will trigger a warning, or throw a
|
||||
DataFormatException if the StrictErrorHandler is configured on the parser.
|
||||
</action>
|
||||
<action type="fix">
|
||||
Calling a HAPI server URL with a chain on a parameter that shouldn't accept
|
||||
chains (e.g.
|
||||
<![CDATA[<code>GET [base]/Patient?name.foo=smith</code>]]>)
|
||||
did not return an error and instead just ignored the chained part
|
||||
and treated the parameter as though it did not have the chain. This
|
||||
led to confusing and potentially unsafe behaviour. This has been
|
||||
corrected to return an error to the client. Thanks to
|
||||
Kevin Tallevi for finding this!
|
||||
</action>
|
||||
</release>
|
||||
<release version="2.0" date="2016-08-30">
|
||||
<action type="fix">
|
||||
|
|
Loading…
Reference in New Issue