Package org.jruby.java.invokers

Source Code of org.jruby.java.invokers.ConstructorInvoker

package org.jruby.java.invokers;

import java.lang.reflect.Constructor;
import org.jruby.javasupport.*;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.RubyProc;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;

public class ConstructorInvoker extends RubyToJavaInvoker {
    private Constructor[] ctors;
   
    public ConstructorInvoker(RubyModule host, List<Constructor> methods) {
        super(host);
        this.ctors = methods.toArray(new Constructor[methods.size()]);
       
        if (!Ruby.isSecurityRestricted()) {
            Method.setAccessible(this.ctors, true);
        }
    }

    // TODO: varargs?
    synchronized void createJavaCallables(Ruby runtime) {
        if (!initialized) { // read-volatile
            if (ctors != null) {
                if (ctors.length == 1) {
                    javaCallable = JavaConstructor.create(runtime, ctors[0]);
                } else {
                    Map methodsMap = new HashMap();
                    int maxArity = 0;
                    for (Constructor ctor: ctors) {
                        // TODO: deal with varargs
                        int arity = ctor.getParameterTypes().length;
                        maxArity = Math.max(arity, maxArity);
                        List<JavaConstructor> methodsForArity = (ArrayList<JavaConstructor>)methodsMap.get(arity);
                        if (methodsForArity == null) {
                            methodsForArity = new ArrayList<JavaConstructor>();
                            methodsMap.put(arity,methodsForArity);
                        }
                        methodsForArity.add(JavaConstructor.create(runtime,ctor));
                    }
                    javaCallables = new JavaConstructor[maxArity + 1][];
                    for (Iterator<Map.Entry> iter = methodsMap.entrySet().iterator(); iter.hasNext();) {
                        Map.Entry entry = iter.next();
                        List<JavaConstructor> ctorsForArity = (List<JavaConstructor>)entry.getValue();

                        JavaConstructor[] methodsArray = ctorsForArity.toArray(new JavaConstructor[ctorsForArity.size()]);
                        javaCallables[((Integer)entry.getKey()).intValue()] = methodsArray;
                    }
                }
                ctors = null;

                // initialize cache of parameter types to method
                cache = new ConcurrentHashMap();
            }
            initialized = true; // write-volatile
        }
    }
   
    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
        createJavaCallables(self.getRuntime());

        int len = args.length;
        Object[] convertedArgs = new Object[len];
        JavaConstructor callable = (JavaConstructor)findCallable(self, name, args, len);
        Class[] targetTypes = callable.getParameterTypes();
        for (int i = len; --i >= 0;) {
            convertedArgs[i] = JavaUtil.convertArgumentToType(context, args[i], targetTypes[i]);
        }
       
        Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));
       
        return self;
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
        createJavaCallables(self.getRuntime());
        JavaConstructor callable = (JavaConstructor)findCallableArityZero(self, name);
       
        Java.JavaUtilities.set_java_object(self, self, callable.new_instance(EMPTY_OBJECT_ARRAY));
       
        return self;
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0) {
        createJavaCallables(self.getRuntime());
        Object[] convertedArgs = new Object[1];
        JavaConstructor callable = (JavaConstructor)findCallableArityOne(self, name, arg0);
        convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
       
        Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));
       
        return self;
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, IRubyObject arg1) {
        createJavaCallables(self.getRuntime());
        Object[] convertedArgs = new Object[2];
        JavaConstructor callable = (JavaConstructor)findCallableArityTwo(self, name, arg0, arg1);
        convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
        convertedArgs[1] = JavaUtil.convertArgumentToType(context, arg1, callable.getParameterTypes()[1]);
       
        Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));
       
        return self;
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2) {
        createJavaCallables(self.getRuntime());
        Object[] convertedArgs = new Object[3];
        JavaConstructor callable = (JavaConstructor)findCallableArityThree(self, name, arg0, arg1, arg2);
        convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
        convertedArgs[1] = JavaUtil.convertArgumentToType(context, arg1, callable.getParameterTypes()[1]);
        convertedArgs[2] = JavaUtil.convertArgumentToType(context, arg2, callable.getParameterTypes()[2]);
       
        Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));
       
        return self;
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
        createJavaCallables(self.getRuntime());
        if (block.isGiven()) {
            int len = args.length;
            Object[] convertedArgs = new Object[len + 1];
            IRubyObject[] intermediate = new IRubyObject[len + 1];
            System.arraycopy(args, 0, intermediate, 0, len);
            intermediate[len] = RubyProc.newProc(self.getRuntime(), block, Block.Type.LAMBDA);
            JavaConstructor callable = (JavaConstructor)findCallable(self, name, intermediate, len + 1);
            for (int i = 0; i < len + 1; i++) {
                convertedArgs[i] = JavaUtil.convertArgumentToType(context, intermediate[i], callable.getParameterTypes()[i]);
            }
       
            Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));

            return self;
        } else {
            return call(context, self, clazz, name, args);
        }
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, Block block) {
        createJavaCallables(self.getRuntime());
        if (block.isGiven()) {
            Object[] convertedArgs = new Object[1];
            RubyProc proc = RubyProc.newProc(self.getRuntime(), block, Block.Type.LAMBDA);
            JavaConstructor callable = (JavaConstructor)findCallableArityOne(self, name, proc);
            convertedArgs[0] = JavaUtil.convertArgumentToType(context, proc, callable.getParameterTypes()[0]);
       
            Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));

            return self;
        } else {
            return call(context, self, clazz, name);
        }
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, Block block) {
        createJavaCallables(self.getRuntime());
        if (block.isGiven()) {
            Object[] convertedArgs = new Object[2];
            RubyProc proc = RubyProc.newProc(self.getRuntime(), block, Block.Type.LAMBDA);
            JavaConstructor callable = (JavaConstructor)findCallableArityTwo(self, name, arg0, proc);
            convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
            convertedArgs[1] = JavaUtil.convertArgumentToType(context, proc, callable.getParameterTypes()[1]);
       
            Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));

            return self;
        } else {
            return call(context, self, clazz, name, arg0);
        }
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, IRubyObject arg1, Block block) {
        createJavaCallables(self.getRuntime());
        if (block.isGiven()) {
            Object[] convertedArgs = new Object[3];
            RubyProc proc = RubyProc.newProc(self.getRuntime(), block, Block
                    .Type.LAMBDA);
            JavaConstructor callable = (JavaConstructor)findCallableArityThree(self, name, arg0, arg1, proc);
            convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
            convertedArgs[1] = JavaUtil.convertArgumentToType(context, arg1, callable.getParameterTypes()[1]);
            convertedArgs[2] = JavaUtil.convertArgumentToType(context, proc, callable.getParameterTypes()[2]);
       
            Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));

            return self;
        } else {
            return call(context, self, clazz, name, arg0, arg1);
        }
    }

    public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, IRubyObject arg1, IRubyObject arg2, Block block) {
        createJavaCallables(self.getRuntime());
        if (block.isGiven()) {
            Object[] convertedArgs = new Object[4];
            RubyProc proc = RubyProc.newProc(self.getRuntime(), block, Block.Type.LAMBDA);
            JavaConstructor callable = (JavaConstructor)findCallableArityFour(self, name, arg0, arg1, arg2, proc);
            convertedArgs[0] = JavaUtil.convertArgumentToType(context, arg0, callable.getParameterTypes()[0]);
            convertedArgs[1] = JavaUtil.convertArgumentToType(context, arg1, callable.getParameterTypes()[1]);
            convertedArgs[2] = JavaUtil.convertArgumentToType(context, arg2, callable.getParameterTypes()[2]);
            convertedArgs[3] = JavaUtil.convertArgumentToType(context, proc, callable.getParameterTypes()[3]);
       
            Java.JavaUtilities.set_java_object(self, self, callable.new_instance(convertedArgs));

            return self;
        } else {
            return call(context, self, clazz, name, arg0, arg1, arg2);
        }
    }
}
TOP

Related Classes of org.jruby.java.invokers.ConstructorInvoker

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.