/** * 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; }
// WARNING: (andrus) if we ever decide to make this method protected or public, we // need to change the signature to avoid API dependency on commons-collections Object runInTransaction(Transformer operation) { // user or container-managed or nested transaction if (Transaction.getThreadTransaction() != null) { return operation.transform(null); } // Cayenne-managed transaction Transaction transaction = createTransaction(); Transaction.bindThreadTransaction(transaction); try { // implicit begin.. Object result = operation.transform(null); transaction.commit(); return result; } catch (Exception ex) { transaction.setRollbackOnly(); // must rethrow if (ex instanceof CayenneRuntimeException) { throw (CayenneRuntimeException) ex; } else { throw new CayenneRuntimeException(ex); } } finally { Transaction.bindThreadTransaction(null); if (transaction.getStatus() == Transaction.STATUS_MARKED_ROLLEDBACK) { try { transaction.rollback(); } catch (Exception rollbackEx) { // although we don't expect an exception here, print the stack, as // there have been some Cayenne bugs already (CAY-557) that were // masked by this 'catch' clause. jdbcEventLogger.logQueryError(rollbackEx); } } } }
/** * Evaluates the predicate returning the result of the decorated predicate once the input has been * transformed * * @param object the input object which will be transformed * @return true if decorated predicate returns true */ public boolean evaluate(Object object) { Object result = iTransformer.transform(object); return iPredicate.evaluate(result); }