package javax.slee.profile.query;
import java.util.ArrayList;
/**
* The <code>CompositeQueryExpression</code> class is the base class for all dynamic
* query expressions that are containers of other query expressions.
*/
public abstract class CompositeQueryExpression extends QueryExpression {
/**
* Get the query expressions that have been added to this composite expression.
* @return the query expressions that have been added to this composite expression.
*/
public final QueryExpression[] getExpressions() {
return (QueryExpression[])exprs.toArray(new QueryExpression[exprs.size()]);
}
// protected
/**
* Add a query expression to this composite expression.
* @param expr the expression to add.
* @throws NullPointerException if <code>expr</code> is <code>null</code>.
* @throws IllegalArgumentException if adding the query expression to this
* composite expression would generate a cyclic expression.
*/
protected final void add(QueryExpression expr) throws NullPointerException, IllegalArgumentException {
if (expr == null) throw new NullPointerException("expr is null");
// check for cycles
if (expr instanceof CompositeQueryExpression) {
((CompositeQueryExpression)expr).checkForCycles(this);
}
else if (expr instanceof Not) {
((Not)expr).checkForCycles(this);
}
// no cycles, so add the expression to the list
exprs.add(expr);
}
// package
/**
* Check whether the specified expression contains a reference, either direct
* or indirect, to this expression.
* @param expr the expression to check and possibly recurse through.
* @throws IllegalArgumentException if a cyclic expression is detected.
*/
void checkForCycles(QueryExpression expr) throws IllegalArgumentException {
// is the expression argument equal to this?
if (expr == this) throw new IllegalArgumentException("Cyclic expression detected");
// recurse through all nested expressions that are composite expressions
for (int i=0; i<exprs.size(); i++) {
QueryExpression nested = (QueryExpression)exprs.get(i);
if (nested instanceof CompositeQueryExpression) {
((CompositeQueryExpression)nested).checkForCycles(expr);
}
else if (nested instanceof Not) {
((Not)nested).checkForCycles(expr);
}
}
}
private final ArrayList exprs = new ArrayList();
}