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