1
2
3
4
5
6
7
8
9
10
11
12
13
14 package org.gbif.ws.client;
15
16 import java.lang.reflect.InvocationHandler;
17 import java.lang.reflect.Method;
18 import java.lang.reflect.Proxy;
19 import java.util.Map;
20 import java.util.Optional;
21
22 import feign.InvocationHandlerFactory;
23 import feign.Target;
24
25 import static feign.Util.checkNotNull;
26
27 @SuppressWarnings("unused")
28 public class ClientInvocationHandlerFactory implements InvocationHandlerFactory {
29
30 @Override
31 public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
32 return new ClientInvocationHandlerFactory.FeignInvocationHandler(target, dispatch);
33 }
34
35 static class FeignInvocationHandler implements InvocationHandler {
36
37 private final Target target;
38 private final Map<Method, MethodHandler> dispatch;
39
40 FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
41 this.target = checkNotNull(target, "target");
42 this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
43 }
44
45 @Override
46 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
47 if ("equals".equals(method.getName())) {
48 try {
49 Object otherHandler =
50 args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
51 return equals(otherHandler);
52 } catch (IllegalArgumentException e) {
53 return false;
54 }
55 } else if ("hashCode".equals(method.getName())) {
56 return hashCode();
57 } else if ("toString".equals(method.getName())) {
58 return toString();
59 }
60
61 return getMethodHandler(method).invoke(args);
62 }
63
64 private MethodHandler getMethodHandler(Method method) {
65 MethodHandler methodHandler = dispatch.get(method);
66
67
68 if (methodHandler != null) {
69 return methodHandler;
70 }
71
72
73 Optional<Method> anotherMethod =
74 dispatch.keySet().stream()
75 .filter(methodFromDispatch -> !methodFromDispatch.equals(method))
76 .filter(methodFromDispatch -> methodFromDispatch.getName().equals(method.getName()))
77 .filter(
78 methodFromDispatch ->
79 methodFromDispatch.getParameterCount() == method.getParameterCount())
80 .findFirst();
81
82 return anotherMethod.map(dispatch::get).orElse(null);
83 }
84
85 @Override
86 public boolean equals(Object obj) {
87 if (obj instanceof ClientInvocationHandlerFactory.FeignInvocationHandler) {
88 ClientInvocationHandlerFactory.FeignInvocationHandler other =
89 (ClientInvocationHandlerFactory.FeignInvocationHandler) obj;
90 return target.equals(other.target);
91 }
92 return false;
93 }
94
95 @Override
96 public int hashCode() {
97 return target.hashCode();
98 }
99
100 @Override
101 public String toString() {
102 return target.toString();
103 }
104 }
105 }