| /* |
| * Copyright (c) 2006, 2021 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. |
| * <p> |
| * 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<CollectionMemberDeclarationStateObject, AbstractFromClauseStateObject> collectionDeclarationBuilder; |
| |
| /** |
| * |
| */ |
| private CollectionExpressionVisitor collectionExpressionVisitor; |
| |
| /** |
| * |
| */ |
| private IBuilder<DeleteStatementStateObject, JPQLQueryStateObject> deleteStatementBuilder; |
| |
| /** |
| * This {@link IBuilder} is responsible to build an <code><b>DELETE</b></code> statement, |
| * which populates the <code><b>DELETE</b></code> clause and the optional <code><b>WHERE</b></code> |
| * clause by converting the information contained in the parsed JPQL query. |
| */ |
| private IBuilder<JoinStateObject, AbstractIdentificationVariableDeclarationStateObject> 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<AbstractIdentificationVariableDeclarationStateObject, FromClauseStateObject> rangeDeclarationBuilder; |
| |
| /** |
| * |
| */ |
| private IBuilder<StateObject, SelectClauseStateObject> selectItemBuilder; |
| |
| /** |
| * This {@link IBuilder} is responsible to build a top-level <code><b>SELECT</b></code> statement, |
| * which populates the various clauses by converting the information contained in the parsed JPQL |
| * query. |
| */ |
| private IBuilder<SelectStatementStateObject, JPQLQueryStateObject> selectStatementBuilder; |
| |
| /** |
| * |
| */ |
| private IBuilder<AbstractIdentificationVariableDeclarationStateObject, SimpleFromClauseStateObject> simpleRangeDeclarationBuilder; |
| |
| /** |
| * This {@link IBuilder} is responsible to build a subquery <code><b>SELECT</b></code> statement, |
| * which populates the various clauses by converting the information contained in the parsed JPQL |
| * query. |
| */ |
| private IBuilder<SimpleSelectStatementStateObject, StateObject> simpleSelectStatementBuilder; |
| |
| /** |
| * The {@link StateObject} that was created based on the visited {@link Expression}. |
| */ |
| protected StateObject stateObject; |
| |
| /** |
| * This {@link IBuilder} is responsible to build an <code><b>UPDATE</b></code> statement, |
| * which populates the <code><b>UPDATE</b></code> clause and the optional <code><b>WHERE</b></code> |
| * clause by converting the information contained in the parsed JPQL query. |
| */ |
| private IBuilder<UpdateStatementStateObject, JPQLQueryStateObject> updateStatementBuilder; |
| |
| /** |
| * This {@link IBuilder} is responsible to build a <code><b>WHEN</b></code> clause for the |
| * <code><b>CASE</b></code> expression by converting the information contained in the parsed |
| * JPQL query. |
| */ |
| private IBuilder<CaseExpressionStateObject, CaseExpressionStateObject> whenClauseBuilder; |
| |
| /** |
| * Creates a new <code>StateObjectBuilder</code>. |
| */ |
| protected BasicStateObjectBuilder() { |
| super(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected <T extends StateObject> List<T> buildChildren(Expression expression) { |
| |
| StateObject oldStateObject = stateObject; |
| List<T> stateObjects = new ArrayList<>(); |
| |
| for (Expression child : children(expression)) { |
| child.accept(this); |
| stateObjects.add((T) stateObject); |
| stateObject = oldStateObject; |
| } |
| |
| return stateObjects; |
| } |
| |
| protected IBuilder<CollectionMemberDeclarationStateObject, AbstractFromClauseStateObject> buildCollectionDeclarationBuilder() { |
| return new CollectionMemberDeclarationBuilder(); |
| } |
| |
| protected IBuilder<DeleteStatementStateObject, JPQLQueryStateObject> buildDeleteStatementBuilder() { |
| return new DeleteStatementBuilder(); |
| } |
| |
| protected IBuilder<JoinStateObject, AbstractIdentificationVariableDeclarationStateObject> 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<AbstractIdentificationVariableDeclarationStateObject, FromClauseStateObject> buildRangeDeclarationBuilder() { |
| return new RangeDeclarationBuilder(); |
| } |
| |
| protected IBuilder<StateObject, SelectClauseStateObject> buildSelectItemBuilder() { |
| return new SelectItemBuilder(); |
| } |
| |
| protected IBuilder<SelectStatementStateObject, JPQLQueryStateObject> buildSelectStatementBuilder() { |
| return new SelectStatementBuilder(); |
| } |
| |
| protected IBuilder<AbstractIdentificationVariableDeclarationStateObject, SimpleFromClauseStateObject> buildSimpleRangeDeclarationBuilder() { |
| return new SimpleRangeDeclarationBuilder(); |
| } |
| |
| protected IBuilder<SimpleSelectStatementStateObject, StateObject> 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 <code>null</code> |
| * if nothing could be created |
| */ |
| protected final StateObject buildStateObjectImp(Expression expression) { |
| expression.accept(this); |
| return stateObject; |
| } |
| |
| protected IBuilder<UpdateStatementStateObject, JPQLQueryStateObject> buildUpdateStatementBuilder() { |
| return new UpdateStatementBuilder(); |
| } |
| |
| protected IBuilder<CaseExpressionStateObject, CaseExpressionStateObject> buildWhenClauseBuilder() { |
| return new WhenClauseBuilder(); |
| } |
| |
| @SuppressWarnings("unchecked") |
| protected <T extends Expression> List<T> children(Expression expression) { |
| CollectionExpressionVisitor visitor = getCollectionExpressionVisitor(); |
| |
| try { |
| expression.accept(visitor); |
| return (List<T>) visitor.children; |
| } |
| finally { |
| visitor.reset(); |
| } |
| } |
| |
| protected IBuilder<CollectionMemberDeclarationStateObject, AbstractFromClauseStateObject> getCollectionDeclarationBuilder() { |
| if (collectionDeclarationBuilder == null) { |
| collectionDeclarationBuilder = buildCollectionDeclarationBuilder(); |
| } |
| return collectionDeclarationBuilder; |
| } |
| |
| protected CollectionExpressionVisitor getCollectionExpressionVisitor() { |
| if (collectionExpressionVisitor == null) { |
| collectionExpressionVisitor = new CollectionExpressionVisitor(); |
| } |
| return collectionExpressionVisitor; |
| } |
| |
| protected IBuilder<DeleteStatementStateObject, JPQLQueryStateObject> getDeleteStatementBuilder() { |
| if (deleteStatementBuilder == null) { |
| deleteStatementBuilder = buildDeleteStatementBuilder(); |
| } |
| return deleteStatementBuilder; |
| } |
| |
| protected IBuilder<JoinStateObject, AbstractIdentificationVariableDeclarationStateObject> getJoinBuilder() { |
| if (joinBuilder == null) { |
| joinBuilder = buildJoinBuilder(); |
| } |
| return joinBuilder; |
| } |
| |
| protected LiteralVisitor getLiteralVisitor() { |
| if (literalVisitor == null) { |
| literalVisitor = buildLiteralVisitor(); |
| } |
| return literalVisitor; |
| } |
| |
| protected IBuilder<AbstractIdentificationVariableDeclarationStateObject, FromClauseStateObject> getRangeDeclarationBuilder() { |
| if (rangeDeclarationBuilder == null) { |
| rangeDeclarationBuilder = buildRangeDeclarationBuilder(); |
| } |
| return rangeDeclarationBuilder; |
| } |
| |
| protected IBuilder<StateObject, SelectClauseStateObject> getSelectItemBuilder() { |
| if (selectItemBuilder == null) { |
| selectItemBuilder = buildSelectItemBuilder(); |
| } |
| return selectItemBuilder; |
| } |
| |
| protected IBuilder<SelectStatementStateObject, JPQLQueryStateObject> getSelectStatementBuilder() { |
| if (selectStatementBuilder == null) { |
| selectStatementBuilder = buildSelectStatementBuilder(); |
| } |
| return selectStatementBuilder; |
| } |
| |
| protected IBuilder<AbstractIdentificationVariableDeclarationStateObject, SimpleFromClauseStateObject> getSimpleRangeDeclarationBuilder() { |
| if (simpleRangeDeclarationBuilder == null) { |
| simpleRangeDeclarationBuilder = buildSimpleRangeDeclarationBuilder(); |
| } |
| return simpleRangeDeclarationBuilder; |
| } |
| |
| protected IBuilder<SimpleSelectStatementStateObject, StateObject> 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<UpdateStatementStateObject, JPQLQueryStateObject> 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; |
| } |
| } |
| |
| @Override |
| public void visit(AbsExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| AbsExpressionStateObject stateObject = new AbsExpressionStateObject(parent, this.stateObject); |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(AbstractSchemaName expression) { |
| |
| AbstractSchemaNameStateObject stateObject = new AbstractSchemaNameStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(BadExpression expression) { |
| |
| BadExpressionStateObject stateObject = new BadExpressionStateObject( |
| parent, |
| expression.getExpression().toActualText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @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.<WhenClauseStateObject>emptyList(), |
| elseStateObject |
| ); |
| |
| whenClauseBuilder().buildStateObject(caseExpressionStateObject, expression); |
| |
| caseExpressionStateObject.setExpression(expression); |
| this.stateObject = caseExpressionStateObject; |
| } |
| |
| @Override |
| public void visit(CoalesceExpression expression) { |
| |
| CoalesceExpressionStateObject stateObject = new CoalesceExpressionStateObject( |
| parent, |
| buildChildren(expression.getExpression()) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(CollectionExpression expression) { |
| |
| List<StateObject> stateObjects = buildChildren(expression); |
| |
| CollectionExpressionStateObject stateObject = new CollectionExpressionStateObject( |
| parent, |
| stateObjects |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(CollectionMemberDeclaration expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(CollectionValuedPathExpression expression) { |
| |
| CollectionValuedPathExpressionStateObject stateObject = new CollectionValuedPathExpressionStateObject( |
| parent, |
| expression.toActualText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(ConcatExpression expression) { |
| |
| ConcatExpressionStateObject stateObject = new ConcatExpressionStateObject( |
| parent, |
| buildChildren(expression.getExpression()) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(ConstructorExpression expression) { |
| |
| ConstructorExpressionStateObject stateObject = new ConstructorExpressionStateObject( |
| parent, |
| expression.getClassName(), |
| buildChildren(expression.getConstructorItems()) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(DateTime expression) { |
| DateTimeStateObject stateObject = new DateTimeStateObject(parent, expression.getText()); |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(DeleteClause expression) { |
| // Done via DeleteStatementBuilder |
| stateObject = null; |
| } |
| |
| @Override |
| public void visit(DeleteStatement expression) { |
| stateObject = getDeleteStatementBuilder().buildStateObject(parent, expression); |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(EntityTypeLiteral expression) { |
| |
| EntityTypeLiteralStateObject stateObject = new EntityTypeLiteralStateObject( |
| parent, |
| expression.getEntityTypeName() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(EntryExpression expression) { |
| |
| EntryExpressionStateObject stateObject = new EntryExpressionStateObject( |
| parent, |
| literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public final void visit(FromClause expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @Override |
| public void visit(FunctionExpression expression) { |
| |
| FunctionExpressionStateObject stateObject = new FunctionExpressionStateObject( |
| parent, |
| expression.getIdentifier(), |
| expression.getUnquotedFunctionName(), |
| buildChildren(expression.getExpression()) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public final void visit(GroupByClause expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @Override |
| public void visit(HavingClause expression) { |
| expression.getConditionalExpression().accept(this); |
| } |
| |
| @Override |
| public void visit(IdentificationVariable expression) { |
| |
| IdentificationVariableStateObject stateObject = new IdentificationVariableStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setVirtual(expression.isVirtual()); |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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); |
| } |
| |
| @Override |
| public void visit(IndexExpression expression) { |
| |
| IndexExpressionStateObject stateObject = new IndexExpressionStateObject( |
| parent, |
| literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(InputParameter expression) { |
| |
| InputParameterStateObject stateObject = new InputParameterStateObject( |
| parent, |
| expression.getParameter() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public final void visit(Join expression) { |
| stateObject = getJoinBuilder().buildStateObject( |
| (IdentificationVariableDeclarationStateObject) stateObject, |
| expression |
| ); |
| } |
| |
| @Override |
| public void visit(JPQLExpression expression) { |
| |
| parent = new JPQLQueryStateObject(jpqlQueryBuilder, managedTypeProvider); |
| parent.setExpression(expression); |
| |
| expression.getQueryStatement().accept(this); |
| parent.setQueryStatement(stateObject); |
| } |
| |
| @Override |
| public void visit(KeyExpression expression) { |
| |
| KeyExpressionStateObject stateObject = new KeyExpressionStateObject( |
| parent, |
| literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(KeywordExpression expression) { |
| |
| KeywordExpressionStateObject stateObject = new KeywordExpressionStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(LengthExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| LengthExpressionStateObject stateObject = new LengthExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(LowerExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| LowerExpressionStateObject stateObject = new LowerExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(NotExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| NotExpressionStateObject stateObject = new NotExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(NullExpression expression) { |
| stateObject = null; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(NumericLiteral expression) { |
| |
| NumericLiteralStateObject stateObject = new NumericLiteralStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(ObjectExpression expression) { |
| |
| ObjectExpressionStateObject stateObject = new ObjectExpressionStateObject( |
| parent, |
| literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(OnClause expression) { |
| expression.getConditionalExpression().accept(this); |
| } |
| |
| @Override |
| public final void visit(OrderByClause expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @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); |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public final void visit(RangeVariableDeclaration expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @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); |
| } |
| |
| @Override |
| public final void visit(SelectClause expression) { |
| // Not done here |
| stateObject = null; |
| } |
| |
| @Override |
| public void visit(SelectStatement expression) { |
| stateObject = getSelectStatementBuilder().buildStateObject(parent, expression); |
| } |
| |
| @Override |
| public final void visit(SimpleFromClause expression) { |
| // Done via SimpleSelectStatementBuilder |
| stateObject = null; |
| } |
| |
| @Override |
| public final void visit(SimpleSelectClause expression) { |
| // Done via SimpleSelectStatementBuilder |
| stateObject = null; |
| } |
| |
| @Override |
| public void visit(SimpleSelectStatement expression) { |
| stateObject = getSimpleSelectStatementBuilder().buildStateObject(parent, expression); |
| } |
| |
| @Override |
| public void visit(SizeExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| SizeExpressionStateObject stateObject = new SizeExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(SqrtExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| SqrtExpressionStateObject stateObject = new SqrtExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(StateFieldPathExpression expression) { |
| |
| StateFieldPathExpressionStateObject stateObject = new StateFieldPathExpressionStateObject( |
| parent, |
| expression.toActualText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(StringLiteral expression) { |
| |
| StringLiteralStateObject stateObject = new StringLiteralStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(SubExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| SubExpressionStateObject stateObject = new SubExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(TreatExpression expression) { |
| // Done by JoinBuilder |
| } |
| |
| @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; |
| } |
| |
| @Override |
| public void visit(TypeExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| TypeExpressionStateObject stateObject = new TypeExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(UnknownExpression expression) { |
| |
| UnknownExpressionStateObject stateObject = new UnknownExpressionStateObject( |
| parent, |
| expression.getText() |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public final void visit(UpdateClause expression) { |
| // Done via UpdateStatementBuilder |
| } |
| |
| @Override |
| public final void visit(UpdateItem expression) { |
| // Done via UpdateStatementBuilder |
| } |
| |
| @Override |
| public void visit(UpdateStatement expression) { |
| stateObject = getUpdateStatementBuilder().buildStateObject(parent, expression); |
| } |
| |
| @Override |
| public void visit(UpperExpression expression) { |
| |
| expression.getExpression().accept(this); |
| |
| UpperExpressionStateObject stateObject = new UpperExpressionStateObject( |
| parent, |
| this.stateObject |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public void visit(ValueExpression expression) { |
| |
| ValueExpressionStateObject stateObject = new ValueExpressionStateObject( |
| parent, |
| literal(expression.getExpression(), LiteralType.IDENTIFICATION_VARIABLE) |
| ); |
| |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| } |
| |
| @Override |
| public final void visit(WhenClause expression) { |
| // Done throw WhenClauseBuilder |
| stateObject = null; |
| } |
| |
| @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 <code><b>WHEN</b></code> clauses |
| */ |
| protected IBuilder<CaseExpressionStateObject, CaseExpressionStateObject> 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 <code><b>FROM</b></code> clause. |
| */ |
| protected abstract class AbstractRangeDeclarationBuilder<S extends AbstractFromClauseStateObject> |
| extends AbstractTraverseChildrenVisitor |
| implements IBuilder<AbstractIdentificationVariableDeclarationStateObject, S> { |
| |
| /** |
| * 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); |
| |
| @Override |
| public AbstractIdentificationVariableDeclarationStateObject buildStateObject(S parent, Expression expression) { |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| this.stateObject = null; |
| } |
| } |
| |
| @Override |
| public void visit(AbstractSchemaName expression) { |
| stateObject.setRootPath(expression.getText()); |
| } |
| |
| @Override |
| public void visit(IdentificationVariable expression) { |
| |
| stateObject.setIdentificationVariable(expression.getText()); |
| |
| IdentificationVariableStateObject variable = stateObject.getRangeVariableDeclaration().getIdentificationVariableStateObject(); |
| variable.setVirtual(expression.isVirtual()); |
| variable.setExpression(expression); |
| } |
| |
| @Override |
| public void visit(IdentificationVariableDeclaration expression) { |
| |
| stateObject = addRangeDeclaration(expression); |
| stateObject.setExpression(expression); |
| |
| getJoinBuilder().buildStateObject(stateObject, expression.getJoins()); |
| |
| expression.getRangeVariableDeclaration().accept(this); |
| } |
| |
| @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 <code><b>SELECT</b></code> statement. |
| */ |
| protected abstract class AbstractSelectStatementBuilder<T extends AbstractSelectStatementStateObject, P extends StateObject> |
| extends AbstractTraverseChildrenVisitor |
| implements IBuilder<T, P> { |
| |
| /** |
| * The parent of the <code><b>SELECT</b></code> statement. |
| */ |
| protected P parent; |
| |
| /** |
| * The concrete class of {@link AbstractSelectStatementStateObject}. |
| */ |
| protected T stateObject; |
| |
| @Override |
| public T buildStateObject(P parent, Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| } |
| } |
| |
| @Override |
| public void visit(CollectionMemberDeclaration expression) { |
| getCollectionDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); |
| } |
| |
| @Override |
| public void visit(GroupByClause expression) { |
| GroupByClauseStateObject groupByClause = stateObject.addGroupByClause(); |
| groupByClause.setExpression(expression); |
| groupByClause.addItems(buildChildren(expression.getGroupByItems())); |
| } |
| |
| @Override |
| public void visit(HavingClause expression) { |
| HavingClauseStateObject havingClause = stateObject.addHavingClause(); |
| havingClause.setConditional(buildStateObjectImp(expression)); |
| havingClause.setExpression(expression); |
| } |
| |
| @Override |
| public abstract void visit(IdentificationVariableDeclaration expression); |
| |
| @Override |
| public void visit(WhereClause expression) { |
| WhereClauseStateObject whereClause = stateObject.addWhereClause(); |
| whereClause.setConditional(buildStateObjectImp(expression)); |
| whereClause.setExpression(expression); |
| } |
| } |
| |
| protected static class CollectionExpressionVisitor extends AnonymousExpressionVisitor { |
| |
| List<Expression> children; |
| |
| CollectionExpressionVisitor() { |
| super(); |
| reset(); |
| } |
| |
| void reset() { |
| children = new ArrayList<>(); |
| } |
| |
| @Override |
| public void visit(CollectionExpression expression) { |
| CollectionTools.addAll(children, expression.children()); |
| } |
| |
| @Override |
| protected void visit(Expression expression) { |
| children.add(expression); |
| } |
| } |
| |
| protected static class CollectionMemberDeclarationBuilder extends AbstractTraverseChildrenVisitor |
| implements IBuilder<CollectionMemberDeclarationStateObject, AbstractFromClauseStateObject> { |
| |
| protected AbstractFromClauseStateObject parent; |
| protected CollectionMemberDeclarationStateObject stateObject; |
| |
| @Override |
| public CollectionMemberDeclarationStateObject buildStateObject(AbstractFromClauseStateObject parent, |
| Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| this.stateObject = null; |
| } |
| } |
| |
| @Override |
| public void visit(CollectionMemberDeclaration expression) { |
| stateObject = parent.addCollectionDeclaration(); |
| stateObject.setAs(expression.hasAs()); |
| stateObject.setExpression(expression); |
| stateObject.setDerived(expression.isDerived()); |
| super.visit(expression); |
| } |
| |
| @Override |
| public void visit(CollectionValuedPathExpression expression) { |
| CollectionValuedPathExpressionStateObject path = stateObject.getCollectionValuedPath(); |
| path.setPaths(expression.paths().iterator()); |
| path.setExpression(expression); |
| } |
| |
| @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 |
| * <code><b>DELETE</b></code> query statement. |
| */ |
| protected class DeleteStatementBuilder extends AbstractTraverseChildrenVisitor |
| implements IBuilder<DeleteStatementStateObject, JPQLQueryStateObject> { |
| |
| protected JPQLQueryStateObject parent; |
| protected DeleteStatementStateObject stateObject; |
| |
| @Override |
| public DeleteStatementStateObject buildStateObject(JPQLQueryStateObject parent, |
| Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| } |
| } |
| |
| @Override |
| public void visit(AbstractSchemaName expression) { |
| AbstractSchemaNameStateObject entityStateObject = stateObject.getAbstractSchemaNameStateObject(); |
| entityStateObject.setText(expression.getText()); |
| entityStateObject.setExpression(expression); |
| } |
| |
| @Override |
| public void visit(DeleteClause expression) { |
| stateObject.getModifyClause().setExpression(expression); |
| super.visit(expression); |
| } |
| |
| @Override |
| public void visit(DeleteStatement expression) { |
| stateObject = parent.addDeleteStatement(); |
| stateObject.setExpression(expression); |
| super.visit(expression); |
| } |
| |
| @Override |
| public void visit(IdentificationVariable expression) { |
| IdentificationVariableStateObject variable = stateObject.getIdentificationVariableStateObject(); |
| variable.setExpression(expression); |
| variable.setText(expression.getText()); |
| variable.setVirtual(expression.isVirtual()); |
| } |
| |
| @Override |
| public void visit(RangeVariableDeclaration expression) { |
| stateObject.getModifyClause().getRangeVariableDeclaration().setExpression(expression); |
| super.visit(expression); |
| } |
| |
| @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<JoinStateObject, AbstractIdentificationVariableDeclarationStateObject> { |
| |
| protected AbstractIdentificationVariableDeclarationStateObject parent; |
| protected JoinStateObject stateObject; |
| |
| @Override |
| public JoinStateObject buildStateObject(AbstractIdentificationVariableDeclarationStateObject parent, |
| Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| this.stateObject = null; |
| } |
| } |
| |
| @Override |
| public void visit(CollectionExpression expression) { |
| expression.acceptChildren(this); |
| } |
| |
| @Override |
| public void visit(IdentificationVariableDeclaration expression) { |
| expression.getRangeVariableDeclaration().accept(this); |
| expression.getJoins().accept(this); |
| } |
| |
| @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); |
| } |
| |
| @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 <code><b>FROM</b></code> clause of the top-level query. |
| */ |
| protected class RangeDeclarationBuilder extends AbstractRangeDeclarationBuilder<FromClauseStateObject> { |
| |
| @Override |
| protected AbstractIdentificationVariableDeclarationStateObject addRangeDeclaration(IdentificationVariableDeclaration expression) { |
| return parent.addRangeDeclaration(); |
| } |
| |
| @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 |
| * <code><b>SELECT</b></code> clause. |
| */ |
| protected class SelectItemBuilder extends AnonymousExpressionVisitor |
| implements IBuilder<StateObject, SelectClauseStateObject> { |
| |
| protected SelectClauseStateObject parent; |
| protected StateObject stateObject; |
| |
| @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; |
| } |
| } |
| |
| @Override |
| protected void visit(Expression expression) { |
| expression.accept(BasicStateObjectBuilder.this); |
| stateObject = BasicStateObjectBuilder.this.stateObject; |
| } |
| |
| @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 |
| * <code><b>SELECT</b></code> query statement. |
| */ |
| protected class SelectStatementBuilder extends AbstractSelectStatementBuilder<SelectStatementStateObject, JPQLQueryStateObject> { |
| |
| @Override |
| public void visit(FromClause expression) { |
| |
| stateObject.getFromClause().setExpression(expression); |
| |
| for (Expression child : children(expression.getDeclaration())) { |
| child.accept(this); |
| } |
| } |
| |
| @Override |
| public void visit(IdentificationVariableDeclaration expression) { |
| getRangeDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); |
| } |
| |
| @Override |
| public void visit(OrderByClause expression) { |
| |
| OrderByClauseStateObject orderByClause = stateObject.addOrderByClause(); |
| orderByClause.setExpression(expression); |
| |
| super.visit(expression); |
| } |
| |
| @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); |
| } |
| |
| @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); |
| } |
| } |
| } |
| |
| @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 <code><b>FROM</b></code> clause of a subquery. |
| */ |
| protected class SimpleRangeDeclarationBuilder extends AbstractRangeDeclarationBuilder<SimpleFromClauseStateObject> { |
| |
| @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(); |
| } |
| |
| @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 |
| * <code><b>SELECT</b></code> subquery. |
| */ |
| protected class SimpleSelectStatementBuilder extends AbstractSelectStatementBuilder<SimpleSelectStatementStateObject, StateObject> { |
| |
| @Override |
| public void visit(IdentificationVariableDeclaration expression) { |
| getSimpleRangeDeclarationBuilder().buildStateObject(stateObject.getFromClause(), expression); |
| } |
| |
| @Override |
| public void visit(SimpleFromClause expression) { |
| |
| stateObject.getFromClause().setExpression(expression); |
| |
| for (Expression child : children(expression.getDeclaration())) { |
| child.accept(this); |
| } |
| } |
| |
| @Override |
| public void visit(SimpleSelectClause expression) { |
| |
| SimpleSelectClauseStateObject selectClause = stateObject.getSelectClause(); |
| selectClause.setDistinct(expression.hasDistinct()); |
| selectClause.setExpression(expression); |
| |
| List<StateObject> children = buildChildren(expression.getSelectExpression()); |
| |
| if (!children.isEmpty()) { |
| selectClause.setSelectItem(children.get(0)); |
| } |
| } |
| |
| @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 |
| * <code><b>UPDATE</b></code> query statement. |
| */ |
| protected class UpdateStatementBuilder extends AbstractTraverseChildrenVisitor |
| implements IBuilder<UpdateStatementStateObject, JPQLQueryStateObject> { |
| |
| protected JPQLQueryStateObject parent; |
| protected UpdateStatementStateObject stateObject; |
| protected UpdateItemStateObject updateItem; |
| |
| @Override |
| public UpdateStatementStateObject buildStateObject(JPQLQueryStateObject parent, |
| Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return stateObject; |
| } |
| finally { |
| this.parent = null; |
| this.stateObject = null; |
| } |
| } |
| |
| @Override |
| public void visit(AbstractSchemaName expression) { |
| stateObject.setEntityName(expression.getText()); |
| stateObject.getModifyClause().getAbstractSchemaNameStateObject().setExpression(expression); |
| } |
| |
| @Override |
| public void visit(IdentificationVariable expression) { |
| |
| if (updateItem == null) { |
| |
| IdentificationVariableStateObject variable = stateObject.getIdentificationVariableStateObject(); |
| |
| variable.setText(expression.getText()); |
| variable.setVirtual(expression.isVirtual()); |
| variable.setExpression(expression); |
| } |
| } |
| |
| @Override |
| public void visit(RangeVariableDeclaration expression) { |
| stateObject.getModifyClause().getRangeVariableDeclaration().setExpression(expression); |
| super.visit(expression); |
| } |
| |
| @Override |
| public void visit(StateFieldPathExpression expression) { |
| updateItem.getStateFieldPath().setPaths(expression.paths().iterator()); |
| updateItem.getStateFieldPath().setExpression(expression); |
| } |
| |
| @Override |
| public void visit(UpdateClause expression) { |
| stateObject.getModifyClause().setExpression(expression); |
| super.visit(expression); |
| } |
| |
| @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; |
| } |
| } |
| |
| @Override |
| public void visit(UpdateStatement expression) { |
| |
| UpdateStatementStateObject stateObject = parent.addUpdateStatement(); |
| stateObject.setExpression(expression); |
| this.stateObject = stateObject; |
| |
| super.visit(expression); |
| } |
| |
| @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 <code><b>WHEN</b></code> clauses for a |
| * <code><b>CASE</b></code> expression. |
| */ |
| protected class WhenClauseBuilder extends AbstractTraverseChildrenVisitor |
| implements IBuilder<CaseExpressionStateObject, CaseExpressionStateObject> { |
| |
| /** |
| * The {@link CaseExpressionStateObject} for which its {@link WhenClauseStateObject |
| * WhenClauseStateObjects} are created by this builder. |
| */ |
| private CaseExpressionStateObject parent; |
| |
| @Override |
| public CaseExpressionStateObject buildStateObject(CaseExpressionStateObject parent, |
| Expression expression) { |
| |
| try { |
| this.parent = parent; |
| expression.accept(this); |
| return parent; |
| } |
| finally { |
| this.parent = null; |
| } |
| } |
| |
| @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); |
| } |
| } |
| } |