package prefuse.data.expression; import java.util.Comparator; import prefuse.data.Schema; import prefuse.data.Tuple; import prefuse.util.TypeLib; import prefuse.util.collections.DefaultLiteralComparator; import prefuse.util.collections.LiteralComparator; /** * Predicate implementation that computes a comparison operation. Supported * operations are equals, not equals, less than, greater than, less than or * equal to, and greater than or equal to. * * @author <a href="http://jheer.org">jeffrey heer</a> */ public class ComparisonPredicate extends BinaryExpression implements Predicate { /** Indicates a less-than comparison. */ public static final int LT = 0; /** Indicates a greater-than comparison. */ public static final int GT = 1; /** Indicates a equals comparison. */ public static final int EQ = 2; /** Indicates a not-equals comparison. */ public static final int NEQ = 3; /** Indicates a less-than-or-equals comparison. */ public static final int LTEQ = 4; /** Indicates a greater-than-or-equals comparison. */ public static final int GTEQ = 5; private Comparator m_cmp; /** * Create a new ComparisonPredicate. Uses a default comparator instance. * @param operation the comparison operation to compute * @param left the left sub-expression * @param right the right sub-expression */ public ComparisonPredicate(int operation, Expression left, Expression right) { this(operation, left, right, DefaultLiteralComparator.getInstance()); } /** * Create a new ComparisonPredicate. * @param operation the comparison operation to compute * @param left the left sub-expression * @param right the right sub-expression * @param cmp the comparator to use to compare values */ public ComparisonPredicate(int operation, Expression left, Expression right, Comparator cmp) { super(operation, LT, GTEQ, left, right); this.m_cmp = cmp; } /** * Get the comparator used to compare instances. * @return the comparator instance */ public Comparator getComparator() { return m_cmp; } // ------------------------------------------------------------------------ /** * @see prefuse.data.expression.Expression#getType(prefuse.data.Schema) */ public Class getType(Schema s) { return boolean.class; } /** * @see prefuse.data.expression.Expression#getBoolean(prefuse.data.Tuple) */ public boolean getBoolean(Tuple t) { Class lType = m_left.getType(t.getSchema()); Class rType = m_right.getType(t.getSchema()); int c = 0; if ( TypeLib.isNumericType(lType) && TypeLib.isNumericType(rType) ) { Class type = TypeLib.getNumericType(lType, rType); if ( type == int.class || type == byte.class ) { int x = m_left.getInt(t); int y = m_right.getInt(t); c = ((LiteralComparator)m_cmp).compare(x,y); } else if ( type == long.class ) { long x = m_left.getLong(t); long y = m_right.getLong(t); c = ((LiteralComparator)m_cmp).compare(x,y); } else if ( type == float.class ) { float x = m_left.getFloat(t); float y = m_right.getFloat(t); c = ((LiteralComparator)m_cmp).compare(x,y); } else if ( type == double.class ) { double x = m_left.getDouble(t); double y = m_right.getDouble(t); c = ((LiteralComparator)m_cmp).compare(x,y); } else { throw new IllegalStateException(); } } else { c = m_cmp.compare(m_left.get(t), m_right.get(t)); } switch ( m_op ) { case LT: return ( c == -1 ); case GT: return ( c == 1 ); case EQ: return ( c == 0 ); case NEQ: return ( c != 0 ); case LTEQ: return ( c <= 0 ); case GTEQ: return ( c >= 0 ); default: throw new IllegalStateException("Unknown operation."); } } /** * @see prefuse.data.expression.Expression#get(prefuse.data.Tuple) */ public Object get(Tuple t) { return ( getBoolean(t) ? Boolean.TRUE : Boolean.FALSE ); } /** * @see java.lang.Object#toString() */ public String toString() { String op = "?"; switch ( m_op ) { case LT: op = "<"; break; case GT: op = ">"; break; case EQ: op = "="; break; case NEQ: op = "!="; break; case LTEQ: op = "<="; break; case GTEQ: op = ">="; break; } return m_left.toString()+' '+op+' '+m_right.toString(); } } // end of class BinaryPredicate