package prefuse.data.expression;
import java.util.ArrayList;
import java.util.Iterator;
/**
* Abstract base class for Predicate instances that maintain one or
* more sub-predicates (clauses).
*
* @author <a href="http://jheer.org">jeffrey heer</a>
*/
public abstract class CompositePredicate extends AbstractPredicate {
protected ArrayList m_clauses = new ArrayList(2);
/**
* Create a new, empty CompositePredicate.
*/
public CompositePredicate() {
}
/**
* Create a new CompositePredicate.
* @param p1 the first sub-predicate
* @param p2 the second sub-predicate
*/
public CompositePredicate(Predicate p1, Predicate p2) {
m_clauses.add(p1);
m_clauses.add(p2);
}
// ------------------------------------------------------------------------
/**
* Add a new clause.
* @param p the Predicate clause to add
*/
public void add(Predicate p) {
if ( m_clauses.contains(p) ) {
throw new IllegalArgumentException("Duplicate predicate.");
}
m_clauses.add(p);
fireExpressionChange();
}
/**
* Remove a new clause.
* @param p the Predicate clause to remove
* @return true if removed, false if not found
*/
public boolean remove(Predicate p) {
if ( m_clauses.remove(p) ) {
fireExpressionChange();
return true;
} else {
return false;
}
}
/**
* Remove all clauses.
*/
public void clear() {
removeChildListeners();
m_clauses.clear();
fireExpressionChange();
}
/**
* Get the number of sub-predicate clauses.
* @return the number of clauses
*/
public int size() {
return m_clauses.size();
}
/**
* Get the sub-predicate at the given index.
* @param idx the index to lookup
* @return the sub-predicate at the given index
*/
public Predicate get(int idx) {
return (Predicate)m_clauses.get(idx);
}
/**
* Set the given predicate to be the only clause of thie composite.
* @param p the new sole sub-predicate clause
*/
public void set(Predicate p) {
removeChildListeners();
m_clauses.clear();
m_clauses.add(p);
if ( hasListeners() ) addChildListeners();
fireExpressionChange();
}
/**
* Set the given predicates to be the clauses of thie composite.
* @param p the new sub-predicate clauses
*/
public void set(Predicate[] p) {
removeChildListeners();
m_clauses.clear();
for ( int i=0; i<p.length; ++i ) {
if ( !m_clauses.contains(p) )
m_clauses.add(p[i]);
}
if ( hasListeners() ) addChildListeners();
fireExpressionChange();
}
/**
* Get a predicate instance just like this one but without
* the given predicate as a clause.
* @param p the predicate clause to ignore
* @return a clone of this predicate, only without the input predicate
*/
public Predicate getSubPredicate(Predicate p) {
CompositePredicate cp = null;
try {
cp = (CompositePredicate)this.getClass().newInstance();
} catch (InstantiationException e) {
// won't happen
} catch (IllegalAccessException e) {
// won't happen
}
for ( int i=0; i<m_clauses.size(); ++i ) {
Predicate pp = (Predicate)m_clauses.get(i);
if ( p != pp ) {
cp.add(pp);
}
}
return cp;
}
// ------------------------------------------------------------------------
/**
* @see prefuse.data.expression.Expression#visit(prefuse.data.expression.ExpressionVisitor)
*/
public void visit(ExpressionVisitor v) {
v.visitExpression(this);
Iterator iter = m_clauses.iterator();
while ( iter.hasNext() ) {
v.down();
((Expression)iter.next()).visit(v);
v.up();
}
}
// ------------------------------------------------------------------------
/**
* @see prefuse.data.expression.AbstractExpression#addChildListeners()
*/
protected void addChildListeners() {
Iterator iter = m_clauses.iterator();
while ( iter.hasNext() ) {
((Expression)iter.next()).addExpressionListener(this);
}
}
/**
* @see prefuse.data.expression.AbstractExpression#removeChildListeners()
*/
protected void removeChildListeners() {
Iterator iter = m_clauses.iterator();
while ( iter.hasNext() ) {
((Expression)iter.next()).removeExpressionListener(this);
}
}
// ------------------------------------------------------------------------
/**
* Return a String representation of this predicate.
* @param op a String describing the operation this Predicate performs
* @return a String representing this Expression
*/
protected String toString(String op) {
if ( m_clauses.size() == 1 ) {
return m_clauses.get(0).toString();
}
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');
Iterator iter = m_clauses.iterator();
while ( iter.hasNext() ) {
sbuf.append(iter.next().toString());
if ( iter.hasNext() ) {
sbuf.append(" ");
sbuf.append(op);
sbuf.append(" ");
}
}
sbuf.append(')');
return sbuf.toString();
}
} // end of abstract class CompositePredicate