001package ca.uhn.fhir.rest.client.method;
002
003/*-
004 * #%L
005 * HAPI FHIR - Client Framework
006 * %%
007 * Copyright (C) 2014 - 2021 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import java.lang.reflect.Method;
024import java.util.List;
025
026import org.hl7.fhir.instance.model.api.IBaseBundle;
027import org.hl7.fhir.instance.model.api.IBaseResource;
028
029import ca.uhn.fhir.context.ConfigurationException;
030import ca.uhn.fhir.context.FhirContext;
031import ca.uhn.fhir.model.valueset.BundleTypeEnum;
032import ca.uhn.fhir.rest.annotation.Transaction;
033import ca.uhn.fhir.rest.annotation.TransactionParam;
034import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
035import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
036import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
037
038public class TransactionMethodBinding extends BaseResourceReturningMethodBinding {
039
040        private int myTransactionParamIndex;
041
042        public TransactionMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
043                super(null, theMethod, theContext, theProvider);
044
045                myTransactionParamIndex = -1;
046                int index = 0;
047                for (IParameter next : getParameters()) {
048                        if (next instanceof TransactionParameter) {
049                                if (myTransactionParamIndex != -1) {
050                                        throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " has multiple parameters annotated with the @" + TransactionParam.class + " annotation, exactly one is required for @" + Transaction.class
051                                                        + " methods");
052                                }
053                                myTransactionParamIndex = index;
054                        }
055                        index++;
056                }
057
058                if (myTransactionParamIndex == -1) {
059                        throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a parameter annotated with the @" + TransactionParam.class + " annotation");
060                }
061        }
062
063        @Override
064        public RestOperationTypeEnum getRestOperationType() {
065                return RestOperationTypeEnum.TRANSACTION;
066        }
067
068        @Override
069        protected BundleTypeEnum getResponseBundleType() {
070                return BundleTypeEnum.TRANSACTION_RESPONSE;
071        }
072
073        @Override
074        public ReturnTypeEnum getReturnType() {
075                return ReturnTypeEnum.BUNDLE;
076        }
077
078
079        @Override
080        public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
081                FhirContext context = getContext();
082                Object arg = theArgs[myTransactionParamIndex];
083                
084                if (arg instanceof IBaseBundle) {
085                        return createTransactionInvocation((IBaseBundle) arg, context);
086                }
087                
088                @SuppressWarnings("unchecked")
089                List<IBaseResource> resources = (List<IBaseResource>) arg;
090                return createTransactionInvocation(resources, context);
091        }
092
093
094        public static BaseHttpClientInvocation createTransactionInvocation(IBaseBundle theBundle, FhirContext theContext) {
095                return new HttpPostClientInvocation(theContext, theBundle);
096        }
097
098        public static BaseHttpClientInvocation createTransactionInvocation(List<? extends IBaseResource> theResources, FhirContext theContext) {
099                return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
100        }
101
102        public static BaseHttpClientInvocation createTransactionInvocation(String theRawBundle, FhirContext theContext) {
103                return new HttpPostClientInvocation(theContext, theRawBundle, true, "");
104        }
105
106}