static private boolean isMethodConvertable()

in src/main/java/org/apache/bsf/util/MethodUtils.java [346:415]


    static private boolean isMethodConvertable(Class parm, Class arg) {
        if (parm.equals(arg)) {
            return true;
        }

        // Accept any type EXCEPT primitives (which can't have null values).
        if (arg == null) {
            return !parm.isPrimitive();
        }

        // Arrays are convertable if their elements are convertable
        // ????? Does this have to be done before isAssignableFrom, or
        // does it successfully handle arrays of primatives?
        while (parm.isArray()) {
            if (!arg.isArray()) {
                return false; // Unequal array depth
            } else {
                parm = parm.getComponentType();
                arg = arg.getComponentType();
            }
        }
        if (arg.isArray()) {
            return false; // Unequal array depth
        }

        // Despite its name, the 1.1.6 docs say that this function does
        // NOT return true for all legal ASSIGNMENT CONVERSIONS
        // (5.2):
        // "Specifically, this method tests whether the type
        // represented by the specified class can be converted
        // to the type represented by this Class object via
        // an identity conversion or via a widening reference
        // conversion."
        if (parm.isAssignableFrom(arg)) {
            return true;
        }

        // That leaves us the Widening Primitives case. Four possibilities:
        // void (can only convert to void), boolean (can only convert to boolean),
        // numeric (which are sequenced) and char (which inserts itself into the
        // numerics by promoting to int or larger)

        if (parm.equals(Void.TYPE) || parm.equals(Boolean.TYPE) || arg.equals(Void.TYPE) || arg.equals(Boolean.TYPE)) {
            return false;
        }

        final Class[] primTypes = { Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE };
        int parmscore, argscore;

        for (parmscore = 0; parmscore < primTypes.length; ++parmscore) {
            if (parm.equals(primTypes[parmscore])) {
                break;
            }
        }
        if (parmscore >= primTypes.length) {
            return false; // Off the end
        }

        for (argscore = 0; argscore < primTypes.length; ++argscore) {
            if (arg.equals(primTypes[argscore])) {
                break;
            }
        }
        if (argscore >= primTypes.length) {
            return false; // Off the end
        }

        // OK if ordered AND NOT char-to-smaller-than-int
        return (argscore < parmscore && (argscore != 0 || parmscore > 2));
    }