in grails-datamapping-core/src/main/groovy/org/grails/datastore/gorm/query/transform/DetachedCriteriaTransformer.java [516:641]
private void addStatementToNewQuery(Statement statement, BlockStatement newCode, boolean addAll, List<String> propertyNames, VariableScope variableScope) {
if (statement instanceof BlockStatement) {
addBlockStatementToNewQuery((BlockStatement) statement, newCode, addAll, propertyNames, variableScope);
} else if (statement instanceof ExpressionStatement) {
ExpressionStatement es = (ExpressionStatement) statement;
Expression expression = es.getExpression();
if (expression instanceof DeclarationExpression) {
DeclarationExpression de = (DeclarationExpression)expression;
Expression leftExpression = de.getLeftExpression();
Expression rightExpression = de.getRightExpression();
if((leftExpression instanceof VariableExpression) && (rightExpression instanceof ClassExpression)) {
ClassExpression classExpression = (ClassExpression) rightExpression;
if(currentClassNode.equals(classExpression.getType())) {
ArgumentListExpression arguments = new ArgumentListExpression();
String aliasName = leftExpression.getText();
aliases.put(aliasName, currentClassNode);
arguments.addExpression(new ConstantExpression(aliasName));
MethodCallExpression setAliasMethodCall = new MethodCallExpression(new VariableExpression("this"), "setAlias", arguments);
newCode.addStatement(new ExpressionStatement(setAliasMethodCall));
}
newCode.addStatement(es);
}
else if((leftExpression instanceof VariableExpression) && (rightExpression instanceof VariableExpression)) {
String referencedProperty = rightExpression.getText();
if(propertyNames.contains(referencedProperty)) {
ArgumentListExpression arguments = new ArgumentListExpression();
arguments.addExpression(new ConstantExpression(referencedProperty));
String aliasName = leftExpression.getText();
aliases.put(aliasName, referencedProperty);
arguments.addExpression(new ConstantExpression(aliasName));
MethodCallExpression createAliasMethodCall = new MethodCallExpression(new VariableExpression("this"), "createAlias", arguments);
newCode.addStatement(new ExpressionStatement(createAliasMethodCall));
}
newCode.addStatement(es);
}
else {
newCode.addStatement(es);
}
} else if (expression instanceof BinaryExpression) {
BinaryExpression be = (BinaryExpression) expression;
addBinaryExpressionToNewBody(propertyNames, newCode, be, addAll, variableScope);
} else if (expression instanceof NotExpression) {
NotExpression not = (NotExpression) expression;
handleNegation(propertyNames, newCode, not, variableScope);
} else if (expression instanceof MethodCallExpression) {
MethodCallExpression methodCall = (MethodCallExpression) expression;
handleAssociationMethodCallExpression(newCode, methodCall, propertyNames, variableScope);
}
} else {
if (statement instanceof IfStatement) {
IfStatement ifs = (IfStatement) statement;
Statement ifb = ifs.getIfBlock();
BlockStatement newIfBlock = new BlockStatement();
addStatementToNewQuery(ifb, newIfBlock, addAll, propertyNames, variableScope);
ifs.setIfBlock(flattenStatementIfNecessary(newIfBlock));
Statement elseBlock = ifs.getElseBlock();
if (elseBlock != null) {
BlockStatement newElseBlock = new BlockStatement();
addStatementToNewQuery(elseBlock, newElseBlock, addAll, propertyNames, variableScope);
ifs.setElseBlock(flattenStatementIfNecessary(newElseBlock));
}
newCode.addStatement(ifs);
} else if (statement instanceof SwitchStatement) {
SwitchStatement sw = (SwitchStatement) statement;
List<CaseStatement> caseStatements = sw.getCaseStatements();
for (CaseStatement caseStatement : caseStatements) {
Statement existingCode = caseStatement.getCode();
BlockStatement newCaseCode = new BlockStatement();
addStatementToNewQuery(existingCode, newCaseCode, addAll, propertyNames, variableScope);
caseStatement.setCode(flattenStatementIfNecessary(newCaseCode));
}
newCode.addStatement(sw);
} else if (statement instanceof ForStatement) {
ForStatement fs = (ForStatement) statement;
Statement loopBlock = fs.getLoopBlock();
BlockStatement newLoopBlock = new BlockStatement();
addStatementToNewQuery(loopBlock, newLoopBlock, addAll, propertyNames, variableScope);
fs.setLoopBlock(flattenStatementIfNecessary(newLoopBlock));
newCode.addStatement(fs);
} else if (statement instanceof WhileStatement) {
WhileStatement ws = (WhileStatement) statement;
Statement loopBlock = ws.getLoopBlock();
BlockStatement newLoopBlock = new BlockStatement();
addStatementToNewQuery(loopBlock, newLoopBlock, addAll, propertyNames, variableScope);
ws.setLoopBlock(flattenStatementIfNecessary(newLoopBlock));
newCode.addStatement(ws);
} else if (statement instanceof TryCatchStatement) {
TryCatchStatement tcs = (TryCatchStatement) statement;
Statement tryStatement = tcs.getTryStatement();
BlockStatement newTryStatement = new BlockStatement();
addStatementToNewQuery(tryStatement, newTryStatement, addAll, propertyNames, variableScope);
tcs.setTryStatement(flattenStatementIfNecessary(newTryStatement));
List<CatchStatement> catchStatements = tcs.getCatchStatements();
for (CatchStatement catchStatement : catchStatements) {
BlockStatement newCatchStatement = new BlockStatement();
Statement code = catchStatement.getCode();
addStatementToNewQuery(code, newCatchStatement, addAll, propertyNames, variableScope);
catchStatement.setCode(flattenStatementIfNecessary(newCatchStatement));
}
Statement finallyStatement = tcs.getFinallyStatement();
if (finallyStatement != null) {
BlockStatement newFinallyStatement = new BlockStatement();
addStatementToNewQuery(finallyStatement, newFinallyStatement, addAll, propertyNames, variableScope);
tcs.setFinallyStatement(flattenStatementIfNecessary(newFinallyStatement));
}
newCode.addStatement(tcs);
} else if (statement instanceof ReturnStatement) {
ReturnStatement rs = (ReturnStatement) statement;
addStatementToNewQuery(new ExpressionStatement(rs.getExpression()), newCode, addAll, propertyNames,variableScope);
}
else {
newCode.addStatement(statement);
}
}
}