private int getApplicability()

in velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/MethodMap.java [534:648]


    private int getApplicability(Method method, Class<?>[] classes)
    {
        Type[] methodArgs = method.getGenericParameterTypes();
        int ret = STRICTLY_CONVERTIBLE;
        if (methodArgs.length > classes.length)
        {
            // if there's just one more methodArg than class arg
            // and the last methodArg is an array, then treat it as a vararg
            if (methodArgs.length == classes.length + 1 && TypeUtils.isArrayType(methodArgs[methodArgs.length - 1]))
            {
                // all the args preceding the vararg must match
                for (int i = 0; i < classes.length; i++)
                {
                    if (!isStrictConvertible(methodArgs[i], classes[i], false))
                    {
                        if (isConvertible(methodArgs[i], classes[i], false))
                        {
                            ret = Math.min(ret, IMPLCITLY_CONVERTIBLE);
                        }
                        else if (isExplicitlyConvertible(methodArgs[i], classes[i], false))
                        {
                            ret = Math.min(ret, EXPLICITLY_CONVERTIBLE);
                        }
                        else
                        {
                            return NOT_CONVERTIBLE;
                        }
                    }
                }
                return ret;
            }
            else
            {
                return NOT_CONVERTIBLE;
            }
        }
        else if (methodArgs.length == classes.length)
        {
            // this will properly match when the last methodArg
            // is an array/varargs and the last class is the type of array
            // (e.g. String when the method is expecting String...)
            for(int i = 0; i < classes.length; ++i)
            {
                boolean possibleVararg = i == classes.length - 1 && TypeUtils.isArrayType(methodArgs[i]);
                if (!isStrictConvertible(methodArgs[i], classes[i], possibleVararg))
                {
                    if (isConvertible(methodArgs[i], classes[i], possibleVararg))
                    {
                        ret = Math.min(ret, IMPLCITLY_CONVERTIBLE);
                    }
                    else if (isExplicitlyConvertible(methodArgs[i], classes[i], possibleVararg))
                    {
                        ret = Math.min(ret, EXPLICITLY_CONVERTIBLE);
                    }
                    else
                    {
                        return NOT_CONVERTIBLE;
                    }
                }
            }
            return ret;
        }
        else if (methodArgs.length > 0) // more arguments given than the method accepts; check for varargs
        {
            // check that the last methodArg is an array
            Type lastarg = methodArgs[methodArgs.length - 1];
            if (!TypeUtils.isArrayType(lastarg))
            {
                return NOT_CONVERTIBLE;
            }

            // check that they all match up to the last method arg component type
            for (int i = 0; i < methodArgs.length - 1; ++i)
            {
                if (!isStrictConvertible(methodArgs[i], classes[i], false))
                {
                    if (isConvertible(methodArgs[i], classes[i], false))
                    {
                        ret = Math.min(ret, IMPLCITLY_CONVERTIBLE);
                    }
                    else if (isExplicitlyConvertible(methodArgs[i], classes[i], false))
                    {
                        ret = Math.min(ret, EXPLICITLY_CONVERTIBLE);
                    }
                    else
                    {
                        return NOT_CONVERTIBLE;
                    }
                }
            }

            // check that all remaining arguments are convertible to the vararg type
            Type vararg = TypeUtils.getArrayComponentType(lastarg);
            for (int i = methodArgs.length - 1; i < classes.length; ++i)
            {
                if (!isStrictConvertible(vararg, classes[i], false))
                {
                    if (isConvertible(vararg, classes[i], false))
                    {
                        ret = Math.min(ret, IMPLCITLY_CONVERTIBLE);
                    }
                    else if (isExplicitlyConvertible(vararg, classes[i], false))
                    {
                        ret = Math.min(ret, EXPLICITLY_CONVERTIBLE);
                    }
                    else
                    {
                        return NOT_CONVERTIBLE;
                    }
                }
            }
            return ret;
        }
        return NOT_CONVERTIBLE;
    }