Package org.eclipse.persistence.jpa.internal.jpql

Source Code of org.eclipse.persistence.jpa.internal.jpql.AbstractValidator$ChildrenCollectorVisitor

/*******************************************************************************
* Copyright (c) 2006, 2011 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.jpa.internal.jpql;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.persistence.jpa.internal.jpql.parser.AbstractExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.AbstractTraverseParentVisitor;
import org.eclipse.persistence.jpa.internal.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.internal.jpql.parser.BadExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.Expression;
import org.eclipse.persistence.jpa.internal.jpql.parser.ExpressionVisitor;
import org.eclipse.persistence.jpa.internal.jpql.parser.FromClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.GroupByClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.HavingClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.IdentificationVariableBNF;
import org.eclipse.persistence.jpa.internal.jpql.parser.InternalOrderByItemBNF;
import org.eclipse.persistence.jpa.internal.jpql.parser.JPQLQueryBNF;
import org.eclipse.persistence.jpa.internal.jpql.parser.NullExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.OrderByClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.ResultVariableBNF;
import org.eclipse.persistence.jpa.internal.jpql.parser.SelectClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.SimpleFromClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.SimpleSelectClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.StateFieldPathExpressionBNF;
import org.eclipse.persistence.jpa.internal.jpql.parser.StringExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.SubExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.UnknownExpression;
import org.eclipse.persistence.jpa.internal.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.internal.jpql.parser.WhereClause;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem;
import org.eclipse.persistence.jpa.jpql.spi.IPlatform;

/**
* The abstract definition of a validator, which provides helper methods and visitors.
*
* @see GrammarValidator
* @see SemanticValidator
*
* @version 2.3
* @since 2.3
* @author Pascal Filion
*/
public abstract class AbstractValidator extends AbstractVisitor {

  /**
   * This visitor is responsible to traverse the children of a {@link CollectionExpression} in
   * order to properly validate the {@link Expression}.
   */
  private BypassChildCollectionExpressionVisitor bypassChildCollectionExpressionVisitor;

  /**
   * This visitor is responsible to traverse the parent hierarchy and to skip {@link SubExpression}
   * if it's a parent.
   */
  private BypassParentSubExpressionVisitor bypassParentSubExpressionVisitor;

  /**
   * This visitor gathers the children of a {@link CollectionExpression} or a single visited
   * {@link Expression}.
   */
  private ChildrenCollectorVisitor childrenCollectorVisitor;

  /**
   * This visitor is responsible to traverse the parent hierarchy and to retrieve the owning clause
   * of the {@link Expression} being visited.
   */
  private OwningClauseVisitor owningClauseVisitor;

  /**
   * The list of {@link QueryProblem QueryProblems} describing grammatical and semantic issues
   * found in the query.
   */
  private List<JPQLQueryProblem> problems;

  /**
   * The {@link ExpressionValidator ExpressionValidators} mapped by the BNF IDs.
   */
  private Map<String, ExpressionValidator> validators;

  /**
   * Creates a new <code>AbstractValidator</code>.
   *
   * @param queryContext The context used to query information about the query
   */
  protected AbstractValidator(JPQLQueryContext queryContext) {
    super(queryContext);
  }

  /**
   * Adds a new validation problem that was found in the given {@link Expression}.
   *
   * @param expression The {@link Expression} that is either not following the BNF grammar or that
   * has semantic problems
   * @param startIndex The position where the problem was encountered
   * @param endIndex The position where the problem ends, inclusively
   * @param messageKey The key used to retrieve the localized message describing the problem
   * @param messageArguments The list of arguments that can be used to format the localized
   * description of the problem
   */
  protected final void addProblem(Expression expression,
                                  int startIndex,
                                  int endIndex,
                                  String messageKey,
                                  String... messageArguments) {

    problems.add(buildProblem(expression, startIndex, endIndex, messageKey, messageArguments));
  }

  /**
   * Adds a new validation problem that was found in the given {@link Expression}. The start index
   * is the position of the given {@link Expression} within the JPQL query and the end index is
   * the end position of the {@link Expression} within the JPQL query.
   *
   * @param expression The {@link Expression} that is either not following the BNF grammar or that
   * has semantic problems
   * @param messageKey The key used to retrieve the localized message describing the problem
   */
  protected final void addProblem(Expression expression, String messageKey) {
    addProblem(expression, messageKey, ExpressionTools.EMPTY_STRING_ARRAY);
  }

  /**
   * Adds a new validation problem that was found in the given {@link Expression}. The start index
   * is the position of the given {@link Expression} within the JPQL query and the end index is
   * the end position of the {@link Expression} within the JPQL query.
   *
   * @param expression The {@link Expression} that is either not following the BNF grammar or that
   * has semantic problems
   * @param messageKey The key used to retrieve the localized message describing the problem
   * @param messageArguments The list of arguments that can be used to format the localized
   * description of the problem
   */
  protected final void addProblem(Expression expression, String messageKey, String... arguments) {
    int startPosition = position(expression);
    int endPosition   = startPosition + length(expression);
    addProblem(expression, startPosition, endPosition, messageKey, arguments);
  }

  protected final ExpressionValidator buildExpressionValidator(String... queryBNFs) {
    JPQLQueryBNF[] bnfs = new JPQLQueryBNF[queryBNFs.length];
    for (int index = queryBNFs.length; --index >= 0; ) {
      bnfs[index] = AbstractExpression.queryBNF(queryBNFs[index]);
    }
    return new ExpressionValidator(bnfs);
  }

  /**
   * Creates a new validation problem that was found in the given {@link Expression}.
   *
   * @param expression The {@link Expression} that is either not following the BNF grammar or that
   * has semantic problems
   * @param startIndex The position where the problem was encountered
   * @param endIndex The position where the problem ends, inclusively
   * @param messageKey The key used to retrieve the localized message describing the problem
   * @param messageArguments The list of arguments that can be used to format the localized
   * description of the problem
   * @return The {@link QueryProblem} describing a problem
   */
  private JPQLQueryProblem buildProblem(Expression expression,
                                        int startIndex,
                                        int endIndex,
                                        String messageKey,
                                        String... messageArguments) {

    return new DefaultJPQLQueryProblem(
      queryContext.getQuery(),
      expression,
      startIndex,
      endIndex,
      messageKey,
      messageArguments
    );
  }

  protected final BypassChildCollectionExpressionVisitor bypassChildCollectionExpressionVisitor() {
    if (bypassChildCollectionExpressionVisitor == null) {
      bypassChildCollectionExpressionVisitor = new BypassChildCollectionExpressionVisitor();
    }
    return bypassChildCollectionExpressionVisitor;
  }

  protected final BypassParentSubExpressionVisitor bypassParentSubExpressionVisitor() {
    if (bypassParentSubExpressionVisitor == null) {
      bypassParentSubExpressionVisitor = new BypassParentSubExpressionVisitor();
    }
    return bypassParentSubExpressionVisitor;
  }

  private int calculatePosition(Expression expression, int position) {

    AbstractExpression parent = (AbstractExpression) expression.getParent();

    // Reach the root
    if (parent == null) {
      return position;
    }

    // Traverse the expression until the expression
    for (Iterator<StringExpression> iter = parent.orderedChildren(); iter.hasNext(); ) {
      StringExpression childExpression = iter.next();

      // Continue to calculate the position by going up the hierarchy
      if (childExpression == expression) {
        return calculatePosition(parent, position);
      }

      position += childExpression.toParsedText().length();
    }

    // Never reach this
    throw new RuntimeException();
  }

  /**
   * Retrieves the children of the given {@link Expression}. If it only has one child and it's a
   * {@link CollectionExpression}, then its children will be added to the collection.
   *
   * @param expression The {@link Expression} to visit
   * @return The children of the given {@link Expression}
   */
  protected final Collection<Expression> children(Expression expression) {
    ChildrenCollectorVisitor visitor = childrenCollectorVisitor();
    try {
      visitor.expressions = new ArrayList<Expression>();
      expression.accept(visitor);
      return visitor.expressions;
    }
    finally {
      visitor.expressions = null;
    }
  }

  private ChildrenCollectorVisitor childrenCollectorVisitor() {
    if (childrenCollectorVisitor == null) {
      childrenCollectorVisitor = new ChildrenCollectorVisitor();
    }
    return childrenCollectorVisitor;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void dispose() {
    super.dispose();
    problems = null;
  }

  protected final ExpressionValidator expressionValidator(String queryBNF) {
    ExpressionValidator validator = validators.get(queryBNF);
    if (validator == null) {
      validator = new ExpressionValidator(AbstractExpression.queryBNF(queryBNF));
      validators.put(queryBNF, validator);
    }
    return validator;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected void initialize() {
    super.initialize();
    validators = new HashMap<String, ExpressionValidator>();
  }

  protected final ExpressionValidator internalOrderByItemBNFValidator(IPlatform platform) {

    if (platform == IPlatform.ECLIPSE_LINK) {
      return buildExpressionValidator(InternalOrderByItemBNF.ID);
    }

    return buildExpressionValidator(
      StateFieldPathExpressionBNF.ID,
      IdentificationVariableBNF.ID,
      ResultVariableBNF.ID
    );
  }

  /**
   * Determines whether the given {@link Expression} is a child of a conditional clause, i.e.
   * either owned by the <b>WHERE</b> or <b>HAVING</b> clause.
   *
   * @param expression The {@link Expression} to visit its parent hierarchy up to the clause
   * @return <code>true</code> if the first parent being a clause is the <b>WHERE</b> or
   * <b>HAVING</b> clause; <code>false</code> otherwise
   */
  protected final boolean isOwnedByConditionalClause(Expression expression) {
    OwningClauseVisitor visitor = owningClauseVisitor();
    try {
      expression.accept(visitor);
      return visitor.whereClause  != null ||
             visitor.havingClause != null;
    }
    finally {
      visitor.dispose();
    }
  }

  /**
   * Determines whether the given {@link Expression} is a child of the <b>FROM</b> clause of the
   * top-level query.
   *
   * @param expression The {@link Expression} to visit its parent hierarchy up to the clause
   * @return <code>true</code> if the first parent being a clause is the top-level <b>FROM</b>
   * clause; <code>false</code> otherwise
   */
  protected final boolean isOwnedByFromClause(Expression expression) {
    OwningClauseVisitor visitor = owningClauseVisitor();
    try {
      expression.accept(visitor);
      return visitor.fromClause != null;
    }
    finally {
      visitor.dispose();
    }
  }

  /**
   * Determines whether the given {@link Expression} is a child of the <b>FROM</b> clause of a
   * subquery.
   *
   * @param expression The {@link Expression} to visit its parent hierarchy up to the clause
   * @return <code>true</code> if the first parent being a clause is the <b>FROM</b> clause of a
   * subquery; <code>false</code> otherwise
   */
  protected final boolean isOwnedBySubFromClause(Expression expression) {
    OwningClauseVisitor visitor = owningClauseVisitor();
    try {
      expression.accept(visitor);
      return visitor.simpleFromClause != null;
    }
    finally {
      visitor.dispose();
    }
  }

  /**
   * Determines whether the given {@link Expression} part is an expression of the given query BNF.
   *
   * @param expression The {@link Expression} to validate based on the query BNF
   * @return <code>true</code> if the {@link Expression} part is a child of the given query BNF;
   * <code>false</code> otherwise
   */
  protected final boolean isValid(Expression expression, String queryBNF) {
    ExpressionValidator validator = expressionValidator(queryBNF);
    try {
      expression.accept(validator);
      return validator.valid;
    }
    finally {
      validator.valid = false;
    }
  }

  /**
   * Determines whether the given variable is a valid Java identifier, which means it follows the
   * Java specification. The first letter has to be a Java identifier start and the others have to
   * be Java identifier parts.
   *
   * @param variable The variable to validate
   * @return <code>true</code> if the given variable follows the Java identifier specification;
   * <code>false</code> otherwise
   */
  protected final boolean isValidJavaIdentifier(String variable) {

    for (int index = 0, count = variable.length(); index < count; index++) {
      int character = variable.charAt(index);

      if ((index == 0) && !Character.isJavaIdentifierStart(character)) {
        return false;
      }

      else if ((index > 0) && !Character.isJavaIdentifierPart(character)) {
        return false;
      }
    }

    return true;
  }

  /**
   * Determines whether the given {@link Expression} part is an expression of the given query BNF.
   * The {@link CollectionExpression} that may be the direct child of the given {@link Expression}
   * will be bypassed.
   *
   * @param expression The {@link Expression} to validate based on the query BNF
   * @return <code>true</code> if the {@link Expression} part is a child of the given query BNF;
   * <code>false</code> otherwise
   */
  protected final boolean isValidWithChildCollectionBypass(Expression expression, String queryBNF) {
    ExpressionValidator validator = expressionValidator(queryBNF);
    BypassChildCollectionExpressionVisitor bypassValidator = bypassChildCollectionExpressionVisitor();
    try {
      bypassValidator.visitor = validator;
      expression.accept(bypassValidator);
      return validator.valid;
    }
    finally {
      bypassValidator.visitor = null;
      validator.valid = false;
    }
  }

  protected final boolean isValidWithFindQueryBNF(AbstractExpression expression, String queryBNF) {
    ExpressionValidator validator = expressionValidator(queryBNF);
    try {
      JPQLQueryBNF childQueryBNF = expression.getParent().findQueryBNF(expression);
      validator.validate(childQueryBNF);
      return validator.valid;
    }
    finally {
      validator.valid = false;
    }
  }

  /**
   * Determines whether the given {@link Expression} part is an expression of the given query BNF.
   * The parent {@link SubExpression} that may be the parent of the given {@link Expression} will
   * be bypassed.
   *
   * @param expression The {@link Expression} to validate based on the query BNF
   * @return <code>true</code> if the {@link Expression} part is a child of the given query BNF;
   * <code>false</code> otherwise
   */
  protected final boolean isValidWithParentSubExpressionBypass(Expression expression, String queryBNF) {
    ExpressionValidator validator = expressionValidator(queryBNF);
    BypassParentSubExpressionVisitor bypassValidator = bypassParentSubExpressionVisitor();
    try {
      bypassValidator.visitor = validator;
      expression.accept(bypassValidator);
      return validator.valid;
    }
    finally {
      bypassValidator.visitor = null;
      validator.valid = false;
    }
  }

  /**
   * Returns the length of the string representation of the given {@link Expression}.
   *
   * @param expression The {@link Expression} to retrieve the length of its string
   * @return The length of the string representation of the given {@link Expression}
   */
  protected final int length(Expression expression) {
    return expression.toParsedText().length();
  }

  /**
   * Returns the visitor that traverses the parent hierarchy of any {@link Expression} and stop at
   * the first {@link Expression} that is a clause.
   *
   * @return {@link OwningClauseVisitor}
   */
  protected final OwningClauseVisitor owningClauseVisitor() {
    if (owningClauseVisitor == null) {
      owningClauseVisitor = new OwningClauseVisitor();
    }
    return owningClauseVisitor;
  }

  /**
   * Calculates the position of the given expression by calculating the length of what is before.
   *
   * @param expression The expression to determine its position within the parsed tree
   * @return The length of the string representation of what comes before the given expression
   */
  protected final int position(Expression expression) {
    return calculatePosition(expression, 0);
  }

  /**
   * Sets the list that will be used to store {@link JPQLQueryProblem problems} this validator will
   * find in the JPQL query.
   *
   * @param problems A non-<code>null</code> list that will be used to store the {@link
   * JPQLQueryProblem problems} if any was found
   */
  public final void setProblems(List<JPQLQueryProblem> problems) {
    this.problems = problems;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected void visit(Expression expression) {
    expression.acceptChildren(this);
  }

  /**
   * This visitor is responsible to traverse the children of a {@link CollectionExpression} in
   * order to properly validate the {@link Expression}.
   */
  protected final static class BypassChildCollectionExpressionVisitor extends AnonymousExpressionVisitor {

    /**
     * The visitor that will visit the {@link Expression}.
     */
    public ExpressionValidator visitor;

    /**
     * Creates a new <code>BypassChildCollectionExpressionVisitor</code>.
     */
    public BypassChildCollectionExpressionVisitor() {
      super();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CollectionExpression expression) {
      for (Expression child : expression.getChildren()) {
        child.accept(this);
        if (!visitor.valid) {
          break;
        }
      }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void visit(Expression expression) {
      expression.accept(visitor);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NullExpression expression) {
      // Ignore this, it should be validated by another validator
    }
  }

  /**
   * This visitor is responsible to traverse the parent hierarchy and to skip {@link SubExpression}
   * if it's a parent.
   */
  protected final static class BypassParentSubExpressionVisitor extends AnonymousExpressionVisitor {

    /**
     * The {@link ExpressionVisitor} that will visit the {@link Expression}.
     */
    public ExpressionVisitor visitor;

    /**
     * Creates a new <code>BypassParentSubExpressionVisitor</code>.
     */
    public BypassParentSubExpressionVisitor() {
      super();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void visit(Expression expression) {
      expression.accept(visitor);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubExpression expression) {
      expression.getParent().accept(this);
    }
  }

  /**
   * This visitor gathers the children of a {@link CollectionExpression} or a single visited
   * {@link Expression}.
   */
  private static class ChildrenCollectorVisitor extends AnonymousExpressionVisitor {

    /**
     * The unique {@link Expression} that was visited or the {@link CollectionExpression}'s
     * children.
     */
    List<Expression> expressions;

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(CollectionExpression expression) {
      expressions.addAll(Arrays.asList(expression.getChildren()));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void visit(Expression expression) {
      expressions.add(expression);
    }
  }

  /**
   * This visitor validates any {@link Expression} by checking its BNF against some BNFs.
   */
  protected static class ExpressionValidator extends AnonymousExpressionVisitor {

    /**
     * The query BNF used to determine if the expression's BNF is valid.
     */
    private JPQLQueryBNF queryBNF;

    /**
     * The list of query BNFs used to determine if the expression's BNF is valid.
     */
    private JPQLQueryBNF[] queryBNFs;

    /**
     * Determines whether the visited {@link Expression}'s BNF is valid based on the BNF that was
     * used for validation.
     */
    public boolean valid;

    /**
     * Creates a new <code>ExpressionValidator</code>.
     *
     * @param queryBNF The query BNF used to determine if the expression's BNF is valid
     */
    protected ExpressionValidator(JPQLQueryBNF queryBNF) {
      super();
      this.queryBNF = queryBNF;
    }

    /**
     * Creates a new <code>ExpressionValidator</code>.
     *
     * @param queryBNF The query BNF used to determine if the expression's BNF is valid
     */
    protected ExpressionValidator(JPQLQueryBNF... queryBNFs) {
      super();
      this.queryBNFs = queryBNFs;
    }

    private void allJPQLQueryBNFs(Set<JPQLQueryBNF> queryBNFs, JPQLQueryBNF queryBNF) {
      if (queryBNFs.add(queryBNF) && !queryBNF.isCompound()) {
        for (JPQLQueryBNF childQueryBNF : queryBNF.nonCompoundChildren()) {
          allJPQLQueryBNFs(queryBNFs, childQueryBNF);
        }
      }
    }

    private void validate(JPQLQueryBNF queryBNF) {

      // By setting the flag to false will assure that if this validator is used for
      // more than one item, it will reflect the global validity state. If all are
      // valid, then the last expression will set the flag to true
      valid = false;

      if (queryBNFs != null) {
        valid = Arrays.asList(queryBNFs).contains(queryBNF);
      }
      else {
        Set<JPQLQueryBNF> allQueryBNFs = new HashSet<JPQLQueryBNF>();
        allJPQLQueryBNFs(allQueryBNFs, this.queryBNF);
        valid = allQueryBNFs.contains(queryBNF);
      }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(BadExpression expression) {
      // This is not a valid expression
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void visit(Expression expression) {
      validate(((AbstractExpression) expression).getQueryBNF());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(NullExpression expression) {
      // The missing expression is validated by GrammarValidator
      valid = true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SubExpression expression) {
      if (expression.hasExpression()) {
        AbstractExpression childExpression = (AbstractExpression) expression.getExpression();
        validate(childExpression.getQueryBNF());
      }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UnknownExpression expression) {
      // This is not a valid expression
    }
  }

  /**
   * This visitor retrieves the clause owning the visited {@link Expression}.
   */
  protected static final class OwningClauseVisitor extends AbstractTraverseParentVisitor {

    public DeleteClause deleteClause;
    public FromClause fromClause;
    public GroupByClause groupByClause;
    public HavingClause havingClause;
    public OrderByClause orderByClause;
    public SelectClause selectClause;
    public SimpleFromClause simpleFromClause;
    public SimpleSelectClause simpleSelectClause;
    public UpdateClause updateClause;
    public WhereClause whereClause;

    /**
     * Creates a new <code>OwningClauseVisitor</code>.
     */
    public OwningClauseVisitor() {
      super();
    }

    /**
     * Disposes the internal data.
     */
    protected void dispose() {
      deleteClause       = null;
      fromClause         = null;
      groupByClause      = null;
      havingClause       = null;
      orderByClause      = null;
      selectClause       = null;
      simpleFromClause   = null;
      simpleSelectClause = null;
      updateClause       = null;
      whereClause        = null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(DeleteClause expression) {
      deleteClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(FromClause expression) {
      fromClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(GroupByClause expression) {
      groupByClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(HavingClause expression) {
      havingClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(OrderByClause expression) {
      orderByClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SelectClause expression) {
      selectClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SimpleFromClause expression) {
      simpleFromClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(SimpleSelectClause expression) {
      simpleSelectClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(UpdateClause expression) {
      updateClause = expression;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void visit(WhereClause expression) {
      whereClause = expression;
    }
  }
}
TOP

Related Classes of org.eclipse.persistence.jpa.internal.jpql.AbstractValidator$ChildrenCollectorVisitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
-20639858-1', 'auto'); ga('send', 'pageview');