Clean up resource parameter handling

This commit is contained in:
jamesagnew 2015-05-31 19:38:01 -04:00
parent 8f27462db7
commit 064f113133
30 changed files with 332 additions and 357 deletions

View File

@ -85,10 +85,12 @@ public class RestfulClientFactory implements IRestfulClientFactory {
myContext = theFhirContext;
}
@Override
public int getConnectionRequestTimeout() {
return myConnectionRequestTimeout;
}
@Override
public int getConnectTimeout() {
return myConnectTimeout;
}
@ -274,6 +276,7 @@ public class RestfulClientFactory implements IRestfulClientFactory {
myHttpClient = null;
}
@SuppressWarnings("unchecked")
void validateServerBase(String theServerBase, HttpClient theHttpClient, BaseClient theClient) {
GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this);

View File

@ -98,6 +98,51 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
myParameters = MethodUtil.getResourceParameters(theContext, theMethod, theProvider, getResourceOperationType());
}
protected IParser createAppropriateParserForParsingResponse(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode) {
EncodingEnum encoding = EncodingEnum.forContentType(theResponseMimeType);
if (encoding == null) {
NonFhirResponseException ex = NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
populateException(ex, theResponseReader);
throw ex;
}
IParser parser = encoding.newParser(getContext());
return parser;
}
protected IParser createAppropriateParserForParsingServerRequest(Request theRequest) {
String contentTypeHeader = theRequest.getServletRequest().getHeader("content-type");
EncodingEnum encoding;
if (isBlank(contentTypeHeader)) {
encoding = EncodingEnum.XML;
} else {
int semicolon = contentTypeHeader.indexOf(';');
if (semicolon != -1) {
contentTypeHeader = contentTypeHeader.substring(0, semicolon);
}
encoding = EncodingEnum.forContentType(contentTypeHeader);
}
if (encoding == null) {
throw new InvalidRequestException("Request contins non-FHIR conent-type header value: " + contentTypeHeader);
}
IParser parser = encoding.newParser(getContext());
return parser;
}
protected Object[] createParametersForServerRequest(Request theRequest, byte[] theRequestContents) {
Object[] params = new Object[getParameters().size()];
for (int i = 0; i < getParameters().size(); i++) {
IParameter param = getParameters().get(i);
if (param == null) {
continue;
}
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, theRequestContents, this);
}
return params;
}
public List<Class<?>> getAllowableParamAnnotations() {
return null;
}
@ -128,6 +173,10 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return myParameters;
}
public Object getProvider() {
return myProvider;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public Set<Include> getRequestIncludesFromParams(Object[] params) {
if (params == null || params.length == 0)
@ -163,16 +212,14 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return null;
}
public Object getProvider() {
return myProvider;
}
/**
* Returns the name of the resource this method handles, or <code>null</code> if this method is not resource
* specific
*/
public abstract String getResourceName();
public abstract RestfulOperationTypeEnum getResourceOperationType();
/**
* Returns the value of {@link #getResourceOperationType()} or {@link #getSystemOperationType()} or {@link #getOtherOperationType()}
*/
@ -192,8 +239,6 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return null;
}
public abstract RestfulOperationTypeEnum getResourceOperationType();
public abstract RestfulOperationSystemEnum getSystemOperationType();
public abstract boolean incomingServerRequestMatchesMethod(Request theRequest);
@ -202,56 +247,6 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
public abstract void invokeServer(RestfulServer theServer, Request theRequest) throws BaseServerResponseException, IOException;
/** For unit tests only */
public void setParameters(List<IParameter> theParameters) {
myParameters = theParameters;
}
protected IParser createAppropriateParserForParsingResponse(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode) {
EncodingEnum encoding = EncodingEnum.forContentType(theResponseMimeType);
if (encoding == null) {
NonFhirResponseException ex = NonFhirResponseException.newInstance(theResponseStatusCode, theResponseMimeType, theResponseReader);
populateException(ex, theResponseReader);
throw ex;
}
IParser parser = encoding.newParser(getContext());
return parser;
}
protected IParser createAppropriateParserForParsingServerRequest(Request theRequest) {
String contentTypeHeader = theRequest.getServletRequest().getHeader("content-type");
EncodingEnum encoding;
if (isBlank(contentTypeHeader)) {
encoding = EncodingEnum.XML;
} else {
int semicolon = contentTypeHeader.indexOf(';');
if (semicolon != -1) {
contentTypeHeader = contentTypeHeader.substring(0, semicolon);
}
encoding = EncodingEnum.forContentType(contentTypeHeader);
}
if (encoding == null) {
throw new InvalidRequestException("Request contins non-FHIR conent-type header value: " + contentTypeHeader);
}
IParser parser = encoding.newParser(getContext());
return parser;
}
protected Object[] createParametersForServerRequest(Request theRequest, IBaseResource theResource) {
Object[] params = new Object[getParameters().size()];
for (int i = 0; i < getParameters().size(); i++) {
IParameter param = getParameters().get(i);
if (param == null) {
continue;
}
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, theResource);
}
return params;
}
protected Object invokeServerMethod(Object[] theMethodParams) {
try {
Method method = getMethod();
@ -267,6 +262,11 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
}
protected byte[] loadRequestContents(Request theRequest) throws IOException {
byte[] requestContents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream());
return requestContents;
}
protected BaseServerResponseException processNon2xxResponseAndReturnExceptionToThrow(int theStatusCode, String theResponseMimeType, Reader theResponseReader) {
BaseServerResponseException ex;
switch (theStatusCode) {
@ -300,6 +300,11 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return ex;
}
/** For unit tests only */
public void setParameters(List<IParameter> theParameters) {
myParameters = theParameters;
}
@SuppressWarnings("unchecked")
public static BaseMethodBinding<?> bindMethod(Method theMethod, FhirContext theContext, Object theProvider) {
Read read = theMethod.getAnnotation(Read.class);
@ -470,6 +475,52 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
// return sm;
}
private static void populateException(BaseServerResponseException theEx, Reader theResponseReader) {
try {
String responseText = IOUtils.toString(theResponseReader);
theEx.setResponseBody(responseText);
} catch (IOException e) {
ourLog.debug("Failed to read response", e);
}
}
private static String toLogString(Class<?> theType) {
if (theType == null) {
return null;
}
return theType.getCanonicalName();
}
protected static IBundleProvider toResourceList(Object response) throws InternalErrorException {
if (response == null) {
return BundleProviders.newEmptyList();
} else if (response instanceof IBundleProvider) {
return (IBundleProvider) response;
} else if (response instanceof IResource) {
return BundleProviders.newList((IResource) response);
} else if (response instanceof Collection) {
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (Object next : ((Collection<?>) response)) {
retVal.add((IBaseResource) next);
}
return BundleProviders.newList(retVal);
} else {
throw new InternalErrorException("Unexpected return type: " + response.getClass().getCanonicalName());
}
}
private static boolean verifyIsValidResourceReturnType(Class<?> theReturnType) {
if (theReturnType == null) {
return false;
}
if (!IBaseResource.class.isAssignableFrom(theReturnType)) {
return false;
}
return true;
// boolean retVal = Modifier.isAbstract(theReturnType.getModifiers()) == false;
// return retVal;
}
public static boolean verifyMethodHasZeroOrOneOperationAnnotation(Method theNextMethod, Object... theAnnotations) {
Object obj1 = null;
for (Object object : theAnnotations) {
@ -493,50 +544,4 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return true;
}
private static void populateException(BaseServerResponseException theEx, Reader theResponseReader) {
try {
String responseText = IOUtils.toString(theResponseReader);
theEx.setResponseBody(responseText);
} catch (IOException e) {
ourLog.debug("Failed to read response", e);
}
}
private static String toLogString(Class<?> theType) {
if (theType == null) {
return null;
}
return theType.getCanonicalName();
}
private static boolean verifyIsValidResourceReturnType(Class<?> theReturnType) {
if (theReturnType == null) {
return false;
}
if (!IBaseResource.class.isAssignableFrom(theReturnType)) {
return false;
}
return true;
// boolean retVal = Modifier.isAbstract(theReturnType.getModifiers()) == false;
// return retVal;
}
protected static IBundleProvider toResourceList(Object response) throws InternalErrorException {
if (response == null) {
return BundleProviders.newEmptyList();
} else if (response instanceof IBundleProvider) {
return (IBundleProvider) response;
} else if (response instanceof IResource) {
return BundleProviders.newList((IResource) response);
} else if (response instanceof Collection) {
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (Object next : ((Collection<?>) response)) {
retVal.add((IBaseResource) next);
}
return BundleProviders.newList(retVal);
} else {
throw new InternalErrorException("Unexpected return type: " + response.getClass().getCanonicalName());
}
}
}

View File

@ -20,30 +20,21 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.IParser;
@ -56,7 +47,6 @@ import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<MethodOutcome> {
@ -149,24 +139,14 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
@Override
public void invokeServer(RestfulServer theServer, Request theRequest) throws BaseServerResponseException, IOException {
IBaseResource resource;
if (requestContainsResource()) {
resource = parseIncomingServerResource(theRequest);
if (theServer.getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
TagList tagList = new TagList();
for (Enumeration<String> enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) {
String nextTagComplete = enumeration.nextElement();
MethodUtil.parseTagValue(tagList, nextTagComplete);
}
if (tagList.isEmpty() == false) {
((IResource)resource).getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
}
}
} else {
resource = null;
}
byte[] requestContents = loadRequestContents(theRequest);
// if (requestContainsResource()) {
// requestContents = parseIncomingServerResource(theRequest);
// } else {
// requestContents = null;
// }
Object[] params = createParametersForServerRequest(theRequest, resource);
Object[] params = createParametersForServerRequest(theRequest, requestContents);
addParametersForServerRequest(theRequest, params);
HttpServletResponse servletResponse = theRequest.getServletResponse();
@ -274,73 +254,8 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
return myReturnVoid;
}
/**
* @throws IOException
*/
protected IBaseResource parseIncomingServerResource(Request theRequest) throws IOException {
Reader requestReader;
EncodingEnum encoding = RestfulServerUtils.determineRequestEncodingNoDefault(theRequest);
if (encoding == null) {
String ctValue = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
if (ctValue != null) {
if (ctValue.startsWith("application/x-www-form-urlencoded")) {
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "invalidContentTypeInRequest", ctValue, getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
}
}
if (isBlank(ctValue)) {
/*
* If the client didn't send a content type, try to guess
*/
requestReader = theRequest.getServletRequest().getReader();
String body = IOUtils.toString(requestReader);
encoding = MethodUtil.detectEncodingNoDefault(body);
if (encoding == null) {
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "noContentTypeInRequest", getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
} else {
requestReader = new StringReader(body);
}
} else {
String msg = getContext().getLocalizer().getMessage(BaseOutcomeReturningMethodBinding.class, "invalidContentTypeInRequest", ctValue, getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
}
} else {
requestReader = theRequest.getServletRequest().getReader();
}
IParser parser = encoding.newParser(getContext());
Class<? extends IBaseResource> wantedResourceType = requestContainsResourceType();
IBaseResource retVal;
if (wantedResourceType != null) {
retVal = parser.parseResource(wantedResourceType, requestReader);
} else {
retVal = parser.parseResource(requestReader);
}
retVal.setId(theRequest.getId());
return retVal;
}
protected abstract Set<RequestTypeEnum> provideAllowableRequestTypes();
/**
* Subclasses may override if the incoming request should not contain a resource
*/
protected boolean requestContainsResource() {
return true;
}
/**
* Subclasses may override to provide a specific resource type that this method wants as a parameter
*/
protected Class<? extends IBaseResource> requestContainsResourceType() {
return null;
}
protected void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingEnum theEncodingNotNull, HttpServletResponse theResponse, Request theRequest)
throws IOException {
theResponse.setStatus(theE.getStatusCode());

View File

@ -20,12 +20,9 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
@ -34,14 +31,12 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ResourceParameter;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOutcomeReturningMethodBinding {
private int myResourceParameterIndex;
private String myResourceName;
private boolean myBinary;
private Class<? extends IBaseResource> myResourceType;
private Integer myIdParamIndex;
@ -64,10 +59,6 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
providerResourceType = ((IResourceProvider) theProvider).getResourceType();
}
if (IBaseBinary.class.isAssignableFrom(providerResourceType)) {
myBinary = true;
}
myResourceType = resourceParameter.getResourceType();
if (Modifier.isAbstract(myResourceType.getModifiers())) {
myResourceType = providerResourceType;
@ -88,27 +79,6 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
}
@Override
protected Class<? extends IBaseResource> requestContainsResourceType() {
return myResourceType;
}
@Override
protected IBaseResource parseIncomingServerResource(Request theRequest) throws IOException {
if (myBinary) {
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
byte[] contents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream());
IBaseBinary binary = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance();
binary.setContentType(ct);
binary.setContent(contents);
return binary;
} else {
return super.parseIncomingServerResource(theRequest);
}
}
@Override
protected void addParametersForServerRequest(Request theRequest, Object[] theParams) {
if (myIdParamIndex != null) {

View File

@ -20,7 +20,7 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.IOException;
import java.io.Reader;
@ -37,20 +37,18 @@ import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.model.api.Include;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
import ca.uhn.fhir.rest.param.ParameterUtil;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IBundleProvider;
@ -244,14 +242,14 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
requestIsBrowser = true;
}
Object requestObject = parseRequestObject(theRequest);
byte[] requestContents = loadRequestContents(theRequest);
// Method params
Object[] params = new Object[getParameters().size()];
for (int i = 0; i < getParameters().size(); i++) {
IParameter param = getParameters().get(i);
if (param != null) {
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, requestObject);
params[i] = param.translateQueryParametersIntoServerArgument(theRequest, requestContents, this);
}
}
@ -392,18 +390,6 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
return true;
}
/**
* Subclasses may override
*
* @param theRequest
* The incoming request
* @throws IOException
* Subclasses may throw this in the event of an IO exception
*/
protected Object parseRequestObject(Request theRequest) throws IOException {
return null;
}
protected void setResourceName(String theResourceName) {
myResourceName = theResourceName;
}

View File

@ -51,7 +51,7 @@ class ConditionalParamBinder implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
if (myOperationType == RestfulOperationTypeEnum.CREATE) {
String retVal = theRequest.getServletRequest().getHeader(Constants.HEADER_IF_NONE_EXIST);

View File

@ -54,7 +54,7 @@ public class CountParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
String[] sinceParams = theRequest.getParameters().remove(Constants.PARAM_COUNT);
if (sinceParams != null) {
if (sinceParams.length > 0) {

View File

@ -20,13 +20,10 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
@ -56,18 +53,6 @@ public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
return Collections.singleton(RequestTypeEnum.POST);
}
@Override
protected IBaseResource parseIncomingServerResource(Request theRequest) throws IOException {
IBaseResource retVal = super.parseIncomingServerResource(theRequest);
if (theRequest.getId() != null && theRequest.getId().hasIdPart()) {
retVal.setId(theRequest.getId());
}
return retVal;
}
@Override
protected BaseHttpClientInvocation createClientInvocation(Object[] theArgs, IResource theResource) {
FhirContext context = getContext();

View File

@ -81,11 +81,6 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
}
@Override
protected boolean requestContainsResource() {
return false;
}
@Override
protected boolean allowVoidReturnType() {
return true;

View File

@ -66,7 +66,7 @@ public class DynamicSearchParameter implements IParameter {
@SuppressWarnings("unchecked")
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
SearchParameterMap retVal = new SearchParameterMap();
for (String next : theRequest.getParameters().keySet()) {

View File

@ -45,9 +45,10 @@ public interface IParameter {
* The incoming request object
* @param theRequestContents
* The parsed contents of the incoming request. E.g. if the request was an HTTP POST with a resource in the body, this argument would contain the parsed {@link IResource} instance.
* @param theMethodBinding TODO
* @return Returns the argument object as it will be passed to the {@link IResourceProvider} method.
*/
Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException;
Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException;
void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType);

View File

@ -1,7 +1,6 @@
package ca.uhn.fhir.rest.method;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.IOException;
import java.io.PushbackReader;
@ -25,10 +24,10 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseMetaType;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IAnyResource;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -76,6 +75,7 @@ import ca.uhn.fhir.rest.param.ReferenceAndListParam;
import ca.uhn.fhir.rest.param.ResourceParameter;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.TokenAndListParam;
import ca.uhn.fhir.rest.param.TransactionParameter;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
@ -411,7 +411,7 @@ public class MethodUtil {
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());
}
param = new ResourceParameter((Class<? extends IResource>) parameterType);
param = new ResourceParameter((Class<? extends IResource>) parameterType, theProvider);
} else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) {
param = new NullParameter();
} else if (nextAnnotation instanceof ServerBase) {
@ -423,12 +423,12 @@ public class MethodUtil {
} else if (nextAnnotation instanceof Sort) {
param = new SortParameter();
} else if (nextAnnotation instanceof TransactionParam) {
param = new TransactionParamBinder(theContext);
param = new TransactionParameter(theContext);
} else if (nextAnnotation instanceof ConditionalUrlParam) {
param = new ConditionalParamBinder(theRestfulOperationTypeEnum);
} else if (nextAnnotation instanceof OperationParam) {
Operation op = theMethod.getAnnotation(Operation.class);
param = new OperationParamBinder(op.name(), (OperationParam) nextAnnotation);
param = new OperationParameter(op.name(), (OperationParam) nextAnnotation);
} else {
continue;
}

View File

@ -47,7 +47,7 @@ class NarrativeModeParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
String val = theRequest.getServletRequest().getParameter(Constants.PARAM_NARRATIVE);
if (val != null) {
try {

View File

@ -39,7 +39,7 @@ class NullParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
// nothing
return null;
}

View File

@ -20,11 +20,8 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@ -46,13 +43,10 @@ import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.Operation;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
@ -196,20 +190,6 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
return retVal;
}
@Override
protected Object parseRequestObject(Request theRequest) throws IOException {
EncodingEnum encoding = RestfulServerUtils.determineRequestEncoding(theRequest);
IParser parser = encoding.newParser(getContext());
BufferedReader requestReader = theRequest.getServletRequest().getReader();
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
return null;
}
Class<? extends IBaseResource> wantedResourceType = getContext().getResourceDefinition("Parameters").getImplementingClass();
return parser.parseResource(wantedResourceType, requestReader);
}
public static BaseHttpClientInvocation createOperationInvocation(FhirContext theContext, String theResourceName, String theId, String theOperationName, IBaseParameters theInput,
boolean theUseHttpGet) {
StringBuilder b = new StringBuilder();

View File

@ -44,11 +44,14 @@ import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.OperationParam;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.param.CollectionBinder;
import ca.uhn.fhir.rest.param.ResourceParameter;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
class OperationParamBinder implements IParameter {
class OperationParameter implements IParameter {
private final String myName;
private Class<?> myParameterType;
@ -56,7 +59,7 @@ class OperationParamBinder implements IParameter {
private Class<? extends Collection> myInnerCollectionType;
private final String myOperationName;
OperationParamBinder(String theOperationName, OperationParam theAnnotation) {
OperationParameter(String theOperationName, OperationParam theAnnotation) {
myOperationName = theOperationName;
myName = theAnnotation.name();
}
@ -109,7 +112,7 @@ class OperationParamBinder implements IParameter {
@SuppressWarnings("unchecked")
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
List<Object> matchingParamValues = new ArrayList<Object>();
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
@ -125,16 +128,21 @@ class OperationParamBinder implements IParameter {
}
} else {
HapiLocalizer localizer = theRequest.getServer().getFhirContext().getLocalizer();
String msg = localizer.getMessage(OperationParamBinder.class, "urlParamNotPrimitive", myOperationName, myName);
String msg = localizer.getMessage(OperationParameter.class, "urlParamNotPrimitive", myOperationName, myName);
throw new MethodNotAllowedException(msg, RequestTypeEnum.POST);
}
}
} else if (theRequestContents == null) {
return null;
} else {
FhirContext ctx = theRequest.getServer().getFhirContext();
IBaseResource requestContents = (IBaseResource) theRequestContents;
if (theRequest.getRequestType() == RequestTypeEnum.GET) {
return null;
}
Class<? extends IBaseResource> wantedResourceType = theMethodBinding.getContext().getResourceDefinition("Parameters").getImplementingClass();
IBaseResource requestContents = ResourceParameter.loadResourceFromRequest(theRequest, theRequestContents, theMethodBinding, wantedResourceType);
RuntimeResourceDefinition def = ctx.getResourceDefinition(requestContents);
BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter");

View File

@ -43,7 +43,7 @@ class ServerBaseParamBinder implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
return theRequest.getFhirServerBase();
}

View File

@ -43,7 +43,7 @@ class ServletRequestParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
return theRequest.getServletRequest();
}

View File

@ -43,7 +43,7 @@ class ServletResponseParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
return theRequest.getServletResponse();
}

View File

@ -54,7 +54,7 @@ class SinceParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
String[] sinceParams = theRequest.getParameters().remove(Constants.PARAM_SINCE);
if (sinceParams != null) {
if (sinceParams.length > 0) {

View File

@ -65,7 +65,7 @@ public class SortParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT)) {
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT_ASC)) {
if (!theRequest.getParameters().containsKey(Constants.PARAM_SORT_DESC)) {

View File

@ -20,9 +20,8 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.IdentityHashMap;
import java.util.List;
@ -44,7 +43,8 @@ import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.method.TransactionParamBinder.ParamStyle;
import ca.uhn.fhir.rest.param.TransactionParameter;
import ca.uhn.fhir.rest.param.TransactionParameter.ParamStyle;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
@ -60,13 +60,13 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
myTransactionParamIndex = -1;
int index = 0;
for (IParameter next : getParameters()) {
if (next instanceof TransactionParamBinder) {
if (next instanceof TransactionParameter) {
if (myTransactionParamIndex != -1) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " has multiple parameters annotated with the @" + TransactionParam.class + " annotation, exactly one is required for @" + Transaction.class
+ " methods");
}
myTransactionParamIndex = index;
myTransactionParamStyle = ((TransactionParamBinder) next).getParamStyle();
myTransactionParamStyle = ((TransactionParameter) next).getParamStyle();
}
index++;
}
@ -182,11 +182,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
return retVal;
}
@Override
protected Object parseRequestObject(Request theRequest) throws IOException {
return null; // This is parsed in TransactionParamBinder
}
public static BaseHttpClientInvocation createTransactionInvocation(Bundle theBundle, FhirContext theContext) {
return new HttpPostClientInvocation(theContext, theBundle);
}

View File

@ -31,6 +31,7 @@ import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.IParameter;
import ca.uhn.fhir.rest.method.QualifiedParamList;
import ca.uhn.fhir.rest.method.Request;
@ -129,7 +130,7 @@ public abstract class BaseQueryParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException {
List<QualifiedParamList> paramList = new ArrayList<QualifiedParamList>();
String name = getName();

View File

@ -20,26 +20,69 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.http.entity.ContentType;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.IParameter;
import ca.uhn.fhir.rest.method.MethodUtil;
import ca.uhn.fhir.rest.method.Request;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class ResourceParameter implements IParameter {
private Class<? extends IResource> myResourceType;
private boolean myBinary;
private Class<? extends IBaseResource> myResourceType;
public ResourceParameter(Class<? extends IResource> theParameterType) {
public ResourceParameter(Class<? extends IResource> theParameterType, Object theProvider) {
myResourceType = theParameterType;
myBinary = IBaseBinary.class.isAssignableFrom(theParameterType);
Class<? extends IBaseResource> providerResourceType = null;
if (theProvider instanceof IResourceProvider) {
providerResourceType = ((IResourceProvider) theProvider).getResourceType();
}
if (Modifier.isAbstract(myResourceType.getModifiers()) && providerResourceType != null) {
myResourceType = providerResourceType;
}
}
public Class<? extends IBaseResource> getResourceType() {
return myResourceType;
}
@Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
// ignore for now
}
@Override
@ -49,18 +92,110 @@ public class ResourceParameter implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
IResource resource = (IResource) theRequestContents;
return resource;
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
if (myBinary) {
FhirContext ctx = theRequest.getServer().getFhirContext();
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
IBaseBinary binary = (IBaseBinary) ctx.getResourceDefinition("Binary").newInstance();
binary.setContentType(ct);
binary.setContent(theRequestContents);
return binary;
}
public Class<? extends IResource> getResourceType() {
return myResourceType;
IBaseResource retVal = loadResourceFromRequest(theRequest, theRequestContents, theMethodBinding, myResourceType);
return retVal;
}
@Override
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
// ignore for now
public static IBaseResource loadResourceFromRequest(Request theRequest, byte[] theRequestContents, BaseMethodBinding<?> theMethodBinding, Class<? extends IBaseResource> theResourceType) {
FhirContext ctx = theRequest.getServer().getFhirContext();
final Charset charset = determineRequestCharset(theRequest);
Reader requestReader = createRequestReader(theRequestContents, charset);
EncodingEnum encoding = RestfulServerUtils.determineRequestEncodingNoDefault(theRequest);
if (encoding == null) {
String ctValue = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
if (ctValue != null) {
if (ctValue.startsWith("application/x-www-form-urlencoded")) {
String msg = theRequest.getServer().getFhirContext().getLocalizer().getMessage(ResourceParameter.class, "invalidContentTypeInRequest", ctValue, theMethodBinding.getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
}
}
if (isBlank(ctValue)) {
/*
* If the client didn't send a content type, try to guess
*/
String body;
try {
body = IOUtils.toString(requestReader);
} catch (IOException e) {
// This shouldn't happen since we're reading from a byte array..
throw new InternalErrorException(e);
}
encoding = MethodUtil.detectEncodingNoDefault(body);
if (encoding == null) {
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "noContentTypeInRequest", theMethodBinding.getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
} else {
requestReader = new InputStreamReader(new ByteArrayInputStream(theRequestContents), charset);
}
} else {
String msg = ctx.getLocalizer().getMessage(ResourceParameter.class, "invalidContentTypeInRequest", ctValue, theMethodBinding.getResourceOrSystemOperationType());
throw new InvalidRequestException(msg);
}
}
IParser parser = encoding.newParser(ctx);
IBaseResource retVal;
if (theResourceType != null) {
retVal = parser.parseResource(theResourceType, requestReader);
} else {
retVal = parser.parseResource(requestReader);
}
if (theRequest.getId() != null && theRequest.getId().hasIdPart()) {
retVal.setId(theRequest.getId());
}
if (theRequest.getServer().getFhirContext().getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
TagList tagList = new TagList();
for (Enumeration<String> enumeration = theRequest.getServletRequest().getHeaders(Constants.HEADER_CATEGORY); enumeration.hasMoreElements();) {
String nextTagComplete = enumeration.nextElement();
MethodUtil.parseTagValue(tagList, nextTagComplete);
}
if (tagList.isEmpty() == false) {
((IResource)retVal).getResourceMetadata().put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
}
}
return retVal;
}
static Reader createRequestReader(byte[] theRequestContents, Charset charset) {
Reader requestReader = new InputStreamReader(new ByteArrayInputStream(theRequestContents), charset);
return requestReader;
}
static Reader createRequestReader(Request theRequest, byte[] theRequestContents) {
return createRequestReader(theRequestContents, determineRequestCharset(theRequest));
}
static Charset determineRequestCharset(Request theRequest) {
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
Charset charset = null;
if (isNotBlank(ct)) {
ContentType parsedCt = ContentType.parse(ct);
charset = parsedCt.getCharset();
}
if (charset == null) {
charset = Charset.forName("UTF-8");
}
return charset;
}
}

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.rest.method;
package ca.uhn.fhir.rest.param;
/*
* #%L
@ -20,8 +20,7 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
@ -39,18 +38,21 @@ import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.IParameter;
import ca.uhn.fhir.rest.method.Request;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
class TransactionParamBinder implements IParameter {
public class TransactionParameter implements IParameter {
private FhirContext myContext;
private ParamStyle myParamStyle;
private Class<? extends IBaseResource> myResourceBundleType;
public TransactionParamBinder(FhirContext theContext) {
public TransactionParameter(FhirContext theContext) {
myContext = theContext;
}
@ -96,19 +98,14 @@ class TransactionParamBinder implements IParameter {
}
@Override
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
public Object translateQueryParametersIntoServerArgument(Request theRequest, byte[] theRequestContents, BaseMethodBinding<?> theMethodBinding) throws InternalErrorException, InvalidRequestException {
// TODO: don't use a default encoding, just fail!
EncodingEnum encoding = RestfulServerUtils.determineRequestEncoding(theRequest);
IParser parser = encoding.newParser(myContext);
BufferedReader reader;
try {
reader = theRequest.getServletRequest().getReader();
} catch (IOException e) {
throw new InternalErrorException("Failed to read incoming payload", e);
}
Reader reader = ResourceParameter.createRequestReader(theRequest, theRequestContents);
switch (myParamStyle) {
case DSTU1_BUNDLE: {
@ -137,7 +134,7 @@ class TransactionParamBinder implements IParameter {
return myParamStyle;
}
enum ParamStyle {
public enum ParamStyle {
/** Old style bundle (defined in hapi-fhir-base) */
DSTU1_BUNDLE,
/** New style bundle (defined in hapi-fhir-structures-* as a resource definition itself */

View File

@ -13,11 +13,9 @@ ca.uhn.fhir.rest.client.GenericClient.cannotDetermineResourceTypeFromUri=Unable
ca.uhn.fhir.rest.client.RestfulClientFactory.failedToRetrieveConformance=Failed to retrieve the server's metadata statement during client initialization. URL used was: {0}
ca.uhn.fhir.rest.client.RestfulClientFactory.wrongVersionInConformance=The server at base URL "{0}" returned a conformance statement indicating that it supports FHIR version "{1}" which corresponds to {2}, but this client is configured to use {3} (via the FhirContext).
ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding.noContentTypeInRequest=No Content-Type header was provided in the request. This is required for "{0}" operation
ca.uhn.fhir.rest.method.BaseOutcomeReturningMethodBinding.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.method.OperationMethodBinding.methodNotSupported=HTTP Method {0} is not allowed for this operation. Allowed method(s): {1}
ca.uhn.fhir.rest.method.OperationParamBinder.urlParamNotPrimitive=Can not invoke operation {0} using HTTP GET because parameter {1} is not a primitive datatype
ca.uhn.fhir.rest.method.OperationParameter.urlParamNotPrimitive=Can not invoke operation {0} using HTTP GET because parameter {1} is not a primitive datatype
ca.uhn.fhir.rest.method.IncludeParameter.invalidIncludeNameInRequest=Invalid {2} parameter value: "{0}". Valid values are: {1}
ca.uhn.fhir.rest.method.IncludeParameter.orIncludeInRequest='OR' query parameters (values containing ',') are not supported in _include parameters
@ -25,6 +23,9 @@ ca.uhn.fhir.rest.method.SearchMethodBinding.invalidSpecialParamName=Method [{0}]
ca.uhn.fhir.rest.method.SearchMethodBinding.idWithoutCompartment=Method [{0}] in provider [{1}] has an @IdParam parameter. This is only allowable for compartment search (e.g. @Search(compartment="foo") )
ca.uhn.fhir.rest.method.SearchMethodBinding.idNullForCompartmentSearch=ID parameter can not be null or empty for compartment search
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.parser.ParserState.wrongResourceTypeFound=Incorrect resource type found, expected "{0}" but found "{1}"
ca.uhn.fhir.rest.server.RestfulServer.getPagesNonHttpGet=Requests for _getpages must use HTTP GET

View File

@ -128,3 +128,4 @@ local.properties
.texlipse
/target/
/target/

View File

@ -27,7 +27,7 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
import ca.uhn.fhir.rest.client.exceptions.FhirClientInappropriateForServerException;
import ca.uhn.fhir.rest.server.Constants;
public class ClientServerValidationTestDstu {
@ -70,7 +70,7 @@ public class ClientServerValidationTestDstu {
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
IGenericClient client = myCtx.newRestfulGenericClient("http://foo");
// don't load the conformance until the first time the client is actually used
@ -98,11 +98,11 @@ public class ClientServerValidationTestDstu {
when(myHttpClient.execute(capt.capture())).thenReturn(myHttpResponse);
myCtx.getRestfulClientFactory().setServerValidationModeEnum(ServerValidationModeEnum.ONCE);
myCtx.getRestfulClientFactory().setServerValidationMode(ServerValidationModeEnum.ONCE);
try {
myCtx.newRestfulGenericClient("http://foo").read(new UriDt("http://foo/Patient/1"));
fail();
} catch (FhirClientConnectionException e) {
} catch (FhirClientInappropriateForServerException e) {
assertThat(e.toString(), containsString("The server at base URL \"http://foo/metadata\" returned a conformance statement indicating that it supports FHIR version \"0.4.0\" which corresponds to DSTU2, but this client is configured to use DSTU1 (via the FhirContext)"));
}
}

View File

@ -78,7 +78,7 @@ public class BaseDateTimeDtTest {
*/
ourDefaultLocale = Locale.getDefault();
Locale[] available = Locale.getAvailableLocales();
Locale[] available = { Locale.CANADA, Locale.GERMANY, Locale.TAIWAN };
Locale newLocale = available[(int) (Math.random() * available.length)];
Locale.setDefault(newLocale);

View File

@ -1,6 +1,5 @@
package ca.uhn.fhir.validation;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.util.Collections;
@ -15,7 +14,6 @@ import org.hl7.fhir.instance.model.StructureDefinition;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.utils.WorkerContext;
import org.hl7.fhir.instance.validation.ValidationMessage;
import org.hl7.fhir.utilities.xml.XMLUtil;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
@ -28,7 +26,6 @@ public class InstanceValidator {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(InstanceValidator.class);
private FhirContext myCtx;
private DocumentBuilderFactory myDocBuilderFactory;
InstanceValidator(FhirContext theContext) {