All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.persistence.jpa.jpql.tools.model.BasicStateObjectBuilder Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation
//
package org.eclipse.persistence.jpa.jpql.tools.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.persistence.jpa.jpql.LiteralType;
import org.eclipse.persistence.jpa.jpql.LiteralVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbsExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSchemaName;
import org.eclipse.persistence.jpa.jpql.parser.AbstractTraverseChildrenVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AdditionExpression;
import org.eclipse.persistence.jpa.jpql.parser.AllOrAnyExpression;
import org.eclipse.persistence.jpa.jpql.parser.AndExpression;
import org.eclipse.persistence.jpa.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ArithmeticFactor;
import org.eclipse.persistence.jpa.jpql.parser.AvgFunction;
import org.eclipse.persistence.jpa.jpql.parser.BadExpression;
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EmptyCollectionComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.EntityTypeLiteral;
import org.eclipse.persistence.jpa.jpql.parser.EntryExpression;
import org.eclipse.persistence.jpa.jpql.parser.ExistsExpression;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
import org.eclipse.persistence.jpa.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.GroupByClause;
import org.eclipse.persistence.jpa.jpql.parser.HavingClause;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.InExpression;
import org.eclipse.persistence.jpa.jpql.parser.IndexExpression;
import org.eclipse.persistence.jpa.jpql.parser.InputParameter;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
import org.eclipse.persistence.jpa.jpql.parser.KeywordExpression;
import org.eclipse.persistence.jpa.jpql.parser.LengthExpression;
import org.eclipse.persistence.jpa.jpql.parser.LikeExpression;
import org.eclipse.persistence.jpa.jpql.parser.LocateExpression;
import org.eclipse.persistence.jpa.jpql.parser.LowerExpression;
import org.eclipse.persistence.jpa.jpql.parser.MaxFunction;
import org.eclipse.persistence.jpa.jpql.parser.MinFunction;
import org.eclipse.persistence.jpa.jpql.parser.ModExpression;
import org.eclipse.persistence.jpa.jpql.parser.MultiplicationExpression;
import org.eclipse.persistence.jpa.jpql.parser.NotExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.jpql.parser.NullIfExpression;
import org.eclipse.persistence.jpa.jpql.parser.NumericLiteral;
import org.eclipse.persistence.jpa.jpql.parser.ObjectExpression;
import org.eclipse.persistence.jpa.jpql.parser.OnClause;
import org.eclipse.persistence.jpa.jpql.parser.OrExpression;
import org.eclipse.persistence.jpa.jpql.parser.OrderByClause;
import org.eclipse.persistence.jpa.jpql.parser.OrderByItem;
import org.eclipse.persistence.jpa.jpql.parser.RangeVariableDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.ResultVariable;
import org.eclipse.persistence.jpa.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.StringLiteral;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubstringExpression;
import org.eclipse.persistence.jpa.jpql.parser.SubtractionExpression;
import org.eclipse.persistence.jpa.jpql.parser.SumFunction;
import org.eclipse.persistence.jpa.jpql.parser.TreatExpression;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
import org.eclipse.persistence.jpa.jpql.parser.UpperExpression;
import org.eclipse.persistence.jpa.jpql.parser.ValueExpression;
import org.eclipse.persistence.jpa.jpql.parser.WhenClause;
import org.eclipse.persistence.jpa.jpql.parser.WhereClause;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbsExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractFromClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractIdentificationVariableDeclarationStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractRangeVariableDeclarationStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractSchemaNameStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractSelectStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractStateObjectVisitor;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AdditionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AllOrAnyExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AndExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ArithmeticFactorStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AvgFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.BadExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.BetweenExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CaseExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CoalesceExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionMemberDeclarationStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionMemberExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionValuedPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConstructorExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CountFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DateTimeStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DeleteStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DerivedPathIdentificationVariableDeclarationStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DivisionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EmptyCollectionComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EntityTypeLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EntryExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ExistsExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.FromClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.FunctionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.GroupByClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.HavingClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IdentificationVariableDeclarationStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IdentificationVariableStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.InExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IndexExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.InputParameterStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.JPQLQueryStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.JoinStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.KeyExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.KeywordExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LengthExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LikeExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LocateExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.LowerExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.MaxFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.MinFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ModExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.MultiplicationExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NotExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NullComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NullIfExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.NumericLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ObjectExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.OrExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.OrderByClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.OrderByItemStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ResultVariableStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SelectClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SelectStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SimpleFromClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SimpleSelectClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SimpleSelectStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SizeExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SqrtExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateFieldPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StateObjectVisitor;
import org.eclipse.persistence.jpa.jpql.tools.model.query.StringLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubstringExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SubtractionExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.SumFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.TreatExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.TrimExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.TypeExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UnknownExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UpdateClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UpdateItemStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UpdateStatementStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.UpperExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ValueExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.WhenClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.WhereClauseStateObject;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedTypeProvider;
import org.eclipse.persistence.jpa.jpql.utility.CollectionTools;

/**
 * The default implementation of a {@link IBuilder}, which creates a {@link StateObject}
 * representation of the {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression} being
 * visited.
 * 

* Provisional API: This interface is part of an interim API that is still under development and * expected to change significantly before reaching stability. It is available at this early stage * to solicit feedback from pioneering adopters on the understanding that any code that uses this * API will almost certainly be broken (repeatedly) as the API evolves. * * @see Expression * @see StateObject * * @version 2.5 * @since 2.4 * @author Pascal Filion */ @SuppressWarnings("nls") public abstract class BasicStateObjectBuilder extends AbstractExpressionVisitor { /** * */ private IBuilder collectionDeclarationBuilder; /** * */ private CollectionExpressionVisitor collectionExpressionVisitor; /** * */ private IBuilder deleteStatementBuilder; /** * This {@link IBuilder} is responsible to build an DELETE statement, * which populates the DELETE clause and the optional WHERE * clause by converting the information contained in the parsed JPQL query. */ private IBuilder joinBuilder; /** * */ IJPQLQueryBuilder jpqlQueryBuilder; /** * This visitor is used to retrieve a variable name from various type of an {@link Expression}. */ private LiteralVisitor literalVisitor; /** * */ protected IManagedTypeProvider managedTypeProvider; /** * The parent {@link StateObject} of the {@link StateObject} to create. */ protected JPQLQueryStateObject parent; /** * */ private IBuilder rangeDeclarationBuilder; /** * */ private IBuilder selectItemBuilder; /** * This {@link IBuilder} is responsible to build a top-level SELECT statement, * which populates the various clauses by converting the information contained in the parsed JPQL * query. */ private IBuilder selectStatementBuilder; /** * */ private IBuilder simpleRangeDeclarationBuilder; /** * This {@link IBuilder} is responsible to build a subquery SELECT statement, * which populates the various clauses by converting the information contained in the parsed JPQL * query. */ private IBuilder simpleSelectStatementBuilder; /** * The {@link StateObject} that was created based on the visited {@link Expression}. */ protected StateObject stateObject; /** * This {@link IBuilder} is responsible to build an UPDATE statement, * which populates the UPDATE clause and the optional WHERE * clause by converting the information contained in the parsed JPQL query. */ private IBuilder updateStatementBuilder; /** * This {@link IBuilder} is responsible to build a WHEN clause for the * CASE expression by converting the information contained in the parsed * JPQL query. */ private IBuilder whenClauseBuilder; /** * Creates a new StateObjectBuilder. */ protected BasicStateObjectBuilder() { super(); } @SuppressWarnings("unchecked") protected List buildChildren(Expression expression) { StateObject oldStateObject = stateObject; List stateObjects = new ArrayList(); for (Expression child : children(expression)) { child.accept(this); stateObjects.add((T) stateObject); stateObject = oldStateObject; } return stateObjects; } protected IBuilder buildCollectionDeclarationBuilder() { return new CollectionMemberDeclarationBuilder(); } protected IBuilder buildDeleteStatementBuilder() { return new DeleteStatementBuilder(); } protected IBuilder buildJoinBuilder() { return new JoinBuilder(); } /** * Creates the visitor that can retrieve the "literal" value from a given {@link Expression} * based on the desired {@link LiteralType}. * * @return A new concrete instance of {@link LiteralVisitor} */ protected abstract LiteralVisitor buildLiteralVisitor(); protected IBuilder buildRangeDeclarationBuilder() { return new RangeDeclarationBuilder(); } protected IBuilder buildSelectItemBuilder() { return new SelectItemBuilder(); } protected IBuilder buildSelectStatementBuilder() { return new SelectStatementBuilder(); } protected IBuilder buildSimpleRangeDeclarationBuilder() { return new SimpleRangeDeclarationBuilder(); } protected IBuilder buildSimpleSelectStatementBuilder() { return new SimpleSelectStatementBuilder(); } /** * Visits the given {@link Expression} and returned its {@link StateObject}. * * @param expression The {@link Expression} to be visited by this builder * @return The {@link StateObject} representation of the given {@link Expression} or null * if nothing could be created */ protected final StateObject buildStateObjectImp(Expression expression) { expression.accept(this); return stateObject; } protected IBuilder buildUpdateStatementBuilder() { return new UpdateStatementBuilder(); } protected IBuilder buildWhenClauseBuilder() { return new WhenClauseBuilder(); } @SuppressWarnings("unchecked") protected List children(Expression expression) { CollectionExpressionVisitor visitor = getCollectionExpressionVisitor(); try { expression.accept(visitor); return (List) visitor.children; } finally { visitor.reset(); } } protected IBuilder getCollectionDeclarationBuilder() { if (collectionDeclarationBuilder == null) { collectionDeclarationBuilder = buildCollectionDeclarationBuilder(); } return collectionDeclarationBuilder; } protected CollectionExpressionVisitor getCollectionExpressionVisitor() { if (collectionExpressionVisitor == null) { collectionExpressionVisitor = new CollectionExpressionVisitor(); } return collectionExpressionVisitor; } protected IBuilder getDeleteStatementBuilder() { if (deleteStatementBuilder == null) { deleteStatementBuilder = buildDeleteStatementBuilder(); } return deleteStatementBuilder; } protected IBuilder getJoinBuilder() { if (joinBuilder == null) { joinBuilder = buildJoinBuilder(); } return joinBuilder; } protected LiteralVisitor getLiteralVisitor() { if (literalVisitor == null) { literalVisitor = buildLiteralVisitor(); } return literalVisitor; } protected IBuilder getRangeDeclarationBuilder() { if (rangeDeclarationBuilder == null) { rangeDeclarationBuilder = buildRangeDeclarationBuilder(); } return rangeDeclarationBuilder; } protected IBuilder getSelectItemBuilder() { if (selectItemBuilder == null) { selectItemBuilder = buildSelectItemBuilder(); } return selectItemBuilder; } protected IBuilder getSelectStatementBuilder() { if (selectStatementBuilder == null) { selectStatementBuilder = buildSelectStatementBuilder(); } return selectStatementBuilder; } protected IBuilder getSimpleRangeDeclarationBuilder() { if (simpleRangeDeclarationBuilder == null) { simpleRangeDeclarationBuilder = buildSimpleRangeDeclarationBuilder(); } return simpleRangeDeclarationBuilder; } protected IBuilder getSimpleSelectStatementBuilder() { if (simpleSelectStatementBuilder == null) { simpleSelectStatementBuilder = buildSimpleSelectStatementBuilder(); } return simpleSelectStatementBuilder; } /** * Returns the {@link StateObject} that was created based on the visited {@link Expression}. * * @return The {@link StateObject} that was created based on the visited {@link Expression} */ public StateObject getStateObject() { return stateObject; } protected IBuilder getUpdateStatementBuilder() { if (updateStatementBuilder == null) { updateStatementBuilder = buildUpdateStatementBuilder(); } return updateStatementBuilder; } /** * Retrieves the "literal" from the given {@link Expression}. The literal to retrieve depends on * the given {@link LiteralType type}. The literal is basically a string value like an * identification variable name, an input parameter, a path expression, an abstract schema name, * etc. * * @param expression The {@link Expression} to visit * @param type The {@link LiteralType} helps to determine what to retrieve from the visited * {@link Expression} * @return A value from the given {@link Expression} or an empty string if the given {@link * Expression} and the {@link LiteralType} do not match */ protected String literal(Expression expression, LiteralType type) { LiteralVisitor visitor = getLiteralVisitor(); try { visitor.setType(type); visitor.literal = null; expression.accept(visitor); return visitor.literal; } finally { visitor.literal = null; } } /** * {@inheritDoc} */ @Override public void visit(AbsExpression expression) { expression.getExpression().accept(this); AbsExpressionStateObject stateObject = new AbsExpressionStateObject(parent, this.stateObject); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(AbstractSchemaName expression) { AbstractSchemaNameStateObject stateObject = new AbstractSchemaNameStateObject( parent, expression.getText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(AdditionExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; AdditionExpressionStateObject stateObject = new AdditionExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(AllOrAnyExpression expression) { expression.getExpression().accept(this); AllOrAnyExpressionStateObject stateObject = new AllOrAnyExpressionStateObject( parent, expression.getIdentifier(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(AndExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; AndExpressionStateObject stateObject = new AndExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ArithmeticFactor expression) { expression.getExpression().accept(this); ArithmeticFactorStateObject stateObject = new ArithmeticFactorStateObject( parent, expression.isPositive(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(AvgFunction expression) { expression.getExpression().accept(this); AvgFunctionStateObject stateObject = new AvgFunctionStateObject( parent, expression.hasDistinct(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(BadExpression expression) { BadExpressionStateObject stateObject = new BadExpressionStateObject( parent, expression.getExpression().toActualText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(BetweenExpression expression) { expression.getExpression().accept(this); StateObject betweenStateObject = stateObject; expression.getLowerBoundExpression().accept(this); StateObject lowerBoundStateObject = stateObject; expression.getUpperBoundExpression().accept(this); StateObject upperBoundStateObject = stateObject; BetweenExpressionStateObject stateObject = new BetweenExpressionStateObject( parent, betweenStateObject, expression.hasNot(), lowerBoundStateObject, upperBoundStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(CaseExpression expression) { expression.getCaseOperand().accept(this); StateObject caseOperand = stateObject; expression.getElseExpression().accept(this); StateObject elseStateObject = stateObject; CaseExpressionStateObject caseExpressionStateObject = new CaseExpressionStateObject( parent, caseOperand, Collections.emptyList(), elseStateObject ); whenClauseBuilder().buildStateObject(caseExpressionStateObject, expression); caseExpressionStateObject.setExpression(expression); this.stateObject = caseExpressionStateObject; } /** * {@inheritDoc} */ @Override public void visit(CoalesceExpression expression) { CoalesceExpressionStateObject stateObject = new CoalesceExpressionStateObject( parent, buildChildren(expression.getExpression()) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(CollectionExpression expression) { List stateObjects = buildChildren(expression); CollectionExpressionStateObject stateObject = new CollectionExpressionStateObject( parent, stateObjects ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(CollectionMemberDeclaration expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(CollectionMemberExpression expression) { expression.getEntityExpression().accept(this); StateObject entityExpression = stateObject; CollectionMemberExpressionStateObject stateObject = new CollectionMemberExpressionStateObject( parent, entityExpression, expression.hasNot(), expression.hasOf(), literal(expression.getCollectionValuedPathExpression(), LiteralType.PATH_EXPRESSION_ALL_PATH) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(CollectionValuedPathExpression expression) { CollectionValuedPathExpressionStateObject stateObject = new CollectionValuedPathExpressionStateObject( parent, expression.toActualText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ComparisonExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; ComparisonExpressionStateObject stateObject = new ComparisonExpressionStateObject( parent, leftStateObject, expression.getComparisonOperator(), rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ConcatExpression expression) { ConcatExpressionStateObject stateObject = new ConcatExpressionStateObject( parent, buildChildren(expression.getExpression()) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ConstructorExpression expression) { ConstructorExpressionStateObject stateObject = new ConstructorExpressionStateObject( parent, expression.getClassName(), buildChildren(expression.getConstructorItems()) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(CountFunction expression) { expression.getExpression().accept(this); CountFunctionStateObject stateObject = new CountFunctionStateObject( parent, expression.hasDistinct(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(DateTime expression) { DateTimeStateObject stateObject = new DateTimeStateObject(parent, expression.getText()); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(DeleteClause expression) { // Done via DeleteStatementBuilder stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(DeleteStatement expression) { stateObject = getDeleteStatementBuilder().buildStateObject(parent, expression); } /** * {@inheritDoc} */ @Override public void visit(DivisionExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; DivisionExpressionStateObject stateObject = new DivisionExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(EmptyCollectionComparisonExpression expression) { EmptyCollectionComparisonExpressionStateObject stateObject = new EmptyCollectionComparisonExpressionStateObject( parent, expression.hasNot(), literal(expression.getExpression(), LiteralType.PATH_EXPRESSION_ALL_PATH) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(EntityTypeLiteral expression) { EntityTypeLiteralStateObject stateObject = new EntityTypeLiteralStateObject( parent, expression.getEntityTypeName() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(EntryExpression expression) { EntryExpressionStateObject stateObject = new EntryExpressionStateObject( parent, literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ExistsExpression expression) { expression.getExpression().accept(this); ExistsExpressionStateObject stateObject = new ExistsExpressionStateObject( parent, expression.hasNot(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(FromClause expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(FunctionExpression expression) { FunctionExpressionStateObject stateObject = new FunctionExpressionStateObject( parent, expression.getIdentifier(), expression.getUnquotedFunctionName(), buildChildren(expression.getExpression()) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(GroupByClause expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(HavingClause expression) { expression.getConditionalExpression().accept(this); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariable expression) { IdentificationVariableStateObject stateObject = new IdentificationVariableStateObject( parent, expression.getText() ); stateObject.setVirtual(expression.isVirtual()); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(final IdentificationVariableDeclaration expression) { StateObjectVisitor visitor = new AbstractStateObjectVisitor() { @Override public void visit(FromClauseStateObject stateObject) { getRangeDeclarationBuilder().buildStateObject(stateObject, expression); } @Override public void visit(SimpleFromClauseStateObject stateObject) { getSimpleRangeDeclarationBuilder().buildStateObject(stateObject, expression); } }; stateObject.accept(visitor); } /** * {@inheritDoc} */ @Override public void visit(IndexExpression expression) { IndexExpressionStateObject stateObject = new IndexExpressionStateObject( parent, literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(InExpression expression) { expression.getExpression().accept(this); InExpressionStateObject stateObject = new InExpressionStateObject( parent, this.stateObject, expression.hasNot(), buildChildren(expression.getInItems()) ); stateObject.setSingleInputParameter(expression.isSingleInputParameter()); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(InputParameter expression) { InputParameterStateObject stateObject = new InputParameterStateObject( parent, expression.getParameter() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(Join expression) { stateObject = getJoinBuilder().buildStateObject( (IdentificationVariableDeclarationStateObject) stateObject, expression ); } /** * {@inheritDoc} */ @Override public void visit(JPQLExpression expression) { parent = new JPQLQueryStateObject(jpqlQueryBuilder, managedTypeProvider); parent.setExpression(expression); expression.getQueryStatement().accept(this); parent.setQueryStatement(stateObject); } /** * {@inheritDoc} */ @Override public void visit(KeyExpression expression) { KeyExpressionStateObject stateObject = new KeyExpressionStateObject( parent, literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(KeywordExpression expression) { KeywordExpressionStateObject stateObject = new KeywordExpressionStateObject( parent, expression.getText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(LengthExpression expression) { expression.getExpression().accept(this); LengthExpressionStateObject stateObject = new LengthExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(LikeExpression expression) { expression.getStringExpression().accept(this); StateObject stringStateObject = stateObject; expression.getPatternValue().accept(this); StateObject patternValue = stateObject; LikeExpressionStateObject stateObject = new LikeExpressionStateObject( parent, stringStateObject, expression.hasNot(), patternValue, literal(expression.getEscapeCharacter(), LiteralType.STRING_LITERAL) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(LocateExpression expression) { expression.getFirstExpression().accept(this); StateObject firstStateObject = stateObject; expression.getSecondExpression().accept(this); StateObject secondStateObject = stateObject; expression.getThirdExpression().accept(this); StateObject thirdStateObject = stateObject; LocateExpressionStateObject stateObject = new LocateExpressionStateObject( parent, firstStateObject, secondStateObject, thirdStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(LowerExpression expression) { expression.getExpression().accept(this); LowerExpressionStateObject stateObject = new LowerExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(MaxFunction expression) { expression.getExpression().accept(this); MaxFunctionStateObject stateObject = new MaxFunctionStateObject( parent, expression.hasDistinct(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(MinFunction expression) { expression.getExpression().accept(this); MinFunctionStateObject stateObject = new MinFunctionStateObject( parent, expression.hasDistinct(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ModExpression expression) { expression.getFirstExpression().accept(this); StateObject firstStateObject = stateObject; expression.getSecondExpression().accept(this); StateObject secondStateObject = stateObject; ModExpressionStateObject stateObject = new ModExpressionStateObject( parent, firstStateObject, secondStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(MultiplicationExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; MultiplicationExpressionStateObject stateObject = new MultiplicationExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(NotExpression expression) { expression.getExpression().accept(this); NotExpressionStateObject stateObject = new NotExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(NullComparisonExpression expression) { expression.getExpression().accept(this); NullComparisonExpressionStateObject stateObject = new NullComparisonExpressionStateObject( parent, expression.hasNot(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(NullExpression expression) { stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(NullIfExpression expression) { expression.getFirstExpression().accept(this); StateObject firstStateObject = stateObject; expression.getSecondExpression().accept(this); StateObject secondStateObject = stateObject; NullIfExpressionStateObject stateObject = new NullIfExpressionStateObject( parent, firstStateObject, secondStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(NumericLiteral expression) { NumericLiteralStateObject stateObject = new NumericLiteralStateObject( parent, expression.getText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ObjectExpression expression) { ObjectExpressionStateObject stateObject = new ObjectExpressionStateObject( parent, literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(OnClause expression) { expression.getConditionalExpression().accept(this); } /** * {@inheritDoc} */ @Override public final void visit(OrderByClause expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public final void visit(OrderByItem expression) { OrderByClauseStateObject orderByClause = (OrderByClauseStateObject) stateObject; OrderByItemStateObject orderByItem = orderByClause.addItem(expression.getOrdering()); orderByItem.setExpression(expression); expression.getExpression().accept(this); orderByItem.setStateObject(stateObject); } /** * {@inheritDoc} */ @Override public void visit(OrExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; OrExpressionStateObject stateObject = new OrExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(RangeVariableDeclaration expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public final void visit(final ResultVariable expression) { StateObjectVisitor visitor = new AbstractStateObjectVisitor() { @Override public void visit(SelectClauseStateObject stateObject) { BasicStateObjectBuilder.this.stateObject = getSelectItemBuilder().buildStateObject( stateObject, expression ); } }; stateObject.accept(visitor); } /** * {@inheritDoc} */ @Override public final void visit(SelectClause expression) { // Not done here stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(SelectStatement expression) { stateObject = getSelectStatementBuilder().buildStateObject(parent, expression); } /** * {@inheritDoc} */ @Override public final void visit(SimpleFromClause expression) { // Done via SimpleSelectStatementBuilder stateObject = null; } /** * {@inheritDoc} */ @Override public final void visit(SimpleSelectClause expression) { // Done via SimpleSelectStatementBuilder stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(SimpleSelectStatement expression) { stateObject = getSimpleSelectStatementBuilder().buildStateObject(parent, expression); } /** * {@inheritDoc} */ @Override public void visit(SizeExpression expression) { expression.getExpression().accept(this); SizeExpressionStateObject stateObject = new SizeExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(SqrtExpression expression) { expression.getExpression().accept(this); SqrtExpressionStateObject stateObject = new SqrtExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(StateFieldPathExpression expression) { StateFieldPathExpressionStateObject stateObject = new StateFieldPathExpressionStateObject( parent, expression.toActualText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(StringLiteral expression) { StringLiteralStateObject stateObject = new StringLiteralStateObject( parent, expression.getText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(SubExpression expression) { expression.getExpression().accept(this); SubExpressionStateObject stateObject = new SubExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(SubstringExpression expression) { expression.getFirstExpression().accept(this); StateObject firstExpression = stateObject; expression.getSecondExpression().accept(this); StateObject secondExpression = stateObject; expression.getThirdExpression().accept(this); StateObject thirdExpression = stateObject; SubstringExpressionStateObject stateObject = new SubstringExpressionStateObject( parent, firstExpression, secondExpression, thirdExpression ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(SubtractionExpression expression) { expression.getLeftExpression().accept(this); StateObject leftStateObject = stateObject; expression.getRightExpression().accept(this); StateObject rightStateObject = stateObject; SubtractionExpressionStateObject stateObject = new SubtractionExpressionStateObject( parent, leftStateObject, rightStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(SumFunction expression) { expression.getExpression().accept(this); SumFunctionStateObject stateObject = new SumFunctionStateObject( parent, expression.hasDistinct(), this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(TreatExpression expression) { // Done by JoinBuilder } /** * {@inheritDoc} */ @Override public void visit(TrimExpression expression) { expression.getExpression().accept(this); StateObject trimStateObject = stateObject; expression.getTrimCharacter().accept(this); StateObject trimCharacter = stateObject; TrimExpressionStateObject stateObject = new TrimExpressionStateObject( parent, expression.getSpecification(), trimCharacter, trimStateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(TypeExpression expression) { expression.getExpression().accept(this); TypeExpressionStateObject stateObject = new TypeExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(UnknownExpression expression) { UnknownExpressionStateObject stateObject = new UnknownExpressionStateObject( parent, expression.getText() ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(UpdateClause expression) { // Done via UpdateStatementBuilder } /** * {@inheritDoc} */ @Override public final void visit(UpdateItem expression) { // Done via UpdateStatementBuilder } /** * {@inheritDoc} */ @Override public void visit(UpdateStatement expression) { stateObject = getUpdateStatementBuilder().buildStateObject(parent, expression); } /** * {@inheritDoc} */ @Override public void visit(UpperExpression expression) { expression.getExpression().accept(this); UpperExpressionStateObject stateObject = new UpperExpressionStateObject( parent, this.stateObject ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public void visit(ValueExpression expression) { ValueExpressionStateObject stateObject = new ValueExpressionStateObject( parent, literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } /** * {@inheritDoc} */ @Override public final void visit(WhenClause expression) { // Done throw WhenClauseBuilder stateObject = null; } /** * {@inheritDoc} */ @Override public void visit(WhereClause expression) { expression.getConditionalExpression().accept(this); } /** * Returns the {@link IBuilder} that is responsible to visit each {@link WhenClause} and to * create the corresponding {@link WhenClauseStateObject}. The new state objects have to be added * to {@link CaseExpressionStateObject} by the builder. * * @return The builder of the WHEN clauses */ protected IBuilder whenClauseBuilder() { if (whenClauseBuilder == null) { whenClauseBuilder = buildWhenClauseBuilder(); } return whenClauseBuilder; } /** * This builder is responsible to create a new identification variable declaration and to add it * to the state object representing the FROM clause. */ protected abstract class AbstractRangeDeclarationBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { /** * The concrete instance of {@link AbstractFromClauseStateObject} where the new identification * variable declaration is added. */ protected S parent; /** * The concrete instance of {@link IdentificationVariableDeclarationStateObject} * that represents the visited {@link IdentificationVariableDeclaration}. */ protected AbstractIdentificationVariableDeclarationStateObject stateObject; /** * Creates the concrete instance of an {@link AbstractIdentificationVariableDeclarationStateObject} * for the given {@link IdentificationVariableDeclaration}. * * @param expression The {@link IdentificationVariableDeclaration} to convert into a * {@link StateObject} * @return A new {@link StateObject} representing an identification variable declaration */ protected abstract AbstractIdentificationVariableDeclarationStateObject addRangeDeclaration(IdentificationVariableDeclaration expression); /** * {@inheritDoc} */ @Override public AbstractIdentificationVariableDeclarationStateObject buildStateObject(S parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; this.stateObject = null; } } /** * {@inheritDoc} */ @Override public void visit(AbstractSchemaName expression) { stateObject.setRootPath(expression.getText()); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariable expression) { stateObject.setIdentificationVariable(expression.getText()); IdentificationVariableStateObject variable = stateObject.getRangeVariableDeclaration().getIdentificationVariableStateObject(); variable.setVirtual(expression.isVirtual()); variable.setExpression(expression); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariableDeclaration expression) { stateObject = addRangeDeclaration(expression); stateObject.setExpression(expression); getJoinBuilder().buildStateObject(stateObject, expression.getJoins()); expression.getRangeVariableDeclaration().accept(this); } /** * {@inheritDoc} */ @Override public void visit(RangeVariableDeclaration expression) { AbstractRangeVariableDeclarationStateObject declaration = stateObject.getRangeVariableDeclaration(); declaration.setAs(expression.hasAs()); declaration.setExpression(expression); super.visit(expression); } } /** * The abstract definition of the builder that is responsible to create the {@link StateObject} * representation of the SELECT statement. */ protected abstract class AbstractSelectStatementBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { /** * The parent of the SELECT statement. */ protected P parent; /** * The concrete class of {@link AbstractSelectStatementStateObject}. */ protected T stateObject; /** * {@inheritDoc} */ @Override public T buildStateObject(P parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; } } /** * {@inheritDoc} */ @Override public void visit(CollectionMemberDeclaration expression) { getCollectionDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); } /** * {@inheritDoc} */ @Override public void visit(GroupByClause expression) { GroupByClauseStateObject groupByClause = stateObject.addGroupByClause(); groupByClause.setExpression(expression); groupByClause.addItems(buildChildren(expression.getGroupByItems())); } /** * {@inheritDoc} */ @Override public void visit(HavingClause expression) { HavingClauseStateObject havingClause = stateObject.addHavingClause(); havingClause.setConditional(buildStateObjectImp(expression)); havingClause.setExpression(expression); } /** * {@inheritDoc} */ @Override public abstract void visit(IdentificationVariableDeclaration expression); /** * {@inheritDoc} */ @Override public void visit(WhereClause expression) { WhereClauseStateObject whereClause = stateObject.addWhereClause(); whereClause.setConditional(buildStateObjectImp(expression)); whereClause.setExpression(expression); } } protected static class CollectionExpressionVisitor extends AnonymousExpressionVisitor { List children; CollectionExpressionVisitor() { super(); reset(); } void reset() { children = new ArrayList(); } /** * {@inheritDoc} */ @Override public void visit(CollectionExpression expression) { CollectionTools.addAll(children, expression.children()); } /** * {@inheritDoc} */ @Override protected void visit(Expression expression) { children.add(expression); } } protected static class CollectionMemberDeclarationBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { protected AbstractFromClauseStateObject parent; protected CollectionMemberDeclarationStateObject stateObject; /** * {@inheritDoc} */ @Override public CollectionMemberDeclarationStateObject buildStateObject(AbstractFromClauseStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; this.stateObject = null; } } /** * {@inheritDoc} */ @Override public void visit(CollectionMemberDeclaration expression) { stateObject = parent.addCollectionDeclaration(); stateObject.setAs(expression.hasAs()); stateObject.setExpression(expression); stateObject.setDerived(expression.isDerived()); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(CollectionValuedPathExpression expression) { CollectionValuedPathExpressionStateObject path = stateObject.getCollectionValuedPath(); path.setPaths(expression.paths().iterator()); path.setExpression(expression); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariable expression) { IdentificationVariableStateObject variable = stateObject.getIdentificationVariable(); variable.setExpression(expression); variable.setText(expression.getText()); variable.setVirtual(expression.isVirtual()); } } /** * This builder is responsible to create the {@link StateObject} representation of the * DELETE query statement. */ protected class DeleteStatementBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { protected JPQLQueryStateObject parent; protected DeleteStatementStateObject stateObject; /** * {@inheritDoc} */ @Override public DeleteStatementStateObject buildStateObject(JPQLQueryStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; } } /** * {@inheritDoc} */ @Override public void visit(AbstractSchemaName expression) { AbstractSchemaNameStateObject entityStateObject = stateObject.getAbstractSchemaNameStateObject(); entityStateObject.setText(expression.getText()); entityStateObject.setExpression(expression); } /** * {@inheritDoc} */ @Override public void visit(DeleteClause expression) { stateObject.getModifyClause().setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(DeleteStatement expression) { stateObject = parent.addDeleteStatement(); stateObject.setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariable expression) { IdentificationVariableStateObject variable = stateObject.getIdentificationVariableStateObject(); variable.setExpression(expression); variable.setText(expression.getText()); variable.setVirtual(expression.isVirtual()); } /** * {@inheritDoc} */ @Override public void visit(RangeVariableDeclaration expression) { stateObject.getModifyClause().getRangeVariableDeclaration().setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(WhereClause expression) { WhereClauseStateObject whereClause = stateObject.addWhereClause(); whereClause.setExpression(expression); expression.getConditionalExpression().accept(BasicStateObjectBuilder.this); StateObject conditionalStateObject = BasicStateObjectBuilder.this.stateObject; whereClause.setConditional(conditionalStateObject); } } protected class JoinBuilder extends AbstractExpressionVisitor implements IBuilder { protected AbstractIdentificationVariableDeclarationStateObject parent; protected JoinStateObject stateObject; /** * {@inheritDoc} */ @Override public JoinStateObject buildStateObject(AbstractIdentificationVariableDeclarationStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; this.stateObject = null; } } /** * {@inheritDoc} */ @Override public void visit(CollectionExpression expression) { expression.acceptChildren(this); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariableDeclaration expression) { expression.getRangeVariableDeclaration().accept(this); expression.getJoins().accept(this); } /** * {@inheritDoc} */ @Override public void visit(Join expression) { stateObject = parent.addJoin( expression.getIdentifier(), literal(expression.getJoinAssociationPath(), LiteralType.PATH_EXPRESSION_ALL_PATH), literal(expression.getIdentificationVariable(), LiteralType.IDENTIFICATION_VARIABLE) ); stateObject.setAs(expression.hasAs()); stateObject.setExpression(expression); expression.getJoinAssociationPath().accept(this); expression.getIdentificationVariable().accept(this); } /** * {@inheritDoc} */ @Override public void visit(TreatExpression expression) { TreatExpressionStateObject treatStateObject = new TreatExpressionStateObject( stateObject, expression.hasAs(), literal(expression.getEntityType(), LiteralType.ENTITY_TYPE) ); treatStateObject.setExpression(expression); stateObject.getJoinAssociationPathStateObject().decorate(treatStateObject); expression.getCollectionValuedPathExpression().accept(this); } } /** * This builder is responsible to create a new identification variable declaration and to add it * to the state object representing the FROM clause of the top-level query. */ protected class RangeDeclarationBuilder extends AbstractRangeDeclarationBuilder { /** * {@inheritDoc} */ @Override protected AbstractIdentificationVariableDeclarationStateObject addRangeDeclaration(IdentificationVariableDeclaration expression) { return parent.addRangeDeclaration(); } /** * {@inheritDoc} */ @Override public void visit(AbstractSchemaName expression) { super.visit(expression); IdentificationVariableDeclarationStateObject stateObject = (IdentificationVariableDeclarationStateObject) this.stateObject; stateObject.getRootStateObject().setExpression(expression); } } /** * This builder is responsible to create the items owned by the top-level * SELECT clause. */ protected class SelectItemBuilder extends AnonymousExpressionVisitor implements IBuilder { protected SelectClauseStateObject parent; protected StateObject stateObject; /** * {@inheritDoc} */ @Override public StateObject buildStateObject(SelectClauseStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return this.stateObject; } finally { this.parent = null; this.stateObject = null; } } /** * {@inheritDoc} */ @Override protected void visit(Expression expression) { expression.accept(BasicStateObjectBuilder.this); stateObject = BasicStateObjectBuilder.this.stateObject; } /** * {@inheritDoc} */ @Override public void visit(ResultVariable expression) { expression.getSelectExpression().accept(BasicStateObjectBuilder.this); ResultVariableStateObject stateObject = new ResultVariableStateObject( parent, BasicStateObjectBuilder.this.stateObject, expression.hasAs(), literal(expression.getResultVariable(), LiteralType.RESULT_VARIABLE) ); stateObject.setExpression(expression); this.stateObject = stateObject; } } /** * This builder is responsible to create the {@link StateObject} representation of the * SELECT query statement. */ protected class SelectStatementBuilder extends AbstractSelectStatementBuilder { /** * {@inheritDoc} */ @Override public void visit(FromClause expression) { stateObject.getFromClause().setExpression(expression); for (Expression child : children(expression.getDeclaration())) { child.accept(this); } } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariableDeclaration expression) { getRangeDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); } /** * {@inheritDoc} */ @Override public void visit(OrderByClause expression) { OrderByClauseStateObject orderByClause = stateObject.addOrderByClause(); orderByClause.setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(OrderByItem expression) { OrderByClauseStateObject orderByClause = stateObject.getOrderByClause(); OrderByItemStateObject orderByItem = orderByClause.addItem(expression.getOrdering()); orderByItem.setExpression(expression); expression.getExpression().accept(BasicStateObjectBuilder.this); orderByItem.setStateObject(BasicStateObjectBuilder.this.stateObject); } /** * {@inheritDoc} */ @Override public void visit(SelectClause expression) { SelectClauseStateObject selectClause = stateObject.getSelectClause(); selectClause.setExpression(expression); selectClause.setDistinct(expression.hasDistinct()); for (Expression child : children(expression.getSelectExpression())) { StateObject stateObject = getSelectItemBuilder().buildStateObject(selectClause, child); if (stateObject != null) { selectClause.addItem(stateObject); } } } /** * {@inheritDoc} */ @Override public void visit(SelectStatement expression) { SelectStatementStateObject stateObject = parent.addSelectStatement(); stateObject.setExpression(expression); this.stateObject = stateObject; super.visit(expression); } } /** * This builder is responsible to create a new identification variable declaration and to add it * to the state object representing the FROM clause of a subquery. */ protected class SimpleRangeDeclarationBuilder extends AbstractRangeDeclarationBuilder { /** * {@inheritDoc} */ @Override protected AbstractIdentificationVariableDeclarationStateObject addRangeDeclaration(IdentificationVariableDeclaration expression) { String root = expression.getRangeVariableDeclaration().toActualText(); int index = root.indexOf(AbstractExpression.SPACE); if (index > 0) { root = root.substring(0, index); } if (root.indexOf(AbstractExpression.DOT) > 0) { return parent.addDerivedPathDeclaration(); } return parent.addRangeDeclaration(); } /** * {@inheritDoc} */ @Override public void visit(CollectionValuedPathExpression expression) { DerivedPathIdentificationVariableDeclarationStateObject stateObject = (DerivedPathIdentificationVariableDeclarationStateObject) this.stateObject; stateObject.setRootPath(expression.toActualText()); stateObject.getRootStateObject().setExpression(expression); } } /** * This builder is responsible to create the {@link StateObject} representation of the * SELECT subquery. */ protected class SimpleSelectStatementBuilder extends AbstractSelectStatementBuilder { /** * {@inheritDoc} */ @Override public void visit(IdentificationVariableDeclaration expression) { getSimpleRangeDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); } /** * {@inheritDoc} */ @Override public void visit(SimpleFromClause expression) { stateObject.getFromClause().setExpression(expression); for (Expression child : children(expression.getDeclaration())) { child.accept(this); } } /** * {@inheritDoc} */ @Override public void visit(SimpleSelectClause expression) { SimpleSelectClauseStateObject selectClause = stateObject.getSelectClause(); selectClause.setDistinct(expression.hasDistinct()); selectClause.setExpression(expression); List children = buildChildren(expression.getSelectExpression()); if (!children.isEmpty()) { selectClause.setSelectItem(children.get(0)); } } /** * {@inheritDoc} */ @Override public void visit(SimpleSelectStatement expression) { stateObject = new SimpleSelectStatementStateObject(parent); stateObject.setExpression(expression); stateObject.setParent(parent); super.visit(expression); } } /** * This builder is responsible to create the {@link StateObject} representation of the * UPDATE query statement. */ protected class UpdateStatementBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { protected JPQLQueryStateObject parent; protected UpdateStatementStateObject stateObject; protected UpdateItemStateObject updateItem; /** * {@inheritDoc} */ @Override public UpdateStatementStateObject buildStateObject(JPQLQueryStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return stateObject; } finally { this.parent = null; this.stateObject = null; } } /** * {@inheritDoc} */ @Override public void visit(AbstractSchemaName expression) { stateObject.setEntityName(expression.getText()); stateObject.getModifyClause().getAbstractSchemaNameStateObject().setExpression(expression); } /** * {@inheritDoc} */ @Override public void visit(IdentificationVariable expression) { if (updateItem == null) { IdentificationVariableStateObject variable = stateObject.getIdentificationVariableStateObject(); variable.setText(expression.getText()); variable.setVirtual(expression.isVirtual()); variable.setExpression(expression); } } /** * {@inheritDoc} */ @Override public void visit(RangeVariableDeclaration expression) { stateObject.getModifyClause().getRangeVariableDeclaration().setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(StateFieldPathExpression expression) { updateItem.getStateFieldPath().setPaths(expression.paths().iterator()); updateItem.getStateFieldPath().setExpression(expression); } /** * {@inheritDoc} */ @Override public void visit(UpdateClause expression) { stateObject.getModifyClause().setExpression(expression); super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(UpdateItem expression) { UpdateClauseStateObject updateClause = stateObject.getModifyClause(); String identificationVariable = updateClause.getIdentificationVariable(); updateItem = updateClause.addItem(); updateItem.setExpression(expression); try { // Retrieve the state field path expression String path = literal( expression.getStateFieldPathExpression(), LiteralType.PATH_EXPRESSION_ALL_PATH ); if (!path.startsWith(identificationVariable + ".")) { updateItem.setPath(identificationVariable + "." + path); } else { updateItem.setPath(path); } // Set the virtual identification variable if (!updateClause.isIdentificationVariableDefined()) { updateItem.setVirtualIdentificationVariable(updateClause.getIdentificationVariable()); } // Create the new value StateObject stateObject = buildStateObjectImp(expression.getNewValue()); updateItem.setNewValue(stateObject); } finally { updateItem = null; } } /** * {@inheritDoc} */ @Override public void visit(UpdateStatement expression) { UpdateStatementStateObject stateObject = parent.addUpdateStatement(); stateObject.setExpression(expression); this.stateObject = stateObject; super.visit(expression); } /** * {@inheritDoc} */ @Override public void visit(WhereClause expression) { WhereClauseStateObject whereClause = stateObject.addWhereClause(); whereClause.setExpression(expression); StateObject stateObject = buildStateObjectImp(expression.getConditionalExpression()); whereClause.setConditional(stateObject); } } /** * This builder is responsible to create the WHEN clauses for a * CASE expression. */ protected class WhenClauseBuilder extends AbstractTraverseChildrenVisitor implements IBuilder { /** * The {@link CaseExpressionStateObject} for which its {@link WhenClauseStateObject * WhenClauseStateObjects} are created by this builder. */ private CaseExpressionStateObject parent; /** * {@inheritDoc} */ @Override public CaseExpressionStateObject buildStateObject(CaseExpressionStateObject parent, Expression expression) { try { this.parent = parent; expression.accept(this); return parent; } finally { this.parent = null; } } /** * {@inheritDoc} */ @Override public void visit(WhenClause expression) { StateObject whenStateObject = buildStateObjectImp(expression.getWhenExpression()); StateObject thenStateObject = buildStateObjectImp(expression.getThenExpression()); WhenClauseStateObject stateObject = parent.addWhenClause(whenStateObject, thenStateObject); stateObject.setExpression(expression); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy