public static final Integer coercedCompare()

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