Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  package org.jruby.java.invokers;
  
  import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import org.jruby.Ruby;
 
 public abstract class RubyToJavaInvoker extends JavaMethod {
     protected static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
     protected final JavaCallable javaCallable;
     protected final JavaCallable[][] javaCallables;
     protected final JavaCallable[] javaVarargsCallables;
     protected final int minVarargsArity;
     protected final Map cache;
     protected final Ruby runtime;
     private Member[] members;
     
     RubyToJavaInvoker(RubyModule hostMember[] members) {
         super(host..);
         this. = members;
         this. = host.getRuntime();
         // we set all Java methods to optional, since many/most have overloads
         setArity(.);
 
         Ruby runtime = host.getRuntime();
 
         // initialize all the callables for this method
         JavaCallable callable = null;
         JavaCallable[][] callables = null;
         JavaCallable[] varargsCallables = null;
         int varargsArity = .;
         
         if (members.length == 1) {
             callable = createCallable(runtimemembers[0]);
             if (callable.isVarArgs()) {
                 varargsCallables = createCallableArray(callable);
             }
         } else {
             Map<IntegerList<JavaCallable>> methodsMap = new HashMap<IntegerList<JavaCallable>>();
             List<JavaCallablevarargsMethods = new ArrayList();
             int maxArity = 0;
             for (Member methodmembers) {
                 int currentArity = getMemberParameterTypes(method).length;
                 maxArity = Math.max(currentAritymaxArity);
                 List<JavaCallablemethodsForArity = methodsMap.get(currentArity);
                 if (methodsForArity == null) {
                     methodsForArity = new ArrayList<JavaCallable>();
                     methodsMap.put(currentArity,methodsForArity);
                 }
                 JavaCallable javaMethod = createCallable(runtime,method);
                 methodsForArity.add(javaMethod);
 
                 if (isMemberVarArgs(method)) {
                     varargsArity = Math.min(currentArity - 1, varargsArity);
                     varargsMethods.add(javaMethod);
                 }
             }
 
             callables = createCallableArrayArray(maxArity + 1);
             for (Map.Entry<Integer,List<JavaCallable>> entry : methodsMap.entrySet()) {
                 List<JavaCallablemethodsForArity = (List<JavaCallable>)entry.getValue();
 
                 JavaCallable[] methodsArray = methodsForArity.toArray(createCallableArray(methodsForArity.size()));
                 callables[((Integer)entry.getKey()).intValue()] = methodsArray;
             }
 
             if (varargsMethods.size() > 0) {
                 // have at least one varargs, build that map too
                 varargsCallables = createCallableArray(varargsMethods.size());
                 varargsMethods.toArray(varargsCallables);
             }
         }
         members = null;
 
         // initialize cache of parameter types to method
         // FIXME: No real reason to use CHM, is there?
          = new ConcurrentHashMap(0, 0.75f, 1);
 
         this. = callable;
         this. = callables;
         this. = varargsCallables;
        this. = varargsArity;
        
        // if it's not overloaded, set up a NativeCall
        if ( != null) {
            // no constructor support yet
            if ( instanceof org.jruby.javasupport.JavaMethod) {
                org.jruby.javasupport.JavaMethod javaMethod = (org.jruby.javasupport.JavaMethod);
                Method method = (Method)javaMethod.getValue();
                // only public, since non-public don't bind
                if (Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
                    setNativeCall(method.getDeclaringClass(), method.getName(), method.getReturnType(), method.getParameterTypes(), Modifier.isStatic(method.getModifiers()), true);
                }
            }
        } else {
            // use the lowest-arity non-overload
            for (JavaCallable[] callablesForArity : ) {
                if (callablesForArity != null
                        && callablesForArity.length == 1
                        && callablesForArity[0] instanceof org.jruby.javasupport.JavaMethod) {
                    Method method = (Method)((org.jruby.javasupport.JavaMethod)callablesForArity[0]).getValue();
                    // only public, since non-public don't bind
                    if (Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers())) {
                        setNativeCall(method.getDeclaringClass(), method.getName(), method.getReturnType(), method.getParameterTypes(), Modifier.isStatic(method.getModifiers()), true);
                    }
                }
            }
        }
    }
    protected Member[] getMembers() {
        return ;
    }
    protected AccessibleObject[] getAccessibleObjects() {
        return (AccessibleObject[])getMembers();
    }
    protected abstract JavaCallable createCallable(Ruby rubyMember member);
    protected abstract JavaCallable[] createCallableArray(JavaCallable callable);
    protected abstract JavaCallable[] createCallableArray(int size);
    protected abstract JavaCallable[][] createCallableArrayArray(int size);
    protected abstract Class[] getMemberParameterTypes(Member member);
    protected abstract boolean isMemberVarArgs(Member member);
    static Object convertArg(IRubyObject argJavaCallable methodint index) {
        return arg.toJava(method.getParameterTypes()[index]);
    }
    static Object convertVarargs(IRubyObject[] argsJavaCallable method) {
        Class[] types = method.getParameterTypes();
        Class varargArrayType = types[types.length - 1];
        Class varargType = varargArrayType.getComponentType();
        int varargsStart = types.length - 1;
        int varargsCount = args.length - varargsStart;
        Object varargs;
        if (args.length == 0) {
            return Array.newInstance(varargType, 0);
        } else if (varargsCount == 1 && args[varargsStartinstanceof ArrayJavaProxy) {
            // we may have a pre-created array to pass; try that first
            varargs = args[varargsStart].toJava(varargArrayType);
        } else {
            varargs = Array.newInstance(varargTypevarargsCount);
            for (int i = 0; i < varargsCounti++) {
                Array.set(varargsiargs[varargsStart + i].toJava(varargType));
            }
        }
        return varargs;
    }
    static JavaProxy castJavaProxy(IRubyObject self) {
        assert self instanceof JavaProxy : "Java methods can only be invoked on Java objects";
        return (JavaProxy)self;
    }
    static void trySetAccessible(AccessibleObject[] accObjs) {
        if (!Ruby.isSecurityRestricted()) {
            try {
                AccessibleObject.setAccessible(accObjstrue);
            } catch(SecurityException e) {}
        }
    }
    void raiseNoMatchingCallableError(String nameIRubyObject proxyObject... args) {
        int len = args.length;
        Class[] argTypes = new Class[args.length];
        for (int i = 0; i < leni++) {
            argTypes[i] = args[i].getClass();
        }
        throw proxy.getRuntime().newArgumentError("no " + name + " with arguments matching " + Arrays.toString(argTypes) + " on object " + proxy.getMetaClass());
    }
    protected JavaCallable findCallable(IRubyObject selfString nameIRubyObject[] argsint arity) {
        JavaCallable callable;
        if ((callable = ) == null) {
            JavaCallable[] callablesForArity = null;
            if (arity >= . || (callablesForArity = [arity]) == null) {
                if ( != null) {
                    callable = CallableSelector.matchingCallableArityN(argsarity);
                    if (callable == null) {
                        throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), self, (Object[])args);
                    }
                    return callable;
                } else {
                    throw self.getRuntime().newArgumentError(args.length. - 1);
                }
            }
            callable = CallableSelector.matchingCallableArityN(callablesForArityargsarity);
            if (callable == null &&  != null) {
                callable = CallableSelector.matchingCallableArityN(argsarity);
                if (callable == null) {
                    throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), self, (Object[])args);
                }
                return callable;
            }
            if (callable == null) {
                throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), selfcallablesForArity, (Object[])args);
            }
        } else {
            if (!callable.isVarArgs() && callable.getParameterTypes().length != args.length) {
                throw self.getRuntime().newArgumentError(args.lengthcallable.getParameterTypes().length);
            }
        }
        return callable;
    }
    protected JavaCallable findCallableArityZero(IRubyObject selfString name) {
        JavaCallable callable;
        if ((callable = ) == null) {
            // TODO: varargs?
            JavaCallable[] callablesForArity = null;
            if (. == 0 || (callablesForArity = [0]) == null) {
                raiseNoMatchingCallableError(nameself);
            }
            callable = callablesForArity[0];
        } else {
            if (callable.getParameterTypes().length != 0) {
                throw self.getRuntime().newArgumentError(0, callable.getParameterTypes().length);
            }
        }
        return callable;
    }
    protected JavaCallable findCallableArityOne(IRubyObject selfString nameIRubyObject arg0) {
        JavaCallable callable;
        if ((callable = ) == null) {
            // TODO: varargs?
            JavaCallable[] callablesForArity = null;
            if (. <= 1 || (callablesForArity = [1]) == null) {
                throw self.getRuntime().newArgumentError(1, . - 1);
            }
            callable = CallableSelector.matchingCallableArityOne(callablesForArityarg0);
            if (callable == null) {
                throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), selfcallablesForArityarg0);
            }
        } else {
            if (callable.getParameterTypes().length != 1) {
                throw self.getRuntime().newArgumentError(1, callable.getParameterTypes().length);
            }
        }
        return callable;
    }
    protected JavaCallable findCallableArityTwo(IRubyObject selfString nameIRubyObject arg0IRubyObject arg1) {
        JavaCallable callable;
        if ((callable = ) == null) {
            // TODO: varargs?
            JavaCallable[] callablesForArity = null;
            if (. <= 2 || (callablesForArity = [2]) == null) {
                throw self.getRuntime().newArgumentError(2, . - 1);
            }
            callable = CallableSelector.matchingCallableArityTwo(callablesForArityarg0arg1);
            if (callable == null) {
                throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), selfcallablesForArityarg0arg1);
            }
        } else {
            if (callable.getParameterTypes().length != 2) {
                throw self.getRuntime().newArgumentError(2, callable.getParameterTypes().length);
            }
        }
        return callable;
    }
    protected JavaCallable findCallableArityThree(IRubyObject selfString nameIRubyObject arg0IRubyObject arg1IRubyObject arg2) {
        JavaCallable callable;
        if ((callable = ) == null) {
            // TODO: varargs?
            JavaCallable[] callablesForArity = null;
            if (. <= 3 || (callablesForArity = [3]) == null) {
                throw self.getRuntime().newArgumentError(3, . - 1);
            }
            callable = CallableSelector.matchingCallableArityThree(callablesForArityarg0arg1arg2);
            if (callable == null) {
                throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), selfcallablesForArityarg0arg1arg2);
            }
        } else {
            if (callable.getParameterTypes().length != 3) {
                throw self.getRuntime().newArgumentError(3, callable.getParameterTypes().length);
            }
        }
        return callable;
    }
    protected JavaCallable findCallableArityFour(IRubyObject selfString nameIRubyObject arg0IRubyObject arg1IRubyObject arg2IRubyObject arg3) {
        JavaCallable callable;
        if ((callable = ) == null) {
            // TODO: varargs?
            JavaCallable[] callablesForArity = null;
            if (. <= 4 || (callablesForArity = [4]) == null) {
                throw self.getRuntime().newArgumentError(4, . - 1);
            }
            callable = CallableSelector.matchingCallableArityFour(callablesForArityarg0arg1arg2arg3);
            if (callable == null) {
                throw CallableSelector.argTypesDoNotMatch(self.getRuntime(), selfcallablesForArityarg0arg1arg2arg3);
            }
        } else {
            if (callable.getParameterTypes().length != 4) {
                throw self.getRuntime().newArgumentError(4, callable.getParameterTypes().length);
            }
        }
        return callable;
    }
New to GrepCode? Check out our FAQ X