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