> getAllHeaders();
+
+ /**
+ * Get the response status information reason phrase associated with the response.
+ * @return the reason phrase.
+ */
+ public String getStatusInfo();
+
+ /**
+ * Returna reader for the response entity
+ */
+ public Reader createReader() throws IOException;
+
+ /**
+ * Read the message entity input stream as an InputStream.
+ */
+ public InputStream readEntity() throws IOException;
+
+ /**
+ * Close the response
+ */
+ public void close();
+
+ /**
+ * Buffer the message entity data.
+ *
+ * In case the message entity is backed by an unconsumed entity input stream,
+ * all the bytes of the original entity input stream are read and stored in a
+ * local buffer. The original entity input stream is consumed.
+ *
+ *
+ * In case the response entity instance is not backed by an unconsumed input stream
+ * an invocation of {@code bufferEntity} method is ignored and the method returns.
+ *
+ *
+ * This operation is idempotent, i.e. it can be invoked multiple times with
+ * the same effect which also means that calling the {@code bufferEntity()}
+ * method on an already buffered (and thus closed) message instance is legal
+ * and has no further effect.
+ *
+ *
+ * Buffering the message entity data allows for multiple invocations of
+ * {@code readEntity(...)} methods on the response instance.
+ */
+ void bufferEntitity() throws IOException;
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java
index ab54bc0bd35..7b7bc2039ba 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/api/IRestfulClient.java
@@ -21,7 +21,6 @@ package ca.uhn.fhir.rest.client.api;
*/
-import org.apache.http.client.HttpClient;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
@@ -51,7 +50,7 @@ public interface IRestfulClient {
* Do not call this method in client code. It is a part of the internal HAPI API and
* is subject to change!
*/
- HttpClient getHttpClient();
+ IHttpClient getHttpClient();
/**
* Base URL for the server, with no trailing "/"
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java
index 05fa7f91f57..00b3d8826bd 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java
@@ -25,10 +25,10 @@ import java.io.UnsupportedEncodingException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@@ -52,7 +52,7 @@ public class BasicAuthInterceptor implements IClientInterceptor {
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
String authorizationUnescaped = StringUtils.defaultString(myUsername) + ":" + StringUtils.defaultString(myPassword);
String encoded;
try {
@@ -64,7 +64,7 @@ public class BasicAuthInterceptor implements IClientInterceptor {
}
@Override
- public void interceptResponse(HttpResponse theResponse) throws IOException {
+ public void interceptResponse(IHttpResponse theResponse) throws IOException {
// nothing
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java
index 437067a5628..4dc60bde084 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java
@@ -21,10 +21,10 @@ package ca.uhn.fhir.rest.client.interceptor;
*/
import org.apache.commons.lang3.Validate;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.util.CoverageIgnore;
@@ -71,12 +71,12 @@ public class BearerTokenAuthInterceptor implements IClientInterceptor {
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
theRequest.addHeader(Constants.HEADER_AUTHORIZATION, (Constants.HEADER_AUTHORIZATION_VALPREFIX_BEARER + myToken));
}
@Override
- public void interceptResponse(HttpResponse theResponse) {
+ public void interceptResponse(IHttpResponse theResponse) {
// nothing
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java
index 4077b1a6e3a..1d1978631e1 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java
@@ -20,10 +20,9 @@ package ca.uhn.fhir.rest.client.interceptor;
* #L%
*/
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
-
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
/**
* Client interceptor which simply captures request and response objects and stores them so that they can be inspected after a client
@@ -31,8 +30,8 @@ import ca.uhn.fhir.rest.client.IClientInterceptor;
*/
public class CapturingInterceptor implements IClientInterceptor {
- private HttpRequestBase myLastRequest;
- private HttpResponse myLastResponse;
+ private IHttpRequest myLastRequest;
+ private IHttpResponse myLastResponse;
/**
* Clear the last request and response values
@@ -42,21 +41,21 @@ public class CapturingInterceptor implements IClientInterceptor {
myLastResponse = null;
}
- public HttpRequestBase getLastRequest() {
+ public IHttpRequest getLastRequest() {
return myLastRequest;
}
- public HttpResponse getLastResponse() {
+ public IHttpResponse getLastResponse() {
return myLastResponse;
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
myLastRequest = theRequest;
}
@Override
- public void interceptResponse(HttpResponse theRequest) {
+ public void interceptResponse(IHttpResponse theRequest) {
myLastResponse = theRequest;
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java
index 7e5658c33a6..c7221b4cf5e 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java
@@ -20,10 +20,9 @@ package ca.uhn.fhir.rest.client.interceptor;
* #L%
*/
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
-
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.Constants;
/**
@@ -42,12 +41,12 @@ public class CookieInterceptor implements IClientInterceptor {
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
theRequest.addHeader(Constants.HEADER_COOKIE, sessionCookie); //$NON-NLS-1$
}
@Override
- public void interceptResponse(HttpResponse theResponse) {
+ public void interceptResponse(IHttpResponse theResponse) {
// nothing
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java
index 69e46eb5222..e325f551024 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java
@@ -20,22 +20,19 @@ package ca.uhn.fhir.rest.client.interceptor;
* #L%
*/
-import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.OutputStream;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
-import org.apache.http.Header;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpEntityEnclosingRequest;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.entity.HttpEntityWrapper;
import org.slf4j.Logger;
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
public class LoggingInterceptor implements IClientInterceptor {
@@ -74,59 +71,39 @@ public class LoggingInterceptor implements IClientInterceptor {
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
if (myLogRequestSummary) {
myLog.info("Client request: {}", theRequest);
}
if (myLogRequestHeaders) {
- StringBuilder b = new StringBuilder();
- for (int i = 0; i < theRequest.getAllHeaders().length; i++) {
- Header next = theRequest.getAllHeaders()[i];
- b.append(next.getName() + ": " + next.getValue());
- if (i + 1 < theRequest.getAllHeaders().length) {
- b.append('\n');
- }
- }
+ StringBuilder b = headersToString(theRequest.getAllHeaders());
myLog.info("Client request headers:\n{}", b.toString());
}
if (myLogRequestBody) {
- if (theRequest instanceof HttpEntityEnclosingRequest) {
- HttpEntity entity = ((HttpEntityEnclosingRequest) theRequest).getEntity();
- if (entity.isRepeatable()) {
- try {
- String content = IOUtils.toString(entity.getContent());
- myLog.info("Client request body:\n{}", content);
- } catch (IllegalStateException e) {
- myLog.warn("Failed to replay request contents (during logging attempt, actual FHIR call did not fail)", e);
- } catch (IOException e) {
- myLog.warn("Failed to replay request contents (during logging attempt, actual FHIR call did not fail)", e);
- }
+ try {
+ String content = theRequest.getRequestBodyFromStream();
+ if (content != null) {
+ myLog.info("Client request body:\n{}", content);
}
+ } catch (IllegalStateException e) {
+ myLog.warn("Failed to replay request contents (during logging attempt, actual FHIR call did not fail)", e);
+ } catch (IOException e) {
+ myLog.warn("Failed to replay request contents (during logging attempt, actual FHIR call did not fail)", e);
}
}
-
}
@Override
- public void interceptResponse(HttpResponse theResponse) throws IOException {
+ public void interceptResponse(IHttpResponse theResponse) throws IOException {
if (myLogResponseSummary) {
- String message = "HTTP " + theResponse.getStatusLine().getStatusCode() + " " + theResponse.getStatusLine().getReasonPhrase();
+ String message = "HTTP " + theResponse.getStatus() + " " + theResponse.getStatusInfo();
myLog.info("Client response: {}", message);
}
if (myLogResponseHeaders) {
- StringBuilder b = new StringBuilder();
- if (theResponse.getAllHeaders() != null) {
- for (int i = 0; i < theResponse.getAllHeaders().length; i++) {
- Header next = theResponse.getAllHeaders()[i];
- b.append(next.getName() + ": " + next.getValue());
- if (i + 1 < theResponse.getAllHeaders().length) {
- b.append('\n');
- }
- }
- }
+ StringBuilder b = headersToString(theResponse.getAllHeaders());
// if (theResponse.getEntity() != null && theResponse.getEntity().getContentEncoding() != null) {
// Header next = theResponse.getEntity().getContentEncoding();
// b.append(next.getName() + ": " + next.getValue());
@@ -143,23 +120,46 @@ public class LoggingInterceptor implements IClientInterceptor {
}
if (myLogResponseBody) {
- HttpEntity respEntity = theResponse.getEntity();
- if (respEntity != null) {
- final byte[] bytes;
- try {
- bytes = IOUtils.toByteArray(respEntity.getContent());
- } catch (IllegalStateException e) {
- throw new InternalErrorException(e);
- }
-
- myLog.info("Client response body:\n{}", new String(bytes, "UTF-8"));
- theResponse.setEntity(new MyEntityWrapper(respEntity, bytes));
- } else {
- myLog.info("Client response body: (none)");
+ theResponse.bufferEntitity();
+ InputStream respEntity = null;
+ try {
+ respEntity = theResponse.readEntity();
+ if (respEntity != null) {
+ final byte[] bytes;
+ try {
+ bytes = IOUtils.toByteArray(respEntity);
+ } catch (IllegalStateException e) {
+ throw new InternalErrorException(e);
+ }
+ myLog.info("Client response body:\n{}", new String(bytes, "UTF-8"));
+ } else {
+ myLog.info("Client response body: (none)");
+ }
+ } finally {
+ IOUtils.closeQuietly(respEntity);
}
}
}
+ private StringBuilder headersToString(Map> theHeaders) {
+ StringBuilder b = new StringBuilder();
+ if (theHeaders != null && !theHeaders.isEmpty()) {
+ Iterator nameEntries = theHeaders.keySet().iterator();
+ while(nameEntries.hasNext()) {
+ String key = nameEntries.next();
+ Iterator values = theHeaders.get(key).iterator();
+ while(values.hasNext()) {
+ String value = values.next();
+ b.append(key + ": " + value);
+ if (nameEntries.hasNext() || values.hasNext()) {
+ b.append('\n');
+ }
+ }
+ }
+ }
+ return b;
+ }
+
/**
* Sets a logger to use to log messages (default is a logger with this class' name). This can be used to redirect
* logs to a differently named logger instead.
@@ -214,25 +214,4 @@ public class LoggingInterceptor implements IClientInterceptor {
myLogResponseSummary = theValue;
}
- private static class MyEntityWrapper extends HttpEntityWrapper {
-
- private byte[] myBytes;
-
- public MyEntityWrapper(HttpEntity theWrappedEntity, byte[] theBytes) {
- super(theWrappedEntity);
- myBytes = theBytes;
- }
-
- @Override
- public InputStream getContent() throws IOException {
- return new ByteArrayInputStream(myBytes);
- }
-
- @Override
- public void writeTo(OutputStream theOutstream) throws IOException {
- theOutstream.write(myBytes);
- }
-
- }
-
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java
index 72e21414f22..fbf4764c7b1 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java
@@ -22,10 +22,9 @@ package ca.uhn.fhir.rest.client.interceptor;
import java.io.IOException;
-import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpRequestBase;
-
import ca.uhn.fhir.rest.client.IClientInterceptor;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.client.api.IHttpResponse;
/**
* HTTP interceptor to be used for adding HTTP headers containing user identifying info for auditing purposes to the request
@@ -48,14 +47,14 @@ public class UserInfoInterceptor implements IClientInterceptor {
}
@Override
- public void interceptRequest(HttpRequestBase theRequest) {
+ public void interceptRequest(IHttpRequest theRequest) {
if(myUserId != null) theRequest.addHeader(HEADER_USER_ID, myUserId);
if(myUserName != null) theRequest.addHeader(HEADER_USER_NAME, myUserName);
if(myAppName != null) theRequest.addHeader(HEADER_APPLICATION_NAME, myAppName);
}
@Override
- public void interceptResponse(HttpResponse theResponse) throws IOException {
+ public void interceptResponse(IHttpResponse theResponse) throws IOException {
// nothing
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/AddTagsMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/AddTagsMethodBinding.java
index 4984e9c79e5..d833212cec5 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/AddTagsMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/AddTagsMethodBinding.java
@@ -28,8 +28,8 @@ import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
class AddTagsMethodBinding extends BaseAddOrDeleteTagsMethodBinding {
- public AddTagsMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider, AddTags theAnnotation) {
- super(theMethod, theConetxt, theProvider, theAnnotation.type());
+ public AddTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, AddTags theAnnotation) {
+ super(theMethod, theContext, theProvider, theAnnotation.type());
}
@Override
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseAddOrDeleteTagsMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseAddOrDeleteTagsMethodBinding.java
index 1a5cf33c0b6..ff1ae23510b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseAddOrDeleteTagsMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseAddOrDeleteTagsMethodBinding.java
@@ -56,8 +56,8 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding
private String myResourceName;
private Integer myTagListParamIndex;
- public BaseAddOrDeleteTagsMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider, Class extends IResource> theTypeFromMethodAnnotation) {
- super(theMethod, theConetxt, theProvider);
+ public BaseAddOrDeleteTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, Class extends IResource> theTypeFromMethodAnnotation) {
+ super(theMethod, theContext, theProvider);
if (theProvider instanceof IResourceProvider) {
myType = ((IResourceProvider) theProvider).getResourceType();
@@ -69,7 +69,7 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding
throw new ConfigurationException("Method '" + theMethod.getName() + "' does not specify a resource type, but has an @" + IdParam.class.getSimpleName() + " parameter. Please specity a resource type in the method annotation on this method");
}
- myResourceName = theConetxt.getResourceDefinition(myType).getName();
+ myResourceName = theContext.getResourceDefinition(myType).getName();
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext());
myVersionIdParamIndex = MethodUtil.findVersionIdParameterIndex(theMethod);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseHttpClientInvocationWithContents.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseHttpClientInvocationWithContents.java
index 4fc82f143e5..02469a665dc 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseHttpClientInvocationWithContents.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseHttpClientInvocationWithContents.java
@@ -23,19 +23,10 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
* #L%
*/
-import java.io.UnsupportedEncodingException;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.entity.AbstractHttpEntity;
-import org.apache.http.entity.ByteArrayEntity;
-import org.apache.http.message.BasicNameValuePair;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -47,10 +38,11 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
-import ca.uhn.fhir.rest.server.Constants;
+import ca.uhn.fhir.rest.client.api.IHttpClient;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
-import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
/**
* @author James Agnew
@@ -63,7 +55,6 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
private final BundleTypeEnum myBundleType;
private final String myContents;
private boolean myContentsIsBundle;
- private final FhirContext myContext;
private Map> myIfNoneExistParams;
private String myIfNoneExistString;
private boolean myOmitResourceId = false;
@@ -74,7 +65,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
private final String myUrlPath;
public BaseHttpClientInvocationWithContents(FhirContext theContext, Bundle theBundle) {
- myContext = theContext;
+ super(theContext);
myResource = null;
myTagList = null;
myUrlPath = null;
@@ -84,8 +75,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundleType = null;
}
- public BaseHttpClientInvocationWithContents(FhirContext theContext, IBaseResource theResource, Map> theParams, String... theUrlPath) {
- myContext = theContext;
+ public BaseHttpClientInvocationWithContents(FhirContext theContext, IBaseResource theResource,
+ Map> theParams, String... theUrlPath) {
+ super(theContext);
myResource = theResource;
myTagList = null;
myUrlPath = StringUtils.join(theUrlPath, '/');
@@ -98,8 +90,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, IBaseResource theResource, String theUrlPath) {
- super();
- myContext = theContext;
+ super(theContext);
myResource = theResource;
myUrlPath = theUrlPath;
myTagList = null;
@@ -109,8 +100,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundleType = null;
}
- public BaseHttpClientInvocationWithContents(FhirContext theContext, List extends IBaseResource> theResources, BundleTypeEnum theBundleType) {
- myContext = theContext;
+ public BaseHttpClientInvocationWithContents(FhirContext theContext, List extends IBaseResource> theResources,
+ BundleTypeEnum theBundleType) {
+ super(theContext);
myResource = null;
myTagList = null;
myUrlPath = null;
@@ -120,8 +112,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundleType = theBundleType;
}
- public BaseHttpClientInvocationWithContents(FhirContext theContext, Map> theParams, String... theUrlPath) {
- myContext = theContext;
+ public BaseHttpClientInvocationWithContents(FhirContext theContext, Map> theParams,
+ String... theUrlPath) {
+ super(theContext);
myResource = null;
myTagList = null;
myUrlPath = StringUtils.join(theUrlPath, '/');
@@ -133,8 +126,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundleType = null;
}
- public BaseHttpClientInvocationWithContents(FhirContext theContext, String theContents, boolean theIsBundle, String theUrlPath) {
- myContext = theContext;
+ public BaseHttpClientInvocationWithContents(FhirContext theContext, String theContents, boolean theIsBundle,
+ String theUrlPath) {
+ super(theContext);
myResource = null;
myTagList = null;
myUrlPath = theUrlPath;
@@ -145,8 +139,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myBundleType = null;
}
- public BaseHttpClientInvocationWithContents(FhirContext theContext, String theContents, Map> theParams, String... theUrlPath) {
- myContext = theContext;
+ public BaseHttpClientInvocationWithContents(FhirContext theContext, String theContents,
+ Map> theParams, String... theUrlPath) {
+ super(theContext);
myResource = null;
myTagList = null;
myUrlPath = StringUtils.join(theUrlPath, '/');
@@ -159,13 +154,12 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
}
public BaseHttpClientInvocationWithContents(FhirContext theContext, TagList theTagList, String... theUrlPath) {
- super();
+ super(theContext);
if (theTagList == null) {
throw new NullPointerException("Tag list must not be null");
}
myResource = null;
- myContext = theContext;
myTagList = theTagList;
myResources = null;
myBundle = null;
@@ -175,23 +169,8 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myUrlPath = StringUtils.join(theUrlPath, '/');
}
- private void addMatchHeaders(HttpRequestBase theHttpRequest, StringBuilder theUrlBase) {
- if (myIfNoneExistParams != null) {
- StringBuilder b = newHeaderBuilder(theUrlBase);
- appendExtraParamsWithQuestionMark(myIfNoneExistParams, b, b.indexOf("?") == -1);
- theHttpRequest.addHeader(Constants.HEADER_IF_NONE_EXIST, b.toString());
- }
-
- if (myIfNoneExistString != null) {
- StringBuilder b = newHeaderBuilder(theUrlBase);
- b.append(b.indexOf("?") == -1 ? '?' : '&');
- b.append(myIfNoneExistString.substring(myIfNoneExistString.indexOf('?') + 1));
- theHttpRequest.addHeader(Constants.HEADER_IF_NONE_EXIST, b.toString());
- }
- }
-
@Override
- public HttpRequestBase asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) throws DataFormatException {
+ public IHttpRequest asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) throws DataFormatException {
StringBuilder url = new StringBuilder();
if (myUrlPath == null) {
@@ -207,43 +186,46 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
}
appendExtraParamsWithQuestionMark(theExtraParams, url, url.indexOf("?") == -1);
+ IHttpClient httpClient = getRestfulClientFactory().getHttpClient(url, myIfNoneExistParams, myIfNoneExistString, getRequestType(), getHeaders());
if (myResource != null && IBaseBinary.class.isAssignableFrom(myResource.getClass())) {
- IBaseBinary binary = (IBaseBinary) myResource;
- if (isBlank(binary.getContentType()) || EncodingEnum.forContentTypeStrict(binary.getContentType()) != null) {
- ourLog.trace("Binary has Content-Type {}, encoding as a FHIR resource instead of raw", binary.getContentType());
+ return httpClient.createBinaryRequest((IBaseBinary) myResource);
+ } else {
+ EncodingEnum encoding = theEncoding;
+ if (myContents != null) {
+ encoding = MethodUtil.detectEncoding(myContents);
+ }
+
+ if (encoding == null) {
+ encoding = EncodingEnum.XML;
+ }
+
+ if (myParams != null) {
+ return httpClient.createParamRequest(myParams, encoding);
} else {
- /*
- * Note: Be careful about changing which constructor we use for ByteArrayEntity,
- * as Android's version of HTTPClient doesn't support the newer ones for
- * whatever reason.
- */
- ByteArrayEntity entity = new ByteArrayEntity(binary.getContent());
-
- HttpRequestBase retVal = createRequest(url, entity);
- addMatchHeaders(retVal, url);
- super.addHeadersToRequest(retVal, null);
- if (isNotBlank(binary.getContentType())) {
- retVal.addHeader(Constants.HEADER_CONTENT_TYPE, binary.getContentType());
- }
- return retVal;
+ String contents = parseContents(thePrettyPrint, encoding);
+ String contentType = getContentType(encoding);
+ return httpClient.createByteRequest(contents, contentType, encoding);
}
}
+ }
- IParser parser;
- String contentType;
- EncodingEnum encoding = null;
- encoding = theEncoding;
-
- if (myContents != null) {
- encoding = MethodUtil.detectEncoding(myContents);
+ private String getContentType(EncodingEnum encoding) {
+ if (myBundle != null || (getFhirContext().getVersion().getVersion() == FhirVersionEnum.DSTU1
+ && ((myContents != null && myContentsIsBundle) || myResources != null))) {
+ return encoding.getBundleContentType();
+ } else {
+ return encoding.getResourceContentType();
}
+ }
+
+ private String parseContents(Boolean thePrettyPrint, EncodingEnum encoding) {
+ IParser parser;
if (encoding == EncodingEnum.JSON) {
- parser = myContext.newJsonParser();
+ parser = getFhirContext().newJsonParser();
} else {
- encoding = EncodingEnum.XML;
- parser = myContext.newXmlParser();
+ parser = getFhirContext().newXmlParser();
}
if (thePrettyPrint != null) {
@@ -251,84 +233,27 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
}
parser.setOmitResourceId(myOmitResourceId);
-
- AbstractHttpEntity entity;
- if (myParams != null) {
- contentType = null;
- List parameters = new ArrayList();
- for (Entry> nextParam : myParams.entrySet()) {
- List value = nextParam.getValue();
- for (String s : value) {
- parameters.add(new BasicNameValuePair(nextParam.getKey(), s));
- }
- }
- try {
- entity = new UrlEncodedFormEntity(parameters, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- throw new InternalErrorException("Server does not support UTF-8 (should not happen)", e);
- }
- } else {
- String contents;
- if (myTagList != null) {
- contents = parser.encodeTagListToString(myTagList);
- contentType = encoding.getResourceContentType();
- } else if (myBundle != null) {
- contents = parser.encodeBundleToString(myBundle);
- contentType = encoding.getBundleContentType();
- } else if (myResources != null) {
- IVersionSpecificBundleFactory bundleFactory = myContext.newBundleFactory();
- bundleFactory.initializeBundleFromResourceList("", myResources, "", "", myResources.size(), myBundleType);
- Bundle bundle = bundleFactory.getDstu1Bundle();
- if (bundle != null) {
- contents = parser.encodeBundleToString(bundle);
- contentType = encoding.getBundleContentType();
- } else {
- IBaseResource bundleRes = bundleFactory.getResourceBundle();
- contents = parser.encodeResourceToString(bundleRes);
- contentType = encoding.getResourceContentType();
- }
- } else if (myContents != null) {
- contents = myContents;
- if (myContentsIsBundle && myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU1)) {
- contentType = encoding.getBundleContentType();
- } else {
- contentType = encoding.getResourceContentType();
- }
+ if (myTagList != null) {
+ return parser.encodeTagListToString(myTagList);
+ } else if (myBundle != null) {
+ return parser.encodeBundleToString(myBundle);
+ } else if (myResources != null) {
+ IVersionSpecificBundleFactory bundleFactory = getFhirContext().newBundleFactory();
+ bundleFactory.initializeBundleFromResourceList("", myResources, "", "", myResources.size(), myBundleType);
+ Bundle bundle = bundleFactory.getDstu1Bundle();
+ if (bundle != null) {
+ return parser.encodeBundleToString(bundle);
} else {
- contents = parser.encodeResourceToString(myResource);
- contentType = encoding.getResourceContentType();
+ IBaseResource bundleRes = bundleFactory.getResourceBundle();
+ return parser.encodeResourceToString(bundleRes);
}
-
- /*
- * We aren't using a StringEntity here because the constructors supported by
- * Android aren't available in non-Android, and vice versa. Since we add the
- * content type header manually, it makes no difference which one
- * we use anyhow.
- */
- entity = new ByteArrayEntity(contents.getBytes(Constants.CHARSET_UTF8));
+ } else if (myContents != null) {
+ return myContents;
+ } else {
+ return parser.encodeResourceToString(myResource);
}
-
- HttpRequestBase retVal = createRequest(url, entity);
- super.addHeadersToRequest(retVal, encoding);
- addMatchHeaders(retVal, url);
-
- if (contentType != null) {
- retVal.addHeader(Constants.HEADER_CONTENT_TYPE, contentType + Constants.HEADER_SUFFIX_CT_UTF_8);
- }
-
- return retVal;
}
- protected abstract HttpRequestBase createRequest(StringBuilder theUrl, AbstractHttpEntity theEntity);
-
- private StringBuilder newHeaderBuilder(StringBuilder theUrlBase) {
- StringBuilder b = new StringBuilder();
- b.append(theUrlBase);
- if (theUrlBase.length() > 0 && theUrlBase.charAt(theUrlBase.length() - 1) == '/') {
- b.deleteCharAt(b.length() - 1);
- }
- return b;
- }
public void setIfNoneExistParams(Map> theIfNoneExist) {
myIfNoneExistParams = theIfNoneExist;
}
@@ -341,4 +266,9 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca
myOmitResourceId = theOmitResourceId;
}
+ /**
+ * Get the HTTP request type.
+ */
+ protected abstract RequestTypeEnum getRequestType();
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConformanceMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConformanceMethodBinding.java
index 34a617fd321..b98367caf19 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConformanceMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ConformanceMethodBinding.java
@@ -60,7 +60,7 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
@Override
public HttpGetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
- HttpGetClientInvocation retVal = MethodUtil.createConformanceInvocation();
+ HttpGetClientInvocation retVal = MethodUtil.createConformanceInvocation(getContext());
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteMethodBinding.java
index 12603ad0596..1642794a39a 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteMethodBinding.java
@@ -119,7 +119,7 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
throw new InvalidRequestException("ID parameter has the wrong resource type, expected '" + getResourceName() + "', found: " + idDt.getResourceType());
}
- HttpDeleteClientInvocation retVal = createDeleteInvocation(idDt);
+ HttpDeleteClientInvocation retVal = createDeleteInvocation(getContext(), idDt);
for (int idx = 0; idx < theArgs.length; idx++) {
IParameter nextParam = getParameters().get(idx);
@@ -129,8 +129,8 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
return retVal;
}
- public static HttpDeleteClientInvocation createDeleteInvocation(IIdType theId) {
- HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theId);
+ public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, IIdType theId) {
+ HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theId);
return retVal;
}
@@ -144,13 +144,13 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBinding {
return null;
}
- public static HttpDeleteClientInvocation createDeleteInvocation(String theSearchUrl) {
- HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theSearchUrl);
+ public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theSearchUrl) {
+ HttpDeleteClientInvocation retVal = new HttpDeleteClientInvocation(theContext, theSearchUrl);
return retVal;
}
- public static HttpDeleteClientInvocation createDeleteInvocation(String theResourceType, Map> theParams) {
- return new HttpDeleteClientInvocation(theResourceType, theParams);
+ public static HttpDeleteClientInvocation createDeleteInvocation(FhirContext theContext, String theResourceType, Map> theParams) {
+ return new HttpDeleteClientInvocation(theContext, theResourceType, theParams);
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteTagsMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteTagsMethodBinding.java
index c1c22b9f63f..08491d306de 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteTagsMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DeleteTagsMethodBinding.java
@@ -28,8 +28,8 @@ import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
public class DeleteTagsMethodBinding extends BaseAddOrDeleteTagsMethodBinding {
- public DeleteTagsMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider, DeleteTags theDeleteTags) {
- super(theMethod, theConetxt, theProvider, theDeleteTags.type());
+ public DeleteTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, DeleteTags theDeleteTags) {
+ super(theMethod, theContext, theProvider, theDeleteTags.type());
}
@Override
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DynamicSearchMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DynamicSearchMethodBinding.java
index e5f3f7aeb86..ebae9055f85 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DynamicSearchMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/DynamicSearchMethodBinding.java
@@ -48,8 +48,8 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
private HashSet myParamNames;
private Integer myIdParamIndex;
- public DynamicSearchMethodBinding(Class extends IBaseResource> theReturnResourceType, Method theMethod, FhirContext theConetxt, IDynamicSearchResourceProvider theProvider) {
- super(theReturnResourceType, theMethod, theConetxt, theProvider);
+ public DynamicSearchMethodBinding(Class extends IBaseResource> theReturnResourceType, Method theMethod, FhirContext theContext, IDynamicSearchResourceProvider theProvider) {
+ super(theReturnResourceType, theMethod, theContext, theProvider);
myProvider = theProvider;
mySearchParameters = myProvider.getSearchParameters();
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/GetTagsMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/GetTagsMethodBinding.java
index bd80413bea6..00d55e79bbd 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/GetTagsMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/GetTagsMethodBinding.java
@@ -54,8 +54,8 @@ public class GetTagsMethodBinding extends BaseMethodBinding {
private Class extends IBaseResource> myType;
private Integer myVersionIdParamIndex;
- public GetTagsMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider, GetTags theAnnotation) {
- super(theMethod, theConetxt, theProvider);
+ public GetTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, GetTags theAnnotation) {
+ super(theMethod, theContext, theProvider);
if (theProvider instanceof IResourceProvider) {
myType = ((IResourceProvider) theProvider).getResourceType();
@@ -64,7 +64,7 @@ public class GetTagsMethodBinding extends BaseMethodBinding {
}
if (!Modifier.isInterface(myType.getModifiers())) {
- myResourceName = theConetxt.getResourceDefinition(myType).getName();
+ myResourceName = theContext.getResourceDefinition(myType).getName();
}
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext());
@@ -127,17 +127,17 @@ public class GetTagsMethodBinding extends BaseMethodBinding {
if (myType != IResource.class) {
if (id != null) {
if (versionId != null) {
- retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, versionId.getValue(), Constants.PARAM_TAGS);
+ retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, versionId.getValue(), Constants.PARAM_TAGS);
} else if (id.hasVersionIdPart()) {
- retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, id.getVersionIdPart(), Constants.PARAM_TAGS);
+ retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_HISTORY, id.getVersionIdPart(), Constants.PARAM_TAGS);
} else {
- retVal = new HttpGetClientInvocation(getResourceName(), id.getIdPart(), Constants.PARAM_TAGS);
+ retVal = new HttpGetClientInvocation(getContext(), getResourceName(), id.getIdPart(), Constants.PARAM_TAGS);
}
} else {
- retVal = new HttpGetClientInvocation(getResourceName(), Constants.PARAM_TAGS);
+ retVal = new HttpGetClientInvocation(getContext(), getResourceName(), Constants.PARAM_TAGS);
}
} else {
- retVal = new HttpGetClientInvocation(Constants.PARAM_TAGS);
+ retVal = new HttpGetClientInvocation(getContext(), Constants.PARAM_TAGS);
}
if (theArgs != null) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HistoryMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HistoryMethodBinding.java
index 0d077d03a7e..5a026d90252 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HistoryMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HistoryMethodBinding.java
@@ -53,8 +53,8 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
private String myResourceName;
private final RestOperationTypeEnum myResourceOperationType;
- public HistoryMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider) {
- super(toReturnType(theMethod, theProvider), theMethod, theConetxt, theProvider);
+ public HistoryMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
+ super(toReturnType(theMethod, theProvider), theMethod, theContext, theProvider);
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext());
@@ -80,7 +80,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
}
if (type != IResource.class) {
- myResourceName = theConetxt.getResourceDefinition(type).getName();
+ myResourceName = theContext.getResourceDefinition(type).getName();
} else {
myResourceName = null;
}
@@ -142,7 +142,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
}
String historyId = id != null ? id.getIdPart() : null;
- HttpGetClientInvocation retVal = createHistoryInvocation(resourceName, historyId, null, null);
+ HttpGetClientInvocation retVal = createHistoryInvocation(getContext(), resourceName, historyId, null, null);
if (theArgs != null) {
for (int idx = 0; idx < theArgs.length; idx++) {
@@ -206,7 +206,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
};
}
- public static HttpGetClientInvocation createHistoryInvocation(String theResourceName, String theId, IPrimitiveType theSince, Integer theLimit) {
+ public static HttpGetClientInvocation createHistoryInvocation(FhirContext theContext, String theResourceName, String theId, IPrimitiveType theSince, Integer theLimit) {
StringBuilder b = new StringBuilder();
if (theResourceName != null) {
b.append(theResourceName);
@@ -230,7 +230,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
b.append(Constants.PARAM_COUNT).append('=').append(theLimit);
}
- HttpGetClientInvocation retVal = new HttpGetClientInvocation(b.toString());
+ HttpGetClientInvocation retVal = new HttpGetClientInvocation(theContext, b.toString());
return retVal;
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpDeleteClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpDeleteClientInvocation.java
index 3621682cb3e..e7e869d8976 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpDeleteClientInvocation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpDeleteClientInvocation.java
@@ -23,11 +23,12 @@ package ca.uhn.fhir.rest.method;
import java.util.List;
import java.util.Map;
-import org.apache.http.client.methods.HttpDelete;
-import org.apache.http.client.methods.HttpRequestBase;
import org.hl7.fhir.instance.model.api.IIdType;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.server.EncodingEnum;
public class HttpDeleteClientInvocation extends BaseHttpClientInvocation {
@@ -35,22 +36,24 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation {
private String myUrlPath;
private Map> myParams;
- public HttpDeleteClientInvocation(IIdType theId) {
- super();
+ public HttpDeleteClientInvocation(FhirContext theContext, IIdType theId) {
+ super(theContext);
myUrlPath = theId.toUnqualifiedVersionless().getValue();
}
- public HttpDeleteClientInvocation(String theSearchUrl) {
+ public HttpDeleteClientInvocation(FhirContext theContext, String theSearchUrl) {
+ super(theContext);
myUrlPath = theSearchUrl;
}
- public HttpDeleteClientInvocation(String theResourceType, Map> theParams) {
+ public HttpDeleteClientInvocation(FhirContext theContext, String theResourceType, Map> theParams) {
+ super(theContext);
myUrlPath = theResourceType;
myParams = theParams;
}
@Override
- public HttpRequestBase asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
+ public IHttpRequest asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
StringBuilder b = new StringBuilder();
b.append(theUrlBase);
if (!theUrlBase.endsWith("/")) {
@@ -61,9 +64,7 @@ public class HttpDeleteClientInvocation extends BaseHttpClientInvocation {
appendExtraParamsWithQuestionMark(myParams, b, b.indexOf("?") == -1);
appendExtraParamsWithQuestionMark(theExtraParams, b, b.indexOf("?") == -1);
- HttpDelete retVal = new HttpDelete(b.toString());
- super.addHeadersToRequest(retVal, theEncoding);
- return retVal;
+ return createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.DELETE);
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpGetClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpGetClientInvocation.java
index 1c4a2470a7b..5e2a1acda3f 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpGetClientInvocation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpGetClientInvocation.java
@@ -28,10 +28,12 @@ import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.client.methods.HttpGet;
import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.server.EncodingEnum;
/**
@@ -43,28 +45,33 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
private final Map> myParameters;
private final String myUrlPath;
- public HttpGetClientInvocation(Map> theParameters, String... theUrlFragments) {
+ public HttpGetClientInvocation(FhirContext theContext, Map> theParameters, String... theUrlFragments) {
+ super(theContext);
myParameters = theParameters;
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
- public HttpGetClientInvocation(Map> theParameters, List theUrlFragments) {
+ public HttpGetClientInvocation(FhirContext theContext, Map> theParameters, List theUrlFragments) {
+ super(theContext);
myParameters = theParameters;
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
- public HttpGetClientInvocation(String theUrlPath) {
+ public HttpGetClientInvocation(FhirContext theContext, String theUrlPath) {
+ super(theContext);
myParameters = new HashMap>();
myUrlPath = theUrlPath;
}
- public HttpGetClientInvocation(String... theUrlFragments) {
+ public HttpGetClientInvocation(FhirContext theContext, String... theUrlFragments) {
+ super(theContext);
myParameters = new HashMap>();
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
- public HttpGetClientInvocation(List theUrlFragments) {
+ public HttpGetClientInvocation(FhirContext theContext, List theUrlFragments) {
+ super(theContext);
myParameters = new HashMap>();
myUrlPath = StringUtils.join(theUrlFragments, '/');
}
@@ -78,7 +85,7 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
}
@Override
- public HttpGet asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
+ public IHttpRequest asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
StringBuilder b = new StringBuilder();
if (!myUrlPath.contains("://")) {
@@ -102,10 +109,7 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
appendExtraParamsWithQuestionMark(theExtraParams, b, first);
- HttpGet retVal = new HttpGet(b.toString());
- super.addHeadersToRequest(retVal, theEncoding);
-
- return retVal;
+ return super.createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.GET);
}
private boolean addQueryParameter(StringBuilder b, boolean first, String nextKey, String nextValue) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPostClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPostClientInvocation.java
index 4b46346d3f0..5426eda3aef 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPostClientInvocation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPostClientInvocation.java
@@ -23,14 +23,13 @@ package ca.uhn.fhir.rest.method;
import java.util.List;
import java.util.Map;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.AbstractHttpEntity;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
public class HttpPostClientInvocation extends BaseHttpClientInvocationWithContents {
@@ -63,11 +62,8 @@ public class HttpPostClientInvocation extends BaseHttpClientInvocationWithConten
super(theContext, theParams, theUrlExtension);
}
- @Override
- protected HttpPost createRequest(StringBuilder theUrlBase, AbstractHttpEntity theEntity) {
- HttpPost retVal = new HttpPost(theUrlBase.toString());
- retVal.setEntity(theEntity);
- return retVal;
+ protected RequestTypeEnum getRequestType() {
+ return RequestTypeEnum.POST;
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPutClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPutClientInvocation.java
index eaec5aab82a..201701759f6 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPutClientInvocation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpPutClientInvocation.java
@@ -20,12 +20,10 @@ package ca.uhn.fhir.rest.method;
* #L%
*/
-import org.apache.http.client.methods.HttpPut;
-import org.apache.http.client.methods.HttpRequestBase;
-import org.apache.http.entity.AbstractHttpEntity;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
public class HttpPutClientInvocation extends BaseHttpClientInvocationWithContents {
@@ -38,10 +36,8 @@ public class HttpPutClientInvocation extends BaseHttpClientInvocationWithContent
}
@Override
- protected HttpRequestBase createRequest(StringBuilder theUrl, AbstractHttpEntity theEntity) {
- HttpPut retVal = new HttpPut(theUrl.toString());
- retVal.setEntity(theEntity);
- return retVal;
+ protected RequestTypeEnum getRequestType() {
+ return RequestTypeEnum.PUT;
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpSimpleGetClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpSimpleGetClientInvocation.java
index cd2f1eff7a8..7371e772d53 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpSimpleGetClientInvocation.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/HttpSimpleGetClientInvocation.java
@@ -23,25 +23,24 @@ package ca.uhn.fhir.rest.method;
import java.util.List;
import java.util.Map;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.client.methods.HttpRequestBase;
-
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.rest.api.RequestTypeEnum;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
+import ca.uhn.fhir.rest.client.api.IHttpRequest;
import ca.uhn.fhir.rest.server.EncodingEnum;
public class HttpSimpleGetClientInvocation extends BaseHttpClientInvocation {
private final String myUrl;
- public HttpSimpleGetClientInvocation(String theUrlPath) {
+ public HttpSimpleGetClientInvocation(FhirContext theContext, String theUrlPath) {
+ super(theContext);
myUrl = theUrlPath;
}
@Override
- public HttpRequestBase asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
- HttpGet retVal = new HttpGet(myUrl);
- super.addHeadersToRequest(retVal, theEncoding);
- return retVal;
+ public IHttpRequest asHttpRequest(String theUrlBase, Map> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
+ return createHttpRequest(myUrl, theEncoding, RequestTypeEnum.GET);
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/MethodUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/MethodUtil.java
index ef3dad739b1..5dfc7fa9b0e 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/MethodUtil.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/MethodUtil.java
@@ -24,7 +24,6 @@ import javax.servlet.http.HttpServletRequest;
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;
@@ -89,6 +88,7 @@ import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
import ca.uhn.fhir.rest.server.SearchParameterMap;
+import ca.uhn.fhir.util.DateUtils;
import ca.uhn.fhir.util.ReflectionUtil;
/*
@@ -146,8 +146,8 @@ public class MethodUtil {
return value;
}
- public static HttpGetClientInvocation createConformanceInvocation() {
- return new HttpGetClientInvocation("metadata");
+ public static HttpGetClientInvocation createConformanceInvocation(FhirContext theContext) {
+ return new HttpGetClientInvocation(theContext, "metadata");
}
public static HttpPostClientInvocation createCreateInvocation(IBaseResource theResource, FhirContext theContext) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/OperationMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/OperationMethodBinding.java
index 6c085f960dd..4ca0f1df3cc 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/OperationMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/OperationMethodBinding.java
@@ -358,7 +358,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding {
IPrimitiveType> primitive = (IPrimitiveType>) value;
params.get(nextName).add(primitive.getValueAsString());
}
- return new HttpGetClientInvocation(params, b.toString());
+ return new HttpGetClientInvocation(theContext, params, b.toString());
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java
index 73b8e8e2932..0636c903b59 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java
@@ -167,15 +167,15 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
if (myVersionIdIndex == null) {
String resourceName = getResourceName();
if (id.hasVersionIdPart()) {
- retVal = createVReadInvocation(new IdDt(resourceName, id.getIdPart(), id.getVersionIdPart()), resourceName);
+ retVal = createVReadInvocation(getContext(), new IdDt(resourceName, id.getIdPart(), id.getVersionIdPart()), resourceName);
} else {
- retVal = createReadInvocation(id, resourceName);
+ retVal = createReadInvocation(getContext(), id, resourceName);
}
} else {
IdDt vid = ((IdDt) theArgs[myVersionIdIndex]);
String resourceName = getResourceName();
- retVal = createVReadInvocation(new IdDt(resourceName, id.getIdPart(), vid.getVersionIdPart()), resourceName);
+ retVal = createVReadInvocation(getContext(), new IdDt(resourceName, id.getIdPart(), vid.getVersionIdPart()), resourceName);
}
for (int idx = 0; idx < theArgs.length; idx++) {
@@ -249,20 +249,20 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
return mySupportsVersion || myVersionIdIndex != null;
}
- public static HttpGetClientInvocation createAbsoluteReadInvocation(IIdType theId) {
- return new HttpGetClientInvocation(theId.toVersionless().getValue());
+ public static HttpGetClientInvocation createAbsoluteReadInvocation(FhirContext theContext, IIdType theId) {
+ return new HttpGetClientInvocation(theContext, theId.toVersionless().getValue());
}
- public static HttpGetClientInvocation createAbsoluteVReadInvocation(IIdType theId) {
- return new HttpGetClientInvocation(theId.getValue());
+ public static HttpGetClientInvocation createAbsoluteVReadInvocation(FhirContext theContext, IIdType theId) {
+ return new HttpGetClientInvocation(theContext, theId.getValue());
}
- public static HttpGetClientInvocation createReadInvocation(IIdType theId, String theResourceName) {
- return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart()).getValue());
+ public static HttpGetClientInvocation createReadInvocation(FhirContext theContext, IIdType theId, String theResourceName) {
+ return new HttpGetClientInvocation(theContext, new IdDt(theResourceName, theId.getIdPart()).getValue());
}
- public static HttpGetClientInvocation createVReadInvocation(IIdType theId, String theResourceName) {
- return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
+ public static HttpGetClientInvocation createVReadInvocation(FhirContext theContext, IIdType theId, String theResourceName) {
+ return new HttpGetClientInvocation(theContext, new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
}
@Override
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
index 4325c567dad..6debd4efd1b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/RequestDetails.java
@@ -4,6 +4,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
/*
* #%L
@@ -274,4 +275,9 @@ public abstract class RequestDetails {
mySecondaryOperation = theSecondaryOperation;
}
+ /**
+ * Return the charset as defined by the header contenttype. Return null if it is not set.
+ */
+ public abstract Charset getCharset();
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
index 75a8ddd1244..e710e80a0b4 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/SearchMethodBinding.java
@@ -340,16 +340,16 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
case GET:
default:
if (compartmentSearch) {
- invocation = new HttpGetClientInvocation(theParameters, theResourceName, theId.getIdPart(), theCompartmentName);
+ invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, theId.getIdPart(), theCompartmentName);
} else {
- invocation = new HttpGetClientInvocation(theParameters, theResourceName);
+ invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName);
}
break;
case GET_WITH_SEARCH:
if (compartmentSearch) {
- invocation = new HttpGetClientInvocation(theParameters, theResourceName, theId.getIdPart(), theCompartmentName, Constants.PARAM_SEARCH);
+ invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, theId.getIdPart(), theCompartmentName, Constants.PARAM_SEARCH);
} else {
- invocation = new HttpGetClientInvocation(theParameters, theResourceName, Constants.PARAM_SEARCH);
+ invocation = new HttpGetClientInvocation(theContext, theParameters, theResourceName, Constants.PARAM_SEARCH);
}
break;
case POST:
@@ -456,8 +456,8 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
}
- public static BaseHttpClientInvocation createSearchInvocation(String theSearchUrl, Map> theParams) {
- return new HttpGetClientInvocation(theParams, theSearchUrl);
+ public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theSearchUrl, Map> theParams) {
+ return new HttpGetClientInvocation(theContext, theParams, theSearchUrl);
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionMethodBinding.java
index 51abc33a9c3..33ead0772c0 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/TransactionMethodBinding.java
@@ -53,8 +53,8 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
private int myTransactionParamIndex;
private ParamStyle myTransactionParamStyle;
- public TransactionMethodBinding(Method theMethod, FhirContext theConetxt, Object theProvider) {
- super(null, theMethod, theConetxt, theProvider);
+ public TransactionMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
+ super(null, theMethod, theContext, theProvider);
myTransactionParamIndex = -1;
int index = 0;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java
index 69a40d90930..b9295c7da69 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/ResourceParameter.java
@@ -20,7 +20,6 @@ package ca.uhn.fhir.rest.param;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isBlank;
-import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -35,7 +34,6 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.Validate;
-import org.apache.http.entity.ContentType;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -130,13 +128,7 @@ public class ResourceParameter implements IParameter {
}
public static Charset determineRequestCharset(RequestDetails theRequest) {
- String ct = theRequest.getHeader(Constants.HEADER_CONTENT_TYPE);
-
- Charset charset = null;
- if (isNotBlank(ct)) {
- ContentType parsedCt = ContentType.parse(ct);
- charset = parsedCt.getCharset();
- }
+ Charset charset = theRequest.getCharset();
if (charset == null) {
charset = Charset.forName("UTF-8");
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
index 83a0cc18212..10dbda5af1c 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServerUtils.java
@@ -43,7 +43,6 @@ import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
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.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
@@ -69,6 +68,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.method.SummaryEnumParameter;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
+import ca.uhn.fhir.util.DateUtils;
public class RestfulServerUtils {
static final Pattern ACCEPT_HEADER_PATTERN = Pattern.compile("\\s*([a-zA-Z0-9+.*/-]+)\\s*(;\\s*([a-zA-Z]+)\\s*=\\s*([a-zA-Z0-9.]+)\\s*)?(,?)");
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRequestDetails.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRequestDetails.java
index 34c8db073d6..cc97eb5b3bd 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRequestDetails.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/servlet/ServletRequestDetails.java
@@ -1,7 +1,5 @@
package ca.uhn.fhir.rest.server.servlet;
-import java.io.ByteArrayInputStream;
-
/*
* #%L
* HAPI FHIR - Core Library
@@ -21,10 +19,13 @@ import java.io.ByteArrayInputStream;
* limitations under the License.
* #L%
*/
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.nio.charset.Charset;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
@@ -37,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
+import org.apache.http.entity.ContentType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.rest.api.RequestTypeEnum;
@@ -176,4 +178,16 @@ public class ServletRequestDetails extends RequestDetails {
return retVal;
}
+ @Override
+ public Charset getCharset() {
+ String ct = getHeader(Constants.HEADER_CONTENT_TYPE);
+
+ Charset charset = null;
+ if (isNotBlank(ct)) {
+ ContentType parsedCt = ContentType.parse(ct);
+ charset = parsedCt.getCharset();
+ }
+ return charset;
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java
new file mode 100644
index 00000000000..3214988ddab
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/DateUtils.java
@@ -0,0 +1,254 @@
+package ca.uhn.fhir.util;
+
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * .
+ *
+ */
+
+import java.lang.ref.SoftReference;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TimeZone;
+
+/**
+ * A utility class for parsing and formatting HTTP dates as used in cookies and
+ * other headers. This class handles dates as defined by RFC 2616 section
+ * 3.3.1 as well as some other common non-standard formats.
+ *
+ * @since 4.3
+ */
+public final class DateUtils {
+
+ /**
+ * Date format pattern used to parse HTTP date headers in RFC 1123 format.
+ */
+ public static final String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
+
+ /**
+ * Date format pattern used to parse HTTP date headers in RFC 1036 format.
+ */
+ public static final String PATTERN_RFC1036 = "EEE, dd-MMM-yy HH:mm:ss zzz";
+
+ /**
+ * Date format pattern used to parse HTTP date headers in ANSI C
+ * {@code asctime()} format.
+ */
+ public static final String PATTERN_ASCTIME = "EEE MMM d HH:mm:ss yyyy";
+
+ private static final String[] DEFAULT_PATTERNS = new String[] {
+ PATTERN_RFC1123,
+ PATTERN_RFC1036,
+ PATTERN_ASCTIME
+ };
+
+ private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
+
+ public static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+ static {
+ final Calendar calendar = Calendar.getInstance();
+ calendar.setTimeZone(GMT);
+ calendar.set(2000, Calendar.JANUARY, 1, 0, 0, 0);
+ calendar.set(Calendar.MILLISECOND, 0);
+ DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
+ }
+
+ /**
+ * Parses a date value. The formats used for parsing the date value are retrieved from
+ * the default http params.
+ *
+ * @param dateValue the date value to parse
+ *
+ * @return the parsed date or null if input could not be parsed
+ */
+ public static Date parseDate(final String dateValue) {
+ return parseDate(dateValue, null, null);
+ }
+
+ /**
+ * Parses the date value using the given date formats.
+ *
+ * @param dateValue the date value to parse
+ * @param dateFormats the date formats to use
+ *
+ * @return the parsed date or null if input could not be parsed
+ */
+ public static Date parseDate(final String dateValue, final String[] dateFormats) {
+ return parseDate(dateValue, dateFormats, null);
+ }
+
+ /**
+ * Parses the date value using the given date formats.
+ *
+ * @param dateValue the date value to parse
+ * @param dateFormats the date formats to use
+ * @param startDate During parsing, two digit years will be placed in the range
+ * {@code startDate} to {@code startDate + 100 years}. This value may
+ * be {@code null}. When {@code null} is given as a parameter, year
+ * {@code 2000} will be used.
+ *
+ * @return the parsed date or null if input could not be parsed
+ */
+ public static Date parseDate(
+ final String dateValue,
+ final String[] dateFormats,
+ final Date startDate) {
+ notNull(dateValue, "Date value");
+ final String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS;
+ final Date localStartDate = startDate != null ? startDate : DEFAULT_TWO_DIGIT_YEAR_START;
+ String v = dateValue;
+ // trim single quotes around date if present
+ // see issue #5279
+ if (v.length() > 1 && v.startsWith("'") && v.endsWith("'")) {
+ v = v.substring (1, v.length() - 1);
+ }
+
+ for (final String dateFormat : localDateFormats) {
+ final SimpleDateFormat dateParser = DateFormatHolder.formatFor(dateFormat);
+ dateParser.set2DigitYearStart(localStartDate);
+ final ParsePosition pos = new ParsePosition(0);
+ final Date result = dateParser.parse(v, pos);
+ if (pos.getIndex() != 0) {
+ return result;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Formats the given date according to the RFC 1123 pattern.
+ *
+ * @param date The date to format.
+ * @return An RFC 1123 formatted date string.
+ *
+ * @see #PATTERN_RFC1123
+ */
+ public static String formatDate(final Date date) {
+ return formatDate(date, PATTERN_RFC1123);
+ }
+
+ /**
+ * Formats the given date according to the specified pattern. The pattern
+ * must conform to that used by the {@link SimpleDateFormat simple date
+ * format} class.
+ *
+ * @param date The date to format.
+ * @param pattern The pattern to use for formatting the date.
+ * @return A formatted date string.
+ *
+ * @throws IllegalArgumentException If the given date pattern is invalid.
+ *
+ * @see SimpleDateFormat
+ */
+ public static String formatDate(final Date date, final String pattern) {
+ notNull(date, "Date");
+ notNull(pattern, "Pattern");
+ final SimpleDateFormat formatter = DateFormatHolder.formatFor(pattern);
+ return formatter.format(date);
+ }
+
+
+ public static T notNull(final T argument, final String name) {
+ if (argument == null) {
+ throw new IllegalArgumentException(name + " may not be null");
+ }
+ return argument;
+ }
+
+ /**
+ * Clears thread-local variable containing {@link java.text.DateFormat} cache.
+ *
+ * @since 4.3
+ */
+ public static void clearThreadLocal() {
+ DateFormatHolder.clearThreadLocal();
+ }
+
+ /** This class should not be instantiated. */
+ private DateUtils() {
+ }
+
+ /**
+ * A factory for {@link SimpleDateFormat}s. The instances are stored in a
+ * threadlocal way because SimpleDateFormat is not threadsafe as noted in
+ * {@link SimpleDateFormat its javadoc}.
+ *
+ */
+ final static class DateFormatHolder {
+
+ private static final ThreadLocal>>
+ THREADLOCAL_FORMATS = new ThreadLocal>>() {
+
+ @Override
+ protected SoftReference