001package org.kohsuke.stapler.jelly.jruby;
002
003import org.jruby.RubyModule;
004import org.jruby.internal.runtime.methods.DynamicMethod;
005import org.jruby.javasupport.Java;
006import org.jruby.runtime.builtin.IRubyObject;
007import org.kohsuke.stapler.lang.MethodRef;
008
009import java.lang.annotation.Annotation;
010import java.lang.reflect.InvocationTargetException;
011import javax.annotation.Nonnull;
012
013/**
014 * @author Kohsuke Kawaguchi
015 */
016public class RubyMethodRef extends MethodRef {
017    @Nonnull
018    private final RubyModule klass;
019    @Nonnull
020    private final DynamicMethod method;
021
022
023    public RubyMethodRef(@Nonnull RubyModule klass, @Nonnull DynamicMethod method) {
024        this.klass = klass;
025        this.method = method;
026    }
027
028    /**
029     * Retrieves the Ruby module (aka class), for which the method is declared.
030     * @return Ruby module, which stores the method reference
031     * @since 1.248
032     */
033    @Nonnull
034    public RubyModule getKlass() {
035        return klass;
036    }
037    
038    /**
039     * Retrieves the referenced method.
040     * @return Referenced method
041     * @since 1.248
042     */
043    @Nonnull
044    public DynamicMethod getMethod() {
045        return method;
046    }
047
048    @Override
049    public String getName() {
050        return method.getName();
051    }
052    
053    @Override
054    public <T extends Annotation> T getAnnotation(Class<T> type) {
055        // TODO: what's the equivalent in JRuby?
056        return null;
057    }
058
059    @Override
060    public Object invoke(Object _this, Object... args) throws InvocationTargetException, IllegalAccessException {
061        IRubyObject[] argList = new IRubyObject[args.length];
062        for (int i=0; i<args.length; i++)
063            argList[i] = Java.getInstance(klass.getRuntime(),args[i]);
064        return method.call(klass.getRuntime().getCurrentContext() , (IRubyObject)_this, klass, method.getName(), argList);
065    }
066}