public static Class promote()

in openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java [129:201]


    public static Class<?> promote(Class<?> c1, Class<?> c2) {
        if (c1 == c2)
            return unwrap(c1);
        Class<?> w1 = wrap(c1);
        Class<?> w2 = wrap(c2);
        if (w1 == w2)
            return unwrap(c1);

        // not numbers?
        boolean w1Number = Number.class.isAssignableFrom(w1);
        boolean w2Number = Number.class.isAssignableFrom(w2);
        if (!w1Number || !w2Number) {
            // the only non-numeric promotion we do is string to char,
            // or from char/string to number
            if (!w1Number) {
                if (w2Number && (w1 == Character.class || w1 == String.class))
                    return (w2 == Byte.class || w2 == Short.class)
                        ? Integer.class : unwrap(c2);
                if (!w2Number && w1 == Character.class && w2 == String.class)
                    return String.class;
                if (w2Number)
                    return unwrap(c2);
            }
            if (!w2Number) {
                if (w1Number && (w2 == Character.class || w2 == String.class))
                    return (w1 == Byte.class || w1 == Short.class)
                        ? Integer.class : unwrap(c1);
                if (!w1Number && w2 == Character.class && w1 == String.class)
                    return String.class;
                if (w1Number)
                    return unwrap(c1);
            }

            // if neither are numbers, use least-derived of the two.  if neither
            // is assignable from the other but one is a standard type, assume
            // the other can be converted to that standard type
            if (!w1Number && !w2Number) {
                if (w1 == Object.class)
                    return unwrap(c2);
                if (w2 == Object.class)
                    return unwrap(c1);
                if (w1.isAssignableFrom(w2))
                    return unwrap(c1);
                if (w2.isAssignableFrom(w1))
                    return unwrap(c2);
                if (isNonstandardType(w1))
                    return (isNonstandardType(w2)) ? Object.class : unwrap(c2);
                if (isNonstandardType(w2))
                    return (isNonstandardType(w1)) ? Object.class : unwrap(c1);
            }
            return Object.class;
        }

        if (w1 == BigDecimal.class || w2 == BigDecimal.class)
            return BigDecimal.class;
        if (w1 == BigInteger.class) {
            if (w2 == Float.class || w2 == Double.class)
                return BigDecimal.class;
            return BigInteger.class;
        }
        if (w2 == BigInteger.class) {
            if (w1 == Float.class || w1 == Double.class)
                return BigDecimal.class;
            return BigInteger.class;
        }
        if (w1 == Double.class || w2 == Double.class)
            return double.class;
        if (w1 == Float.class || w2 == Float.class)
            return float.class;
        if (w1 == Long.class || w2 == Long.class)
            return long.class;
        return int.class;
    }