use of groovy.lang.ProxyMetaClass in project groovy by apache.
the class ClosureMetaClass method invokeMethod.
@Override
public Object invokeMethod(final Class sender, final Object object, final String methodName, final Object[] originalArguments, final boolean isCallToSuper, final boolean fromInsideClass) {
checkInitalised();
if (object == null) {
throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
}
final Object[] arguments = makeArguments(originalArguments, methodName);
final Class<?>[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
unwrap(arguments);
MetaMethod method = null;
final Closure<?> closure = (Closure<?>) object;
final int resolveStrategy = closure.getResolveStrategy();
if (CLOSURE_DO_CALL_METHOD.equals(methodName) || CLOSURE_CALL_METHOD.equals(methodName)) {
method = pickClosureMethod(argClasses);
if (method == null && arguments.length == 1 && arguments[0] instanceof List) {
Object[] newArguments = ((List<?>) arguments[0]).toArray();
Class<?>[] newArgClasses = MetaClassHelper.convertToTypeArray(newArguments);
method = createTransformMetaMethod(pickClosureMethod(newArgClasses));
}
if (method == null)
throw new MissingMethodException(methodName, theClass, arguments, false);
}
boolean shouldDefer = resolveStrategy == Closure.DELEGATE_ONLY && isInternalMethod(methodName);
if (method == null && !shouldDefer) {
method = CLOSURE_METACLASS.pickMethod(methodName, argClasses);
}
if (method != null)
return method.doMethodInvoke(object, arguments);
MissingMethodException last = null;
Object callObject = object;
final Object owner = closure.getOwner();
final Object delegate = closure.getDelegate();
boolean invokeOnDelegate = false;
boolean invokeOnOwner = false;
boolean ownerFirst = true;
switch(resolveStrategy) {
case Closure.TO_SELF:
break;
case Closure.DELEGATE_ONLY:
method = getDelegateMethod(closure, delegate, methodName, argClasses);
callObject = delegate;
if (method == null) {
invokeOnDelegate = delegate != closure && (delegate instanceof GroovyObject);
}
break;
case Closure.OWNER_ONLY:
method = getDelegateMethod(closure, owner, methodName, argClasses);
callObject = owner;
if (method == null) {
invokeOnOwner = owner != closure && (owner instanceof GroovyObject);
}
break;
case Closure.DELEGATE_FIRST:
method = getDelegateMethod(closure, delegate, methodName, argClasses);
callObject = delegate;
if (method == null) {
invokeOnDelegate = delegate != closure;
invokeOnOwner = owner != closure;
ownerFirst = false;
}
break;
default:
// Closure.OWNER_FIRST:
method = getDelegateMethod(closure, owner, methodName, argClasses);
callObject = owner;
if (method == null) {
invokeOnDelegate = delegate != closure;
invokeOnOwner = owner != closure;
ownerFirst = true;
}
break;
}
if (method == null && (invokeOnOwner || invokeOnDelegate)) {
try {
if (ownerFirst) {
return invokeOnDelegationObjects(invokeOnOwner, owner, invokeOnDelegate, delegate, methodName, arguments);
} else {
return invokeOnDelegationObjects(invokeOnDelegate, delegate, invokeOnOwner, owner, methodName, arguments);
}
} catch (MissingMethodException mme) {
last = mme;
}
}
if (method != null) {
MetaClass metaClass = registry.getMetaClass(callObject.getClass());
if (metaClass instanceof ProxyMetaClass) {
return metaClass.invokeMethod(callObject, methodName, arguments);
} else {
return method.doMethodInvoke(callObject, arguments);
}
} else {
// no method was found; try to find a closure defined as a field of the class and run it
Object value = null;
try {
value = getProperty(sender, object, methodName, isCallToSuper, fromInsideClass);
} catch (MissingPropertyException mpe) {
// ignore
}
if (value instanceof Closure) {
// This test ensures that value != this If you ever change this ensure that value != this
Closure<?> cl = (Closure<?>) value;
MetaClass delegateMetaClass = cl.getMetaClass();
return delegateMetaClass.invokeMethod(cl.getClass(), closure, CLOSURE_DO_CALL_METHOD, originalArguments, false, fromInsideClass);
}
}
throw last != null ? last : new MissingMethodException(methodName, theClass, arguments, false);
}
Aggregations