All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.groovy.runtime.Invoker Maven / Gradle / Ivy

There is a newer version: 1.5.8
Show newest version
/*
 * 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




© 2015 - 2024 Weber Informatics LLC | Privacy Policy