001package ca.uhn.fhir.rest.client.method;
002
003/*-
004 * #%L
005 * HAPI FHIR - Client Framework
006 * %%
007 * Copyright (C) 2014 - 2022 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 ca.uhn.fhir.i18n.Msg;
024import java.lang.reflect.Method;
025import java.util.List;
026
027import org.hl7.fhir.instance.model.api.IBaseBundle;
028import org.hl7.fhir.instance.model.api.IBaseResource;
029
030import ca.uhn.fhir.context.ConfigurationException;
031import ca.uhn.fhir.context.FhirContext;
032import ca.uhn.fhir.model.valueset.BundleTypeEnum;
033import ca.uhn.fhir.rest.annotation.Transaction;
034import ca.uhn.fhir.rest.annotation.TransactionParam;
035import ca.uhn.fhir.rest.api.RestOperationTypeEnum;
036import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
037import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
038
039public class TransactionMethodBinding extends BaseResourceReturningMethodBinding {
040
041        private int myTransactionParamIndex;
042
043        public TransactionMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
044                super(null, theMethod, theContext, theProvider);
045
046                myTransactionParamIndex = -1;
047                int index = 0;
048                for (IParameter next : getParameters()) {
049                        if (next instanceof TransactionParameter) {
050                                if (myTransactionParamIndex != -1) {
051                                        throw new ConfigurationException(Msg.code(1418) + "Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " has multiple parameters annotated with the @" + TransactionParam.class + " annotation, exactly one is required for @" + Transaction.class
052                                                        + " methods");
053                                }
054                                myTransactionParamIndex = index;
055                        }
056                        index++;
057                }
058
059                if (myTransactionParamIndex == -1) {
060                        throw new ConfigurationException(Msg.code(1419) + "Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a parameter annotated with the @" + TransactionParam.class + " annotation");
061                }
062        }
063
064        @Override
065        public RestOperationTypeEnum getRestOperationType() {
066                return RestOperationTypeEnum.TRANSACTION;
067        }
068
069        @Override
070        protected BundleTypeEnum getResponseBundleType() {
071                return BundleTypeEnum.TRANSACTION_RESPONSE;
072        }
073
074        @Override
075        public ReturnTypeEnum getReturnType() {
076                return ReturnTypeEnum.BUNDLE;
077        }
078
079
080        @Override
081        public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
082                FhirContext context = getContext();
083                Object arg = theArgs[myTransactionParamIndex];
084                
085                if (arg instanceof IBaseBundle) {
086                        return createTransactionInvocation((IBaseBundle) arg, context);
087                }
088                
089                @SuppressWarnings("unchecked")
090                List<IBaseResource> resources = (List<IBaseResource>) arg;
091                return createTransactionInvocation(resources, context);
092        }
093
094
095        public static BaseHttpClientInvocation createTransactionInvocation(IBaseBundle theBundle, FhirContext theContext) {
096                return new HttpPostClientInvocation(theContext, theBundle);
097        }
098
099        public static BaseHttpClientInvocation createTransactionInvocation(List<? extends IBaseResource> theResources, FhirContext theContext) {
100                return new HttpPostClientInvocation(theContext, theResources, BundleTypeEnum.TRANSACTION);
101        }
102
103        public static BaseHttpClientInvocation createTransactionInvocation(String theRawBundle, FhirContext theContext) {
104                return new HttpPostClientInvocation(theContext, theRawBundle, true, "");
105        }
106
107}