View Javadoc
1   package ca.uhn.fhir.rest.client;
2   
3   /*
4    * #%L
5    * HAPI FHIR - Core Library
6    * %%
7    * Copyright (C) 2014 University Health Network
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import java.lang.reflect.InvocationHandler;
24  import java.lang.reflect.Method;
25  import java.util.HashMap;
26  import java.util.Map;
27  
28  import org.apache.http.client.HttpClient;
29  
30  import ca.uhn.fhir.context.ConfigurationException;
31  import ca.uhn.fhir.context.FhirContext;
32  import ca.uhn.fhir.rest.client.api.IRestfulClient;
33  import ca.uhn.fhir.rest.method.BaseMethodBinding;
34  import ca.uhn.fhir.rest.server.EncodingEnum;
35  
36  public class ClientInvocationHandler extends BaseClient implements InvocationHandler {
37  
38  	private final Map<Method, BaseMethodBinding<?>> myBindings = new HashMap<Method, BaseMethodBinding<?>>();
39  
40  	private final Map<Method, ILambda> myMethodToLambda = new HashMap<Method, ILambda>();
41  
42  	private final Map<Method, Object> myMethodToReturnValue = new HashMap<Method, Object>();
43  
44  	private FhirContext myContext;
45  
46  	public ClientInvocationHandler(HttpClient theClient, FhirContext theContext, String theUrlBase, Class<? extends IRestfulClient> theClientType) {
47  		super(theClient, theUrlBase);
48  
49  		myContext =theContext;
50  		
51  		try {
52  			myMethodToReturnValue.put(theClientType.getMethod("getFhirContext"), theContext);
53  			myMethodToReturnValue.put(theClientType.getMethod("getHttpClient"), theClient);
54  			myMethodToReturnValue.put(theClientType.getMethod("getServerBase"), theUrlBase);
55  
56  			myMethodToLambda.put(theClientType.getMethod("setEncoding", EncodingEnum.class), new SetEncodingLambda());
57  			myMethodToLambda.put(theClientType.getMethod("setPrettyPrint", boolean.class), new SetPrettyPrintLambda());
58  			myMethodToLambda.put(theClientType.getMethod("registerInterceptor", IClientInterceptor.class), new RegisterInterceptorLambda());
59  			myMethodToLambda.put(theClientType.getMethod("unregisterInterceptor", IClientInterceptor.class), new UnregisterInterceptorLambda());
60  
61  		} catch (NoSuchMethodException e) {
62  			throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!", e);
63  		} catch (SecurityException e) {
64  			throw new ConfigurationException("Failed to find methods on client. This is a HAPI bug!", e);
65  		}
66  	}
67  
68  	public void addBinding(Method theMethod, BaseMethodBinding<?> theBinding) {
69  		myBindings.put(theMethod, theBinding);
70  	}
71  
72  	@Override
73  	public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
74  		Object directRetVal = myMethodToReturnValue.get(theMethod);
75  		if (directRetVal != null) {
76  			return directRetVal;
77  		}
78  
79  		BaseMethodBinding<?> binding = myBindings.get(theMethod);
80  		if (binding != null) {
81  			BaseHttpClientInvocation clientInvocation = binding.invokeClient(theArgs);
82  			return invokeClient(myContext, binding, clientInvocation);
83  		}
84  
85  		ILambda lambda = myMethodToLambda.get(theMethod);
86  		if (lambda != null) {
87  			return lambda.handle(theArgs);
88  		}
89  
90  		throw new UnsupportedOperationException("The method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getSimpleName() + " has no handler. Did you forget to annotate it with a RESTful method annotation?");
91  	}
92  
93  	private interface ILambda {
94  		Object handle(Object[] theArgs);
95  	}
96  
97  	private class SetEncodingLambda implements ILambda {
98  		@Override
99  		public Object handle(Object[] theArgs) {
100 			EncodingEnum encoding = (EncodingEnum) theArgs[0];
101 			setEncoding(encoding);
102 			return null;
103 		}
104 	}
105 
106 	private class SetPrettyPrintLambda implements ILambda {
107 		@Override
108 		public Object handle(Object[] theArgs) {
109 			Boolean prettyPrint = (Boolean) theArgs[0];
110 			setPrettyPrint(prettyPrint);
111 			return null;
112 		}
113 	}
114 	private class UnregisterInterceptorLambda implements ILambda {
115 		@Override
116 		public Object handle(Object[] theArgs) {
117 			IClientInterceptor interceptor = (IClientInterceptor) theArgs[0];
118 			unregisterInterceptor(interceptor);
119 			return null;
120 		}
121 	}
122 
123 	private class RegisterInterceptorLambda implements ILambda {
124 		@Override
125 		public Object handle(Object[] theArgs) {
126 			IClientInterceptor interceptor = (IClientInterceptor) theArgs[0];
127 			registerInterceptor(interceptor);
128 			return null;
129 		}
130 	}
131 
132 }