org.codehaus.groovy.runtime.Invoker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of groovy-all-minimal Show documentation
Show all versions of groovy-all-minimal Show documentation
Groovy: A powerful, dynamic language for the JVM
/*
* Copyright 2003-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.codehaus.groovy.runtime;
import groovy.lang.*;
import org.codehaus.groovy.runtime.wrappers.PojoWrapper;
/**
* A helper class to invoke methods or extract properties on arbitrary Java objects dynamically
*
* @author James Strachan
* @version $Revision: 9487 $
*/
public class Invoker {
protected static final Object[] EMPTY_ARGUMENTS = {
};
protected static final Class[] EMPTY_TYPES = {
};
public MetaClassRegistry getMetaRegistry() {
return metaRegistry;
}
private final MetaClassRegistry metaRegistry = GroovySystem.getMetaClassRegistry();
public MetaClass getMetaClass(Object object) {
return metaRegistry.getMetaClass(object.getClass());
}
/**
* Invokes the given method on the object.
*/
public Object invokeMethod(Object object, String methodName, Object arguments) {
/*
System
.out
.println(
"Invoker - Invoking method on object: "
+ object
+ " method: "
+ methodName
+ " arguments: "
+ InvokerHelper.toString(arguments));
*/
if (object == null) {
object = NullObject.getNullObject();
//throw new NullPointerException("Cannot invoke method " + methodName + "() on null object");
}
// if the object is a Class, call a static method from that class
if (object instanceof Class) {
Class theClass = (Class) object;
MetaClass metaClass = metaRegistry.getMetaClass(theClass);
return metaClass.invokeStaticMethod(object, methodName, asArray(arguments));
}
else // it's an instance
{
// if it's not an object implementing GroovyObject (thus not builder, nor a closure)
if (!(object instanceof GroovyObject)) {
return invokePojoMethod(object, methodName, arguments);
}
// it's an object implementing GroovyObject
else {
return invokePogoMethod(object, methodName, arguments);
}
}
}
private Object invokePojoMethod(Object object, String methodName, Object arguments) {
Class theClass = object.getClass();
MetaClass metaClass = metaRegistry.getMetaClass(theClass);
return metaClass.invokeMethod(object, methodName, asArray(arguments));
}
private Object invokePogoMethod(Object object, String methodName, Object arguments) {
GroovyObject groovy = (GroovyObject) object;
boolean intercepting = groovy instanceof GroovyInterceptable;
try {
// if it's a pure interceptable object (even intercepting toString(), clone(), ...)
if (intercepting) {
return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
}
//else try a statically typed method or a GDK method
return groovy.getMetaClass().invokeMethod(object, methodName, asArray(arguments));
} catch (MissingMethodException e) {
if (!intercepting && e.getMethod().equals(methodName) && object.getClass() == e.getType()) {
// in case there's nothing else, invoke the object's own invokeMethod()
return groovy.invokeMethod(methodName, asUnwrappedArray(arguments));
}
throw e;
}
}
public Object invokeSuperMethod(Object object, String methodName, Object arguments) {
if (object == null) {
throw new NullPointerException("Cannot invoke method " + methodName + "() on null object");
}
Class theClass = object.getClass();
MetaClass metaClass = metaRegistry.getMetaClass(theClass.getSuperclass());
return metaClass.invokeMethod(object, methodName, asArray(arguments));
}
public Object invokeStaticMethod(Class type, String method, Object arguments) {
MetaClass metaClass = metaRegistry.getMetaClass(type);
return metaClass.invokeStaticMethod(type, method, asArray(arguments));
}
public Object invokeConstructorOf(Class type, Object arguments) {
MetaClass metaClass = metaRegistry.getMetaClass(type);
return metaClass.invokeConstructor(asArray(arguments));
}
/**
* Converts the given object into an array; if its an array then just
* cast otherwise wrap it in an array
*/
public Object[] asArray(Object arguments) {
if (arguments == null) {
return EMPTY_ARGUMENTS;
}
if (arguments instanceof Object[]) {
return (Object[]) arguments;
}
return new Object[]{arguments};
}
public Object[] asUnwrappedArray(Object arguments) {
Object[] args = asArray(arguments);
for (int i=0; i