001package ca.uhn.fhir.rest.client.impl;
002
003/*
004 * #%L
005 * HAPI FHIR - Client Framework
006 * %%
007 * Copyright (C) 2014 - 2023 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.InvocationHandler;
025import java.lang.reflect.Method;
026import java.util.Map;
027
028import ca.uhn.fhir.context.FhirContext;
029import ca.uhn.fhir.rest.client.api.IHttpClient;
030import ca.uhn.fhir.rest.client.impl.ClientInvocationHandlerFactory.ILambda;
031import ca.uhn.fhir.rest.client.method.BaseMethodBinding;
032
033public class ClientInvocationHandler extends BaseClient implements InvocationHandler {
034
035        private final Map<Method, BaseMethodBinding<?>> myBindings;
036        private final Map<Method, Object> myMethodToReturnValue;
037        private FhirContext myContext;
038        private Map<Method, ILambda> myMethodToLambda;
039
040        public ClientInvocationHandler(IHttpClient theClient, FhirContext theContext, String theUrlBase, Map<Method, Object> theMethodToReturnValue, Map<Method, BaseMethodBinding<?>> theBindings, Map<Method, ILambda> theMethodToLambda, RestfulClientFactory theFactory) {
041                super(theClient, theUrlBase, theFactory);
042
043                myContext = theContext;
044                myMethodToReturnValue = theMethodToReturnValue;
045                myBindings = theBindings;
046                myMethodToLambda = theMethodToLambda;
047        }
048
049        public void addBinding(Method theMethod, BaseMethodBinding<?> theBinding) {
050                myBindings.put(theMethod, theBinding);
051        }
052
053        @Override
054        public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
055                Object directRetVal = myMethodToReturnValue.get(theMethod);
056                if (directRetVal != null) {
057                        return directRetVal;
058                }
059
060                BaseMethodBinding<?> binding = myBindings.get(theMethod);
061                if (binding != null) {
062                        BaseHttpClientInvocation clientInvocation = binding.invokeClient(theArgs);
063                        return invokeClient(myContext, binding, clientInvocation);
064                }
065
066                ILambda lambda = myMethodToLambda.get(theMethod);
067                if (lambda != null) {
068                        return lambda.handle(this, theArgs);
069                }
070
071                throw new UnsupportedOperationException(Msg.code(1403) + "The method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getSimpleName() + " has no handler. Did you forget to annotate it with a RESTful method annotation?");
072        }
073
074        @Override
075        public FhirContext getFhirContext() {
076                return myContext;
077        }
078
079}