001: package prefuse.data.expression;
002:
003: import java.util.Comparator;
004:
005: import prefuse.data.Schema;
006: import prefuse.data.Tuple;
007: import prefuse.util.TypeLib;
008: import prefuse.util.collections.DefaultLiteralComparator;
009: import prefuse.util.collections.LiteralComparator;
010:
011: /**
012: * Predicate implementation that computes a comparison operation. Supported
013: * operations are equals, not equals, less than, greater than, less than or
014: * equal to, and greater than or equal to.
015: *
016: * @author <a href="http://jheer.org">jeffrey heer</a>
017: */
018: public class ComparisonPredicate extends BinaryExpression implements
019: Predicate {
020:
021: /** Indicates a less-than comparison. */
022: public static final int LT = 0;
023: /** Indicates a greater-than comparison. */
024: public static final int GT = 1;
025: /** Indicates a equals comparison. */
026: public static final int EQ = 2;
027: /** Indicates a not-equals comparison. */
028: public static final int NEQ = 3;
029: /** Indicates a less-than-or-equals comparison. */
030: public static final int LTEQ = 4;
031: /** Indicates a greater-than-or-equals comparison. */
032: public static final int GTEQ = 5;
033:
034: private Comparator m_cmp;
035:
036: /**
037: * Create a new ComparisonPredicate. Uses a default comparator instance.
038: * @param operation the comparison operation to compute
039: * @param left the left sub-expression
040: * @param right the right sub-expression
041: */
042: public ComparisonPredicate(int operation, Expression left,
043: Expression right) {
044: this (operation, left, right, DefaultLiteralComparator
045: .getInstance());
046: }
047:
048: /**
049: * Create a new ComparisonPredicate.
050: * @param operation the comparison operation to compute
051: * @param left the left sub-expression
052: * @param right the right sub-expression
053: * @param cmp the comparator to use to compare values
054: */
055: public ComparisonPredicate(int operation, Expression left,
056: Expression right, Comparator cmp) {
057: super (operation, LT, GTEQ, left, right);
058: this .m_cmp = cmp;
059: }
060:
061: /**
062: * Get the comparator used to compare instances.
063: * @return the comparator instance
064: */
065: public Comparator getComparator() {
066: return m_cmp;
067: }
068:
069: // ------------------------------------------------------------------------
070:
071: /**
072: * @see prefuse.data.expression.Expression#getType(prefuse.data.Schema)
073: */
074: public Class getType(Schema s) {
075: return boolean.class;
076: }
077:
078: /**
079: * @see prefuse.data.expression.Expression#getBoolean(prefuse.data.Tuple)
080: */
081: public boolean getBoolean(Tuple t) {
082: Class lType = m_left.getType(t.getSchema());
083: Class rType = m_right.getType(t.getSchema());
084:
085: int c = 0;
086: if (TypeLib.isNumericType(lType)
087: && TypeLib.isNumericType(rType)) {
088: Class type = TypeLib.getNumericType(lType, rType);
089: if (type == int.class || type == byte.class) {
090: int x = m_left.getInt(t);
091: int y = m_right.getInt(t);
092: c = ((LiteralComparator) m_cmp).compare(x, y);
093: } else if (type == long.class) {
094: long x = m_left.getLong(t);
095: long y = m_right.getLong(t);
096: c = ((LiteralComparator) m_cmp).compare(x, y);
097: } else if (type == float.class) {
098: float x = m_left.getFloat(t);
099: float y = m_right.getFloat(t);
100: c = ((LiteralComparator) m_cmp).compare(x, y);
101: } else if (type == double.class) {
102: double x = m_left.getDouble(t);
103: double y = m_right.getDouble(t);
104: c = ((LiteralComparator) m_cmp).compare(x, y);
105: } else {
106: throw new IllegalStateException();
107: }
108: } else {
109: c = m_cmp.compare(m_left.get(t), m_right.get(t));
110: }
111:
112: switch (m_op) {
113: case LT:
114: return (c == -1);
115: case GT:
116: return (c == 1);
117: case EQ:
118: return (c == 0);
119: case NEQ:
120: return (c != 0);
121: case LTEQ:
122: return (c <= 0);
123: case GTEQ:
124: return (c >= 0);
125: default:
126: throw new IllegalStateException("Unknown operation.");
127: }
128: }
129:
130: /**
131: * @see prefuse.data.expression.Expression#get(prefuse.data.Tuple)
132: */
133: public Object get(Tuple t) {
134: return (getBoolean(t) ? Boolean.TRUE : Boolean.FALSE);
135: }
136:
137: /**
138: * @see java.lang.Object#toString()
139: */
140: public String toString() {
141: String op = "?";
142: switch (m_op) {
143: case LT:
144: op = "<";
145: break;
146: case GT:
147: op = ">";
148: break;
149: case EQ:
150: op = "=";
151: break;
152: case NEQ:
153: op = "!=";
154: break;
155: case LTEQ:
156: op = "<=";
157: break;
158: case GTEQ:
159: op = ">=";
160: break;
161: }
162: return m_left.toString() + ' ' + op + ' ' + m_right.toString();
163: }
164:
165: } // end of class BinaryPredicate
|