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