/** * FEEL spec Table 41: Specific semantics of equality * Delegates to {@link EvalHelper} except evaluationcontext */ public static Boolean eq(Object left, Object right) { return EvalHelper.isEqual(left, right, null); }
private static Boolean isEqual(Object l, Object r) { if( l instanceof Iterable && r instanceof Iterable && !isEqual( (Iterable) l, (Iterable) r ) ) { return false; } else if( l instanceof Map && r instanceof Map && !isEqual( (Map) l, (Map) r ) ) { return false; } else if( l != null && r != null && !l.equals( r ) ) { return false; } else if( ( l == null || r == null ) && l != r ) { return false; } return true; }
/** * For a Unary Test an = (equal) semantic depends on the RIGHT value. * If the RIGHT is NOT a list, then standard equals semantic applies * If the RIGHT is a LIST, then the semantic is "right contains left" */ private Boolean utEqualSemantic(Object left, Object right, EvaluationContext context) { if (right instanceof Collection) { return ((Collection) right).contains(left); } else { // evaluate single entity return EvalHelper.isEqual(left, right, context); } }
private static Boolean isEqual(Map<?,?> left, Map<?,?> right) { if( left.size() != right.size() ) { return false; } for( Map.Entry le : left.entrySet() ) { Object l = le.getValue(); Object r = right.get( le.getKey() ); if ( !isEqual( l, r ) ) return false; } return true; }
private static Boolean isEqual(Iterable left, Iterable right) { Iterator li = left.iterator(); Iterator ri = right.iterator(); while( li.hasNext() && ri.hasNext() ) { Object l = li.next(); Object r = ri.next(); if ( !isEqual( l, r ) ) return false; } return li.hasNext() == ri.hasNext(); }
/** * FEEL spec Table 39 */ public static Boolean ne(Object left, Object right) { return not(EvalHelper.isEqual(left, right, null)); }
/** * Compares left and right for equality applying FEEL semantics to specific data types * * @param left * @param right * @param ctx * @return */ public static Boolean isEqual(Object left, Object right, EvaluationContext ctx ) { if ( left == null || right == null ) { return left == right; } // spec defines that "a=[a]", i.e., singleton collections should be treated as the single element // and vice-versa if( left instanceof Collection && !(right instanceof Collection) && ((Collection)left).size() == 1 ) { left = ((Collection)left).toArray()[0]; } else if( right instanceof Collection && !(left instanceof Collection) && ((Collection)right).size()==1 ) { right = ((Collection) right).toArray()[0]; } if( left instanceof Range && right instanceof Range ) { return isEqual( (Range)left, (Range) right ); } else if( left instanceof Iterable && right instanceof Iterable ) { return isEqual( (Iterable)left, (Iterable) right ); } else if( left instanceof Map && right instanceof Map ) { return isEqual( (Map)left, (Map) right ); } return compare( left, right, ctx, (l, r) -> l.compareTo( r ) == 0 ); }