* call. These arguments should match standard optional parameters (Closure, Object, Map).
* If there are it will then try to call the method on the current node (if any). Otherwise it will attempt to find a class in
* via {@link ObjectFactoryInstantiator#instantiateNode(ObjectFactoryInterceptor, String, Object)}.
*/
public Object handleInvokedMethod(InterceptorContext<T, S> ctx) {
MetaMethod method = ctx.getMetaMethod();
T builder = ctx.getBuilder();
S stack = ctx.getStack();
Object[] args = ctx.getArgs();
String name = ctx.getMethodName();
// If we should attempt method calls on the builder first
// we will do so, only catching MME's, other exceptions mean
// the method was probably called and should be propagated.
if (method != null && !callProxyFirst) try {
return method.invoke(builder, args);
} catch (MissingMethodException mme) {}
Closure closure = null;
Object nodeInstance = stack.getCurrent();
Map attributes = null;
// If this is not the first node we want to try
// to invoke a method corresponding to the node object.
if (nodeInstance != null) {
try {
return InvokerHelper.invokeMethod(nodeInstance, name, args);
} catch (MissingMethodException e) {
if (attemptBinding)
try { return builder.getBinding().invokeMethod(name, args); }
catch (MissingMethodException ee) {}
catch (MissingPropertyException ee) {}
}
nodeInstance = null;
}
// If this is a three argument or less having unique arguments being one of
// Object, Map or Closure then this can be considered a valid node invocation
// from the builder source.
if (args.length <= 3) {
try {
Map<Class, Object> ps = ParameterUtil.scan(args, Closure.class, Map.class, Object.class);
closure = (Closure) ps.get(Closure.class);
attributes = (Map) ps.get(Map.class);
if (ps.containsKey(Object.class)) {
if (attributes == null) attributes = new HashMap();
attributes.put("value", ps.get(Object.class));
}
nodeInstance = this.instantiator.instantiateNode(builder, this, name, stack.getCurrent());
} catch (InvalidParameterException e) {}
}
// If a node object was created then we want to push it onto the stack, call
// the closure if one was passed and then pop it off the stack.
if (nodeInstance != null) {
return this.handleNode(builder, stack, name, nodeInstance, attributes, closure);
}
// If no node instance could be created then we will
// do a last attempt (if not already attempted above)
// to call the method on the builder
if (method != null && callProxyFirst) return method.invoke(builder, args);
// If we get here we have attempted all methods for valid invocation
// thus we must throw a MME
throw new MissingMethodException(name, builder.getClass(), args);