/*
 * Copyright (c) 2011, 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;

import org.eclipse.persistence.jpa.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.JPQLStatementBNF;
import org.eclipse.persistence.jpa.jpql.tools.model.IJPQLQueryBuilder;
import org.eclipse.persistence.jpa.jpql.tools.model.IJPQLQueryFormatter;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractSchemaNameStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.AbstractTraverseChildrenVisitor;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionValuedPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConstructorExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.EntityTypeLiteralStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.IdentificationVariableStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.JPQLQueryStateObject;
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.SelectStatementStateObject;
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.TreatExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.spi.IManagedTypeProvider;
import org.eclipse.persistence.jpa.jpql.tools.spi.IMapping;
import org.eclipse.persistence.jpa.jpql.tools.spi.IType;

/**
 * The abstract implementation providing refactoring support for JPQL queries.
 * <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 DefaultRefactoringTool
 * @see EclipseLinkRefactoringTool
 *
 * @version 2.4
 * @since 2.4
 * @author Pascal Filion
 */
public abstract class RefactoringTool extends AbstractRefactoringTool {

    /**
     * The builder that creates the {@link StateObject} representation of the JPQL query.
     */
    private IJPQLQueryBuilder jpqlQueryBuilder;

    /**
     * The formatter that converts a {@link StateObject} representation of the JPQL query into a
     * string representation.
     */
    private IJPQLQueryFormatter jpqlQueryFormatter;

    /**
     * The editable representation of the JPQL query.
     */
    private JPQLQueryStateObject stateObject;

    /**
     * Creates a new <code>RefactoringTool</code>.
     *
     * @param managedTypeProvider The external form of a provider that gives access to the JPA metadata
     * @param jpqlQueryBuilder The builder that creates the {@link StateObject} representation of the
     * JPQL query
     * @param jpqlQuery The JPQL query to manipulate
     */
    protected RefactoringTool(IManagedTypeProvider managedTypeProvider,
                              IJPQLQueryBuilder jpqlQueryBuilder,
                              CharSequence jpqlQuery) {

        this(managedTypeProvider, jpqlQueryBuilder, jpqlQuery, JPQLStatementBNF.ID);
    }

    /**
     * Creates a new <code>RefactoringTool</code>.
     *
     * @param managedTypeProvider The external form of a provider that gives access to the JPA metadata
     * @param jpqlQueryBuilder The builder that creates the {@link StateObject} representation of the
     * JPQL query
     * @param jpqlFragment The JPQL query to manipulate or a single JPQL fragment, which is parsed
     * using the JPQL query BNF identifier by the given ID
     * @param jpqlQueryBNFId The unique identifier of the {@link
     * org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF JPQLQueryBNF} that determines how to parse the JPQL fragment
     */
    protected RefactoringTool(IManagedTypeProvider managedTypeProvider,
                              IJPQLQueryBuilder jpqlQueryBuilder,
                              CharSequence jpqlFragment,
                              String jpqlQueryBNFId) {

        super(jpqlFragment, managedTypeProvider, jpqlQueryBNFId);
        this.jpqlQueryBuilder = jpqlQueryBuilder;
    }

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename the fully qualified class name.
     *
     * @param oldClassName The current name of the class to rename
     * @param newClassName The new name of the class
     * @return A new {@link ClassNameRenamer}
     */
    protected ClassNameRenamer buildClassNameRenamer(String oldClassName, String newClassName) {
        return new ClassNameRenamer(oldClassName, newClassName);
    }

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename the entity name.
     *
     * @param oldEntityName The current name of the entity to rename
     * @param newEntityName The new name of the entity
     * @return A new {@link EntityNameRenamer}
     */
    protected EntityNameRenamer buildEntityNameRenamer(String oldEntityName, String newEntityName) {
        return new EntityNameRenamer(oldEntityName, newEntityName);
    }

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename the enum constant.
     *
     * @param oldClassName The new name of the enum constant
     * @param newClassName The current name of the enum constant to rename
     * @return A new {@link EnumConstantRenamer}
     */
    protected EnumConstantRenamer buildEnumConstantRenamer(String oldClassName, String newClassName) {
        return new EnumConstantRenamer(getManagedTypeProvider(), oldClassName, newClassName);
    }

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename a type's attribute name.
     *
     * @param typeName The fully qualified name of the type that got one of its attributes renamed
     * @param oldFieldName The current name of the attribute to rename
     * @param newFieldName The new name of the attribute
     * @return A new {@link org.eclipse.persistence.jpa.jpql.tools.BasicRefactoringTool.AttributeNameRenamer
     * AttributeNameRenamer}
     */
    protected FieldNameRenamer buildFieldNameRenamer(String typeName,
                                                     String oldFieldName,
                                                     String newFieldName) {

        return new FieldNameRenamer(getManagedTypeProvider(), typeName, oldFieldName, newFieldName);
    }

    /**
     * Creates a new formatter that will convert the {@link StateObject} representation of the JPQL
     * query, once the refactoring occurred into a string.
     *
     * @return A new concrete instance of {@link IJPQLQueryFormatter}
     */
    protected abstract IJPQLQueryFormatter buildFormatter();

    /**
     * Creates a new {@link JPQLQueryContext} that can retrieve information from the declaration
     * portion of the JPQL query.
     * <p>
     * <b>NOTE:</b> This is temporary because the {@link StateObject} API does not have that
     * knowledge yet.
     *
     * @return A new concrete instance of {@link JPQLQueryContext}
     */
    protected abstract JPQLQueryContext buildJPQLQueryContext();

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename a result variable.
     *
     * @param oldVariableName The current result variable name
     * @param newVariableName The new name of the result variable
     * @return A new {@link ResultVariableNameRenamer}
     */
    protected ResultVariableNameRenamer buildResultVariableNameRenamer(String oldVariableName,
                                                                       String newVariableName) {

        return new ResultVariableNameRenamer(oldVariableName, newVariableName);
    }

    /**
     * Creates the {@link StateObject} representation of the JPQL fragment to manipulate.
     *
     * @return The parsed and editable JPQL query
     * @see #getStateObject()
     */
    protected JPQLQueryStateObject buildStateObject() {
        return jpqlQueryBuilder.buildStateObject(
            getManagedTypeProvider(),
            getJPQLFragment(),
            getJPQLQueryBNFId(),
            isTolerant()
        );
    }

    /**
     * Creates the visitor that will traverse the {@link StateObject} representation of the JPQL
     * query and will rename an identification variable.
     *
     * @param oldVariableName The current identification variable name
     * @param newVariableName The new name of the identification variable
     * @return A new {@link VariableNameRenamer}
     */
    protected VariableNameRenamer buildVariableNameRenamer(String oldVariableName,
                                                           String newVariableName) {

        return new VariableNameRenamer(oldVariableName, newVariableName);
    }

    /**
     * Returns the {@link IJPQLQueryFormatter} that creates an accurate representation of the {@link
     * StateObject}, i.e. that output the JPQL query with the case used for the JPQL identifier.
     *
     * @return An instance of {@link IJPQLQueryFormatter}
     */
    public IJPQLQueryFormatter getFormatter() {
        if (jpqlQueryFormatter == null) {
            jpqlQueryFormatter = buildFormatter();
        }
        return jpqlQueryFormatter;
    }

    /**
     * Returns the {@link JPQLGrammar} that is associated with this builder.
     *
     * @return The {@link JPQLGrammar} that was used to parse the JPQL query or JPQL fragments
     */
    public JPQLGrammar getGrammar() {
        return jpqlQueryBuilder.getGrammar();
    }

    /**
     * Returns the builder that creates the {@link StateObject} representation of the JPQL query.
     *
     * @return The builder of the {@link StateObject} to be manipulated
     */
    public IJPQLQueryBuilder getJPQLQueryBuilder() {
        return jpqlQueryBuilder;
    }

    /**
     * Returns the {@link StateObject} representation of the JPQL query or JPQL fragment that was parsed.
     *
     * @return The editable state model
     */
    public JPQLQueryStateObject getStateObject() {
        if (stateObject == null) {
            stateObject = buildStateObject();
        }
        return stateObject;
    }

    /**
     * Renames a fully qualified class name.
     *
     * @param oldClassName The current fully qualified class name of the class to rename
     * @param newClassName The new fully qualified class name
     */
    public void renameClassName(String oldClassName, String newClassName) {
        ClassNameRenamer renamer = buildClassNameRenamer(oldClassName, newClassName);
        getStateObject().accept(renamer);
    }

    /**
     * Renames a given entity name.
     *
     * @param oldEntityName The current name of the entity to rename
     * @param newEntityName The new name of the entity
     */
    public void renameEntityName(String oldEntityName, String newEntityName) {
        EntityNameRenamer renamer = buildEntityNameRenamer(oldEntityName, newEntityName);
        getStateObject().accept(renamer);
    }

    /**
     * Renames an enum constant, which has to be fully qualified.
     *
     * @param oldEnumConstant The current fully qualified name of the enum constant to rename
     * @param newEnumConstant The new fully qualified name of the enum constant
     */
    public void renameEnumConstant(String oldEnumConstant, String newEnumConstant) {
        EnumConstantRenamer renamer = buildEnumConstantRenamer(oldEnumConstant, newEnumConstant);
        getStateObject().accept(renamer);
    }

    /**
     * Renames a field from the given type.
     *
     * @param type The Java class from which the change originate
     * @param oldFieldName The current name of the attribute to rename
     * @param newFieldName The new name of the attribute
     */
    public void renameField(Class<?> type, String oldFieldName, String newFieldName) {
        renameField(type.getName(), oldFieldName, newFieldName);
    }

    /**
     * Renames a field from the given type.
     *
     * @param type The {@link IType} from which the change originate
     * @param oldFieldName The current name of the attribute to rename
     * @param newFieldName The new name of the attribute
     */
    public void renameField(IType type, String oldFieldName, String newFieldName) {
        renameField(type.getName(), oldFieldName, newFieldName);
    }

    /**
     * Renames a field from the given type.
     *
     * @param typeName The fully qualified name of the type that got one of its attributes renamed
     * @param oldFieldName The current name of the attribute to rename
     * @param newFieldName The new name of the attribute
     */
    public void renameField(String typeName, String oldFieldName, String newFieldName) {
        FieldNameRenamer renamer = buildFieldNameRenamer(typeName, oldFieldName, newFieldName);
        getStateObject().accept(renamer);
    }

    /**
     * Renames a result variable name.
     *
     * @param oldVariableName The current identification variable name
     * @param newVariableName The new name of the identification variable
     */
    public void renameResultVariable(String oldVariableName, String newVariableName) {
        ResultVariableNameRenamer renamer = buildResultVariableNameRenamer(oldVariableName, newVariableName);
        getStateObject().accept(renamer);
    }

    /**
     * Renames a variable name.
     *
     * @param oldVariableName The current identification variable name
     * @param newVariableName The new name of the identification variable
     */
    public void renameVariable(String oldVariableName, String newVariableName) {
        VariableNameRenamer renamer = buildVariableNameRenamer(oldVariableName, newVariableName);
        getStateObject().accept(renamer);
    }

    /**
     * Sets the {@link IJPQLQueryFormatter} that creates an accurate representation of the {@link
     * StateObject}, i.e. that output the JPQL query with the case used for the JPQL identifier.
     *
     * @param jpqlQueryFormatter This formatter converts a {@link StateObject} representation of the
     * JPQL query into a string representation
     */
    public void setFormatter(IJPQLQueryFormatter jpqlQueryFormatter) {
        this.jpqlQueryFormatter = jpqlQueryFormatter;
    }

    @Override
    public String toActualText() {
        return getFormatter().toString(getStateObject());
    }

    /**
     * This visitor renames a fully qualified class name.
     */
    protected static class ClassNameRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The {@link StateObjectUpdater} that updates the class name when notified.
         */
        protected StateObjectUpdater<ConstructorExpressionStateObject> constructorUpdater;

        /**
         * The current name of the class to rename.
         */
        protected final String newClassName;

        /**
         * The new name of the class.
         */
        protected final String oldClassName;

        /**
         * The {@link StateObjectUpdater} that updates the state field path expression when notified.
         */
        protected StateObjectUpdater<StateFieldPathExpressionStateObject> pathExpressionUpdater;

        /**
         * Creates a new <code>ClassNameRenamer</code>.
         *
         * @param oldClassName The current name of the class to rename
         * @param newClassName The new name of the class
         */
        public ClassNameRenamer(String oldClassName, String newClassName) {
            super();
            this.oldClassName = oldClassName;
            this.newClassName = newClassName;
        }

        protected StateObjectUpdater<ConstructorExpressionStateObject> buildConstructorUpdater() {
            return new StateObjectUpdater<ConstructorExpressionStateObject>() {
                @Override
                public void update(ConstructorExpressionStateObject stateObject, CharSequence newValue) {
                    stateObject.setClassName(newValue);
                }
            };
        }

        protected StateObjectUpdater<StateFieldPathExpressionStateObject> buildPathExpressionStateObjectUpdater() {
            return new StateObjectUpdater<StateFieldPathExpressionStateObject>() {
                @Override
                public void update(StateFieldPathExpressionStateObject stateObject, CharSequence newValue) {
                    stateObject.setPath(newValue);
                }
            };
        }

        protected StateObjectUpdater<ConstructorExpressionStateObject> constructorUpdater() {
            if (constructorUpdater == null ){
                constructorUpdater = buildConstructorUpdater();
            }
            return constructorUpdater;
        }

        protected StateObjectUpdater<StateFieldPathExpressionStateObject> pathExpressionUpdater() {
            if (pathExpressionUpdater == null ){
                pathExpressionUpdater = buildPathExpressionStateObjectUpdater();
            }
            return pathExpressionUpdater;
        }

        @Override
        public void visit(ConstructorExpressionStateObject stateObject) {
            visit(stateObject, stateObject.getClassName(), constructorUpdater());
        }

        @Override
        public void visit(StateFieldPathExpressionStateObject stateObject) {
            visit(stateObject, stateObject.getPath(), pathExpressionUpdater());
        }

        /**
         * Visits the given {@link StateObject} and if its value is the same as the old class name or
         * if the value represents an inner class of that old class name, then the given {@link
         * StateObjectUpdater} will be notified to replace the value.
         *
         * @param stateObject The {@link StateObject} that is being visited
         * @param value The value to check if it's the old class name
         * @param updater The {@link StateObjectUpdater} is notified when to replace the value
         */
        protected <T extends StateObject> void visit(T stateObject,
                                                     String value,
                                                     StateObjectUpdater<T> updater) {

            if (oldClassName.equals(value)) {
                updater.update(stateObject, newClassName);
            }
            else {
                int index = value.lastIndexOf(AbstractExpression.DOT);

                // Traverse the value by retrieving a fragment up to the last dot (based on the index)
                for (; index > -1; index = value.lastIndexOf(AbstractExpression.DOT, index - 1)) {
                    String fragment = value.substring(0, index);

                    if (oldClassName.equals(fragment)) {
                        StringBuilder newValue = new StringBuilder(newClassName);
                        newValue.append(AbstractExpression.DOT);

                        // The path does not end with '.'
                        if (index + 1 < value.length()) {
                            newValue.append(value.substring(index + 1));
                        }

                        updater.update(stateObject, newValue);
                        break;
                    }
                    // No need to continue the search
                    else if (fragment.length() < oldClassName.length()) {
                        break;
                    }
                }
            }
        }
    }

    /**
     * This visitor renames an entity name. There are three possible {@link StateObject StateObjects}
     * that can represent an entity name:
     * <ul>
     * <li>
     * {@link AbstractSchemaNameStateObject}:
     * <i>Employee</i> in<br><br>
     * <code><b>SELECT</b> e<br>
     * <b>FROM</b> Employee e</code><br><br>
     * </li>
     * <li>
     * {@link EntityTypeLiteralStateObject}:
     * <i>Exempt</i> in<br><br>
     * <code><b>SELECT CASE TYPE</b>(e) <b>WHEN</b> Exempt <b>THEN</b> 'Exempt'</code><p>
     * <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
     * <b>ELSE</b> 'NONE'</code><p>
     * <code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
     * <b>END</b></code><p>
     * <code><b>FROM</b> Employee e</code><br><br>
     * </li>
     * <li>
     * {@link IdentificationVariableStateObject}:
     * <i>Exempt</i> in<br><br>
     * <code><b>SELECT</b> e<br>
     * <b>FROM</b> Employee e</code><br>
     * <b>WHERE TYPE</b>(e) {@literal <>} Exempt
     * </li>
     * </ul>
     */
    protected static class EntityNameRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The current name of the entity to rename.
         */
        protected final String newEntityName;

        /**
         * The new name of the entity.
         */
        protected final String oldEntityName;

        /**
         * Creates a new <code>EntityNameRenamer</code>.
         *
         * @param oldEntityName The current name of the entity to rename
         * @param newEntityName The new name of the entity
         */
        public EntityNameRenamer(String oldEntityName, String newEntityName) {
            super();
            this.oldEntityName = oldEntityName;
            this.newEntityName = newEntityName;
        }

        @Override
        public void visit(AbstractSchemaNameStateObject stateObject) {
            if (oldEntityName.equals(stateObject.getText())) {
                stateObject.setText(newEntityName);
            }
        }

        @Override
        public void visit(EntityTypeLiteralStateObject stateObject) {
            if (oldEntityName.equals(stateObject.getText())) {
                stateObject.setText(newEntityName);
            }
        }

        @Override
        public void visit(IdentificationVariableStateObject stateObject) {
            if (oldEntityName.equals(stateObject.getText())) {
                stateObject.setText(newEntityName);
            }
        }

        @Override
        public void visit(TreatExpressionStateObject stateObject) {
            if (oldEntityName.equals(stateObject.getEntityTypeName())) {
                stateObject.setEntityTypeName(newEntityName);
            }
        }
    }

    /**
     * This visitor renames an enum constant. An enum constant is represented by a path expression.
     */
    protected static class EnumConstantRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The external form of a provider that gives access to the JPA metadata.
         */
        protected final IManagedTypeProvider managedTypeProvider;

        /**
         * The current name of the enum constant to rename.
         */
        protected final String newEnumConstant;

        /**
         * The new name of the enum constant.
         */
        protected final String oldEnumConstant;

        /**
         * Creates a new <code>ClassNameRenamer</code>.
         *
         * @param managedTypeProvider The provider of managed types
         * @param oldEnumConstant The new name of the enum constant
         * @param newEnumConstant The current name of the enum constant to rename
         */
        public EnumConstantRenamer(IManagedTypeProvider managedTypeProvider,
                                   String oldEnumConstant,
                                   String newEnumConstant) {

            super();
            this.oldEnumConstant     = oldEnumConstant;
            this.newEnumConstant     = newEnumConstant;
            this.managedTypeProvider = managedTypeProvider;
        }

        protected void renameEnumConstant(AbstractPathExpressionStateObject stateObject) {

            String path = stateObject.toString();

            if (path.equals(oldEnumConstant)) {

                IType type = managedTypeProvider.getTypeRepository().getEnumType(path);

                if (type != null) {
                    stateObject.setPath(newEnumConstant);
                }
            }
        }

        @Override
        public void visit(CollectionValuedPathExpressionStateObject stateObject) {
            renameEnumConstant(stateObject);
        }

        @Override
        public void visit(StateFieldPathExpressionStateObject stateObject) {
            renameEnumConstant(stateObject);
        }
    }

    /**
     * This visitor renames any segment of a path expression.
     */
    protected static class FieldNameRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The external form of a provider that gives access to the JPA metadata.
         */
        protected final IManagedTypeProvider managedTypeProvider;

        /**
         * The new name of the attribute.
         */
        protected final String newFieldName;

        /**
         * The current name of the attribute to rename.
         */
        protected final String oldFieldName;

        /**
         * The fully qualified name of the type that got one of its attributes renamed.
         */
        protected final String typeName;

        /**
         * Creates a new <code>AttributeNameRenamer</code>.
         *
         * @param typeName The fully qualified name of the type that got one of its attributes renamed
         * @param oldFieldName The current name of the attribute to rename
         * @param newFieldName The new name of the attribute
         */
        public FieldNameRenamer(IManagedTypeProvider managedTypeProvider,
                                String typeName,
                                String oldFieldName,
                                String newFieldName) {

            super();
            this.typeName            = typeName;
            this.oldFieldName        = oldFieldName;
            this.newFieldName        = newFieldName;
            this.managedTypeProvider = managedTypeProvider;
        }

        /**
         * Performs the rename on the path expression.
         *
         * @param stateObject The {@link AbstractPathExpressionStateObject} being visited, which may
         * have to have its path renamed
         */
        protected void rename(AbstractPathExpressionStateObject stateObject) {

            // Now traverse the path expression after the identification variable
            for (int index = 1, count = stateObject.itemsSize(); index < count; index++) {

                // Retrieve the mapping for the path at the current position
                IMapping mapping = stateObject.getMapping(index);

                if (mapping == null) {
                    break;
                }

                // The name matches
                if (mapping.getName().equals(oldFieldName)) {

                    // Make sure the field name is from the right type
                    String parentTypeName = mapping.getParent().getType().getName();

                    if (parentTypeName.equals(typeName)) {
                        stateObject.setPath(index, newFieldName);
                        break;
                    }
                }
            }
        }

        @Override
        public void visit(CollectionValuedPathExpressionStateObject stateObject) {
            rename(stateObject);
        }

        @Override
        public void visit(StateFieldPathExpressionStateObject stateObject) {
            rename(stateObject);
        }
    }

    /**
     * This visitor renames all the result variables found in the JPQL query.
     */
    protected static class ResultVariableNameRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The new name of the result variable.
         */
        protected final String newVariableName;

        /**
         * The current result variable name.
         */
        protected final String oldVariableName;

        /**
         * Makes sure an identification variable is renamed only when it's used by an order by item.
         */
        protected boolean renameIdentificationVariable;

        /**
         * Creates a new <code>ResultVariableNameRenamer</code>.
         *
         * @param oldVariableName The current result variable name
         * @param newVariableName The new name of the result variable
         */
        public ResultVariableNameRenamer(String oldVariableName, String newVariableName) {
            super();
            this.oldVariableName = oldVariableName;
            this.newVariableName = newVariableName;
        }

        @Override
        public void visit(IdentificationVariableStateObject stateObject) {

            if (renameIdentificationVariable &&
                oldVariableName.equalsIgnoreCase(stateObject.getText())) {

                stateObject.setText(newVariableName);
            }
        }

        @Override
        public void visit(JPQLQueryStateObject stateObject) {
            if (stateObject.hasQueryStatement()) {
                stateObject.getQueryStatement().accept(this);
            }
        }

        @Override
        public void visit(OrderByItemStateObject stateObject) {
            if (stateObject.hasStateObject()) {
                stateObject.getStateObject().accept(this);
            }
        }

        @Override
        public void visit(ResultVariableStateObject stateObject) {
            if (oldVariableName.equalsIgnoreCase(stateObject.getResultVariable())) {
                stateObject.setResultVariable(newVariableName);
            }
        }

        @Override
        public void visit(SelectStatementStateObject stateObject) {

            // Result variables defined in the SELECT clause
            stateObject.getSelectClause().accept(this);

            // Result variables used in the ORDER BY clause
            if (stateObject.hasOrderByClause()) {
                renameIdentificationVariable = true;
                try {
                    stateObject.getOrderByClause().accept(this);
                }
                finally {
                    renameIdentificationVariable = false;
                }
            }
        }
    }

    /**
     * This interface is used to transparently push the new value into the {@link StateObject}.
     */
    protected static interface StateObjectUpdater<T extends StateObject> {

        /**
         * Updates the given {@link StateObject} by updating its state with the given new value.
         *
         * @param stateObject The {@link StateObject} to update
         * @param newValue The new value to push into the object
         */
        void update(T stateObject, CharSequence newValue);
    }

    /**
     * This visitor renames all the identification variables found in the JPQL query.
     */
    protected static class VariableNameRenamer extends AbstractTraverseChildrenVisitor {

        /**
         * The new name of the identification variable.
         */
        protected final String newVariableName;

        /**
         * The current identification variable name.
         */
        protected final String oldVariableName;

        /**
         * Creates a new <code>VariableNameRenamer</code>.
         *
         * @param oldVariableName The current identification variable name
         * @param newVariableName The new name of the identification variable
         */
        public VariableNameRenamer(String oldVariableName, String newVariableName) {
            super();
            this.oldVariableName = oldVariableName;
            this.newVariableName = newVariableName;
        }

        @Override
        public void visit(CollectionValuedPathExpressionStateObject stateObject) {

            // Make sure the collection-valued path expression's identification variable was created
            stateObject.getIdentificationVariable();

            super.visit(stateObject);
        }

        @Override
        public void visit(IdentificationVariableStateObject stateObject) {
            if (oldVariableName.equalsIgnoreCase(stateObject.getText())) {
                stateObject.setText(newVariableName);
            }
        }

        @Override
        public void visit(StateFieldPathExpressionStateObject stateObject) {

            // Make sure the collection-valued path expression's identification variable was created
            stateObject.getIdentificationVariable();

            super.visit(stateObject);
        }
    }
}
