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