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