001package ca.uhn.fhir.rest.client.impl; 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.HashMap; 026import java.util.Map; 027 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.rest.api.EncodingEnum; 033import ca.uhn.fhir.rest.api.SummaryEnum; 034import ca.uhn.fhir.rest.client.api.IClientInterceptor; 035import ca.uhn.fhir.rest.client.api.IHttpClient; 036import ca.uhn.fhir.rest.client.api.IRestfulClient; 037import ca.uhn.fhir.rest.client.method.BaseMethodBinding; 038 039public class ClientInvocationHandlerFactory { 040 041 private final Map<Method, BaseMethodBinding<?>> myBindings = new HashMap<Method, BaseMethodBinding<?>>(); 042 private final IHttpClient myClient; 043 private final FhirContext myContext; 044 private final Map<Method, ILambda> myMethodToLambda = new HashMap<Method, ILambda>(); 045 private final Map<Method, Object> myMethodToReturnValue = new HashMap<Method, Object>(); 046 private final String myUrlBase; 047 048 public ClientInvocationHandlerFactory(IHttpClient theClient, FhirContext theContext, String theUrlBase, Class<? extends IRestfulClient> theClientType) { 049 myClient = theClient; 050 myUrlBase = theUrlBase; 051 myContext = theContext; 052 053 try { 054 myMethodToReturnValue.put(theClientType.getMethod("getFhirContext"), theContext); 055 myMethodToReturnValue.put(theClientType.getMethod("getHttpClient"), theClient); 056 myMethodToReturnValue.put(theClientType.getMethod("getServerBase"), theUrlBase); 057 058 myMethodToLambda.put(theClientType.getMethod("setEncoding", EncodingEnum.class), new SetEncodingLambda()); 059 myMethodToLambda.put(theClientType.getMethod("setPrettyPrint", Boolean.class), new SetPrettyPrintLambda()); 060 myMethodToLambda.put(theClientType.getMethod("registerInterceptor", Object.class), new RegisterInterceptorLambda()); 061 myMethodToLambda.put(theClientType.getMethod("unregisterInterceptor", Object.class), new UnregisterInterceptorLambda()); 062 myMethodToLambda.put(theClientType.getMethod("setSummary", SummaryEnum.class), new SetSummaryLambda()); 063 myMethodToLambda.put(theClientType.getMethod("fetchResourceFromUrl", Class.class, String.class), new FetchResourceFromUrlLambda()); 064 065 } catch (NoSuchMethodException e) { 066 throw new ConfigurationException(Msg.code(1352) + "Failed to find methods on client. This is a HAPI bug!", e); 067 } catch (SecurityException e) { 068 throw new ConfigurationException(Msg.code(1353) + "Failed to find methods on client. This is a HAPI bug!", e); 069 } 070 } 071 072 public void addBinding(Method theMethod, BaseMethodBinding<?> theBinding) { 073 myBindings.put(theMethod, theBinding); 074 } 075 076 ClientInvocationHandler newInvocationHandler(RestfulClientFactory theRestfulClientFactory) { 077 return new ClientInvocationHandler(myClient, myContext, myUrlBase, myMethodToReturnValue, myBindings, myMethodToLambda, theRestfulClientFactory); 078 } 079 080 public interface ILambda { 081 Object handle(ClientInvocationHandler theTarget, Object[] theArgs); 082 } 083 084 class RegisterInterceptorLambda implements ILambda { 085 @Override 086 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 087 Object interceptor = theArgs[0]; 088 theTarget.registerInterceptor(interceptor); 089 return null; 090 } 091 } 092 093 class FetchResourceFromUrlLambda implements ILambda { 094 @Override 095 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 096 @SuppressWarnings("unchecked") 097 Class<? extends IBaseResource> type = (Class<? extends IBaseResource>) theArgs[0]; 098 String url = (String) theArgs[1]; 099 100 return theTarget.fetchResourceFromUrl(type, url); 101 } 102 } 103 104 class SetEncodingLambda implements ILambda { 105 @Override 106 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 107 EncodingEnum encoding = (EncodingEnum) theArgs[0]; 108 theTarget.setEncoding(encoding); 109 return null; 110 } 111 } 112 113 class SetPrettyPrintLambda implements ILambda { 114 @Override 115 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 116 Boolean prettyPrint = (Boolean) theArgs[0]; 117 theTarget.setPrettyPrint(prettyPrint); 118 return null; 119 } 120 } 121 122 class SetSummaryLambda implements ILambda { 123 @Override 124 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 125 SummaryEnum encoding = (SummaryEnum) theArgs[0]; 126 theTarget.setSummary(encoding); 127 return null; 128 } 129 } 130 131 class UnregisterInterceptorLambda implements ILambda { 132 @Override 133 public Object handle(ClientInvocationHandler theTarget, Object[] theArgs) { 134 Object interceptor = theArgs[0]; 135 theTarget.unregisterInterceptor(interceptor); 136 return null; 137 } 138 } 139 140}