/** * Creates a transformed copy of this expression, applying transformation provided by Transformer * to all its nodes. Null transformer will result in an identical deep copy of this expression. * * <p>To force a node and its children to be pruned from the copy, Transformer should return null * for a given node. * * <p>There is one limitation on what Transformer is expected to do: if a node is an Expression it * must be transformed to null or another Expression. Any other object type would result in an * exception. * * @since 1.1 */ public Expression transform(Transformer transformer) { Expression copy = shallowCopy(); int count = getOperandCount(); for (int i = 0, j = 0; i < count; i++) { Object operand = getOperand(i); Object transformedChild = operand; if (operand instanceof Expression) { transformedChild = ((Expression) operand).transform(transformer); } else if (transformer != null) { transformedChild = transformer.transform(operand); } if (transformedChild != null) { Object value = (transformedChild != nullValue) ? transformedChild : null; copy.setOperand(j, value); j++; } else if (pruneNodeForPrunedChild(operand)) { // bail out early... return null; } } // all the children are processed, only now transform this copy return (transformer != null) ? (Expression) transformer.transform(copy) : copy; }
/** * Creates a new expression that joins this object with another expression, using specified join * type. It is very useful for incrementally building chained expressions, like long AND or OR * statements. */ public Expression joinExp(int type, Expression exp) { Expression join = ExpressionFactory.expressionOfType(type); join.setOperand(0, this); join.setOperand(1, exp); join.flattenTree(); return join; }
/** * Traverses itself and child expressions, notifying visitor via callback methods as it goes. * * @since 1.1 */ protected void traverse(Expression parentExp, TraversalHandler visitor) { visitor.startNode(this, parentExp); // recursively traverse each child int count = getOperandCount(); for (int i = 0; i < count; i++) { Object child = getOperand(i); if (child instanceof Expression) { Expression childExp = (Expression) child; childExp.traverse(this, visitor); } else { visitor.objectNode(child, this); } visitor.finishedChild(this, i, i < count - 1); } visitor.endNode(this, parentExp); }
public boolean equals(Object object) { if (!(object instanceof Expression)) { return false; } Expression e = (Expression) object; if (e.getType() != getType() || e.getOperandCount() != getOperandCount()) { return false; } // compare operands int len = e.getOperandCount(); for (int i = 0; i < len; i++) { if (!Util.nullSafeEquals(e.getOperand(i), getOperand(i))) { return false; } } return true; }
/** * Convenience method to log nested expressions. Used mainly for debugging. Called from * "toString". * * @deprecated Since 1.1 <code>encode</code> is used to recursively print expressions. */ protected void toStringBuffer(StringBuffer buf) { for (int i = 0; i < getOperandCount(); i++) { if (i > 0 || getOperandCount() == 1) { buf.append(" ").append(expName()).append(" "); } Object op = getOperand(i); if (op == null) { buf.append("<null>"); } else if (op instanceof String) { buf.append("'").append(op).append("'"); } else if (op instanceof Expression) { buf.append('('); ((Expression) op).toStringBuffer(buf); buf.append(')'); } else { buf.append(String.valueOf(op)); } } }
/** * Returns a logical NOT of current expression. * * @since 1.0.6 */ public Expression notExp() { Expression exp = ExpressionFactory.expressionOfType(Expression.NOT); exp.setOperand(0, this); return exp; }