/**
*
*/
package prefuse.util;
import prefuse.data.Tuple;
import prefuse.data.expression.Expression;
import prefuse.data.expression.IfExpression;
import prefuse.data.expression.ObjectLiteral;
import prefuse.data.expression.Predicate;
/**
* A chain of Predicates and associated values, maintain a large
* if-statement structure for looking up values based on a Predicate
* condition.
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public class PredicateChain {
private Expression m_head = new ObjectLiteral(null);
private IfExpression m_tail = null;
/**
* Return the backing predicate chain as an Expression instance.
* @return the predicate chain, either an IfExpression or
* the single terminal default Expression instance.
*/
public Expression getExpression() {
return m_head;
}
/**
* Evaluate the predicate chain for the given Tuple.
* @param t the Tuple
* @return the object associated with the first Predicate
* that successfully matches the Tuple.
*/
public Object get(Tuple t) {
return m_head.get(t);
}
/**
* Add a new rule to the end of the chain, associating a Predicate
* condition with an Object value.
* @param p the Predicate condition
* @param val the associated Object value
*/
public void add(Predicate p, Object val) {
if ( m_tail == null ) {
m_tail = new IfExpression(p, new ObjectLiteral(val), m_head);
m_head = m_tail;
} else {
IfExpression ie = new IfExpression(p, new ObjectLiteral(val),
m_tail.getElseExpression());
m_tail.setElseExpression(ie);
m_tail = ie;
}
}
/**
* Remove rules using the given predicate from this predicate chain.
* This method will not remove rules in which this predicate is used
* within a composite of clauses, such as an AND or OR. It only removes
* rules using this predicate as the top-level trigger.
* @param p the predicate to remove from the chain
* @return true if a rule was successfully removed, false otherwise
*/
public boolean remove(Predicate p) {
if ( p == null ) return false;
IfExpression prev = null;
Expression expr = m_head;
while ( expr instanceof IfExpression ) {
IfExpression ifex = (IfExpression)expr;
Predicate test = (Predicate)ifex.getTestPredicate();
if ( p.equals(test) ) {
Expression elseex = ifex.getElseExpression();
ifex.setElseExpression(new ObjectLiteral(null));
if ( prev != null ) {
prev.setElseExpression(elseex);
if ( ifex == m_tail )
m_tail = prev;
} else {
m_head = elseex;
if ( ifex == m_tail )
m_tail = null;
}
return true;
} else {
prev = ifex;
expr = ifex.getElseExpression();
}
}
return false;
}
/**
* Remove all rules from the predicate chain.
*/
public void clear() {
m_head = new ObjectLiteral(null);
m_tail = null;
}
} // end of class PredicateChain