Fix SpEL comparison operator for comparable types

Prior to this commit, the SpEL relational operators for comparison
would have the following problem:

* their implementation would claim that incompatible types
  could be compared and later fail during comparison
* not delegate the comparison to the actual `TypeComparator`
  implementation but rely on operator specifics

This commit ensures that the `TypeComparator` implementation is used for
both `canCompare` and `compare` calls in the operators.

See gh-1581
This commit is contained in:
Tin Pavlinic
2017-11-01 14:32:40 +11:00
committed by Brian Clozel
parent 804b343cab
commit d178eafc11
4 changed files with 69 additions and 8 deletions

View File

@@ -309,11 +309,8 @@ public abstract class Operator extends SpelNodeImpl {
return true;
}
if (left instanceof Comparable && right instanceof Comparable) {
Class<?> ancestor = ClassUtils.determineCommonAncestor(left.getClass(), right.getClass());
if (ancestor != null && Comparable.class.isAssignableFrom(ancestor)) {
return (context.getTypeComparator().compare(left, right) == 0);
}
if (context.getTypeComparator().canCompare(left, right)) {
return context.getTypeComparator().compare(left, right) == 0;
}
return false;

View File

@@ -23,6 +23,7 @@ import org.springframework.expression.TypeComparator;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelMessage;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
import org.springframework.util.NumberUtils;
/**
@@ -44,8 +45,9 @@ public class StandardTypeComparator implements TypeComparator {
if (left instanceof Number && right instanceof Number) {
return true;
}
if (left instanceof Comparable) {
return true;
if (left instanceof Comparable && right instanceof Comparable) {
Class<?> ancestor = ClassUtils.determineCommonAncestor(left.getClass(), right.getClass());
return ancestor != null && Comparable.class.isAssignableFrom(ancestor);
}
return false;
}