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

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

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

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

/**
 * The UNION clause allows the results of two queries to be combined.
 *
 * 
BNF: union_clause ::= { UNION | INTERSECT | EXCEPT } [ALL] subquery
* * @version 2.5 * @since 2.4 * @author James Sutherland */ public final class UnionClause extends AbstractExpression { /** * The actual identifier found in the string representation of the JPQL query. */ private String actualIdentifier; /** * The actual All identifier found in the string representation of the JPQL query. */ private String allIdentifier; /** * Determines whether a whitespace was parsed after ALL. */ private boolean hasSpaceAfterAll; /** * Determines whether a whitespace was parsed after UNION. */ private boolean hasSpaceAfterIdentifier; /** * The {@link Expression} representing the unioned query. */ private AbstractExpression query; /** * Creates a new UnionClause. * * @param parent The parent of this expression * @param identifier Either UNION, INTERSECT or * EXCEPT */ public UnionClause(AbstractExpression parent, String identifier) { super(parent, identifier); } @Override public void accept(ExpressionVisitor visitor) { acceptUnknownVisitor(visitor); } @Override public void acceptChildren(ExpressionVisitor visitor) { getQuery().accept(visitor); } @Override protected void addChildrenTo(Collection children) { children.add(getQuery()); } @Override protected void addOrderedChildrenTo(List children) { // 'UNION' or 'INTERSECT' or 'EXCEPT' children.add(buildStringExpression(getText())); if (hasSpaceAfterIdentifier) { children.add(buildStringExpression(SPACE)); } // 'ALL' if (allIdentifier != null) { children.add(buildStringExpression(ALL)); if (hasSpaceAfterAll) { children.add(buildStringExpression(SPACE)); } } // Subquery if (query != null) { children.add(query); } } @Override public JPQLQueryBNF findQueryBNF(Expression expression) { if ((query != null) && query.isAncestor(expression)) { return getQueryBNF(SubqueryBNF.ID); } return super.findQueryBNF(expression); } /** * Returns the actual ALL found in the string representation of the JPQL * query, which has the actual case that was used. * * @return The ALL identifier that was actually parsed */ public String getActualAll() { return allIdentifier; } /** * Returns the actual identifier found in the string representation of the JPQL query, which * has the actual case that was used. * * @return The identifier that was actually parsed */ public String getActualIdentifier() { return actualIdentifier; } /** * Returns the union identifier. * * @return Either "UNION", "INTERSECT", "EXCEPT" */ public String getIdentifier() { return getText(); } /** * Returns the {@link Expression} representing the unioned query. * * @return The {@link Expression} representing the subquery */ public Expression getQuery() { if (query == null) { query = buildNullExpression(); } return query; } @Override public JPQLQueryBNF getQueryBNF() { return getQueryBNF(UnionClauseBNF.ID); } /** * Determines whether ALL was parsed. * * @return true if ALL was parsed; false otherwise */ public boolean hasAll() { return allIdentifier != null; } /** * Determines whether the query was parsed. * * @return true the query was parsed; false otherwise */ public boolean hasQuery() { return query != null && !query.isNull(); } /** * Determines whether a whitespace was parsed after ALL. * * @return true if a whitespace was parsed after ALL; * false otherwise */ public boolean hasSpaceAfterAll() { return hasSpaceAfterAll; } /** * Determines whether a whitespace was parsed after the identifier. * * @return true if a whitespace was parsed after the identifier; false otherwise */ public boolean hasSpaceAfterIdentifier() { return hasSpaceAfterIdentifier; } /** * Determines whether this {@link UnionClause} uses the EXCEPT identifier. * * @return true if the identifier is EXCEPT; false otherwise */ public boolean isExcept() { return getText() == EXCEPT; } /** * Determines whether this {@link UnionClause} uses the INTERSECT identifier. * * @return true if the identifier is INTERSECT; false otherwise */ public boolean isIntersect() { return getText() == INTERSECT; } @Override protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) { return word.equalsIgnoreCase(UNION) || word.equalsIgnoreCase(INTERSECT) || word.equalsIgnoreCase(EXCEPT) || super.isParsingComplete(wordParser, word, expression); } /** * Determines whether this {@link UnionClause} uses the UNION identifier. * * @return true if the identifier is UNION; false otherwise */ public boolean isUnion() { return getText() == UNION; } @Override protected void parse(WordParser wordParser, boolean tolerant) { // Parse the identifier String identifier = parseIdentifier(); actualIdentifier = wordParser.moveForward(identifier); setText(identifier); hasSpaceAfterIdentifier = wordParser.skipLeadingWhitespace() > 0; // Parse 'ALL' if (wordParser.startsWithIdentifier(ALL)) { allIdentifier = wordParser.moveForward(ALL); hasSpaceAfterAll = wordParser.skipLeadingWhitespace() > 0; } // Query if (tolerant) { query = parse(wordParser, SubqueryBNF.ID, tolerant); } else { query = new SimpleSelectStatement(this); query.parse(wordParser, tolerant); } } /** * Parses the JPQL identifier identifier the type of union. * * @return Either {@link Expression#UNION UNION}, {@link Expression#INTERSECT INTERSECT} or * {@link Expression#EXCEPT EXCEPT} */ protected String parseIdentifier() { switch (getText().charAt(0)) { case 'U': case 'u': return UNION; case 'I': case 'i': return INTERSECT; case 'E': case 'e': return EXCEPT; default: return null; // Never happens } } @Override protected void toParsedText(StringBuilder writer, boolean actual) { // 'UNION', 'INTERSECT' or 'EXCEPT' writer.append(actual ? actualIdentifier : getText()); if (hasSpaceAfterIdentifier) { writer.append(SPACE); } // 'ALL' if (allIdentifier != null) { writer.append(actual ? allIdentifier : ALL); if (hasSpaceAfterAll) { writer.append(SPACE); } } // Query if (query != null) { query.toParsedText(writer, actual); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy