package org.xbib.elasticsearch.helper.client;
import org.elasticsearch.common.settings.Settings;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public final class ClientInvocationHandler implements InvocationHandler {
private static final Object[] NO_ARGS = new Object[0];
private final Settings settings;
private final RemoteInvoker remoteInvoker;
private final Class<?> interfaceClass;
public ClientInvocationHandler(RemoteInvoker remoteInvoker, Class<?> interfaceClass,
Settings settings) {
this.settings = settings;
this.remoteInvoker = remoteInvoker;
this.interfaceClass = interfaceClass;
}
public Settings getSettings() {
return settings;
}
public Class<?> interfaceClass() {
return interfaceClass;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final Class<?> declaringClass = method.getDeclaringClass();
if (declaringClass == Object.class) {
return invokeObjectMethod(proxy, method, args);
}
assert declaringClass == interfaceClass;
return invokeClientMethod(method, args);
}
private Object invokeObjectMethod(Object proxy, Method method, Object[] args) {
final String methodName = method.getName();
switch (methodName) {
case "toString":
return interfaceClass.getSimpleName() + '(' + settings.getAsMap() + ')';
case "hashCode":
return System.identityHashCode(proxy);
case "equals":
return proxy == args[0];
default:
throw new Error("unknown method: " + methodName);
}
}
private Object invokeClientMethod(Method method, Object[] args) throws Throwable {
if (args == null) {
args = NO_ARGS;
}
Future<Object> resultFuture = remoteInvoker.invoke(settings, method, args);
return method.getReturnType().isInstance(resultFuture) ? resultFuture : null;
}
}