diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java index 019375d2be9..9efd35be412 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java @@ -37,6 +37,7 @@ import ca.uhn.fhir.model.api.*; import ca.uhn.fhir.model.view.ViewGenerator; import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.parser.*; +import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.client.api.*; import ca.uhn.fhir.util.*; import ca.uhn.fhir.validation.FhirValidator; @@ -460,6 +461,10 @@ public class FhirContext { return !myDefaultTypeForProfile.isEmpty(); } + public IVersionSpecificBundleFactory newBundleFactory() { + return myVersion.newBundleFactory(this); + } + /** * Creates a new FluentPath engine which can be used to exvaluate * path expressions over FHIR resources. Note that this engine will use the @@ -818,7 +823,7 @@ public class FhirContext { public void setValidationSupport(IContextValidationSupport theValidationSupport) { myValidationSupport = theValidationSupport; } - + @SuppressWarnings({ "cast" }) private List> toElementList(Collection> theResourceTypes) { if (theResourceTypes == null) { @@ -830,7 +835,7 @@ public class FhirContext { } return resTypes; } - + private void validateInitialized() { // See #610 if (!myInitialized) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IFhirVersion.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IFhirVersion.java index 69725f6ba0f..e3c352babb5 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IFhirVersion.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IFhirVersion.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.model.api; * 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 + * 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, @@ -33,6 +33,7 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.support.IContextValidationSupport; import ca.uhn.fhir.fluentpath.IFluentPath; +import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory; /** * Each structure version JAR will have an implementation of this interface. @@ -44,7 +45,7 @@ import ca.uhn.fhir.fluentpath.IFluentPath; public interface IFhirVersion { IFluentPath createFluentPathExecutor(FhirContext theFhirContext); - + IContextValidationSupport createValidationSupport(); IBaseResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase); @@ -61,6 +62,8 @@ public interface IFhirVersion { FhirVersionEnum getVersion(); + IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext); + IBase newCodingDt(); IIdType newIdType(); diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IVersionSpecificBundleFactory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java similarity index 81% rename from hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IVersionSpecificBundleFactory.java rename to hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java index 9ef8bf1de83..d5d7ee434f9 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IVersionSpecificBundleFactory.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/api/IVersionSpecificBundleFactory.java @@ -1,4 +1,4 @@ -package ca.uhn.fhir.rest.api.server; +package ca.uhn.fhir.rest.api; /* * #%L @@ -19,7 +19,9 @@ package ca.uhn.fhir.rest.api.server; * limitations under the License. * #L% */ -import java.util.*; +import java.util.Date; +import java.util.List; +import java.util.Set; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; @@ -28,7 +30,6 @@ import ca.uhn.fhir.context.api.BundleInclusionRule; import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.model.valueset.BundleTypeEnum; -import ca.uhn.fhir.rest.api.EncodingEnum; /** * This interface should be considered experimental and will likely change in future releases of HAPI. Use with caution! @@ -39,8 +40,8 @@ public interface IVersionSpecificBundleFactory { void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType theLastUpdated); - void initializeBundleFromBundleProvider(IRestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, - int theOffset, Integer theCount, String theSearchId, BundleTypeEnum theBundleType, Set theIncludes); +// void initializeBundleFromBundleProvider(IRestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, +// int theOffset, Integer theCount, String theSearchId, BundleTypeEnum theBundleType, Set theIncludes); Bundle getDstu1Bundle(); diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpClient.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpClient.java index 1e11bddedff..0f5f8229e4a 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpClient.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpClient.java @@ -21,20 +21,29 @@ package ca.uhn.fhir.rest.client.apache; */ import java.io.UnsupportedEncodingException; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.*; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.message.BasicNameValuePair; import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.client.api.Header; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; /** diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpResponse.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpResponse.java index 9195579e921..d04fc5eac55 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpResponse.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheHttpResponse.java @@ -28,7 +28,6 @@ import java.io.Reader; import java.io.StringReader; import java.nio.charset.Charset; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -41,7 +40,6 @@ import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.entity.ContentType; import ca.uhn.fhir.rest.client.api.IHttpResponse; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; /** diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheRestfulClientFactory.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheRestfulClientFactory.java index 677c4115e61..00ce90070dc 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheRestfulClientFactory.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/ApacheRestfulClientFactory.java @@ -31,7 +31,10 @@ import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; -import org.apache.http.impl.client.*; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.client.ProxyAuthenticationStrategy; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import ca.uhn.fhir.context.FhirContext; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/BaseHttpClient.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/BaseHttpClient.java index e29083e2f38..8289464006e 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/BaseHttpClient.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/BaseHttpClient.java @@ -26,10 +26,13 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IBaseBinary; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.client.api.Header; +import ca.uhn.fhir.rest.client.api.HttpClientUtil; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.*; public abstract class BaseHttpClient implements IHttpClient { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/GZipContentInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/GZipContentInterceptor.java index 98872777998..ec0d52668d0 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/GZipContentInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/apache/GZipContentInterceptor.java @@ -29,8 +29,9 @@ import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.entity.ByteArrayEntity; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; /** * Client interceptor which GZip compresses outgoing (POST/PUT) contents being uploaded diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseClient.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseClient.java index ea24eb345fc..463a0d5e801 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseClient.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseClient.java @@ -22,25 +22,51 @@ package ca.uhn.fhir.rest.client.impl; import static org.apache.commons.lang3.StringUtils.isNotBlank; -import java.io.*; -import java.util.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; -import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.instance.model.api.IBase; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; +import org.hl7.fhir.instance.model.api.IPrimitiveType; -import ca.uhn.fhir.context.*; +import ca.uhn.fhir.context.BaseRuntimeChildDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; +import ca.uhn.fhir.context.BaseRuntimeElementDefinition; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.IParser; -import ca.uhn.fhir.rest.api.*; -import ca.uhn.fhir.rest.client.*; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.client.exceptions.*; -import ca.uhn.fhir.rest.method.HttpGetClientInvocation; -import ca.uhn.fhir.rest.method.IClientResponseHandler; -import ca.uhn.fhir.rest.method.IClientResponseHandlerHandlesBinary; -import ca.uhn.fhir.rest.method.MethodUtil; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.SummaryEnum; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; +import ca.uhn.fhir.rest.client.api.IRestfulClient; +import ca.uhn.fhir.rest.client.api.IRestfulClientFactory; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException; +import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException; +import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; +import ca.uhn.fhir.rest.client.method.HttpGetClientInvocation; +import ca.uhn.fhir.rest.client.method.IClientResponseHandler; +import ca.uhn.fhir.rest.client.method.IClientResponseHandlerHandlesBinary; +import ca.uhn.fhir.rest.client.method.MethodUtil; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.util.OperationOutcomeUtil; import ca.uhn.fhir.util.XmlUtil; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseHttpClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseHttpClientInvocation.java index 83ca9b517b5..3c73e72ce1e 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseHttpClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/BaseHttpClientInvocation.java @@ -28,9 +28,12 @@ import java.util.Map; import java.util.Map.Entry; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.rest.client.api.Header; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IRestfulClientFactory; public abstract class BaseHttpClientInvocation { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandler.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandler.java index b889f179f84..cafc608c92b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandler.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandler.java @@ -27,7 +27,7 @@ import java.util.Map; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.client.api.IHttpClient; import ca.uhn.fhir.rest.client.impl.ClientInvocationHandlerFactory.ILambda; -import ca.uhn.fhir.rest.method.BaseMethodBinding; +import ca.uhn.fhir.rest.client.method.BaseMethodBinding; public class ClientInvocationHandler extends BaseClient implements InvocationHandler { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandlerFactory.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandlerFactory.java index a7a3cd0d77a..396d4e82a56 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandlerFactory.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/ClientInvocationHandlerFactory.java @@ -28,10 +28,12 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.method.BaseMethodBinding; -import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IRestfulClient; +import ca.uhn.fhir.rest.client.method.BaseMethodBinding; public class ClientInvocationHandlerFactory { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java index b9e454e3eea..282a5a0ae49 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/GenericClient.java @@ -71,15 +71,35 @@ import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.UriDt; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.PatchTypeEnum; import ca.uhn.fhir.rest.api.PreferReturnEnum; +import ca.uhn.fhir.rest.api.SearchStyleEnum; import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor; +import ca.uhn.fhir.rest.client.method.DeleteMethodBinding; +import ca.uhn.fhir.rest.client.method.HistoryMethodBinding; +import ca.uhn.fhir.rest.client.method.HttpDeleteClientInvocation; +import ca.uhn.fhir.rest.client.method.HttpGetClientInvocation; +import ca.uhn.fhir.rest.client.method.HttpSimpleGetClientInvocation; +import ca.uhn.fhir.rest.client.method.IClientResponseHandler; +import ca.uhn.fhir.rest.client.method.MethodUtil; +import ca.uhn.fhir.rest.client.method.OperationMethodBinding; +import ca.uhn.fhir.rest.client.method.ReadMethodBinding; +import ca.uhn.fhir.rest.client.method.SearchMethodBinding; +import ca.uhn.fhir.rest.client.method.SortParameter; +import ca.uhn.fhir.rest.client.method.TransactionMethodBinding; +import ca.uhn.fhir.rest.client.method.ValidateMethodBindingDstu1; +import ca.uhn.fhir.rest.client.method.ValidateMethodBindingDstu2Plus; import ca.uhn.fhir.rest.gclient.IClientExecutable; import ca.uhn.fhir.rest.gclient.ICreate; import ca.uhn.fhir.rest.gclient.ICreateTyped; @@ -133,27 +153,9 @@ import ca.uhn.fhir.rest.gclient.IUpdateWithQuery; import ca.uhn.fhir.rest.gclient.IUpdateWithQueryTyped; import ca.uhn.fhir.rest.gclient.IValidate; import ca.uhn.fhir.rest.gclient.IValidateUntyped; -import ca.uhn.fhir.rest.method.DeleteMethodBinding; -import ca.uhn.fhir.rest.method.HistoryMethodBinding; -import ca.uhn.fhir.rest.method.HttpDeleteClientInvocation; -import ca.uhn.fhir.rest.method.HttpGetClientInvocation; -import ca.uhn.fhir.rest.method.HttpSimpleGetClientInvocation; -import ca.uhn.fhir.rest.method.IClientResponseHandler; -import ca.uhn.fhir.rest.method.MethodUtil; -import ca.uhn.fhir.rest.method.OperationMethodBinding; -import ca.uhn.fhir.rest.method.ReadMethodBinding; -import ca.uhn.fhir.rest.method.SearchMethodBinding; -import ca.uhn.fhir.rest.method.SearchStyleEnum; -import ca.uhn.fhir.rest.method.SortParameter; -import ca.uhn.fhir.rest.method.TransactionMethodBinding; -import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu1; -import ca.uhn.fhir.rest.method.ValidateMethodBindingDstu2Plus; import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.EncodingEnum; -import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.NotModifiedException; @@ -216,11 +218,7 @@ public class GenericClient extends BaseClient implements IGenericClient { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding(), isPrettyPrint()); } - RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); - final String resourceName = def.getName(); - - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); - + OutcomeResponseHandler binding = new OutcomeResponseHandler(); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; @@ -239,8 +237,7 @@ public class GenericClient extends BaseClient implements IGenericClient { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding(), isPrettyPrint()); } - final String resourceName = myContext.getResourceDefinition(theType).getName(); - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); + OutcomeResponseHandler binding = new OutcomeResponseHandler(); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; } @@ -555,10 +552,7 @@ public class GenericClient extends BaseClient implements IGenericClient { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding(), isPrettyPrint()); } - RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); - final String resourceName = def.getName(); - - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); + OutcomeResponseHandler binding = new OutcomeResponseHandler(); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; } @@ -586,10 +580,7 @@ public class GenericClient extends BaseClient implements IGenericClient { myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding(), isPrettyPrint()); } - RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource); - final String resourceName = def.getName(); - - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName); + OutcomeResponseHandler binding = new OutcomeResponseHandler(); MethodOutcome resp = invokeClient(myContext, binding, invocation, myLogRequestAndResponse); return resp; } @@ -742,7 +733,7 @@ public class GenericClient extends BaseClient implements IGenericClient { } protected IBaseResource parseResourceBody(String theResourceBody) { - EncodingEnum encoding = MethodUtil.detectEncodingNoDefault(theResourceBody); + EncodingEnum encoding = EncodingEnum.detectEncodingNoDefault(theResourceBody); if (encoding == null) { throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType")); } @@ -853,9 +844,7 @@ public class GenericClient extends BaseClient implements IGenericClient { addPreferHeader(myPrefer, invocation); RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource); - final String resourceName = def.getName(); - - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName, myPrefer); + OutcomeResponseHandler binding = new OutcomeResponseHandler(myPrefer); Map> params = new HashMap>(); return invoke(params, binding, invocation); @@ -1765,14 +1754,13 @@ public class GenericClient extends BaseClient implements IGenericClient { private final class OutcomeResponseHandler implements IClientResponseHandler { private PreferReturnEnum myPrefer; - // private final String myResourceName; - private OutcomeResponseHandler(String theResourceName) { - // myResourceName = theResourceName; + private OutcomeResponseHandler() { + super(); } - private OutcomeResponseHandler(String theResourceName, PreferReturnEnum thePrefer) { - this(theResourceName); + private OutcomeResponseHandler(PreferReturnEnum thePrefer) { + this(); myPrefer = thePrefer; } @@ -2357,7 +2345,7 @@ public class GenericClient extends BaseClient implements IGenericClient { public TransactionExecutable(String theBundle) { myRawBundle = theBundle; - myRawBundleEncoding = MethodUtil.detectEncodingNoDefault(myRawBundle); + myRawBundleEncoding = EncodingEnum.detectEncodingNoDefault(myRawBundle); if (myRawBundleEncoding == null) { throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType")); } @@ -2381,7 +2369,7 @@ public class GenericClient extends BaseClient implements IGenericClient { * If the user has explicitly requested a given encoding, we may need to re-encode the raw string */ if (getParamEncoding() != null) { - if (MethodUtil.detectEncodingNoDefault(myRawBundle) != getParamEncoding()) { + if (EncodingEnum.detectEncodingNoDefault(myRawBundle) != getParamEncoding()) { IBaseResource parsed = parseResourceBody(myRawBundle); myRawBundle = getParamEncoding().newParser(getFhirContext()).encodeResourceToString(parsed); } @@ -2480,7 +2468,7 @@ public class GenericClient extends BaseClient implements IGenericClient { addPreferHeader(myPrefer, invocation); - OutcomeResponseHandler binding = new OutcomeResponseHandler(null, myPrefer); + OutcomeResponseHandler binding = new OutcomeResponseHandler(myPrefer); Map> params = new HashMap>(); return invoke(params, binding, invocation); @@ -2529,7 +2517,7 @@ public class GenericClient extends BaseClient implements IGenericClient { myPatchBody = thePatchBody; - EncodingEnum encoding = MethodUtil.detectEncodingNoDefault(thePatchBody); + EncodingEnum encoding = EncodingEnum.detectEncodingNoDefault(thePatchBody); if (encoding == EncodingEnum.XML) { myPatchType = PatchTypeEnum.XML_PATCH; } else if (encoding == EncodingEnum.JSON) { @@ -2607,9 +2595,7 @@ public class GenericClient extends BaseClient implements IGenericClient { addPreferHeader(myPrefer, invocation); RuntimeResourceDefinition def = myContext.getResourceDefinition(myResource); - final String resourceName = def.getName(); - - OutcomeResponseHandler binding = new OutcomeResponseHandler(resourceName, myPrefer); + OutcomeResponseHandler binding = new OutcomeResponseHandler(myPrefer); Map> params = new HashMap>(); return invoke(params, binding, invocation); @@ -2693,7 +2679,7 @@ public class GenericClient extends BaseClient implements IGenericClient { Validate.notBlank(theResourceRaw, "theResourceRaw must not be null or blank"); myResource = parseResourceBody(theResourceRaw); - EncodingEnum enc = MethodUtil.detectEncodingNoDefault(theResourceRaw); + EncodingEnum enc = EncodingEnum.detectEncodingNoDefault(theResourceRaw); if (enc == null) { throw new IllegalArgumentException(myContext.getLocalizer().getMessage(GenericClient.class, "cantDetermineRequestType")); } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/HttpBasicAuthInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/HttpBasicAuthInterceptor.java index a9cdbc5fef5..dc37d763168 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/HttpBasicAuthInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/HttpBasicAuthInterceptor.java @@ -12,7 +12,9 @@ import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.auth.BasicScheme; import org.apache.http.protocol.HttpContext; -import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.client.api.IBasicClient; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IGenericClient; /* * #%L diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/RestfulClientFactory.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/RestfulClientFactory.java index 01149c73691..8e0836da5fd 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/RestfulClientFactory.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/impl/RestfulClientFactory.java @@ -23,42 +23,31 @@ package ca.uhn.fhir.rest.client.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.Map; -import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; -import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IPrimitiveType; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.FhirVersionEnum; -import ca.uhn.fhir.parser.DataFormatException; -import ca.uhn.fhir.rest.client.*; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException; -import ca.uhn.fhir.rest.client.exceptions.FhirClientInappropriateForServerException; -import ca.uhn.fhir.rest.method.BaseMethodBinding; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.util.FhirTerser; +import ca.uhn.fhir.rest.client.api.IGenericClient; +import ca.uhn.fhir.rest.client.api.IHttpClient; +import ca.uhn.fhir.rest.client.api.IRestfulClient; +import ca.uhn.fhir.rest.client.api.IRestfulClientFactory; +import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum; +import ca.uhn.fhir.rest.client.method.BaseMethodBinding; /** * Base class for a REST client factory implementation */ public abstract class RestfulClientFactory implements IRestfulClientFactory { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestfulClientFactory.class); private int myConnectionRequestTimeout = DEFAULT_CONNECTION_REQUEST_TIMEOUT; private int myConnectTimeout = DEFAULT_CONNECT_TIMEOUT; private FhirContext myContext; private Map, ClientInvocationHandlerFactory> myInvocationHandlers = new HashMap, ClientInvocationHandlerFactory>(); private ServerValidationModeEnum myServerValidationMode = DEFAULT_SERVER_VALIDATION_MODE; private int mySocketTimeout = DEFAULT_SOCKET_TIMEOUT; - private Set myValidatedServerBaseUrls = Collections.synchronizedSet(new HashSet()); private String myProxyUsername; private String myProxyPassword; private int myPoolMaxTotal = DEFAULT_POOL_MAX; @@ -192,21 +181,6 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory { return new GenericClient(myContext, httpClient, theServerBase, this); } - @Override - public void validateServerBaseIfConfiguredToDoSo(String theServerBase, IHttpClient theHttpClient, BaseClient theClient) { - String serverBase = normalizeBaseUrlForMap(theServerBase); - - switch (getServerValidationMode()) { - case NEVER: - break; - case ONCE: - if (!myValidatedServerBaseUrls.contains(serverBase)) { - validateServerBase(serverBase, theHttpClient, theClient); - } - break; - } - - } private String normalizeBaseUrlForMap(String theServerBase) { String serverBase = theServerBase; @@ -270,84 +244,6 @@ public abstract class RestfulClientFactory implements IRestfulClientFactory { resetHttpClient(); } - @SuppressWarnings("unchecked") - @Override - public void validateServerBase(String theServerBase, IHttpClient theHttpClient, BaseClient theClient) { - GenericClient client = new GenericClient(myContext, theHttpClient, theServerBase, this); - client.setEncoding(theClient.getEncoding()); - for (IClientInterceptor interceptor : theClient.getInterceptors()) { - client.registerInterceptor(interceptor); - } - client.setDontValidateConformance(true); - - IBaseResource conformance; - try { - String capabilityStatementResourceName = "CapabilityStatement"; - if (myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { - capabilityStatementResourceName = "Conformance"; - } - - @SuppressWarnings("rawtypes") - Class implementingClass; - try { - implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass(); - } catch (DataFormatException e) { - if (!myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3)) { - capabilityStatementResourceName = "Conformance"; - implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass(); - } else { - throw e; - } - } - try { - conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute(); - } catch (FhirClientConnectionException e) { - if (!myContext.getVersion().getVersion().isOlderThan(FhirVersionEnum.DSTU3) && e.getCause() instanceof DataFormatException) { - capabilityStatementResourceName = "Conformance"; - implementingClass = myContext.getResourceDefinition(capabilityStatementResourceName).getImplementingClass(); - conformance = (IBaseResource) client.fetchConformance().ofType(implementingClass).execute(); - } else { - throw e; - } - } - } catch (FhirClientConnectionException e) { - String msg = myContext.getLocalizer().getMessage(RestfulClientFactory.class, "failedToRetrieveConformance", theServerBase + Constants.URL_TOKEN_METADATA); - throw new FhirClientConnectionException(msg, e); - } - - FhirTerser t = myContext.newTerser(); - String serverFhirVersionString = null; - Object value = t.getSingleValueOrNull(conformance, "fhirVersion"); - if (value instanceof IPrimitiveType) { - serverFhirVersionString = IPrimitiveType.class.cast(value).getValueAsString(); - } - FhirVersionEnum serverFhirVersionEnum = null; - if (StringUtils.isBlank(serverFhirVersionString)) { - // we'll be lenient and accept this - } else { - //FIXME null access on serverFhirVersionString - if (serverFhirVersionString.startsWith("0.80") || serverFhirVersionString.startsWith("0.0.8")) { - serverFhirVersionEnum = FhirVersionEnum.DSTU1; - } else if (serverFhirVersionString.startsWith("0.4")) { - serverFhirVersionEnum = FhirVersionEnum.DSTU2; - } else if (serverFhirVersionString.startsWith("0.5")) { - serverFhirVersionEnum = FhirVersionEnum.DSTU2; - } else { - // we'll be lenient and accept this - ourLog.debug("Server conformance statement indicates unknown FHIR version: {}", serverFhirVersionString); - } - } - - if (serverFhirVersionEnum != null) { - FhirVersionEnum contextFhirVersion = myContext.getVersion().getVersion(); - if (!contextFhirVersion.isEquivalentTo(serverFhirVersionEnum)) { - throw new FhirClientInappropriateForServerException(myContext.getLocalizer().getMessage(RestfulClientFactory.class, "wrongVersionInConformance", theServerBase + Constants.URL_TOKEN_METADATA, serverFhirVersionString, serverFhirVersionEnum, contextFhirVersion)); - } - } - - myValidatedServerBaseUrls.add(normalizeBaseUrlForMap(theServerBase)); - - } @Deprecated //override deprecated method @Override diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java index 6f6704cfa98..231f6328d10 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BasicAuthInterceptor.java @@ -26,8 +26,9 @@ import java.io.UnsupportedEncodingException; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang3.StringUtils; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.client.api.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; /** diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java index 760606f1265..f7872d9be2b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/BearerTokenAuthInterceptor.java @@ -22,8 +22,9 @@ package ca.uhn.fhir.rest.client.interceptor; import org.apache.commons.lang3.Validate; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; import ca.uhn.fhir.util.CoverageIgnore; /** diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java index bf52f9330c5..765daf9459c 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CapturingInterceptor.java @@ -1,11 +1,14 @@ package ca.uhn.fhir.rest.client.interceptor; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import java.io.IOException; + import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; -import java.io.IOException; +import ca.uhn.fhir.rest.client.api.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; /** * Client interceptor which simply captures request and response objects and stores them so that they can be inspected after a client diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java index f244a1eb2fd..baa3a3cd413 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/CookieInterceptor.java @@ -1,7 +1,8 @@ package ca.uhn.fhir.rest.client.interceptor; -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; /** * HTTP interceptor to be used for adding Cookie to requests. diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java index 521607da9c1..41a3ce05c0a 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/LoggingInterceptor.java @@ -30,7 +30,9 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.Validate; import org.slf4j.Logger; -import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.client.api.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 { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/SimpleRequestHeaderInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/SimpleRequestHeaderInterceptor.java index 162bc186fc9..f57c926c78b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/SimpleRequestHeaderInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/SimpleRequestHeaderInterceptor.java @@ -23,14 +23,10 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; */ import java.io.IOException; -import java.io.UnsupportedEncodingException; -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.lang3.StringUtils; - -import ca.uhn.fhir.rest.client.api.*; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.client.api.IClientInterceptor; +import ca.uhn.fhir.rest.client.api.IHttpRequest; +import ca.uhn.fhir.rest.client.api.IHttpResponse; /** * This interceptor adds an arbitrary header to requests made by this client. Both the diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java index 13b3ffbe1d3..770ef39cf51 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/interceptor/UserInfoInterceptor.java @@ -22,7 +22,9 @@ package ca.uhn.fhir.rest.client.interceptor; import java.io.IOException; -import ca.uhn.fhir.rest.client.api.*; +import ca.uhn.fhir.rest.client.api.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 diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/AtParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/AtParameter.java index 0ded43dbb70..b06ba0a7290 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/AtParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/AtParameter.java @@ -21,7 +21,7 @@ package ca.uhn.fhir.rest.client.method; */ import ca.uhn.fhir.rest.annotation.At; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.api.Constants; class AtParameter extends SinceOrAtParameter { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseAddOrDeleteTagsMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseAddOrDeleteTagsMethodBinding.java index a62970e4db6..d0237b8596f 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseAddOrDeleteTagsMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseAddOrDeleteTagsMethodBinding.java @@ -1,26 +1,5 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.io.IOException; import java.io.Reader; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -33,15 +12,15 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.TagListParam; -import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.exceptions.*; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; +import ca.uhn.fhir.rest.param.IParameter; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding { @@ -54,11 +33,7 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding public BaseAddOrDeleteTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, Class theTypeFromMethodAnnotation) { super(theMethod, theContext, theProvider); - if (theProvider instanceof IResourceProvider) { - myType = ((IResourceProvider) theProvider).getResourceType(); - } else { - myType = theTypeFromMethodAnnotation; - } + myType = theTypeFromMethodAnnotation; if (Modifier.isInterface(myType.getModifiers())) { 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"); @@ -145,65 +120,6 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding return retVal; } - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - Object[] params = createParametersForServerRequest(theRequest); - params[myIdParamIndex] = theRequest.getId(); - - if (myVersionIdParamIndex != null) { - params[myVersionIdParamIndex] = theRequest.getId(); - } - - IParser parser = createAppropriateParserForParsingServerRequest(theRequest); - Reader reader = theRequest.getReader(); - try { - TagList tagList = parser.parseTagList(reader); - params[myTagListParamIndex] = tagList; - } finally { - reader.close(); - } - invokeServerMethod(theServer, theRequest, params); - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest); - if (!continueProcessing) { - return null; - } - } - - return theRequest.getResponse().returnResponse(null, Constants.STATUS_HTTP_200_OK, false, null, null); - } - - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (theRequest.getRequestType() != RequestTypeEnum.POST) { - return false; - } - if (!Constants.PARAM_TAGS.equals(theRequest.getOperation())) { - return false; - } - - if (!myResourceName.equals(theRequest.getResourceName())) { - return false; - } - - if (theRequest.getId() == null) { - return false; - } - - if (isDelete()) { - if (Constants.PARAM_DELETE.equals(theRequest.getSecondaryOperation()) == false) { - return false; - } - } else { - if (theRequest.getSecondaryOperation() != null) { - return false; - } - } - - return true; - } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseHttpClientInvocationWithContents.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseHttpClientInvocationWithContents.java index a8c87854c3b..4da831809db 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseHttpClientInvocationWithContents.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseHttpClientInvocationWithContents.java @@ -38,12 +38,12 @@ import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.api.server.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.client.api.IHttpClient; import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.EncodingEnum; /** * @author James Agnew @@ -194,7 +194,7 @@ abstract class BaseHttpClientInvocationWithContents extends BaseHttpClientInvoca EncodingEnum encoding = theEncoding; if (myContents != null) { - encoding = MethodUtil.detectEncoding(myContents); + encoding = EncodingEnum.detectEncoding(myContents); } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseJavaPrimitiveBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseJavaPrimitiveBinder.java index 12cb1a36ab2..4ae5e0e0d5d 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseJavaPrimitiveBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseJavaPrimitiveBinder.java @@ -27,6 +27,7 @@ import java.util.List; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterOr; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.param.StringParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseMethodBinding.java index 7b4d2fa87be..3f7ba8ed4f2 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseMethodBinding.java @@ -1,34 +1,9 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ -import static org.apache.commons.lang3.StringUtils.isBlank; - import java.io.IOException; -import java.io.InputStream; import java.io.Reader; -import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.TreeSet; @@ -42,22 +17,31 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; 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.TagList; import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; import ca.uhn.fhir.parser.IParser; -import ca.uhn.fhir.rest.annotation.*; +import ca.uhn.fhir.rest.annotation.AddTags; +import ca.uhn.fhir.rest.annotation.Create; +import ca.uhn.fhir.rest.annotation.Delete; +import ca.uhn.fhir.rest.annotation.DeleteTags; +import ca.uhn.fhir.rest.annotation.GetPage; +import ca.uhn.fhir.rest.annotation.GetTags; +import ca.uhn.fhir.rest.annotation.History; +import ca.uhn.fhir.rest.annotation.Metadata; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.Patch; +import ca.uhn.fhir.rest.annotation.Read; +import ca.uhn.fhir.rest.annotation.Search; +import ca.uhn.fhir.rest.annotation.Transaction; +import ca.uhn.fhir.rest.annotation.Update; +import ca.uhn.fhir.rest.annotation.Validate; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.BundleProviders; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.EncodingEnum; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider; -import ca.uhn.fhir.rest.server.IResourceProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; @@ -67,9 +51,6 @@ import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; import ca.uhn.fhir.util.ReflectionUtil; public abstract class BaseMethodBinding implements IClientResponseHandler { @@ -112,45 +93,12 @@ public abstract class BaseMethodBinding implements IClientResponseHandler } IParser parser = encoding.newParser(getContext()); - + parser.setPreferTypes(thePreferTypes); - + return parser; } - protected IParser createAppropriateParserForParsingServerRequest(RequestDetails theRequest) { - String contentTypeHeader = theRequest.getHeader(Constants.HEADER_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(RequestDetails theRequest) { - 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, this); - } - return params; - } - public List> getAllowableParamAnnotations() { return null; } @@ -181,43 +129,6 @@ public abstract class BaseMethodBinding implements IClientResponseHandler return myProvider; } - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Set getRequestIncludesFromParams(Object[] params) { - if (params == null || params.length == 0) { - return null; - } - int index = 0; - boolean match = false; - for (IParameter parameter : myParameters) { - if (parameter instanceof IncludeParameter) { - match = true; - break; - } - index++; - } - if (!match) { - return null; - } - if (index >= params.length) { - ourLog.warn("index out of parameter range (should never happen"); - return null; - } - if (params[index] instanceof Set) { - return (Set) params[index]; - } - if (params[index] instanceof Iterable) { - Set includes = new HashSet(); - for (Object o : (Iterable) params[index]) { - if (o instanceof Include) { - includes.add(o); - } - } - return includes; - } - ourLog.warn("include params wasn't Set or Iterable, it was {}", params[index].getClass()); - return null; - } - /** * Returns the name of the resource this method handles, or null if this method is not resource specific */ @@ -225,47 +136,8 @@ public abstract class BaseMethodBinding implements IClientResponseHandler public abstract RestOperationTypeEnum getRestOperationType(); - /** - * Determine which operation is being fired for a specific request - * - * @param theRequestDetails - * The request - */ - public RestOperationTypeEnum getRestOperationType(RequestDetails theRequestDetails) { - return getRestOperationType(); - } - - public abstract boolean incomingServerRequestMatchesMethod(RequestDetails theRequest); - public abstract BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException; - public abstract Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException; - - protected final Object invokeServerMethod(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) { - // Handle server action interceptors - RestOperationTypeEnum operationType = getRestOperationType(theRequest); - if (operationType != null) { - for (IServerInterceptor next : theServer.getInterceptors()) { - ActionRequestDetails details = new ActionRequestDetails(theRequest); - populateActionRequestDetailsForInterceptor(theRequest, details, theMethodParams); - next.incomingRequestPreHandled(operationType, details); - } - } - - // Actually invoke the method - try { - Method method = getMethod(); - return method.invoke(getProvider(), theMethodParams); - } catch (InvocationTargetException e) { - if (e.getCause() instanceof BaseServerResponseException) { - throw (BaseServerResponseException) e.getCause(); - } - throw new InternalErrorException("Failed to call access method", e); - } catch (Exception e) { - throw new InternalErrorException("Failed to call access method", e); - } - } - /** * Does this method have a parameter annotated with {@link ConditionalParamBinder}. Note that many operations don't actually support this paramter, so this will only return true occasionally. */ @@ -280,21 +152,6 @@ public abstract class BaseMethodBinding implements IClientResponseHandler return mySupportsConditionalMultiple; } - /** - * Subclasses may override this method (but should also call super.{@link #populateActionRequestDetailsForInterceptor(RequestDetails, ActionRequestDetails, Object[])} to provide method specifics to the - * interceptors. - * - * @param theRequestDetails - * The server request details - * @param theDetails - * The details object to populate - * @param theMethodParams - * The method params as generated by the specific method binding - */ - protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) { - // nothing by default - } - protected BaseServerResponseException processNon2xxResponseAndReturnExceptionToThrow(int theStatusCode, String theResponseMimeType, Reader theResponseReader) { BaseServerResponseException ex; switch (theStatusCode) { @@ -333,30 +190,6 @@ public abstract class BaseMethodBinding implements IClientResponseHandler myParameters = theParameters; } - protected IBundleProvider toResourceList(Object response) throws InternalErrorException { - if (response == null) { - return BundleProviders.newEmptyList(); - } else if (response instanceof IBundleProvider) { - return (IBundleProvider) response; - } else if (response instanceof IBaseResource) { - return BundleProviders.newList((IBaseResource) response); - } else if (response instanceof Collection) { - List retVal = new ArrayList(); - for (Object next : ((Collection) response)) { - retVal.add((IBaseResource) next); - } - return BundleProviders.newList(retVal); - } else if (response instanceof MethodOutcome) { - IBaseResource retVal = ((MethodOutcome) response).getOperationOutcome(); - if (retVal == null) { - retVal = getContext().getResourceDefinition("OperationOutcome").newInstance(); - } - return BundleProviders.newList(retVal); - } else { - throw new InternalErrorException("Unexpected return type: " + response.getClass().getCanonicalName()); - } - } - @SuppressWarnings("unchecked") public static BaseMethodBinding bindMethod(Method theMethod, FhirContext theContext, Object theProvider) { Read read = theMethod.getAnnotation(Read.class); @@ -376,24 +209,18 @@ public abstract class BaseMethodBinding implements IClientResponseHandler Patch patch = theMethod.getAnnotation(Patch.class); // ** if you add another annotation above, also add it to the next line: - if (!verifyMethodHasZeroOrOneOperationAnnotation(theMethod, read, search, conformance, create, update, delete, history, validate, getTags, addTags, deleteTags, transaction, operation, getPage, patch)) { + if (!verifyMethodHasZeroOrOneOperationAnnotation(theMethod, read, search, conformance, create, update, delete, history, validate, getTags, addTags, deleteTags, transaction, operation, getPage, + patch)) { return null; } if (getPage != null) { return new PageMethodBinding(theContext, theMethod); } - + Class returnType; Class returnTypeFromRp = null; - if (theProvider instanceof IResourceProvider) { - returnTypeFromRp = ((IResourceProvider) theProvider).getResourceType(); - if (!verifyIsValidResourceReturnType(returnTypeFromRp)) { - throw new ConfigurationException("getResourceType() from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returned " - + toLogString(returnTypeFromRp) + " - Must return a resource type"); - } - } Class returnTypeFromMethod = theMethod.getReturnType(); if (getTags != null) { @@ -403,8 +230,6 @@ public abstract class BaseMethodBinding implements IClientResponseHandler } } else if (MethodOutcome.class.isAssignableFrom(returnTypeFromMethod)) { // returns a method outcome - } else if (IBundleProvider.class.equals(returnTypeFromMethod)) { - // returns a bundle provider } else if (Bundle.class.equals(returnTypeFromMethod)) { // returns a bundle } else if (void.class.equals(returnTypeFromMethod)) { @@ -414,14 +239,14 @@ public abstract class BaseMethodBinding implements IClientResponseHandler if (returnTypeFromMethod == null) { ourLog.trace("Method {} returns a non-typed list, can't verify return type", theMethod); } else if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !isResourceInterface(returnTypeFromMethod)) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + throw new ConfigurationException("Method '" + theMethod.getName() + "' from client type " + theMethod.getDeclaringClass().getCanonicalName() + " returns a collection with generic type " + toLogString(returnTypeFromMethod) + " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List or List )"); } } else { if (!isResourceInterface(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() - + " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + throw new ConfigurationException("Method '" + theMethod.getName() + "' from client type " + theMethod.getDeclaringClass().getCanonicalName() + + " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, " + Bundle.class.getSimpleName() + ", etc., see the documentation for more details)"); } } @@ -451,48 +276,26 @@ public abstract class BaseMethodBinding implements IClientResponseHandler returnTypeFromAnnotation = deleteTags.type(); } - if (returnTypeFromRp != null) { - if (returnTypeFromAnnotation != null && !isResourceInterface(returnTypeFromAnnotation)) { - if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) { - //FIXME potential null access on retunrTypeFromMethod - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " - + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract"); - } - if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) { - throw new ConfigurationException( - "Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " claims to return type " + returnTypeFromAnnotation.getCanonicalName() - + " per method annotation - Must return " + returnTypeFromRp.getCanonicalName() + " (or a subclass of it) per IResourceProvider contract"); - } - returnType = returnTypeFromAnnotation; - } else { - returnType = returnTypeFromRp; + if (!isResourceInterface(returnTypeFromAnnotation)) { + if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) { + throw new ConfigurationException("Method '" + theMethod.getName() + "' from client type " + theMethod.getDeclaringClass().getCanonicalName() + + " returns " + toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type"); } + returnType = returnTypeFromAnnotation; } else { - if (!isResourceInterface(returnTypeFromAnnotation)) { - if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() - + " returns " + toLogString(returnTypeFromAnnotation) + " according to annotation - Must return a resource type"); - } - returnType = returnTypeFromAnnotation; - } else { - // if (IRestfulClient.class.isAssignableFrom(theMethod.getDeclaringClass())) { - // Clients don't define their methods in resource specific types, so they can - // infer their resource type from the method return type. - returnType = (Class) returnTypeFromMethod; - // } else { - // This is a plain provider method returning a resource, so it should be - // an operation or global search presumably - // returnType = null; - } + // if (IRestfulClient.class.isAssignableFrom(theMethod.getDeclaringClass())) { + // Clients don't define their methods in resource specific types, so they can + // infer their resource type from the method return type. + returnType = (Class) returnTypeFromMethod; + // } else { + // This is a plain provider method returning a resource, so it should be + // an operation or global search presumably + // returnType = null; } if (read != null) { return new ReadMethodBinding(returnType, theMethod, theContext, theProvider); } else if (search != null) { - if (search.dynamic()) { - IDynamicSearchResourceProvider provider = (IDynamicSearchResourceProvider) theProvider; - return new DynamicSearchMethodBinding(returnType, theMethod, theContext, provider); - } return new SearchMethodBinding(returnType, theMethod, theContext, theProvider); } else if (conformance != null) { return new ConformanceMethodBinding(theMethod, theContext, theProvider); @@ -602,31 +405,4 @@ public abstract class BaseMethodBinding implements IClientResponseHandler return true; } - /** - * @see ServletRequestDetails#getByteStreamRequestContents() - */ - public static class ActiveRequestReader implements IRequestReader { - @Override - public InputStream getInputStream(RequestDetails theRequestDetails) throws IOException { - return theRequestDetails.getInputStream(); - } - } - - /** - * @see ServletRequestDetails#getByteStreamRequestContents() - */ - public static class InactiveRequestReader implements IRequestReader { - @Override - public InputStream getInputStream(RequestDetails theRequestDetails) { - throw new IllegalStateException("The servlet-api JAR is not found on the classpath. Please check that this library is available."); - } - } - - /** - * @see ServletRequestDetails#getByteStreamRequestContents() - */ - public static interface IRequestReader { - InputStream getInputStream(RequestDetails theRequestDetails) throws IOException; - } - } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBinding.java index 2bcc7195b59..8c0a67a0912 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBinding.java @@ -1,61 +1,25 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.io.IOException; import java.io.Reader; -import java.io.Writer; import java.lang.reflect.Method; -import java.util.Collections; import java.util.EnumSet; import java.util.List; import java.util.Map; import java.util.Set; -import javax.servlet.http.HttpServletResponse; - import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; -import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IResource; -import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.api.PreferReturnEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; -import ca.uhn.fhir.rest.api.SummaryEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.EncodingEnum; -import ca.uhn.fhir.rest.server.IRestfulResponse; -import ca.uhn.fhir.rest.server.IRestfulServer; -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.interceptor.IServerInterceptor; abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding { static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseOutcomeReturningMethodBinding.class); @@ -76,8 +40,6 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding allowableRequestTypes = provideAllowableRequestTypes(); - RequestTypeEnum requestType = theRequest.getRequestType(); - if (!allowableRequestTypes.contains(requestType)) { - return false; - } - if (!getResourceName().equals(theRequest.getResourceName())) { - return false; - } - if (getMatchingOperation() == null && StringUtils.isNotBlank(theRequest.getOperation())) { - return false; - } - if (getMatchingOperation() != null && !getMatchingOperation().equals(theRequest.getOperation())) { - return false; - } - - /* - * Note: Technically this will match an update (PUT) method even if - * there is no ID in the URL - We allow this here because there is no - * better match for that, and this allows the update/PUT method to give - * a helpful error if the client has forgotten to include the - * ID in the URL. - * - * It's also needed for conditional update.. - */ - - return true; - } @Override public MethodOutcome invokeClient(String theResponseMimeType, Reader theResponseReader, int theResponseStatusCode, Map> theHeaders) throws BaseServerResponseException { @@ -168,121 +101,13 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - - Object[] params = createParametersForServerRequest(theRequest); - addParametersForServerRequest(theRequest, params); - - /* - * No need to catch and handle exceptions here, we already handle them one level up including invoking interceptors - * on them - */ - MethodOutcome response; - Object methodReturn = invokeServerMethod(theServer, theRequest, params); - - if (methodReturn instanceof IBaseOperationOutcome) { - response = new MethodOutcome(); - response.setOperationOutcome((IBaseOperationOutcome) methodReturn); - } else { - response = (MethodOutcome) methodReturn; - } - - if (response != null && response.getId() != null && response.getId().hasResourceType()) { - if (getContext().getResourceDefinition(response.getId().getResourceType()) == null) { - throw new InternalErrorException("Server method returned invalid resource ID: " + response.getId().getValue()); - } - } - - IBaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null; - IBaseResource resource = response != null ? response.getResource() : null; - - return returnResponse(theServer, theRequest, response, outcome, resource); - } public boolean isReturnVoid() { return myReturnVoid; } protected abstract Set provideAllowableRequestTypes(); - private Object returnResponse(IRestfulServer theServer, RequestDetails theRequest, MethodOutcome response, IBaseResource originalOutcome, IBaseResource resource) throws IOException { - boolean allowPrefer = false; - int operationStatus = getOperationStatus(response); - IBaseResource outcome = originalOutcome; - if (ourOperationsWhichAllowPreferHeader.contains(getRestOperationType())) { - allowPrefer = true; - } - - if (resource != null && allowPrefer) { - String prefer = theRequest.getHeader(Constants.HEADER_PREFER); - PreferReturnEnum preferReturn = RestfulServerUtils.parsePreferHeader(prefer); - if (preferReturn != null) { - if (preferReturn == PreferReturnEnum.REPRESENTATION) { - outcome = resource; - } - } - } - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest, outcome); - if (!continueProcessing) { - return null; - } - } - - IRestfulResponse restfulResponse = theRequest.getResponse(); - - if (response != null) { - if (response.getResource() != null) { - restfulResponse.setOperationResourceLastUpdated(RestfulServerUtils.extractLastUpdatedFromResource(response.getResource())); - } - - IIdType responseId = response.getId(); - if (responseId != null && responseId.getResourceType() == null && responseId.hasIdPart()) { - responseId = responseId.withResourceType(getResourceName()); - } - - if (responseId != null) { - String serverBase = theRequest.getFhirServerBase(); - responseId = RestfulServerUtils.fullyQualifyResourceIdOrReturnNull(theServer, resource, serverBase, responseId); - restfulResponse.setOperationResourceId(responseId); - } - } - - boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest); - Set summaryMode = Collections.emptySet(); - - return restfulResponse.streamResponseAsResource(outcome, prettyPrint, summaryMode, operationStatus, null, theRequest.isRespondGzip(), true); -// return theRequest.getResponse().returnResponse(ParseAction.create(outcome), operationStatus, allowPrefer, response, getResourceName()); - } - - protected void streamOperationOutcome(BaseServerResponseException theE, RestfulServer theServer, EncodingEnum theEncodingNotNull, HttpServletResponse theResponse, RequestDetails theRequest) throws IOException { - theResponse.setStatus(theE.getStatusCode()); - - theServer.addHeadersToResponse(theResponse); - - if (theE.getOperationOutcome() != null) { - theResponse.setContentType(theEncodingNotNull.getResourceContentType()); - IParser parser = theEncodingNotNull.newParser(theServer.getFhirContext()); - parser.setPrettyPrint(RestfulServerUtils.prettyPrintResponse(theServer, theRequest)); - Writer writer = theResponse.getWriter(); - try { - parser.encodeResourceToWriter(theE.getOperationOutcome(), writer); - } finally { - writer.close(); - } - } else { - theResponse.setContentType(Constants.CT_TEXT); - Writer writer = theResponse.getWriter(); - try { - writer.append(theE.getMessage()); - } finally { - writer.close(); - } - } - } protected static void parseContentLocation(FhirContext theContext, MethodOutcome theOutcomeToPopulate, String theLocationHeader) { if (StringUtils.isBlank(theLocationHeader)) { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBindingWithResourceParam.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBindingWithResourceParam.java index 6f4735a94f2..ca24ecbeaed 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBindingWithResourceParam.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseOutcomeReturningMethodBindingWithResourceParam.java @@ -34,6 +34,7 @@ import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.rest.annotation.ResourceParam; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseQueryParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseQueryParameter.java new file mode 100644 index 00000000000..96e48dc8a60 --- /dev/null +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseQueryParameter.java @@ -0,0 +1,94 @@ +package ca.uhn.fhir.rest.client.method; + +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2017 University Health Network + * %% + * Licensed 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. + * #L% + */ + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.hl7.fhir.instance.model.api.IBaseResource; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.QualifiedParamList; +import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; + +public abstract class BaseQueryParameter implements IParameter { + + public abstract List encode(FhirContext theContext, Object theObject) throws InternalErrorException; + + public abstract String getName(); + + public abstract RestSearchParameterTypeEnum getParamType(); + + /** + * Parameter should return true if {@link #parse(FhirContext, List)} should be called even if the query string + * contained no values for the given parameter + */ + public abstract boolean handlesMissing(); + + @Override + public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { + // ignore for now + } + + public abstract boolean isRequired(); + + public abstract Object parse(FhirContext theContext, List theString) throws InternalErrorException, InvalidRequestException; + + @Override + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { + if (theSourceClientArgument == null) { + if (isRequired()) { + throw new NullPointerException("SearchParameter '" + getName() + "' is required and may not be null"); + } + } else { + List value = encode(theContext, theSourceClientArgument); + + for (QualifiedParamList nextParamEntry : value) { + StringBuilder b = new StringBuilder(); + for (String str : nextParamEntry) { + if (b.length() > 0) { + b.append(","); + } + b.append(str); + } + + String qualifier = nextParamEntry.getQualifier(); + String paramName = isNotBlank(qualifier) ? getName() + qualifier : getName(); + List paramValues = theTargetQueryArguments.get(paramName); + if (paramValues == null) { + paramValues = new ArrayList(value.size()); + theTargetQueryArguments.put(paramName, paramValues); + } + + paramValues.add(b.toString()); + } + + } + } + +} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseResourceReturningMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseResourceReturningMethodBinding.java index 75432f8593a..8659aaf6f68 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseResourceReturningMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/BaseResourceReturningMethodBinding.java @@ -1,61 +1,33 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; - -import java.io.IOException; import java.io.Reader; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.hl7.fhir.instance.model.api.IBaseBundle; import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; import org.hl7.fhir.instance.model.api.IBaseResource; -import org.hl7.fhir.instance.model.api.IPrimitiveType; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; 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.valueset.BundleTypeEnum; import ca.uhn.fhir.parser.IParser; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.MethodOutcome; -import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.api.server.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException; -import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding; -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.exceptions.ResourceNotFoundException; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; -import ca.uhn.fhir.rest.server.interceptor.ResponseHighlighterInterceptor; import ca.uhn.fhir.util.BundleUtil; import ca.uhn.fhir.util.ReflectionUtil; -import ca.uhn.fhir.util.UrlUtil; public abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding { protected static final Set ALLOWED_PARAMS; @@ -72,7 +44,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi set.add(Constants.PARAM_COUNT); set.add(Constants.PARAM_SUMMARY); set.add(Constants.PARAM_ELEMENTS); - set.add(ResponseHighlighterInterceptor.PARAM_RAW); ALLOWED_PARAMS = Collections.unmodifiableSet(set); } @@ -107,8 +78,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi } } else if (Bundle.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.BUNDLE; - } else if (IBundleProvider.class.isAssignableFrom(methodReturnType)) { - myMethodReturnType = MethodReturnTypeEnum.BUNDLE_PROVIDER; } else if (MethodOutcome.class.isAssignableFrom(methodReturnType)) { myMethodReturnType = MethodReturnTypeEnum.METHOD_OUTCOME; } else { @@ -195,8 +164,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi } else { throw new InvalidResponseException(theResponseStatusCode, "FHIR server call returned a bundle with multiple resources, but this method is only able to returns one."); } - case BUNDLE_PROVIDER: - throw new IllegalStateException("Return type of " + IBundleProvider.class.getSimpleName() + " is not supported in clients"); default: break; } @@ -219,8 +186,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi return Collections.singletonList(resource); case RESOURCE: return resource; - case BUNDLE_PROVIDER: - throw new IllegalStateException("Return type of " + IBundleProvider.class.getSimpleName() + " is not supported in clients"); case BUNDLE_RESOURCE: return resource; case METHOD_OUTCOME: @@ -248,176 +213,6 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi return preferTypes; } - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - - final ResourceOrDstu1Bundle responseObject = doInvokeServer(theServer, theRequest); - - Set summaryMode = RestfulServerUtils.determineSummaryMode(theRequest); - if (responseObject.getResource() != null) { - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getResource()); - if (!continueProcessing) { - return null; - } - } - - boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest); - - return theRequest.getResponse().streamResponseAsResource(responseObject.getResource(), prettyPrint, summaryMode, Constants.STATUS_HTTP_200_OK, null, theRequest.isRespondGzip(), - isAddContentLocationHeader()); - - } - // Is this request coming from a browser - String uaHeader = theRequest.getHeader("user-agent"); - boolean requestIsBrowser = false; - if (uaHeader != null && uaHeader.contains("Mozilla")) { - requestIsBrowser = true; - } - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest, responseObject.getDstu1Bundle()); - if (!continueProcessing) { - ourLog.debug("Interceptor {} returned false, not continuing processing"); - return null; - } - } - - return theRequest.getResponse().streamResponseAsBundle(responseObject.getDstu1Bundle(), summaryMode, theRequest.isRespondGzip(), requestIsBrowser); - } - - public ResourceOrDstu1Bundle doInvokeServer(IRestfulServer theServer, RequestDetails 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, this); - } - } - - Object resultObj = invokeServer(theServer, theRequest, params); - - Integer count = RestfulServerUtils.extractCountParameter(theRequest); - - final ResourceOrDstu1Bundle responseObject; - - switch (getReturnType()) { - case BUNDLE: { - - /* - * Figure out the self-link for this request - */ - String serverBase = theRequest.getServerBaseForRequest(); - String linkSelf; - StringBuilder b = new StringBuilder(); - b.append(serverBase); - if (isNotBlank(theRequest.getRequestPath())) { - b.append('/'); - b.append(theRequest.getRequestPath()); - } - // For POST the URL parameters get jumbled with the post body parameters so don't include them, they might be huge - if (theRequest.getRequestType() == RequestTypeEnum.GET) { - boolean first = true; - Map parameters = theRequest.getParameters(); - for (String nextParamName : new TreeSet(parameters.keySet())) { - for (String nextParamValue : parameters.get(nextParamName)) { - if (first) { - b.append('?'); - first = false; - } else { - b.append('&'); - } - b.append(UrlUtil.escape(nextParamName)); - b.append('='); - b.append(UrlUtil.escape(nextParamValue)); - } - } - } - linkSelf = b.toString(); - - if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) { - IBaseResource resource; - IPrimitiveType lastUpdated; - if (resultObj instanceof IBundleProvider) { - IBundleProvider result = (IBundleProvider) resultObj; - resource = result.getResources(0, 1).get(0); - lastUpdated = result.getPublished(); - } else { - resource = (IBaseResource) resultObj; - lastUpdated = theServer.getFhirContext().getVersion().getLastUpdated(resource); - } - - /* - * We assume that the bundle we got back from the handling method may not have everything populated (e.g. self links, bundle type, etc) so we do that here. - */ - IVersionSpecificBundleFactory bundleFactory = theServer.getFhirContext().newBundleFactory(); - bundleFactory.initializeWithBundleResource(resource); - bundleFactory.addRootPropertiesToBundle(null, theRequest.getFhirServerBase(), linkSelf, count, getResponseBundleType(), lastUpdated); - - responseObject = new ResourceOrDstu1Bundle(resource); - } else { - Set includes = getRequestIncludesFromParams(params); - - IBundleProvider result = (IBundleProvider) resultObj; - if (count == null) { - count = result.preferredPageSize(); - } - - Integer offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_PAGINGOFFSET); - if (offsetI == null || offsetI < 0) { - offsetI = 0; - } - - Integer resultSize = result.size(); - int start; - if (resultSize != null) { - start = Math.max(0, Math.min(offsetI, resultSize - 1)); - } else { - start = offsetI; - } - - IVersionSpecificBundleFactory bundleFactory = theServer.getFhirContext().newBundleFactory(); - - ResponseEncoding responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest, theServer.getDefaultResponseEncoding()); - EncodingEnum linkEncoding = theRequest.getParameters().containsKey(Constants.PARAM_FORMAT) && responseEncoding != null ? responseEncoding.getEncoding() : null; - - boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest); - bundleFactory.initializeBundleFromBundleProvider(theServer, result, linkEncoding, theRequest.getFhirServerBase(), linkSelf, prettyPrint, start, count, null, getResponseBundleType(), - includes); - Bundle bundle = bundleFactory.getDstu1Bundle(); - if (bundle != null) { - responseObject = new ResourceOrDstu1Bundle(bundle); - } else { - IBaseResource resBundle = bundleFactory.getResourceBundle(); - responseObject = new ResourceOrDstu1Bundle(resBundle); - } - } - break; - } - case RESOURCE: { - IBundleProvider result = (IBundleProvider) resultObj; - if (result.size() == 0) { - throw new ResourceNotFoundException(theRequest.getId()); - } else if (result.size() > 1) { - throw new InternalErrorException("Method returned multiple resources"); - } - - IBaseResource resource = result.getResources(0, 1).get(0); - responseObject = new ResourceOrDstu1Bundle(resource); - break; - } - default: - throw new IllegalStateException(); // should not happen - } - return responseObject; - } - - public abstract Object invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException; - /** * Should the response include a Content-Location header. Search method bunding (and any others?) may override this to disable the content-location, since it doesn't make sense */ @@ -430,7 +225,7 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi } public enum MethodReturnTypeEnum { - BUNDLE, BUNDLE_PROVIDER, BUNDLE_RESOURCE, LIST_OF_RESOURCES, METHOD_OUTCOME, RESOURCE + BUNDLE, BUNDLE_RESOURCE, LIST_OF_RESOURCES, METHOD_OUTCOME, RESOURCE } public static class ResourceOrDstu1Bundle { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConditionalParamBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConditionalParamBinder.java index b6d013aacf1..7381d90cae3 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConditionalParamBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConditionalParamBinder.java @@ -32,6 +32,7 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.annotation.ConditionalUrlParam; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConformanceMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConformanceMethodBinding.java index 8653816b744..ab314eb55b5 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConformanceMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ConformanceMethodBinding.java @@ -23,28 +23,18 @@ package ca.uhn.fhir.rest.client.method; import java.lang.reflect.Method; import org.hl7.fhir.instance.model.api.IBaseConformance; -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.valueset.BundleTypeEnum; -import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; -import ca.uhn.fhir.rest.server.SimpleBundleProvider; -import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding { public ConformanceMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { super(theMethod.getReturnType(), theMethod, theContext, theProvider); -// if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) { -// throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract"); -// } MethodReturnTypeEnum methodReturnType = getMethodReturnType(); Class genericReturnType = (Class) theMethod.getGenericReturnType(); if (methodReturnType != MethodReturnTypeEnum.RESOURCE || !IBaseConformance.class.isAssignableFrom(genericReturnType)) { @@ -72,33 +62,6 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding return retVal; } - @Override - public IBundleProvider invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException { - IBaseResource conf = (IBaseResource) invokeServerMethod(theServer, theRequest, theMethodParams); - return new SimpleBundleProvider(conf); - } - - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (theRequest.getRequestType() == RequestTypeEnum.OPTIONS) { - if (theRequest.getOperation() == null && theRequest.getResourceName() == null) { - return true; - } - } - - if (theRequest.getResourceName() != null) { - return false; - } - - if ("metadata".equals(theRequest.getOperation())) { - if (theRequest.getRequestType() == RequestTypeEnum.GET) { - return true; - } - throw new MethodNotAllowedException("/metadata request must use HTTP GET", RequestTypeEnum.GET); - } - - return false; - } @Override public RestOperationTypeEnum getRestOperationType() { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CountParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CountParameter.java index 6cb0c87387e..c26ae20a62d 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CountParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CountParameter.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.client.method; * 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 + * 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, @@ -26,25 +26,21 @@ import java.util.Collections; import java.util.List; import java.util.Map; -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.model.primitive.IntegerDt; -import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.annotation.Since; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.param.ParameterUtil; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class CountParameter implements IParameter { - private Class myType; - @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { if (theSourceClientArgument != null) { IntegerDt since = ParameterUtil.toInteger(theSourceClientArgument); if (since.isEmpty() == false) { @@ -53,33 +49,16 @@ public class CountParameter implements IParameter { } } - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - String[] sinceParams = theRequest.getParameters().get(Constants.PARAM_COUNT); - if (sinceParams != null) { - if (sinceParams.length > 0) { - if (StringUtils.isNotBlank(sinceParams[0])) { - try { - IntegerDt since = new IntegerDt(sinceParams[0]); - return ParameterUtil.fromInteger(myType, since); - } catch (DataFormatException e) { - throw new InvalidRequestException("Invalid " + Constants.PARAM_COUNT + " value: " + sinceParams[0]); - } - } - } - } - return ParameterUtil.fromInteger(myType, null); - } - @Override public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { if (theOuterCollectionType != null) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" +theMethod.getDeclaringClass().getCanonicalName()+ "' is annotated with @" + Since.class.getName() + " but can not be of collection type"); + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Since.class.getName() + + " but can not be of collection type"); } if (!ParameterUtil.getBindableIntegerTypes().contains(theParameterType)) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" +theMethod.getDeclaringClass().getCanonicalName()+ "' is annotated with @" + Since.class.getName() + " but type '" + theParameterType + "' is an invalid type, must be one of: " + ParameterUtil.getBindableIntegerTypes()); + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + Since.class.getName() + + " but type '" + theParameterType + "' is an invalid type, must be one of: " + ParameterUtil.getBindableIntegerTypes()); } - myType = theParameterType; } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CreateMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CreateMethodBinding.java index beb491754a5..1490242801f 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CreateMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/CreateMethodBinding.java @@ -36,6 +36,7 @@ import ca.uhn.fhir.rest.annotation.Create; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class CreateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java index 600a06d77da..7286725b2db 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DeleteMethodBinding.java @@ -94,10 +94,6 @@ public class DeleteMethodBinding extends BaseOutcomeReturningMethodBindingWithRe return retVal; } - @Override - protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) { - theParams[getIdParameterIndex()] = theRequest.getId(); - } @Override protected String getMatchingOperation() { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchMethodBinding.java deleted file mode 100644 index 00412098829..00000000000 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchMethodBinding.java +++ /dev/null @@ -1,167 +0,0 @@ -package ca.uhn.fhir.rest.client.method; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; - -import org.hl7.fhir.instance.model.api.IBaseResource; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.model.valueset.BundleTypeEnum; -import ca.uhn.fhir.rest.api.RequestTypeEnum; -import ca.uhn.fhir.rest.api.RestOperationTypeEnum; -import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; - -public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBinding { - - private IDynamicSearchResourceProvider myProvider; - private List mySearchParameters; - private HashSet myParamNames; - private Integer myIdParamIndex; - - public DynamicSearchMethodBinding(Class theReturnResourceType, Method theMethod, FhirContext theContext, IDynamicSearchResourceProvider theProvider) { - super(theReturnResourceType, theMethod, theContext, theProvider); - - myProvider = theProvider; - mySearchParameters = myProvider.getSearchParameters(); - - myParamNames = new HashSet(); - for (RuntimeSearchParam next : mySearchParameters) { - myParamNames.add(next.getName()); - } - - myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); - - } - - @Override - protected BundleTypeEnum getResponseBundleType() { - return BundleTypeEnum.SEARCHSET; - } - - - @Override - public List getParameters() { - List retVal = new ArrayList(super.getParameters()); - - for (RuntimeSearchParam next : mySearchParameters) { - // TODO: what is this? - } - - return retVal; - } - - @Override - public ReturnTypeEnum getReturnType() { - return ReturnTypeEnum.BUNDLE; - } - - @Override - public IBundleProvider invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - if (myIdParamIndex != null) { - theMethodParams[myIdParamIndex] = theRequest.getId(); - } - - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - return toResourceList(response); - } - - @Override - public RestOperationTypeEnum getRestOperationType() { - return RestOperationTypeEnum.SEARCH_TYPE; - } - - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchMethodBinding.class); - - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (!theRequest.getResourceName().equals(getResourceName())) { - ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } ); - return false; - } - if (theRequest.getId() != null && myIdParamIndex == null) { - ourLog.trace("Method {} doesn't match because ID is not null: {}", theRequest.getId()); - return false; - } - if (theRequest.getRequestType() == RequestTypeEnum.GET && theRequest.getOperation() != null && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) { - ourLog.trace("Method {} doesn't match because request type is GET but operation is not null: {}", theRequest.getId(), theRequest.getOperation()); - return false; - } - if (theRequest.getRequestType() == RequestTypeEnum.POST && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) { - ourLog.trace("Method {} doesn't match because request type is POST but operation is not _search: {}", theRequest.getId(), theRequest.getOperation()); - return false; - } - if (theRequest.getRequestType() != RequestTypeEnum.GET && theRequest.getRequestType() != RequestTypeEnum.POST) { - ourLog.trace("Method {} doesn't match because request type is {}", getMethod()); - return false; - } - if (theRequest.getCompartmentName() != null) { - ourLog.trace("Method {} doesn't match because it is for compartment {}", new Object[] { getMethod(), theRequest.getCompartmentName() }); - return false; - } - - for (String next : theRequest.getParameters().keySet()) { - if (next.charAt(0) == '_') { - continue; - } - String nextQualified = next; - int colonIndex = next.indexOf(':'); - int dotIndex = next.indexOf('.'); - if (colonIndex != -1 || dotIndex != -1) { - int index; - if (colonIndex != -1 && dotIndex != -1) { - index = Math.min(colonIndex, dotIndex); - } else { - index = (colonIndex != -1) ? colonIndex : dotIndex; - } - next = next.substring(0, index); - } - if (!myParamNames.contains(next)) { - ourLog.trace("Method {} doesn't match because has parameter {}", new Object[] { getMethod(), nextQualified }); - return false; - } - } - - return true; - } - - @Override - public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { - // there should be no way to call this.... - throw new UnsupportedOperationException("Dynamic search methods are only used for server implementations"); - } - - public Collection getSearchParams() { - return mySearchParameters; - } - -} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchParameter.java deleted file mode 100644 index 115d96e10ab..00000000000 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/DynamicSearchParameter.java +++ /dev/null @@ -1,183 +0,0 @@ -package ca.uhn.fhir.rest.client.method; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.hl7.fhir.instance.model.api.IBaseResource; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.RuntimeSearchParam; -import ca.uhn.fhir.model.api.IQueryParameterType; -import ca.uhn.fhir.rest.param.CompositeOrListParam; -import ca.uhn.fhir.rest.param.DateOrListParam; -import ca.uhn.fhir.rest.param.DateParam; -import ca.uhn.fhir.rest.param.NumberOrListParam; -import ca.uhn.fhir.rest.param.NumberParam; -import ca.uhn.fhir.rest.param.QuantityOrListParam; -import ca.uhn.fhir.rest.param.QuantityParam; -import ca.uhn.fhir.rest.param.ReferenceOrListParam; -import ca.uhn.fhir.rest.param.ReferenceParam; -import ca.uhn.fhir.rest.param.StringOrListParam; -import ca.uhn.fhir.rest.param.StringParam; -import ca.uhn.fhir.rest.param.TokenOrListParam; -import ca.uhn.fhir.rest.param.TokenParam; -import ca.uhn.fhir.rest.param.UriOrListParam; -import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider; -import ca.uhn.fhir.rest.server.SearchParameterMap; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; - -public class DynamicSearchParameter implements IParameter { - - private Map myNameToParam = new HashMap(); - - public DynamicSearchParameter(IDynamicSearchResourceProvider theProvider) { - for (RuntimeSearchParam next : theProvider.getSearchParameters()) { - myNameToParam.put(next.getName(), next); - } - } - - @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { - throw new UnsupportedOperationException("Dynamic search is not supported in client mode (use fluent client for dynamic-like searches)"); - } - - @SuppressWarnings("unchecked") - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - SearchParameterMap retVal = new SearchParameterMap(); - - for (String next : theRequest.getParameters().keySet()) { - String qualifier = null; - String qualifiedParamName = next; - String unqualifiedParamName = next; - RuntimeSearchParam param = myNameToParam.get(next); - if (param == null) { - int colonIndex = next.indexOf(':'); - int dotIndex = next.indexOf('.'); - if (colonIndex != -1 || dotIndex != -1) { - int index; - if (colonIndex != -1 && dotIndex != -1) { - index = Math.min(colonIndex, dotIndex); - } else { - index = (colonIndex != -1) ? colonIndex : dotIndex; - } - qualifier = next.substring(index); - next = next.substring(0, index); - unqualifiedParamName = next; - param = myNameToParam.get(next); - } - } - - if (param != null) { - - for (String nextValue : theRequest.getParameters().get(qualifiedParamName)) { - QualifiedParamList paramList = QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifier, nextValue); - - FhirContext ctx = theRequest.getServer().getFhirContext(); - - switch (param.getParamType()) { - case COMPOSITE: - Class left = toParamType(param.getCompositeOf().get(0)); - Class right = toParamType(param.getCompositeOf().get(0)); - @SuppressWarnings({ "rawtypes" }) - CompositeOrListParam compositeOrListParam = new CompositeOrListParam(left, right); - compositeOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, compositeOrListParam); - break; - case DATE: - DateOrListParam dateOrListParam = new DateOrListParam(); - dateOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, dateOrListParam); - break; - case NUMBER: - NumberOrListParam numberOrListParam = new NumberOrListParam(); - numberOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, numberOrListParam); - break; - case QUANTITY: - QuantityOrListParam quantityOrListParam = new QuantityOrListParam(); - quantityOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, quantityOrListParam); - break; - case REFERENCE: - ReferenceOrListParam referenceOrListParam = new ReferenceOrListParam(); - referenceOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, referenceOrListParam); - break; - case STRING: - StringOrListParam stringOrListParam = new StringOrListParam(); - stringOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, stringOrListParam); - break; - case TOKEN: - TokenOrListParam tokenOrListParam = new TokenOrListParam(); - tokenOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, tokenOrListParam); - break; - case URI: - UriOrListParam uriOrListParam = new UriOrListParam(); - uriOrListParam.setValuesAsQueryTokens(ctx, unqualifiedParamName, paramList); - retVal.add(next, uriOrListParam); - break; - case HAS: - // Should not happen - break; - } - } - } - } - - return retVal; - } - - private Class toParamType(RuntimeSearchParam theRuntimeSearchParam) { - switch (theRuntimeSearchParam.getParamType()) { - case COMPOSITE: - throw new IllegalStateException("Composite subtype"); - case DATE: - return DateParam.class; - case NUMBER: - return NumberParam.class; - case QUANTITY: - return QuantityParam.class; - case REFERENCE: - return ReferenceParam.class; - case STRING: - return StringParam.class; - case TOKEN: - return TokenParam.class; - default: - throw new IllegalStateException("null type"); - } - } - - @Override - public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { - // nothing - } - -} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ElementsParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ElementsParameter.java index ad840f08a49..2a060a00fb8 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ElementsParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ElementsParameter.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.client.method; * 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 + * 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, @@ -24,31 +24,23 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; -import java.util.StringTokenizer; -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.rest.api.Constants; import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.param.CollectionBinder; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class ElementsParameter implements IParameter { - @SuppressWarnings("rawtypes") - private Class myInnerCollectionType; - @SuppressWarnings("unchecked") @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { if (theSourceClientArgument instanceof Collection) { StringBuilder values = new StringBuilder(); for (String next : (Collection) theSourceClientArgument) { @@ -68,62 +60,11 @@ public class ElementsParameter implements IParameter { } } - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - Set value = getElementsValueOrNull(theRequest); - if (value == null || value.isEmpty()) { - return null; - } - - if (myInnerCollectionType == null) { - return StringUtils.join(value, ','); - } - - try { - Collection retVal = myInnerCollectionType.newInstance(); - retVal.addAll(value); - return retVal; - } catch (InstantiationException e) { - throw new InternalErrorException("Failed to instantiate " + myInnerCollectionType, e); - } catch (IllegalAccessException e) { - throw new InternalErrorException("Failed to instantiate " + myInnerCollectionType, e); - } - } - - public static Set getElementsValueOrNull(RequestDetails theRequest) { - String[] summary = theRequest.getParameters().get(Constants.PARAM_ELEMENTS); - - if (summary != null && summary.length > 0) { - Set retVal = new HashSet(); - for (String next : summary) { - StringTokenizer tok = new StringTokenizer(next, ","); - while (tok.hasMoreTokens()) { - String token = tok.nextToken(); - if (isNotBlank(token)) { - retVal.add(token); - } - } - } - if (retVal.isEmpty()) { - return null; - } - - // Always include the meta element even for subsetted values - retVal.add("meta"); - - return retVal; - } - return null; - } - @Override public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { if (theOuterCollectionType != null) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + " but can not be a collection of collections"); - } - if (theInnerCollectionType != null) { - myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, SummaryEnum.class.getSimpleName()); + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + + " but can not be a collection of collections"); } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/GetTagsMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/GetTagsMethodBinding.java index 769ce09cb99..af8bb697a00 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/GetTagsMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/GetTagsMethodBinding.java @@ -1,26 +1,5 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.io.IOException; import java.io.Reader; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -37,15 +16,12 @@ import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.annotation.GetTags; import ca.uhn.fhir.rest.annotation.IdParam; -import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.IResourceProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; public class GetTagsMethodBinding extends BaseMethodBinding { @@ -57,11 +33,7 @@ public class GetTagsMethodBinding extends BaseMethodBinding { public GetTagsMethodBinding(Method theMethod, FhirContext theContext, Object theProvider, GetTags theAnnotation) { super(theMethod, theContext, theProvider); - if (theProvider instanceof IResourceProvider) { - myType = ((IResourceProvider) theProvider).getResourceType(); - } else { - myType = theAnnotation.type(); - } + myType = theAnnotation.type(); if (!Modifier.isInterface(myType.getModifiers())) { myResourceName = theContext.getResourceDefinition(myType).getName(); @@ -86,30 +58,6 @@ public class GetTagsMethodBinding extends BaseMethodBinding { return RestOperationTypeEnum.GET_TAGS; } - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (theRequest.getRequestType() != RequestTypeEnum.GET) { - return false; - } - if (!Constants.PARAM_TAGS.equals(theRequest.getOperation())) { - return false; - } - if (myResourceName == null) { - if (getResourceName() != null) { - return false; - } - } else if (!myResourceName.equals(theRequest.getResourceName())) { - return false; - - } - if ((myIdParamIndex != null) != (theRequest.getId() != null)) { - return false; - } - // if ((myVersionIdParamIndex != null) != (theRequest.getVersionId() != null)) { - // return false; - // } - return true; - } @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { @@ -159,28 +107,5 @@ public class GetTagsMethodBinding extends BaseMethodBinding { } throw processNon2xxResponseAndReturnExceptionToThrow(theResponseStatusCode, theResponseMimeType, theResponseReader); } - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - Object[] params = createParametersForServerRequest(theRequest); - - if (myIdParamIndex != null) { - params[myIdParamIndex] = theRequest.getId(); - } - if (myVersionIdParamIndex != null) { - params[myVersionIdParamIndex] = theRequest.getId(); - } - - TagList resp = (TagList) invokeServerMethod(theServer, theRequest, params); - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest, resp); - if (!continueProcessing) { - return null; - } - } - - return theRequest.getResponse().returnResponse(ParseAction.create(resp), Constants.STATUS_HTTP_200_OK, false, null, null); - } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HistoryMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HistoryMethodBinding.java index e873569b0e3..ea014be9197 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HistoryMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HistoryMethodBinding.java @@ -10,7 +10,7 @@ package ca.uhn.fhir.rest.client.method; * 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 + * 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, @@ -25,23 +25,20 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Date; -import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IResource; -import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.History; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.*; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { @@ -57,16 +54,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { History historyAnnotation = theMethod.getAnnotation(History.class); Class type = historyAnnotation.type(); if (Modifier.isInterface(type.getModifiers())) { - if (theProvider instanceof IResourceProvider) { - type = ((IResourceProvider) theProvider).getResourceType(); - if (myIdParamIndex != null) { - myResourceOperationType = RestOperationTypeEnum.HISTORY_INSTANCE; - } else { - myResourceOperationType = RestOperationTypeEnum.HISTORY_TYPE; - } - } else { - myResourceOperationType = RestOperationTypeEnum.HISTORY_SYSTEM; - } + myResourceOperationType = RestOperationTypeEnum.HISTORY_SYSTEM; } else { if (myIdParamIndex != null) { myResourceOperationType = RestOperationTypeEnum.HISTORY_INSTANCE; @@ -98,34 +86,6 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { return ReturnTypeEnum.BUNDLE; } - // ObjectUtils.equals is replaced by a JDK7 method.. - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (!Constants.PARAM_HISTORY.equals(theRequest.getOperation())) { - return false; - } - if (theRequest.getResourceName() == null) { - return myResourceOperationType == RestOperationTypeEnum.HISTORY_SYSTEM; - } - if (!StringUtils.equals(theRequest.getResourceName(), myResourceName)) { - return false; - } - - boolean haveIdParam = theRequest.getId() != null && !theRequest.getId().isEmpty(); - boolean wantIdParam = myIdParamIndex != null; - if (haveIdParam != wantIdParam) { - return false; - } - - if (theRequest.getId() == null) { - return myResourceOperationType == RestOperationTypeEnum.HISTORY_TYPE; - } else if (theRequest.getId().hasVersionIdPart()) { - return false; - } - - return true; - } - @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { IdDt id = null; @@ -150,64 +110,6 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { return retVal; } - @Override - public IBundleProvider invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - if (myIdParamIndex != null) { - theMethodParams[myIdParamIndex] = theRequest.getId(); - } - - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - - final IBundleProvider resources = toResourceList(response); - - /* - * We wrap the response so we can verify that it has the ID and version set, - * as is the contract for history - */ - return new IBundleProvider() { - - @Override - public IPrimitiveType getPublished() { - return resources.getPublished(); - } - - @Override - public List getResources(int theFromIndex, int theToIndex) { - List retVal = resources.getResources(theFromIndex, theToIndex); - int index = theFromIndex; - for (IBaseResource nextResource : retVal) { - if (nextResource.getIdElement() == null || isBlank(nextResource.getIdElement().getIdPart())) { - throw new InternalErrorException("Server provided resource at index " + index + " with no ID set (using IResource#setId(IdDt))"); - } - if (isBlank(nextResource.getIdElement().getVersionIdPart()) && nextResource instanceof IResource) { - //TODO: Use of a deprecated method should be resolved. - IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get((IResource) nextResource); - if (versionId == null || versionId.isEmpty()) { - throw new InternalErrorException("Server provided resource at index " + index + " with no Version ID set (using IResource#setId(IdDt))"); - } - } - index++; - } - return retVal; - } - - @Override - public Integer size() { - return resources.size(); - } - - @Override - public Integer preferredPageSize() { - return resources.preferredPageSize(); - } - - @Override - public String getUuid() { - return resources.getUuid(); - } - }; - } - public static HttpGetClientInvocation createHistoryInvocation(FhirContext theContext, String theResourceName, String theId, IPrimitiveType theSince, Integer theLimit) { StringBuilder b = new StringBuilder(); if (theResourceName != null) { @@ -237,9 +139,6 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding { } private static Class toReturnType(Method theMethod, Object theProvider) { - if (theProvider instanceof IResourceProvider) { - return ((IResourceProvider) theProvider).getResourceType(); - } History historyAnnotation = theMethod.getAnnotation(History.class); Class type = historyAnnotation.type(); if (type != IBaseResource.class && type != IResource.class) { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java index e01cbe75a6f..dd69b07fd7b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpDeleteClientInvocation.java @@ -26,10 +26,10 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.EncodingEnum; public class HttpDeleteClientInvocation extends BaseHttpClientInvocation { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpGetClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpGetClientInvocation.java index 24eb581dd52..10d62b74595 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpGetClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpGetClientInvocation.java @@ -31,10 +31,10 @@ import org.apache.commons.lang3.StringUtils; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.EncodingEnum; /** * @author James Agnew diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpPatchClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpPatchClientInvocation.java index fbd10fa96e5..143284b8c72 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpPatchClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpPatchClientInvocation.java @@ -26,11 +26,11 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.client.api.IHttpClient; import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.EncodingEnum; public class HttpPatchClientInvocation extends BaseHttpClientInvocation { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpSimpleGetClientInvocation.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpSimpleGetClientInvocation.java index 27f76300e75..ae10d21fa0c 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpSimpleGetClientInvocation.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/HttpSimpleGetClientInvocation.java @@ -24,10 +24,10 @@ import java.util.List; import java.util.Map; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.client.api.IHttpRequest; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.EncodingEnum; public class HttpSimpleGetClientInvocation extends BaseHttpClientInvocation { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParamBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParamBinder.java index 4289510ee18..1c9959ad3f9 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParamBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParamBinder.java @@ -24,6 +24,7 @@ import java.util.List; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterOr; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParameter.java new file mode 100644 index 00000000000..8ea63ffb8a4 --- /dev/null +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IParameter.java @@ -0,0 +1,40 @@ +package ca.uhn.fhir.rest.client.method; + +/* + * #%L + * HAPI FHIR - Core Library + * %% + * Copyright (C) 2014 - 2017 University Health Network + * %% + * Licensed 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. + * #L% + */ + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.hl7.fhir.instance.model.api.IBaseResource; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; + +public interface IParameter { + + void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType); + + void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException; + +} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IncludeParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IncludeParameter.java index 118f9689460..7971c9dee44 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IncludeParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/IncludeParameter.java @@ -32,9 +32,10 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Include; import ca.uhn.fhir.rest.annotation.IncludeParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.BaseQueryParameter; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/MethodUtil.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/MethodUtil.java index d05e3d2f199..36ad3f9a689 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/MethodUtil.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/MethodUtil.java @@ -8,31 +8,79 @@ import java.io.PushbackReader; import java.io.Reader; import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Map.Entry; +import java.util.Set; -import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; -import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.instance.model.api.IAnyResource; +import org.hl7.fhir.instance.model.api.IBaseMetaType; +import org.hl7.fhir.instance.model.api.IBaseOperationOutcome; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; -import ca.uhn.fhir.context.*; -import ca.uhn.fhir.model.api.*; +import ca.uhn.fhir.context.ConfigurationException; +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.context.FhirVersionEnum; +import ca.uhn.fhir.context.RuntimeResourceDefinition; +import ca.uhn.fhir.context.RuntimeSearchParam; +import ca.uhn.fhir.model.api.IQueryParameterAnd; +import ca.uhn.fhir.model.api.IQueryParameterOr; +import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.model.api.Include; +import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; +import ca.uhn.fhir.model.api.Tag; +import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.parser.IParser; -import ca.uhn.fhir.rest.annotation.*; -import ca.uhn.fhir.rest.api.*; +import ca.uhn.fhir.rest.annotation.At; +import ca.uhn.fhir.rest.annotation.ConditionalUrlParam; +import ca.uhn.fhir.rest.annotation.Count; +import ca.uhn.fhir.rest.annotation.Elements; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.IncludeParam; +import ca.uhn.fhir.rest.annotation.Operation; +import ca.uhn.fhir.rest.annotation.OperationParam; +import ca.uhn.fhir.rest.annotation.OptionalParam; +import ca.uhn.fhir.rest.annotation.RawParam; +import ca.uhn.fhir.rest.annotation.RequiredParam; +import ca.uhn.fhir.rest.annotation.ResourceParam; +import ca.uhn.fhir.rest.annotation.ServerBase; +import ca.uhn.fhir.rest.annotation.Since; +import ca.uhn.fhir.rest.annotation.Sort; +import ca.uhn.fhir.rest.annotation.TagListParam; +import ca.uhn.fhir.rest.annotation.TransactionParam; +import ca.uhn.fhir.rest.annotation.Validate; +import ca.uhn.fhir.rest.annotation.VersionIdParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.EncodingEnum; +import ca.uhn.fhir.rest.api.MethodOutcome; +import ca.uhn.fhir.rest.api.PatchTypeEnum; +import ca.uhn.fhir.rest.api.QualifiedParamList; +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; +import ca.uhn.fhir.rest.api.SummaryEnum; +import ca.uhn.fhir.rest.api.ValidationModeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.method.OperationParameter.IOperationParamConverter; -import ca.uhn.fhir.rest.param.*; -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.rest.server.method.ResourceParameter; -import ca.uhn.fhir.rest.server.method.TransactionParameter; -import ca.uhn.fhir.rest.server.method.ResourceParameter.Mode; +import ca.uhn.fhir.rest.param.CollectionBinder; +import ca.uhn.fhir.rest.param.DateAndListParam; +import ca.uhn.fhir.rest.param.HasAndListParam; +import ca.uhn.fhir.rest.param.NumberAndListParam; +import ca.uhn.fhir.rest.param.QuantityAndListParam; +import ca.uhn.fhir.rest.param.ReferenceAndListParam; +import ca.uhn.fhir.rest.param.StringAndListParam; +import ca.uhn.fhir.rest.param.TokenAndListParam; +import ca.uhn.fhir.rest.param.UriAndListParam; import ca.uhn.fhir.util.DateUtils; import ca.uhn.fhir.util.ParametersUtil; import ca.uhn.fhir.util.ReflectionUtil; @@ -323,14 +371,7 @@ public class MethodUtil { Class parameterType = parameterTypes[paramIndex]; Class> outerCollectionType = null; Class> innerCollectionType = null; - if (SearchParameterMap.class.equals(parameterType)) { - if (theProvider instanceof IDynamicSearchResourceProvider) { - Search searchAnnotation = theMethod.getAnnotation(Search.class); - if (searchAnnotation != null && searchAnnotation.dynamic()) { - param = new DynamicSearchParameter((IDynamicSearchResourceProvider) theProvider); - } - } - } else if (TagList.class.isAssignableFrom(parameterType)) { + if (TagList.class.isAssignableFrom(parameterType)) { // TagList is handled directly within the method bindings param = new NullParameter(); } else { @@ -348,20 +389,7 @@ public class MethodUtil { } } - /* - * Note: for the first two here, we're using strings instead of static binding - * so that we don't need the java.servlet JAR on the classpath in order to use - * this class - */ - if (ourServletRequestTypes.contains(parameterType.getName())) { - param = new ServletRequestParameter(); - } else if (ourServletResponseTypes.contains(parameterType.getName())) { - param = new ServletResponseParameter(); - } else if (parameterType.equals(RequestDetails.class)) { - param = new RequestDetailsParameter(); - } else if (parameterType.equals(IRequestOperationCallback.class)) { - param = new RequestOperationCallbackParameter(); - } else if (parameterType.equals(SummaryEnum.class)) { + if (parameterType.equals(SummaryEnum.class)) { param = new SummaryEnumParameter(); } else if (parameterType.equals(PatchTypeEnum.class)) { param = new PatchTypeParameter(); @@ -407,15 +435,14 @@ public class MethodUtil { param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType, specType); } else if (nextAnnotation instanceof ResourceParam) { - Mode mode; if (IBaseResource.class.isAssignableFrom(parameterType)) { - mode = Mode.RESOURCE; + // good } else if (String.class.equals(parameterType)) { - mode = ResourceParameter.Mode.BODY; + // good } else if (byte[].class.equals(parameterType)) { - mode = ResourceParameter.Mode.BODY_BYTE_ARRAY; + // good } else if (EncodingEnum.class.equals(parameterType)) { - mode = Mode.ENCODING; + // good } else { StringBuilder b = new StringBuilder(); b.append("Method '"); @@ -427,7 +454,7 @@ public class MethodUtil { b.append(" or String or byte[]"); throw new ConfigurationException(b.toString()); } - param = new ResourceParameter((Class) parameterType, theProvider, mode); + param = new ResourceParameter(); } else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) { param = new NullParameter(); } else if (nextAnnotation instanceof ServerBase) { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/NullParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/NullParameter.java index d18e9d82549..8ecd11f8073 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/NullParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/NullParameter.java @@ -28,6 +28,7 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java index ba0e67fa66f..493678eeebe 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationMethodBinding.java @@ -22,7 +22,6 @@ package ca.uhn.fhir.rest.client.method; import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; -import java.io.IOException; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -49,16 +48,9 @@ import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.Operation; import ca.uhn.fhir.rest.annotation.OperationParam; -import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; -import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.rest.server.method.ResourceParameter; import ca.uhn.fhir.util.FhirTerser; public class OperationMethodBinding extends BaseResourceReturningMethodBinding { @@ -134,11 +126,7 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { + theMethod.getDeclaringClass().getName()); } - if (theMethod.getReturnType().equals(IBundleProvider.class)) { - myReturnType = ReturnTypeEnum.BUNDLE; - } else { - myReturnType = ReturnTypeEnum.RESOURCE; - } + myReturnType = ReturnTypeEnum.RESOURCE; if (getResourceName() == null) { myOtherOperatiopnType = RestOperationTypeEnum.EXTENDED_OPERATION_SERVER; @@ -213,40 +201,6 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { return myReturnType; } - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (getResourceName() == null) { - if (isNotBlank(theRequest.getResourceName())) { - return false; - } - } else if (!getResourceName().equals(theRequest.getResourceName())) { - return false; - } - - if (!myName.equals(theRequest.getOperation())) { - return false; - } - - RequestTypeEnum requestType = theRequest.getRequestType(); - if (requestType != RequestTypeEnum.GET && requestType != RequestTypeEnum.POST) { - // Operations can only be invoked with GET and POST - return false; - } - - boolean requestHasId = theRequest.getId() != null; - if (requestHasId) { - if (isCanOperateAtInstanceLevel() == false) { - return false; - } - } else { - if (myCanOperateAtTypeLevel == false) { - return false; - } - } - - return true; - } - @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { String id = null; @@ -266,42 +220,6 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { return createOperationInvocation(getContext(), getResourceName(), id, myName, parameters, false); } - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - if (theRequest.getRequestType() == RequestTypeEnum.POST) { - IBaseResource requestContents = ResourceParameter.loadResourceFromRequest(theRequest, this, null); - theRequest.getUserData().put(OperationParameter.REQUEST_CONTENTS_USERDATA_KEY, requestContents); - } - return super.invokeServer(theServer, theRequest); - } - - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException { - if (theRequest.getRequestType() == RequestTypeEnum.POST) { - // all good - } else if (theRequest.getRequestType() == RequestTypeEnum.GET) { - if (!myIdempotent) { - String message = getContext().getLocalizer().getMessage(OperationMethodBinding.class, "methodNotSupported", theRequest.getRequestType(), RequestTypeEnum.POST.name()); - throw new MethodNotAllowedException(message, RequestTypeEnum.POST); - } - } else { - if (!myIdempotent) { - String message = getContext().getLocalizer().getMessage(OperationMethodBinding.class, "methodNotSupported", theRequest.getRequestType(), RequestTypeEnum.POST.name()); - throw new MethodNotAllowedException(message, RequestTypeEnum.POST); - } - String message = getContext().getLocalizer().getMessage(OperationMethodBinding.class, "methodNotSupported", theRequest.getRequestType(), RequestTypeEnum.GET.name(), RequestTypeEnum.POST.name()); - throw new MethodNotAllowedException(message, RequestTypeEnum.GET, RequestTypeEnum.POST); - } - - if (myIdParamIndex != null) { - theMethodParams[myIdParamIndex] = theRequest.getId(); - } - - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - IBundleProvider retVal = toResourceList(response); - return retVal; - } - public boolean isCanOperateAtInstanceLevel() { return this.myCanOperateAtInstanceLevel; } @@ -318,12 +236,6 @@ public class OperationMethodBinding extends BaseResourceReturningMethodBinding { return myIdempotent; } - @Override - protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) { - super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams); - theDetails.setResource((IBaseResource) theRequestDetails.getUserData().get(OperationParameter.REQUEST_CONTENTS_USERDATA_KEY)); - } - public void setDescription(String theDescription) { myDescription = theDescription; } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationParameter.java index f4c592a9f9b..c1499d82db8 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/OperationParameter.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.rest.client.method; -import static org.apache.commons.lang3.StringUtils.isNotBlank; - /* * #%L * HAPI FHIR - Core Library @@ -24,8 +22,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -33,37 +29,22 @@ import java.util.Map; import org.apache.commons.lang3.Validate; import org.hl7.fhir.instance.model.api.IBase; -import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseResource; import org.hl7.fhir.instance.model.api.IPrimitiveType; -import ca.uhn.fhir.context.BaseRuntimeChildDefinition; -import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IAccessor; -import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition; -import ca.uhn.fhir.context.BaseRuntimeElementDefinition; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.context.IRuntimeDatatypeDefinition; -import ca.uhn.fhir.context.RuntimeChildPrimitiveDatatypeDefinition; -import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition; -import ca.uhn.fhir.context.RuntimeResourceDefinition; -import ca.uhn.fhir.i18n.HapiLocalizer; import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; import ca.uhn.fhir.rest.annotation.OperationParam; -import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.ValidationModeEnum; -import ca.uhn.fhir.rest.param.BaseAndListParam; -import ca.uhn.fhir.rest.param.CollectionBinder; import ca.uhn.fhir.rest.param.DateRangeParam; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; -import ca.uhn.fhir.util.FhirTerser; import ca.uhn.fhir.util.ParametersUtil; -import ca.uhn.fhir.util.ReflectionUtil; public class OperationParameter implements IParameter { @@ -72,16 +53,12 @@ public class OperationParameter implements IParameter { static final String REQUEST_CONTENTS_USERDATA_KEY = OperationParam.class.getName() + "_PARSED_RESOURCE"; - private boolean myAllowGet; - private final FhirContext myContext; private IOperationParamConverter myConverter; @SuppressWarnings("rawtypes") - private Class myInnerCollectionType; private int myMax; private int myMin; private final String myName; - private final String myOperationName; private Class myParameterType; private String myParamType; private SearchParameter mySearchParameterBinding; @@ -91,39 +68,16 @@ public class OperationParameter implements IParameter { } OperationParameter(FhirContext theCtx, String theOperationName, String theParameterName, int theMin, int theMax) { - myOperationName = theOperationName; myName = theParameterName; myMin = theMin; myMax = theMax; myContext = theCtx; } - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void addValueToList(List matchingParamValues, Object values) { - if (values != null) { - if (BaseAndListParam.class.isAssignableFrom(myParameterType) && matchingParamValues.size() > 0) { - BaseAndListParam existing = (BaseAndListParam) matchingParamValues.get(0); - BaseAndListParam newAndList = (BaseAndListParam) values; - for (IQueryParameterOr nextAnd : newAndList.getValuesAsQueryTokens()) { - existing.addAnd(nextAnd); - } - } else { - matchingParamValues.add(values); - } - } - } - protected FhirContext getContext() { return myContext; } - public int getMax() { - return myMax; - } - - public int getMin() { - return myMin; - } public String getName() { return myName; @@ -151,7 +105,6 @@ public class OperationParameter implements IParameter { myParameterType = theParameterType; if (theInnerCollectionType != null) { - myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, myName); if (myMax == OperationParam.MAX_DEFAULT) { myMax = OperationParam.MAX_UNLIMITED; } @@ -181,8 +134,6 @@ public class OperationParameter implements IParameter { */ isSearchParam &= typeIsConcrete && !IBase.class.isAssignableFrom(myParameterType); - myAllowGet = IPrimitiveType.class.isAssignableFrom(myParameterType) || String.class.equals(myParameterType) || isSearchParam || ValidationModeEnum.class.equals(myParameterType); - /* * The parameter can be of type string for validation methods - This is a bit weird. See ValidateDstu2Test. We * should probably clean this up.. @@ -193,7 +144,6 @@ public class OperationParameter implements IParameter { } else if (DateRangeParam.class.isAssignableFrom(myParameterType)) { myParamType = "date"; myMax = 2; - myAllowGet = true; } else if (myParameterType.equals(ValidationModeEnum.class)) { myParamType = "code"; } else if (IBase.class.isAssignableFrom(myParameterType) && typeIsConcrete) { @@ -217,10 +167,6 @@ public class OperationParameter implements IParameter { return this; } - private void throwWrongParamType(Object nextValue) { - throw new InvalidRequestException("Request has parameter " + myName + " of type " + nextValue.getClass().getSimpleName() + " but method expects type " + myParameterType.getSimpleName()); - } - @Override public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { assert theTargetResource != null; @@ -236,185 +182,7 @@ public class OperationParameter implements IParameter { ParametersUtil.addParameterToParameters(theContext, theTargetResource, sourceClientArgument, myName); } - @SuppressWarnings("unchecked") - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - List matchingParamValues = new ArrayList(); - if (theRequest.getRequestType() == RequestTypeEnum.GET) { - translateQueryParametersIntoServerArgumentForGet(theRequest, matchingParamValues); - } else { - translateQueryParametersIntoServerArgumentForPost(theRequest, matchingParamValues); - } - - if (matchingParamValues.isEmpty()) { - return null; - } - - if (myInnerCollectionType == null) { - return matchingParamValues.get(0); - } - - Collection retVal = ReflectionUtil.newInstance(myInnerCollectionType); - retVal.addAll(matchingParamValues); - return retVal; - } - - private void translateQueryParametersIntoServerArgumentForGet(RequestDetails theRequest, List matchingParamValues) { - if (mySearchParameterBinding != null) { - - List params = new ArrayList(); - String nameWithQualifierColon = myName + ":"; - - for (String nextParamName : theRequest.getParameters().keySet()) { - String qualifier; - if (nextParamName.equals(myName)) { - qualifier = null; - } else if (nextParamName.startsWith(nameWithQualifierColon)) { - qualifier = nextParamName.substring(nextParamName.indexOf(':')); - } else { - // This is some other parameter, not the one bound by this instance - continue; - } - String[] values = theRequest.getParameters().get(nextParamName); - if (values != null) { - for (String nextValue : values) { - params.add(QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifier, nextValue)); - } - } - } - if (!params.isEmpty()) { - for (QualifiedParamList next : params) { - Object values = mySearchParameterBinding.parse(myContext, Collections.singletonList(next)); - addValueToList(matchingParamValues, values); - } - - } - - } else { - String[] paramValues = theRequest.getParameters().get(myName); - if (paramValues != null && paramValues.length > 0) { - if (myAllowGet) { - - if (DateRangeParam.class.isAssignableFrom(myParameterType)) { - List parameters = new ArrayList(); - parameters.add(QualifiedParamList.singleton(paramValues[0])); - if (paramValues.length > 1) { - parameters.add(QualifiedParamList.singleton(paramValues[1])); - } - DateRangeParam dateRangeParam = new DateRangeParam(); - FhirContext ctx = theRequest.getServer().getFhirContext(); - dateRangeParam.setValuesAsQueryTokens(ctx, myName, parameters); - matchingParamValues.add(dateRangeParam); - } else if (String.class.isAssignableFrom(myParameterType)) { - - for (String next : paramValues) { - matchingParamValues.add(next); - } - } else if (ValidationModeEnum.class.equals(myParameterType)) { - - if (isNotBlank(paramValues[0])) { - ValidationModeEnum validationMode = ValidationModeEnum.forCode(paramValues[0]); - if (validationMode != null) { - matchingParamValues.add(validationMode); - } else { - throwInvalidMode(paramValues[0]); - } - } - - } else { - for (String nextValue : paramValues) { - FhirContext ctx = theRequest.getServer().getFhirContext(); - RuntimePrimitiveDatatypeDefinition def = (RuntimePrimitiveDatatypeDefinition) ctx.getElementDefinition(myParameterType.asSubclass(IBase.class)); - IPrimitiveType instance = def.newInstance(); - instance.setValueAsString(nextValue); - matchingParamValues.add(instance); - } - } - } else { - HapiLocalizer localizer = theRequest.getServer().getFhirContext().getLocalizer(); - String msg = localizer.getMessage(OperationParameter.class, "urlParamNotPrimitive", myOperationName, myName); - throw new MethodNotAllowedException(msg, RequestTypeEnum.POST); - } - } - } - } - - private void translateQueryParametersIntoServerArgumentForPost(RequestDetails theRequest, List matchingParamValues) { - IBaseResource requestContents = (IBaseResource) theRequest.getUserData().get(REQUEST_CONTENTS_USERDATA_KEY); - RuntimeResourceDefinition def = myContext.getResourceDefinition(requestContents); - if (def.getName().equals("Parameters")) { - - BaseRuntimeChildDefinition paramChild = def.getChildByName("parameter"); - BaseRuntimeElementCompositeDefinition paramChildElem = (BaseRuntimeElementCompositeDefinition) paramChild.getChildByName("parameter"); - - RuntimeChildPrimitiveDatatypeDefinition nameChild = (RuntimeChildPrimitiveDatatypeDefinition) paramChildElem.getChildByName("name"); - BaseRuntimeChildDefinition valueChild = paramChildElem.getChildByName("value[x]"); - BaseRuntimeChildDefinition resourceChild = paramChildElem.getChildByName("resource"); - - IAccessor paramChildAccessor = paramChild.getAccessor(); - List values = paramChildAccessor.getValues(requestContents); - for (IBase nextParameter : values) { - List nextNames = nameChild.getAccessor().getValues(nextParameter); - if (nextNames != null && nextNames.size() > 0) { - IPrimitiveType nextName = (IPrimitiveType) nextNames.get(0); - if (myName.equals(nextName.getValueAsString())) { - - if (myParameterType.isAssignableFrom(nextParameter.getClass())) { - matchingParamValues.add(nextParameter); - } else { - List paramValues = valueChild.getAccessor().getValues(nextParameter); - List paramResources = resourceChild.getAccessor().getValues(nextParameter); - if (paramValues != null && paramValues.size() > 0) { - tryToAddValues(paramValues, matchingParamValues); - } else if (paramResources != null && paramResources.size() > 0) { - tryToAddValues(paramResources, matchingParamValues); - } - } - - } - } - } - - } else { - - if (myParameterType.isAssignableFrom(requestContents.getClass())) { - tryToAddValues(Arrays.asList((IBase) requestContents), matchingParamValues); - } - - } - } - - @SuppressWarnings("unchecked") - private void tryToAddValues(List theParamValues, List theMatchingParamValues) { - for (Object nextValue : theParamValues) { - if (nextValue == null) { - continue; - } - if (myConverter != null) { - nextValue = myConverter.incomingServer(nextValue); - } - if (!myParameterType.isAssignableFrom(nextValue.getClass())) { - Class sourceType = (Class) nextValue.getClass(); - Class targetType = (Class) myParameterType; - BaseRuntimeElementDefinition sourceTypeDef = myContext.getElementDefinition(sourceType); - BaseRuntimeElementDefinition targetTypeDef = myContext.getElementDefinition(targetType); - if (targetTypeDef instanceof IRuntimeDatatypeDefinition && sourceTypeDef instanceof IRuntimeDatatypeDefinition) { - IRuntimeDatatypeDefinition targetTypeDtDef = (IRuntimeDatatypeDefinition) targetTypeDef; - if (targetTypeDtDef.isProfileOf(sourceType)) { - FhirTerser terser = myContext.newTerser(); - IBase newTarget = targetTypeDef.newInstance(); - terser.cloneInto((IBase) nextValue, newTarget, true); - theMatchingParamValues.add(newTarget); - continue; - } - } - throwWrongParamType(nextValue); - } - - addValueToList(theMatchingParamValues, nextValue); - } - } public static void throwInvalidMode(String paramValues) { throw new InvalidRequestException("Invalid mode value: \"" + paramValues + "\""); diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PageMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PageMethodBinding.java index 06310879eac..7e32454353b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PageMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PageMethodBinding.java @@ -1,47 +1,14 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import static org.apache.commons.lang3.StringUtils.isBlank; - import java.lang.reflect.Method; -import java.util.HashSet; -import java.util.Set; -import org.hl7.fhir.instance.model.api.IBase; 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.Include; import ca.uhn.fhir.model.valueset.BundleTypeEnum; -import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; -import ca.uhn.fhir.rest.api.server.IVersionSpecificBundleFactory; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.RestfulServerUtils.ResponseEncoding; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.exceptions.ResourceGoneException; import ca.uhn.fhir.util.CoverageIgnore; public class PageMethodBinding extends BaseResourceReturningMethodBinding { @@ -50,143 +17,19 @@ public class PageMethodBinding extends BaseResourceReturningMethodBinding { super(null, theMethod, theContext, null); } - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(PageMethodBinding.class); - - public IBaseResource provider() { - return null; - } - @Override protected BundleTypeEnum getResponseBundleType() { return null; } - @Override - public ReturnTypeEnum getReturnType() { - return ReturnTypeEnum.BUNDLE; - } - - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - return handlePagingRequest(theServer, theRequest, theRequest.getParameters().get(Constants.PARAM_PAGINGACTION)[0]); - } - - @Override - public ResourceOrDstu1Bundle doInvokeServer(IRestfulServer theServer, RequestDetails theRequest) { - IBase bundle = handlePagingRequest(theServer, theRequest, theRequest.getParameters().get(Constants.PARAM_PAGINGACTION)[0]); - if (bundle instanceof Bundle) { - return new ResourceOrDstu1Bundle((Bundle) bundle); - } - return new ResourceOrDstu1Bundle((IBaseResource) bundle); - } - - private IBase handlePagingRequest(IRestfulServer theServer, RequestDetails theRequest, String thePagingAction) { - IPagingProvider pagingProvider = theServer.getPagingProvider(); - if (pagingProvider == null) { - throw new InvalidRequestException("This server does not support paging"); - } - IBundleProvider resultList = pagingProvider.retrieveResultList(thePagingAction); - if (resultList == null) { - ourLog.info("Client requested unknown paging ID[{}]", thePagingAction); - String msg = getContext().getLocalizer().getMessage(PageMethodBinding.class, "unknownSearchId", thePagingAction); - throw new ResourceGoneException(msg); - } - - Integer count = RestfulServerUtils.extractCountParameter(theRequest); - if (count == null) { - count = pagingProvider.getDefaultPageSize(); - } else if (count > pagingProvider.getMaximumPageSize()) { - count = pagingProvider.getMaximumPageSize(); - } - - Integer offsetI = RestfulServerUtils.tryToExtractNamedParameter(theRequest, Constants.PARAM_PAGINGOFFSET); - if (offsetI == null || offsetI < 0) { - offsetI = 0; - } - - Integer totalNum = resultList.size(); - int start = offsetI; - if (totalNum != null) { - start = Math.min(start, totalNum - 1); - } - - ResponseEncoding responseEncoding = RestfulServerUtils.determineResponseEncodingNoDefault(theRequest, theServer.getDefaultResponseEncoding()); - boolean prettyPrint = RestfulServerUtils.prettyPrintResponse(theServer, theRequest); - - IVersionSpecificBundleFactory bundleFactory = theServer.getFhirContext().newBundleFactory(); - - Set includes = new HashSet(); - String[] reqIncludes = theRequest.getParameters().get(Constants.PARAM_INCLUDE); - if (reqIncludes != null) { - for (String nextInclude : reqIncludes) { - includes.add(new Include(nextInclude)); - } - } - - String linkSelfBase = theRequest.getFhirServerBase(); // myServerAddressStrategy.determineServerBase(getServletContext(), - // theRequest.getServletRequest()); - String completeUrl = theRequest.getCompleteUrl(); - String linkSelf = linkSelfBase + completeUrl.substring(theRequest.getCompleteUrl().indexOf('?')); - - BundleTypeEnum bundleType = null; - String[] bundleTypeValues = theRequest.getParameters().get(Constants.PARAM_BUNDLETYPE); - if (bundleTypeValues != null) { - bundleType = BundleTypeEnum.VALUESET_BINDER.fromCodeString(bundleTypeValues[0]); - } - - EncodingEnum encodingEnum = null; - if (responseEncoding != null) { - encodingEnum = responseEncoding.getEncoding(); - } - bundleFactory.initializeBundleFromBundleProvider(theServer, resultList, encodingEnum, theRequest.getFhirServerBase(), linkSelf, prettyPrint, start, count, thePagingAction, bundleType, includes); - - Bundle bundle = bundleFactory.getDstu1Bundle(); - if (bundle != null) { - return bundle; - } - return bundleFactory.getResourceBundle(); - // if (bundle != null) { - // for (int i = getInterceptors().size() - 1; i >= 0; i--) { - // IServerInterceptor next = getInterceptors().get(i); - // boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(), - // theRequest.getServletResponse()); - // if (!continueProcessing) { - // ourLog.debug("Interceptor {} returned false, not continuing processing"); - // return; - // } - // } - // theRequest.getResponse().streamResponseAsBundle(bundle, summaryMode, respondGzip, requestIsBrowser); - // } else { - // IBaseResource resBundle = bundleFactory.getResourceBundle(); - // for (int i = getInterceptors().size() - 1; i >= 0; i--) { - // IServerInterceptor next = getInterceptors().get(i); - // boolean continueProcessing = next.outgoingResponse(theRequest, resBundle, theRequest.getServletRequest(), - // theRequest.getServletResponse()); - // if (!continueProcessing) { - // ourLog.debug("Interceptor {} returned false, not continuing processing"); - // return; - // } - // } - // theRequest.getResponse().streamResponseAsResource(resBundle, prettyPrint, summaryMode, - // Constants.STATUS_HTTP_200_OK, theRequest.isRespondGzip(), false); - // } - } - @Override public RestOperationTypeEnum getRestOperationType() { return RestOperationTypeEnum.GET_PAGE; } @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - String[] pageId = theRequest.getParameters().get(Constants.PARAM_PAGINGACTION); - if (pageId == null || pageId.length == 0 || isBlank(pageId[0])) { - return false; - } - if (theRequest.getRequestType() != RequestTypeEnum.GET) { - return false; - } - return true; + public ReturnTypeEnum getReturnType() { + return ReturnTypeEnum.BUNDLE; } @CoverageIgnore @@ -195,4 +38,8 @@ public class PageMethodBinding extends BaseResourceReturningMethodBinding { throw new UnsupportedOperationException(); } + public IBaseResource provider() { + return null; + } + } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchMethodBinding.java index 22679c5d0a1..39c8442970d 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchMethodBinding.java @@ -22,7 +22,12 @@ package ca.uhn.fhir.rest.client.method; import java.lang.annotation.Annotation; import java.lang.reflect.Method; -import java.util.*; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; import org.hl7.fhir.instance.model.api.IIdType; @@ -35,6 +40,7 @@ import ca.uhn.fhir.rest.api.PatchTypeEnum; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchTypeParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchTypeParameter.java index 013e5570535..13c3c8b6b07 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchTypeParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/PatchTypeParameter.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.rest.client.method; -import static org.apache.commons.lang3.StringUtils.defaultString; - /* * #%L * HAPI FHIR - Core Library @@ -12,7 +10,7 @@ import static org.apache.commons.lang3.StringUtils.defaultString; * 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 + * 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, @@ -30,42 +28,18 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.api.PatchTypeEnum; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; class PatchTypeParameter implements IParameter { @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { // nothing } - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - return getTypeForRequestOrThrowInvalidRequestException(theRequest); - } - @Override public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { // ignore } - public static PatchTypeEnum getTypeForRequestOrThrowInvalidRequestException(RequestDetails theRequest) { - String contentTypeAll = defaultString(theRequest.getHeader(Constants.HEADER_CONTENT_TYPE)); - String contentType = contentTypeAll; - int semiColonIdx = contentType.indexOf(';'); - if (semiColonIdx != -1) { - contentType = contentTypeAll.substring(0, semiColonIdx); - } - contentType = contentType.trim(); - if (Constants.CT_JSON_PATCH.equals(contentType)) { - return PatchTypeEnum.JSON_PATCH; - } else if (Constants.CT_XML_PATCH.equals(contentType)) { - return PatchTypeEnum.XML_PATCH; - } else { - throw new InvalidRequestException("Invalid Content-Type for PATCH operation: " + contentTypeAll); - } - } - } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterAndBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterAndBinder.java index 21b1e0f0519..df6f8f53d6b 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterAndBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterAndBinder.java @@ -26,6 +26,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterAnd; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterOrBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterOrBinder.java index 9d88705102d..3ba977abc9f 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterOrBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterOrBinder.java @@ -26,6 +26,7 @@ import java.util.List; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterTypeBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterTypeBinder.java index 85efb098e96..4565aec2d13 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterTypeBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/QueryParameterTypeBinder.java @@ -28,6 +28,7 @@ import org.apache.commons.lang3.StringUtils; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IQueryParameterOr; import ca.uhn.fhir.model.api.IQueryParameterType; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RawParamsParmeter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RawParamsParmeter.java index 523be4871c6..feafca99a53 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RawParamsParmeter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RawParamsParmeter.java @@ -32,7 +32,8 @@ import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.rest.annotation.RawParam; -import ca.uhn.fhir.rest.client.method.SearchMethodBinding.QualifierDetails; +import ca.uhn.fhir.rest.param.IParameter; +import ca.uhn.fhir.rest.param.QualifierDetails; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ReadMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ReadMethodBinding.java index fd02c023210..a2464dabbb5 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ReadMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ReadMethodBinding.java @@ -1,7 +1,5 @@ package ca.uhn.fhir.rest.client.method; -import static org.apache.commons.lang3.StringUtils.isNotBlank; - /* * #%L * HAPI FHIR - Core Library @@ -12,7 +10,7 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; * 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 + * 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, @@ -25,29 +23,31 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; import org.apache.commons.io.IOUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; -import org.hl7.fhir.instance.model.api.*; +import org.hl7.fhir.instance.model.api.IBaseBinary; +import org.hl7.fhir.instance.model.api.IBaseResource; +import org.hl7.fhir.instance.model.api.IIdType; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.model.api.*; +import ca.uhn.fhir.model.api.Bundle; +import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.valueset.BundleTypeEnum; -import ca.uhn.fhir.rest.annotation.*; -import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.annotation.Elements; +import ca.uhn.fhir.rest.annotation.IdParam; +import ca.uhn.fhir.rest.annotation.Read; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; -import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.exceptions.*; -import ca.uhn.fhir.util.DateUtils; +import ca.uhn.fhir.rest.param.IParameter; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class); - private Integer myIdIndex; private boolean mySupportsVersion; private Integer myVersionIdIndex; @@ -69,7 +69,8 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem myVersionIdIndex = versionIdIndex; if (myIdIndex == null) { - throw new ConfigurationException("@" + Read.class.getSimpleName() + " method " + theMethod.getName() + " on type \"" + theMethod.getDeclaringClass().getName() + "\" does not have a parameter annotated with @" + IdParam.class.getSimpleName()); + throw new ConfigurationException("@" + Read.class.getSimpleName() + " method " + theMethod.getName() + " on type \"" + theMethod.getDeclaringClass().getName() + + "\" does not have a parameter annotated with @" + IdParam.class.getSimpleName()); } myIdParameterType = (Class) parameterTypes[myIdIndex]; @@ -82,14 +83,6 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem } - @Override - public RestOperationTypeEnum getRestOperationType(RequestDetails theRequestDetails) { - if (mySupportsVersion && theRequestDetails.getId().hasVersionIdPart()) { - return RestOperationTypeEnum.VREAD; - } - return RestOperationTypeEnum.READ; - } - @Override public List> getAllowableParamAnnotations() { ArrayList> retVal = new ArrayList>(); @@ -108,44 +101,6 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem return ReturnTypeEnum.RESOURCE; } - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (!theRequest.getResourceName().equals(getResourceName())) { - return false; - } - for (String next : theRequest.getParameters().keySet()) { - if (!ALLOWED_PARAMS.contains(next)) { - return false; - } - } - if (theRequest.getId() == null) { - return false; - } - if (mySupportsVersion == false) { - if (theRequest.getId().hasVersionIdPart()) { - return false; - } - } - if (isNotBlank(theRequest.getCompartmentName())) { - return false; - } - if (theRequest.getRequestType() != RequestTypeEnum.GET) { - ourLog.trace("Method {} doesn't match because request type is not GET: {}", theRequest.getId(), theRequest.getRequestType()); - return false; - } - if (Constants.PARAM_HISTORY.equals(theRequest.getOperation())) { - if (mySupportsVersion == false && myVersionIdIndex == null) { - return false; - } - if (theRequest.getId().hasVersionIdPart() == false) { - return false; - } - } else if (!StringUtils.isBlank(theRequest.getOperation())) { - return false; - } - return true; - } - @Override public HttpGetClientInvocation invokeClient(Object[] theArgs) { HttpGetClientInvocation retVal; @@ -173,7 +128,8 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem } @Override - public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map> theHeaders) throws IOException, BaseServerResponseException { + public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map> theHeaders) + throws IOException, BaseServerResponseException { byte[] contents = IOUtils.toByteArray(theResponseReader); IBaseBinary resource = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance(); @@ -187,8 +143,6 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem return Collections.singletonList(resource); case RESOURCE: return resource; - case BUNDLE_PROVIDER: - return new SimpleBundleProvider(resource); case BUNDLE_RESOURCE: case METHOD_OUTCOME: break; @@ -197,61 +151,6 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem throw new IllegalStateException("" + getMethodReturnType()); // should not happen } - @Override - public IBundleProvider invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - theMethodParams[myIdIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParameterType); - if (myVersionIdIndex != null) { - theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart()); - } - - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - IBundleProvider retVal = toResourceList(response); - - - if (retVal.size() == 1) { - List responseResources = retVal.getResources(0, 1); - IBaseResource responseResource = responseResources.get(0); - - // If-None-Match - if (theRequest.getServer().getETagSupport() == ETagSupportEnum.ENABLED) { - String ifNoneMatch = theRequest.getHeader(Constants.HEADER_IF_NONE_MATCH_LC); - if (StringUtils.isNotBlank(ifNoneMatch)) { - ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch); - if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) { - if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) { - ourLog.debug("Returning HTTP 301 because request specified {}={}", Constants.HEADER_IF_NONE_MATCH, ifNoneMatch); - throw new NotModifiedException("Not Modified"); - } - } - } - } - - // If-Modified-Since - String ifModifiedSince = theRequest.getHeader(Constants.HEADER_IF_MODIFIED_SINCE_LC); - if (isNotBlank(ifModifiedSince)) { - Date ifModifiedSinceDate = DateUtils.parseDate(ifModifiedSince); - Date lastModified = null; - if (responseResource instanceof IResource) { - InstantDt lastModifiedDt = ResourceMetadataKeyEnum.UPDATED.get((IResource) responseResource); - if (lastModifiedDt != null) { - lastModified = lastModifiedDt.getValue(); - } - } else { - lastModified = ((IAnyResource)responseResource).getMeta().getLastUpdated(); - } - - if (lastModified != null && lastModified.getTime() > ifModifiedSinceDate.getTime()) { - ourLog.debug("Returning HTTP 301 because If-Modified-Since does not match"); - throw new NotModifiedException("Not Modified"); - } - } - - } // if we have at least 1 result - - - return retVal; - } - @Override public boolean isBinary() { return "Binary".equals(getResourceName()); diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RequestOperationCallbackParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RequestOperationCallbackParameter.java deleted file mode 100644 index 0f73ec8c3f4..00000000000 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/RequestOperationCallbackParameter.java +++ /dev/null @@ -1,54 +0,0 @@ -package ca.uhn.fhir.rest.client.method; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.hl7.fhir.instance.model.api.IBaseResource; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.util.CoverageIgnore; - -class RequestOperationCallbackParameter implements IParameter { -// private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestParameter.class); - - @CoverageIgnore - @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { - // nothing - } - - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - return theRequest.getRequestOperationCallback(); - } - - @Override - public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { - // ignore - } - -} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ResourceParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ResourceParameter.java new file mode 100644 index 00000000000..430cafea359 --- /dev/null +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ResourceParameter.java @@ -0,0 +1,40 @@ +package ca.uhn.fhir.rest.client.method; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.hl7.fhir.instance.model.api.IBaseResource; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; + +public class ResourceParameter implements IParameter { + + /** + * Constructor + */ + public ResourceParameter() { + super(); + } + + @Override + public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { + // ignore for now + } + + @Override + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { + // ignore, as this is handles as a special case + } + + public enum Mode { + BODY, + BODY_BYTE_ARRAY, + ENCODING, + RESOURCE + } + +} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchMethodBinding.java index 9e535787f34..134760bfcd3 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchMethodBinding.java @@ -23,14 +23,11 @@ import static org.apache.commons.lang3.StringUtils.isBlank; import static org.apache.commons.lang3.StringUtils.isNotBlank; import java.lang.reflect.Method; -import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -41,24 +38,19 @@ import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.Search; -import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; +import ca.uhn.fhir.rest.api.SearchStyleEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.param.BaseQueryParameter; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class SearchMethodBinding extends BaseResourceReturningMethodBinding { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchMethodBinding.class); - private String myCompartmentName; private String myDescription; private Integer myIdParamIndex; private String myQueryName; - private boolean myAllowUnknownParams; public SearchMethodBinding(Class theReturnResourceType, Method theMethod, FhirContext theContext, Object theProvider) { super(theReturnResourceType, theMethod, theContext, theProvider); @@ -66,7 +58,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding { this.myQueryName = StringUtils.defaultIfBlank(search.queryName(), null); this.myCompartmentName = StringUtils.defaultIfBlank(search.compartmentName(), null); this.myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod, getContext()); - this.myAllowUnknownParams = search.allowUnknownParams(); Description desc = theMethod.getAnnotation(Description.class); if (desc != null) { @@ -119,13 +110,13 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding { } @Override - public RestOperationTypeEnum getRestOperationType() { - return RestOperationTypeEnum.SEARCH_TYPE; + protected BundleTypeEnum getResponseBundleType() { + return BundleTypeEnum.SEARCHSET; } @Override - protected BundleTypeEnum getResponseBundleType() { - return BundleTypeEnum.SEARCHSET; + public RestOperationTypeEnum getRestOperationType() { + return RestOperationTypeEnum.SEARCH_TYPE; } @Override @@ -133,129 +124,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding { return ReturnTypeEnum.BUNDLE; } - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - - String clientPreference = theRequest.getHeader(Constants.HEADER_PREFER); - boolean lenientHandling = false; - if(clientPreference != null) - { - String[] preferences = clientPreference.split(";"); - for( String p : preferences){ - if("handling:lenient".equalsIgnoreCase(p)) - { - lenientHandling = true; - break; - } - } - } - - if (theRequest.getId() != null && myIdParamIndex == null) { - ourLog.trace("Method {} doesn't match because ID is not null: {}", theRequest.getId()); - return false; - } - if (theRequest.getRequestType() == RequestTypeEnum.GET && theRequest.getOperation() != null && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) { - ourLog.trace("Method {} doesn't match because request type is GET but operation is not null: {}", theRequest.getId(), theRequest.getOperation()); - return false; - } - if (theRequest.getRequestType() == RequestTypeEnum.POST && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) { - ourLog.trace("Method {} doesn't match because request type is POST but operation is not _search: {}", theRequest.getId(), theRequest.getOperation()); - return false; - } - if (theRequest.getRequestType() != RequestTypeEnum.GET && theRequest.getRequestType() != RequestTypeEnum.POST) { - ourLog.trace("Method {} doesn't match because request type is {}", getMethod()); - return false; - } - if (!StringUtils.equals(myCompartmentName, theRequest.getCompartmentName())) { - ourLog.trace("Method {} doesn't match because it is for compartment {} but request is compartment {}", new Object[] { getMethod(), myCompartmentName, theRequest.getCompartmentName() }); - return false; - } - // This is used to track all the parameters so we can reject queries that - // have additional params we don't understand - Set methodParamsTemp = new HashSet(); - - Set unqualifiedNames = theRequest.getUnqualifiedToQualifiedNames().keySet(); - Set qualifiedParamNames = theRequest.getParameters().keySet(); - for (int i = 0; i < this.getParameters().size(); i++) { - if (!(getParameters().get(i) instanceof BaseQueryParameter)) { - continue; - } - BaseQueryParameter temp = (BaseQueryParameter) getParameters().get(i); - String name = temp.getName(); - if (temp.isRequired()) { - - if (qualifiedParamNames.contains(name)) { - QualifierDetails qualifiers = extractQualifiersFromParameterName(name); - if (qualifiers.passes(temp.getQualifierWhitelist(), temp.getQualifierBlacklist())) { - methodParamsTemp.add(name); - } - } - if (unqualifiedNames.contains(name)) { - List qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name); - qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, temp.getQualifierWhitelist(), temp.getQualifierBlacklist()); - methodParamsTemp.addAll(qualifiedNames); - } - if (!qualifiedParamNames.contains(name) && !unqualifiedNames.contains(name)) - { - ourLog.trace("Method {} doesn't match param '{}' is not present", getMethod().getName(), name); - return false; - } - - } else { - if (qualifiedParamNames.contains(name)) { - QualifierDetails qualifiers = extractQualifiersFromParameterName(name); - if (qualifiers.passes(temp.getQualifierWhitelist(), temp.getQualifierBlacklist())) { - methodParamsTemp.add(name); - } - } - if (unqualifiedNames.contains(name)) { - List qualifiedNames = theRequest.getUnqualifiedToQualifiedNames().get(name); - qualifiedNames = processWhitelistAndBlacklist(qualifiedNames, temp.getQualifierWhitelist(), temp.getQualifierBlacklist()); - methodParamsTemp.addAll(qualifiedNames); - } - if (!qualifiedParamNames.contains(name)) { - methodParamsTemp.add(name); - } - } - } - if (myQueryName != null) { - String[] queryNameValues = theRequest.getParameters().get(Constants.PARAM_QUERY); - if (queryNameValues != null && StringUtils.isNotBlank(queryNameValues[0])) { - String queryName = queryNameValues[0]; - if (!myQueryName.equals(queryName)) { - ourLog.trace("Query name does not match {}", myQueryName); - return false; - } - methodParamsTemp.add(Constants.PARAM_QUERY); - } else { - ourLog.trace("Query name does not match {}", myQueryName); - return false; - } - } else { - String[] queryNameValues = theRequest.getParameters().get(Constants.PARAM_QUERY); - if (queryNameValues != null && StringUtils.isNotBlank(queryNameValues[0])) { - ourLog.trace("Query has name"); - return false; - } - } - for (String next : theRequest.getParameters().keySet()) { - if (ALLOWED_PARAMS.contains(next)) { - methodParamsTemp.add(next); - } - } - Set keySet = theRequest.getParameters().keySet(); - if(lenientHandling == true) - return true; - - if (myAllowUnknownParams == false) { - for (String next : keySet) { - if (!methodParamsTemp.contains(next)) { - return false; - } - } - } - return true; - } @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { @@ -282,43 +150,23 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding { return retVal; } - @Override - public IBundleProvider invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - if (myIdParamIndex != null) { - theMethodParams[myIdParamIndex] = theRequest.getId(); - } - - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - - return toResourceList(response); - - } @Override protected boolean isAddContentLocationHeader() { return false; } - private List processWhitelistAndBlacklist(List theQualifiedNames, Set theQualifierWhitelist, Set theQualifierBlacklist) { - if (theQualifierWhitelist == null && theQualifierBlacklist == null) { - return theQualifiedNames; - } - ArrayList retVal = new ArrayList(theQualifiedNames.size()); - for (String next : theQualifiedNames) { - QualifierDetails qualifiers = extractQualifiersFromParameterName(next); - if (!qualifiers.passes(theQualifierWhitelist, theQualifierBlacklist)) { - continue; - } - retVal.add(next); - } - return retVal; - } @Override public String toString() { return getMethod().toString(); } + public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theSearchUrl, Map> theParams) { + return new HttpGetClientInvocation(theContext, theParams, theSearchUrl); + } + + public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map> theParameters, IdDt theId, String theCompartmentName, SearchStyleEnum theSearchStyle) { SearchStyleEnum searchStyle = theSearchStyle; @@ -379,9 +227,4 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding { return invocation; } - - public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theSearchUrl, Map> theParams) { - return new HttpGetClientInvocation(theContext, theParams, theSearchUrl); - } - } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchParameter.java index 140215c0de8..4eeb07d6b6d 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SearchParameter.java @@ -45,6 +45,8 @@ import ca.uhn.fhir.model.base.composite.BaseIdentifierDt; import ca.uhn.fhir.model.base.composite.BaseQuantityDt; import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.rest.annotation.OptionalParam; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.QualifiedParamList; import ca.uhn.fhir.rest.api.RestSearchParameterTypeEnum; import ca.uhn.fhir.rest.param.BaseQueryParameter; import ca.uhn.fhir.rest.param.CompositeAndListParam; @@ -75,7 +77,6 @@ import ca.uhn.fhir.rest.param.TokenParam; import ca.uhn.fhir.rest.param.UriAndListParam; import ca.uhn.fhir.rest.param.UriOrListParam; import ca.uhn.fhir.rest.param.UriParam; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.util.CollectionUtil; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServerBaseParamBinder.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServerBaseParamBinder.java index 884a185ecc9..9830155dc4e 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServerBaseParamBinder.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServerBaseParamBinder.java @@ -28,6 +28,7 @@ import java.util.Map; import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletRequestParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletRequestParameter.java deleted file mode 100644 index 14f6b919460..00000000000 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletRequestParameter.java +++ /dev/null @@ -1,60 +0,0 @@ -package ca.uhn.fhir.rest.client.method; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.hl7.fhir.instance.model.api.IBaseResource; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; - -class ServletRequestParameter implements IParameter { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletRequestParameter.class); - - ServletRequestParameter() { - super(); - } - - @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { - /* - * Does nothing, since we just ignore HttpServletRequest arguments - */ - ourLog.trace("Ignoring HttpServletRequest argument: {}", theSourceClientArgument); - } - - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - return ((ServletRequestDetails) theRequest).getServletRequest(); - } - - @Override - public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { - // ignore - } - -} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletResponseParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletResponseParameter.java deleted file mode 100644 index d9f0b13f48f..00000000000 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ServletResponseParameter.java +++ /dev/null @@ -1,57 +0,0 @@ -package ca.uhn.fhir.rest.client.method; - -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.lang.reflect.Method; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.hl7.fhir.instance.model.api.IBaseResource; - -import ca.uhn.fhir.context.FhirContext; -import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails; - -class ServletResponseParameter implements IParameter { - private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ServletResponseParameter.class); - - @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { - /* - * Does nothing, since we just ignore HttpServletResponse arguments - */ - ourLog.trace("Ignoring HttpServletResponse argument: {}", theSourceClientArgument); - } - - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - return ((ServletRequestDetails) theRequest).getServletResponse(); - } - - - @Override - public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { - // ignore - } - -} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SinceParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SinceParameter.java index 6ac1df5d6a6..8c8b9c69718 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SinceParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SinceParameter.java @@ -21,7 +21,6 @@ package ca.uhn.fhir.rest.client.method; */ import ca.uhn.fhir.rest.annotation.Since; -import ca.uhn.fhir.rest.server.Constants; class SinceParameter extends SinceOrAtParameter { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SortParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SortParameter.java index ba587e311b7..fcdd55e03ae 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SortParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SortParameter.java @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.StringTokenizer; import org.hl7.fhir.instance.model.api.IBaseResource; @@ -34,12 +33,11 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.rest.annotation.Sort; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.SortOrderEnum; import ca.uhn.fhir.rest.api.SortSpec; import ca.uhn.fhir.rest.param.ParameterUtil; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class SortParameter implements IParameter { @@ -97,81 +95,6 @@ public class SortParameter implements IParameter { } } - @Override - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, 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)) { - return null; - } - } - } - - SortSpec outerSpec = null; - SortSpec innerSpec = null; - for (String nextParamName : theRequest.getParameters().keySet()) { - SortOrderEnum order; - if (Constants.PARAM_SORT.equals(nextParamName)) { - order = null; - } else if (Constants.PARAM_SORT_ASC.equals(nextParamName)) { - order = SortOrderEnum.ASC; - } else if (Constants.PARAM_SORT_DESC.equals(nextParamName)) { - order = SortOrderEnum.DESC; - } else { - continue; - } - - String[] values = theRequest.getParameters().get(nextParamName); - if (values != null) { - - for (String nextValue : values) { - - if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU2) && order == null) { - StringTokenizer tok = new StringTokenizer(nextValue, ","); - while (tok.hasMoreTokens()) { - String next = tok.nextToken(); - if (isNotBlank(next) && !next.equals("-")) { - order = SortOrderEnum.ASC; - if (next.startsWith("-")) { - order = SortOrderEnum.DESC; - next = next.substring(1); - } - - SortSpec spec = new SortSpec(); - spec.setOrder(order); - spec.setParamName(next); - if (innerSpec == null) { - outerSpec = spec; - innerSpec = spec; - } else { - innerSpec.setChain(spec); - innerSpec = spec; - } - - } - } - - } else { - - if (isNotBlank(nextValue)) { - SortSpec spec = new SortSpec(); - spec.setOrder(order); - spec.setParamName(nextValue); - if (innerSpec == null) { - outerSpec = spec; - innerSpec = spec; - } else { - innerSpec.setChain(spec); - innerSpec = spec; - } - } - } - } - } - } - - return outerSpec; - } public static String createSortStringDstu3(SortSpec ss) { StringBuilder val = new StringBuilder(); diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SummaryEnumParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SummaryEnumParameter.java index c080bf810c3..47868101916 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SummaryEnumParameter.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/SummaryEnumParameter.java @@ -1,53 +1,26 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ -import static org.apache.commons.lang3.StringUtils.isBlank; - import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import org.hl7.fhir.instance.model.api.IBaseResource; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.rest.api.Constants; import ca.uhn.fhir.rest.api.SummaryEnum; -import ca.uhn.fhir.rest.param.CollectionBinder; -import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class SummaryEnumParameter implements IParameter { - @SuppressWarnings("rawtypes") - private Class myInnerCollectionType; - @SuppressWarnings("unchecked") @Override - public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) throws InternalErrorException { + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { if (theSourceClientArgument instanceof Collection) { List values = new ArrayList(); for (SummaryEnum next : (Collection) theSourceClientArgument) { @@ -64,81 +37,11 @@ public class SummaryEnumParameter implements IParameter { } } - @Override - @SuppressWarnings({ "rawtypes", "unchecked" }) - public Object translateQueryParametersIntoServerArgument(RequestDetails theRequest, BaseMethodBinding theMethodBinding) throws InternalErrorException, InvalidRequestException { - Set value = getSummaryValueOrNull(theRequest); - if (value == null || value.isEmpty()) { - return null; - } - - if (myInnerCollectionType == null) { - return value.iterator().next(); - } - - try { - Collection retVal = myInnerCollectionType.newInstance(); - retVal.addAll(value); - return retVal; - } catch (InstantiationException e) { - throw new InternalErrorException("Failed to instantiate " + myInnerCollectionType, e); - } catch (IllegalAccessException e) { - throw new InternalErrorException("Failed to instantiate " + myInnerCollectionType, e); - } - } - - public static Set getSummaryValueOrNull(RequestDetails theRequest) { - String[] summary = theRequest.getParameters().get(Constants.PARAM_SUMMARY); - - Set retVal; - if (summary == null || summary.length == 0) { - retVal = null; - } else if (isBlank(summary[0])) { - retVal = null; - } else if (summary.length == 1) { - retVal = toCollectionOrNull(SummaryEnum.fromCode(summary[0])); - if (retVal == null) { - retVal = toCollectionOrNull(SummaryEnum.fromCode(summary[0].toLowerCase())); - } - } else { - retVal = new HashSet(); - for (String next : summary) { - SummaryEnum value = SummaryEnum.fromCode(next); - if (value == null) { - value = SummaryEnum.fromCode(next.toLowerCase()); - } - if (value != null) { - retVal.add(value); - } - } - } - - if (retVal != null) { - if (retVal.contains(SummaryEnum.TEXT)) { - if (retVal.size() > 1) { - String msg = theRequest.getServer().getFhirContext().getLocalizer().getMessage(SummaryEnumParameter.class, "cantCombineText"); - throw new InvalidRequestException(msg); - } - } - } - - return retVal; - } - - private static Set toCollectionOrNull(SummaryEnum theFromCode) { - if (theFromCode == null) { - return null; - } - return Collections.singleton(theFromCode); - } - @Override public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { if (theOuterCollectionType != null) { - throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + " but can not be a collection of collections"); - } - if (theInnerCollectionType != null) { - myInnerCollectionType = CollectionBinder.getInstantiableCollectionType(theInnerCollectionType, SummaryEnum.class.getSimpleName()); + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of type " + SummaryEnum.class + + " but can not be a collection of collections"); } } diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionMethodBinding.java index 4ea88fc72c8..809754e8949 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionMethodBinding.java @@ -1,28 +1,6 @@ package ca.uhn.fhir.rest.client.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ -import static org.apache.commons.lang3.StringUtils.isNotBlank; - import java.lang.reflect.Method; -import java.util.IdentityHashMap; import java.util.List; import org.hl7.fhir.instance.model.api.IBaseBundle; @@ -31,29 +9,16 @@ 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.ResourceMetadataKeyEnum; -import ca.uhn.fhir.model.base.resource.BaseOperationOutcome; -import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.valueset.BundleTypeEnum; 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.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.IBundleProvider; -import ca.uhn.fhir.rest.server.IRestfulServer; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; -import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails; -import ca.uhn.fhir.rest.server.method.ResourceParameter; -import ca.uhn.fhir.rest.server.method.TransactionParameter; -import ca.uhn.fhir.rest.server.method.TransactionParameter.ParamStyle; public class TransactionMethodBinding extends BaseResourceReturningMethodBinding { private int myTransactionParamIndex; - private ParamStyle myTransactionParamStyle; public TransactionMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) { super(null, theMethod, theContext, theProvider); @@ -67,7 +32,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding + " methods"); } myTransactionParamIndex = index; - myTransactionParamStyle = ((TransactionParameter) next).getParamStyle(); } index++; } @@ -92,19 +56,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding return ReturnTypeEnum.BUNDLE; } - @Override - public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { - if (theRequest.getRequestType() != RequestTypeEnum.POST) { - return false; - } - if (isNotBlank(theRequest.getOperation())) { - return false; - } - if (isNotBlank(theRequest.getResourceName())) { - return false; - } - return true; - } @Override public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException { @@ -118,81 +69,6 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding return createTransactionInvocation(resources, context); } - @SuppressWarnings("unchecked") - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException { - - /* - * The design of HAPI's transaction method for DSTU1 support assumed that a transaction was just an update on a - * bunch of resources (because that's what it was), but in DSTU2 transaction has become much more broad, so we - * no longer hold the user's hand much here. - */ - if (myTransactionParamStyle == ParamStyle.RESOURCE_BUNDLE) { - // This is the DSTU2 style - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - return response; - } - - // Grab the IDs of all of the resources in the transaction - List resources; - if (theMethodParams[myTransactionParamIndex] instanceof Bundle) { - resources = ((Bundle) theMethodParams[myTransactionParamIndex]).toListOfResources(); - } else { - resources = (List) theMethodParams[myTransactionParamIndex]; - } - - IdentityHashMap oldIds = new IdentityHashMap(); - for (IResource next : resources) { - oldIds.put(next, next.getId()); - } - - // Call the server implementation method - Object response = invokeServerMethod(theServer, theRequest, theMethodParams); - IBundleProvider retVal = toResourceList(response); - - /* - * int offset = 0; if (retVal.size() != resources.size()) { if (retVal.size() > 0 && retVal.getResources(0, - * 1).get(0) instanceof OperationOutcome) { offset = 1; } else { throw new - * InternalErrorException("Transaction bundle contained " + resources.size() + - * " entries, but server method response contained " + retVal.size() + " entries (must be the same)"); } } - */ - - List retResources = retVal.getResources(0, retVal.size()); - for (int i = 0; i < retResources.size(); i++) { - IdDt oldId = oldIds.get(retResources.get(i)); - IBaseResource newRes = retResources.get(i); - if (newRes.getIdElement() == null || newRes.getIdElement().isEmpty()) { - if (!(newRes instanceof BaseOperationOutcome)) { - throw new InternalErrorException("Transaction method returned resource at index " + i + " with no id specified - IResource#setId(IdDt)"); - } - } - - if (oldId != null && !oldId.isEmpty()) { - if (!oldId.equals(newRes.getIdElement()) && newRes instanceof IResource) { - ((IResource)newRes).getResourceMetadata().put(ResourceMetadataKeyEnum.PREVIOUS_ID, oldId); - } - } - } - - return retVal; - } - - - @Override - protected void populateActionRequestDetailsForInterceptor(RequestDetails theRequestDetails, ActionRequestDetails theDetails, Object[] theMethodParams) { - super.populateActionRequestDetailsForInterceptor(theRequestDetails, theDetails, theMethodParams); - - /* - * If the method has no parsed resource parameter, we parse here in order to have something for the interceptor. - */ - if (myTransactionParamIndex != -1) { - theDetails.setResource((IBaseResource) theMethodParams[myTransactionParamIndex]); - } else { - Class resourceType = getContext().getResourceDefinition("Bundle").getImplementingClass(); - theDetails.setResource(ResourceParameter.parseResourceFromRequest(theRequestDetails, this, resourceType)); - } - - } public static BaseHttpClientInvocation createTransactionInvocation(Bundle theBundle, FhirContext theContext) { return new HttpPostClientInvocation(theContext, theBundle); diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionParameter.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionParameter.java new file mode 100644 index 00000000000..b0d417a52a8 --- /dev/null +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/TransactionParameter.java @@ -0,0 +1,85 @@ +package ca.uhn.fhir.rest.client.method; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +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.RuntimeResourceDefinition; +import ca.uhn.fhir.model.api.Bundle; +import ca.uhn.fhir.model.api.IResource; +import ca.uhn.fhir.rest.annotation.TransactionParam; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; + +public class TransactionParameter implements IParameter { + + // private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TransactionParameter.class); + private FhirContext myContext; + private ParamStyle myParamStyle; + + public TransactionParameter(FhirContext theContext) { + myContext = theContext; + } + + private String createParameterTypeError(Method theMethod) { + return "Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + TransactionParam.class.getName() + + " but is not of type List<" + IResource.class.getCanonicalName() + "> or Bundle"; + } + + @Override + public void initializeTypes(Method theMethod, Class> theOuterCollectionType, Class> theInnerCollectionType, Class theParameterType) { + if (theOuterCollectionType != null) { + throw new ConfigurationException("Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is annotated with @" + + TransactionParam.class.getName() + " but can not be a collection of collections"); + } + if (theParameterType.equals(Bundle.class)) { + myParamStyle = ParamStyle.DSTU1_BUNDLE; + if (theInnerCollectionType != null) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + } else if (Modifier.isInterface(theParameterType.getModifiers()) == false && IBaseResource.class.isAssignableFrom(theParameterType)) { + @SuppressWarnings("unchecked") + Class parameterType = (Class) theParameterType; + RuntimeResourceDefinition def = myContext.getResourceDefinition(parameterType); + if ("Bundle".equals(def.getName())) { + myParamStyle = ParamStyle.RESOURCE_BUNDLE; + } else { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + } else { + if (theInnerCollectionType.equals(List.class) == false) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + if (theParameterType.equals(IResource.class) == false) { + throw new ConfigurationException(createParameterTypeError(theMethod)); + } + myParamStyle = ParamStyle.RESOURCE_LIST; + } + } + + @Override + public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map> theTargetQueryArguments, IBaseResource theTargetResource) + throws InternalErrorException { + // nothing + + } + + public ParamStyle getParamStyle() { + return myParamStyle; + } + + 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 */ + RESOURCE_BUNDLE, + /** List of resources */ + RESOURCE_LIST + } + +} diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/UpdateMethodBinding.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/UpdateMethodBinding.java index de20494766d..0d861472252 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/UpdateMethodBinding.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/UpdateMethodBinding.java @@ -37,7 +37,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithResourceParam { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu1.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu1.java index b9676130329..a6e7f239476 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu1.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu1.java @@ -33,7 +33,7 @@ import ca.uhn.fhir.rest.annotation.Validate; import ca.uhn.fhir.rest.api.RequestTypeEnum; import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; +import ca.uhn.fhir.rest.param.IParameter; public class ValidateMethodBindingDstu1 extends BaseOutcomeReturningMethodBindingWithResourceParam { diff --git a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java index 59b2fa69441..a7ff2e28366 100644 --- a/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java +++ b/hapi-fhir-client/src/main/java/ca/uhn/fhir/rest/client/method/ValidateMethodBindingDstu2Plus.java @@ -31,9 +31,9 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.valueset.BundleTypeEnum; import ca.uhn.fhir.rest.annotation.OperationParam; import ca.uhn.fhir.rest.annotation.Validate; +import ca.uhn.fhir.rest.api.EncodingEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; -import ca.uhn.fhir.rest.server.Constants; -import ca.uhn.fhir.rest.server.EncodingEnum; +import ca.uhn.fhir.rest.param.IParameter; import ca.uhn.fhir.rest.server.method.ResourceParameter; import ca.uhn.fhir.util.ParametersUtil; diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IFhirVersionServer.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IFhirVersionServer.java index 4890b478b2a..a6c5ebcc045 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IFhirVersionServer.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/api/server/IFhirVersionServer.java @@ -2,7 +2,6 @@ package ca.uhn.fhir.rest.api.server; import org.hl7.fhir.instance.model.api.IBaseResource; -import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IServerConformanceProvider; @@ -17,6 +16,4 @@ public interface IFhirVersionServer { IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer); - IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext); - } diff --git a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseAddOrDeleteTagsMethodBinding.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseAddOrDeleteTagsMethodBinding.java index 039b542994f..07351debe90 100644 --- a/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseAddOrDeleteTagsMethodBinding.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseAddOrDeleteTagsMethodBinding.java @@ -1,26 +1,5 @@ package ca.uhn.fhir.rest.server.method; -/* - * #%L - * HAPI FHIR - Core Library - * %% - * Copyright (C) 2014 - 2017 University Health Network - * %% - * Licensed 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. - * #L% - */ - -import java.io.IOException; import java.io.Reader; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -33,17 +12,18 @@ import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.TagList; import ca.uhn.fhir.model.primitive.IdDt; -import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.rest.annotation.IdParam; import ca.uhn.fhir.rest.annotation.TagListParam; -import ca.uhn.fhir.rest.api.*; -import ca.uhn.fhir.rest.api.server.IRestfulServer; -import ca.uhn.fhir.rest.api.server.RequestDetails; +import ca.uhn.fhir.rest.api.Constants; +import ca.uhn.fhir.rest.api.RequestTypeEnum; +import ca.uhn.fhir.rest.api.RestOperationTypeEnum; import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation; +import ca.uhn.fhir.rest.client.method.RequestDetails; import ca.uhn.fhir.rest.param.IParameter; -import ca.uhn.fhir.rest.server.*; -import ca.uhn.fhir.rest.server.exceptions.*; -import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; +import ca.uhn.fhir.rest.server.IResourceProvider; +import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; +import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; +import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding { @@ -147,37 +127,6 @@ abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding return retVal; } - @Override - public Object invokeServer(IRestfulServer theServer, RequestDetails theRequest) throws BaseServerResponseException, IOException { - Object[] params = createParametersForServerRequest(theRequest); - - params[myIdParamIndex] = theRequest.getId(); - - if (myVersionIdParamIndex != null) { - params[myVersionIdParamIndex] = theRequest.getId(); - } - - IParser parser = createAppropriateParserForParsingServerRequest(theRequest); - Reader reader = theRequest.getReader(); - try { - TagList tagList = parser.parseTagList(reader); - params[myTagListParamIndex] = tagList; - } finally { - reader.close(); - } - invokeServerMethod(theServer, theRequest, params); - - for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) { - IServerInterceptor next = theServer.getInterceptors().get(i); - boolean continueProcessing = next.outgoingResponse(theRequest); - if (!continueProcessing) { - return null; - } - } - - return theRequest.getResponse().returnResponse(null, Constants.STATUS_HTTP_200_OK, false, null, null); - } - @Override public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) { if (theRequest.getRequestType() != RequestTypeEnum.POST) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseQueryParameter.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseQueryParameter.java similarity index 99% rename from hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseQueryParameter.java rename to hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseQueryParameter.java index 7c5fcf9f631..a0b3162cc59 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/BaseQueryParameter.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/BaseQueryParameter.java @@ -1,4 +1,4 @@ -package ca.uhn.fhir.rest.param; +package ca.uhn.fhir.rest.server.method; import static org.apache.commons.lang3.StringUtils.isNotBlank; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/IParameter.java b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IParameter.java similarity index 98% rename from hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/IParameter.java rename to hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IParameter.java index 8b7c9bcd95e..ac8795beb44 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/param/IParameter.java +++ b/hapi-fhir-server/src/main/java/ca/uhn/fhir/rest/server/method/IParameter.java @@ -1,4 +1,4 @@ -package ca.uhn.fhir.rest.param; +package ca.uhn.fhir.rest.server.method; /* * #%L