public List<Expression> copyDerivedExpressions(Map alreadyDone) { if (this.derivedExpressions == null) { return null; } List<Expression> derivedExpressionsCopy; synchronized (this) { derivedExpressionsCopy = new ArrayList(this.derivedExpressions); } List<Expression> result = new ArrayList(derivedExpressionsCopy.size()); for (Expression exp : derivedExpressionsCopy) { result.add(exp.copiedVersionFrom(alreadyDone)); } return result; }
/** * INTERNAL: Parses an expression to return the first non-AggregateObjectMapping expression after * the base ExpressionBuilder. This is used by joining and batch fetch to get the list of mappings * that really need to be processed (non-aggregates). * * @param aggregateMappingsEncountered - collection of aggregateObjectMapping expressions * encountered in the returned expression between the first expression and the * ExpressionBuilder * @return first non-AggregateObjectMapping expression after the base ExpressionBuilder from the * fullExpression */ public ObjectExpression getFirstNonAggregateExpressionAfterExpressionBuilder( List aggregateMappingsEncountered) { boolean done = false; ObjectExpression baseExpression = this; ObjectExpression prevExpression = this; while (!baseExpression.getBaseExpression().isExpressionBuilder() && !done) { baseExpression = (ObjectExpression) baseExpression.getBaseExpression(); while (!baseExpression.isExpressionBuilder() && baseExpression.getMapping().isAggregateObjectMapping()) { aggregateMappingsEncountered.add(baseExpression.getMapping()); baseExpression = (ObjectExpression) baseExpression.getBaseExpression(); } if (baseExpression.isExpressionBuilder()) { done = true; // use the one closest to the expression builder that wasn't an aggregate baseExpression = prevExpression; } else { prevExpression = baseExpression; } } return baseExpression; }