/**
* Dispatches a client request made on a proxy
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Interceptor headInterceptor = null;
ConfigHolder holder = configuration.get(method);
if (holder == null) {
TargetException e = new TargetException("Operation not configured");
e.setIdentifier(method.getName());
throw e;
}
InvocationConfiguration config = holder.config;
if (config != null) {
headInterceptor = config.getHeadInterceptor();
}
TargetInvoker invoker;
if (holder.cachedInvoker == null) {
assert config != null;
if(config.getTargetInvoker() == null){
TargetException e= new TargetException("No target invoker configured for operation");
e.setIdentifier(config.getMethod().getName());
throw e;
}
if (config.getTargetInvoker().isCacheable()) {
// clone and store the invoker locally
holder.cachedInvoker = (TargetInvoker) config.getTargetInvoker().clone();
invoker = holder.cachedInvoker;
} else {
invoker = config.getTargetInvoker();
}
} else {
assert config != null;
invoker = config.getTargetInvoker();
}
if (headInterceptor == null) {
try {
// short-circuit the dispatch and invoke the target directly
if (config.getTargetInvoker() == null) {
throw new AssertionError("No target invoker [" + method.getName() + "]");
}
return config.getTargetInvoker().invokeTarget(args);
} catch (InvocationTargetException e) {
// the cause was thrown by the target so throw it
throw e.getCause();
}
} else {
Message msg = messageFactory.createMessage();
msg.setTargetInvoker(invoker);
msg.setBody(args);
// dispatch the wire down the chain and get the response
Message resp = headInterceptor.invoke(msg);
Object body = resp.getBody();
if (body instanceof Throwable) {
throw (Throwable) body;
}