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

org.eclipse.persistence.jpa.jpql.parser.CollectionExpression Maven / Gradle / Ivy

There is a newer version: 5.0.0-B03
Show newest version
/*
 * Copyright (c) 2006, 2020 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.parser;

import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.WordParser;

/**
 * A CollectionExpression wraps many expression which they are separated by spaces
 * and/or commas.
 *
 * 
BNF: expression ::= child_item {, child_item }*
*
* or *
*
BNF: expression ::= child_item { child_item }*

* * @version 2.5 * @since 2.3 * @author Pascal Filion */ @SuppressWarnings("nls") public final class CollectionExpression extends AbstractExpression { /** * The {@link Expression Expressions} that forms a collection within another expression. */ private List children; /** * The list of flags used to determine where to separate two child {@link Expression Expressions} * with a comma or with a space only. */ private List commas; /** * Flag used to determine when a space is required after a comma. */ private List spaces; /** * Creates a new CollectionExpression. * * @param parent The parent of this expression * @param children The list of children that are regrouped together * @param spaces The list of flags used to determine when to add a space after an {@link Expression} * @param commas The list of flags used to determine when to add a comma after an {@link Expression} */ public CollectionExpression(AbstractExpression parent, List children, List commas, List spaces) { this(parent, children, commas, spaces, false); } /** * Creates a new CollectionExpression. * * @param parent The parent of this expression * @param children The list of children that are regrouped together * @param commas The list of flags used to determine when to add a comma after an {@link Expression} * @param spaces The list of flags used to determine when to add a space after an {@link Expression} * @param temporary Flag used to determine if this expression is temporarily used, which means * the children will not be parented to this object */ public CollectionExpression(AbstractExpression parent, List children, List commas, List spaces, boolean temporary) { super(parent); this.children = children; this.commas = commas; this.spaces = spaces; if (!temporary) { updateBackpointers(); } } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } /** * Visits the child {@link Expression} at the given position by the given {@link ExpressionVisitor * visitor}. * * @param index The index of the child to visit * @param visitor The {@link ExpressionVisitor} to visit a specific child * @since 2.4 */ public void accept(int index, ExpressionVisitor visitor) { getChild(index).accept(visitor); } @Override public void acceptChildren(ExpressionVisitor visitor) { for (Expression child : children()) { child.accept(visitor); } } @Override protected void addChildrenTo(Collection children) { // Make sure all children are non null for (int index = 0, childCount = this.children.size(); index < childCount; index++) { getChildInternal(index); } children.addAll(this.children); } @Override protected void addOrderedChildrenTo(List children) { children(); for (int index = 0, count = this.children.size(); index < count; index++) { Expression expression = getChild(index); children.add(expression); // Write ',' if (hasComma(index)) { children.add(buildStringExpression(COMMA)); } // Write whitespace if (hasSpace(index)) { children.add(buildStringExpression(SPACE)); } } } /** * Returns the count of child {@link Expression expressions}. * * @return The total count of {@link Expression expressions} aggregated with spaces and/or commas */ public int childrenSize() { children(); return children.size(); } /** * Determines whether this {@link CollectionExpression} ends with a comma, which means the last * {@link Expression} is a "null" expression. * * @return true if the string representation of this {@link CollectionExpression} * ends with a comma (the ending space is not checked) */ public boolean endsWithComma() { children(); if (children.get(children.size() - 1).isNull()) { return commas.get(commas.size() - 2); } return false; } /** * Determines whether this {@link CollectionExpression} ends with a space, which means the last * {@link Expression} is a "null" expression. * * @return true if the string representation of this {@link CollectionExpression} * ends with a space (the ending comma is not checked) */ public boolean endsWithSpace() { children(); if (children.get(children.size() - 1).isNull()) { return spaces.get(spaces.size() - 2); } return false; } @Override public JPQLQueryBNF findQueryBNF(Expression expression) { return getParent().findQueryBNF(expression); } /** * Retrieves the child {@link Expression} at the given position. * * @param index The position of the child {@link Expression} to retrieve * @return The child {@link Expression} at the given position */ public Expression getChild(int index) { return getChildInternal(index); } private AbstractExpression getChildInternal(int index) { AbstractExpression child = children.get(index); if (child == null) { child = buildNullExpression(); children.set(index, child); } return child; } @Override public JPQLQueryBNF getQueryBNF() { return getParent().getQueryBNF(); } /** * Determines whether a comma was parsed at the given position. The index is the position of the * comma that is following the child at the same position. * * @param index The index of the child {@link Expression} to verify if there is a comma following it * @return true if a comma is following the child {@link Expression} at the given * index; false otherwise */ public boolean hasComma(int index) { children(); return (index < commas.size()) && commas.get(index); } /** * Determines whether a space was parsed at the given position. The index is the position of the * space that is following the child at the same position, which is after a comma, if one was * also parsed at that location. * * @param index The index of the child {@link Expression} to verify if there is a space following * it, which could be after a comma, if one was parsed * @return true if a space is following the child {@link Expression} at the given * index; false otherwise */ public boolean hasSpace(int index) { children(); return (index < spaces.size()) && (spaces.get(index) || hasComma(index) && (index + 1 < children.size() ? !getChildInternal(index + 1).isNull() : false)); } /** * Retrieves the index of the given Expression. * * @param expression The Expression that might be a child of this expression * @return The index in the collection of the given Expression or -1 if it is not a child */ public int indexOf(Expression expression) { children(); return children.indexOf(expression); } @Override protected void parse(WordParser wordParser, boolean tolerant) { throw new IllegalAccessError("This method shouln't be invoked, text=" + wordParser); } /** * Returns a string representation of this {@link Expression} and its children. The expression * should contain whitespace even if the beautified version would not have any. For instance, * "SELECT e " should be returned where {@link Expression#toParsedText()} would return "SELECT e". * * @param endIndex The index used to determine when to create the string representation, which * is exclusive * @return The string representation of this {@link Expression} */ public String toActualText(int endIndex) { StringBuilder writer = new StringBuilder(); toParsedText(writer, endIndex, true); return writer.toString(); } /** * Generates a string representation of this {@link CollectionExpression}. * * @param endIndex The index used to determine when to create the string representation, which * is exclusive * @return The string representation of this {@link Expression} */ public String toParsedText(int endIndex) { StringBuilder writer = new StringBuilder(); toParsedText(writer, endIndex, false); return writer.toString(); } @Override protected void toParsedText(StringBuilder writer, boolean actual) { toParsedText(writer, childrenSize(), actual); } private void toParsedText(StringBuilder writer, int endIndex, boolean actual) { for (int index = 0, count = children.size(); index < endIndex; index++) { AbstractExpression expression = children.get(index); // Write the child expression if (expression != null) { expression.toParsedText(writer, actual); } // Write ',' if (commas.get(index)) { writer.append(COMMA); // If there is a space, then add it if (spaces.get(index)) { writer.append(SPACE); } // Otherwise check if the next expression is not null, if it's null, // then a space will not be added else if (index + 1 < count) { AbstractExpression nextExpression = children.get(index + 1); if ((nextExpression != null) && !nextExpression.isNull()) { writer.append(SPACE); } } } // Write ' ' else if (spaces.get(index)) { writer.append(SPACE); } } } private void updateBackpointers() { for (AbstractExpression child : children) { if (child != null) { child.setParent(this); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy