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;
}