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}