in core/src/main/java/org/apache/brooklyn/util/core/predicates/DslPredicates.java [180:233]
public static final Integer coercedCompare(Object a, Object b) {
if (a==null || b==null) return 0;
// if either believes they're equal, believe it
if (a.equals(b) || b.equals(a)) return 0;
if (a instanceof Number || b instanceof Number) {
try {
// if either number is a string try to treat both as string
if (a instanceof String) a = new BigDecimal((String) a);
if (b instanceof String) b = new BigDecimal((String) b);
if (a instanceof Number && b instanceof Number) {
if (a.getClass().equals(b.getClass())) {
if (a instanceof BigDecimal) return ((BigDecimal) a).compareTo((BigDecimal) b);
if (a instanceof BigInteger) return ((BigInteger) a).compareTo((BigInteger) b);
if (a instanceof Long) return ((Long) a).compareTo((Long) b);
if (a instanceof Integer) return ((Integer) a).compareTo((Integer) b);
return ((Double) (((Number) a).doubleValue())).compareTo(((Number) b).doubleValue());
}
if (a instanceof Integer || a instanceof Long || a instanceof Byte) a = BigDecimal.valueOf(((Number) a).longValue());
if (b instanceof Integer || b instanceof Long || a instanceof Byte) b = BigDecimal.valueOf(((Number) b).longValue());
if (a instanceof Double || a instanceof Float) a = BigDecimal.valueOf(((Number) a).doubleValue());
if (b instanceof Double || b instanceof Float) b = BigDecimal.valueOf(((Number) b).doubleValue());
// all now normally big decimal
if (a instanceof BigDecimal && b instanceof BigDecimal) return ((BigDecimal) a).compareTo((BigDecimal) b);
// some weird type; proceed to string stuff below
}
} catch (Exception e) {
// one number is not parseable as a string; proceed to natural order comparator
}
}
if (isStringOrPrimitiveOrNumber(a) && isStringOrPrimitiveOrNumber(b)) {
return NaturalOrderComparator.INSTANCE.compare(toStringForPrimitives(a), toStringForPrimitives(b));
}
if (a instanceof DeferredSupplier || b instanceof DeferredSupplier)
return coercedCompare(undeferred(a), undeferred(b));
// if classes are equal or one is a subclass of the other, and the above check was false, that is decisive
if (a.getClass().isAssignableFrom(b.getClass()) && b instanceof Comparable) return -((Comparable) b).compareTo(a);
if (b.getClass().isAssignableFrom(a.getClass()) && a instanceof Comparable) return ((Comparable) a).compareTo(b);
BiFunction<Maybe<?>,Maybe<?>,Integer> maybeCoercedCompare = (ma,mb) -> {
if (ma.isPresent() && mb.isPresent()) return coercedCompare(ma.get(), mb.get());
return null;
};
// different type hierarchies, consider coercion
if (isJson(a) && !isJson(b)) return maybeCoercedCompare.apply( TypeCoercions.tryCoerce(a, b.getClass()), Maybe.of(b) );
if (isJson(b) && !isJson(a)) return maybeCoercedCompare.apply( Maybe.of(a), TypeCoercions.tryCoerce(b, a.getClass()) );
return null;
}