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

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

There is a newer version: 5.0.0-B03
Show newest version
/*
 * 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.parser;

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

/**
 * 
BNF: general_case_expression ::= CASE when_clause {when_clause}* ELSE scalar_expression END
* or *
BNF: simple_case_expression ::= CASE case_operand simple_when_clause {simple_when_clause}* ELSE scalar_expression END
* * @version 2.5 * @since 2.3 * @author Pascal Filion */ public final class CaseExpression extends AbstractExpression { /** * The actual CASE identifier found in the string representation of the JPQL query. */ private String caseIdentifier; /** * The {@link Expression} representing the case operand. */ private AbstractExpression caseOperand; /** * The {@link Expression} representing the ELSE expression. */ private AbstractExpression elseExpression; /** * The actual ELSE identifier found in the string representation of the JPQL query. */ private String elseIdentifier; /** * The actual END identifier found in the string representation of the JPQL query. */ private String endIdentifier; /** * Determines whether a whitespace was parsed after CASE. */ private boolean hasSpaceAfterCase; /** * Determines whether a whitespace was parsed after the case operand. */ private boolean hasSpaceAfterCaseOperand; /** * Determines whether a whitespace was parsed after ELSE. */ private boolean hasSpaceAfterElse; /** * Determines whether a whitespace was parsed after the BETWEEN expression. */ private boolean hasSpaceAfterElseExpression; /** * Determines whether a whitespace was parsed after WHEN clause. */ private boolean hasSpaceAfterWhenClauses; /** * Used to determine how to check if the parsing is complete. */ private ParsingType parsingType; /** * The {@link Expression} representing the WHEN clauses. */ private AbstractExpression whenClauses; /** * Creates a new CaseExpression. * * @param parent The parent of this expression */ public CaseExpression(AbstractExpression parent) { super(parent, CASE); } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } @Override public void acceptChildren(ExpressionVisitor visitor) { getCaseOperand().accept(visitor); getWhenClauses().accept(visitor); getElseExpression().accept(visitor); } @Override protected void addChildrenTo(Collection children) { children.add(getCaseOperand()); children.add(getWhenClauses()); children.add(getElseExpression()); } @Override protected void addOrderedChildrenTo(List children) { // 'CASE' children.add(buildStringExpression(CASE)); if (hasSpaceAfterCase) { children.add(buildStringExpression(SPACE)); } // Case operand if (caseOperand != null) { children.add(caseOperand); } if (hasSpaceAfterCaseOperand) { children.add(buildStringExpression(SPACE)); } // WHEN clauses if (whenClauses != null) { children.add(whenClauses); } if (hasSpaceAfterWhenClauses) { children.add(buildStringExpression(SPACE)); } // 'ELSE' if (elseIdentifier != null) { children.add(buildStringExpression(ELSE)); } if (hasSpaceAfterElse) { children.add(buildStringExpression(SPACE)); } // Else expression if (elseExpression != null) { children.add(elseExpression); } if (hasSpaceAfterElseExpression) { children.add(buildStringExpression(SPACE)); } // 'END' if (endIdentifier != null) { children.add(buildStringExpression(END)); } } @Override public JPQLQueryBNF findQueryBNF(Expression expression) { if ((caseOperand != null) && caseOperand.isAncestor(expression)) { return getQueryBNF(CaseOperandBNF.ID); } if ((whenClauses != null) && whenClauses.isAncestor(expression)) { return getQueryBNF(WhenClauseBNF.ID); } if ((elseExpression != null) && elseExpression.isAncestor(expression)) { return getQueryBNF(ElseExpressionBNF.ID); } return super.findQueryBNF(expression); } /** * Returns the actual CASE identifier found in the string representation of the JPQL * query, which has the actual case that was used. * * @return The CASE identifier that was actually parsed */ public String getActualCaseIdentifier() { return caseIdentifier; } /** * Returns the actual ELSE identifier found in the string representation of the JPQL * query, which has the actual case that was used. * * @return The ELSE identifier that was actually parsed, or an empty string if it was not * parsed */ public String getActualElseIdentifier() { return (elseIdentifier != null) ? elseIdentifier : ExpressionTools.EMPTY_STRING; } /** * Returns the actual END identifier found in the string representation of the JPQL query, * which has the actual case that was used. * * @return The END identifier that was actually parsed, or an empty string if it was not * parsed */ public String getActualEndIdentifier() { return (endIdentifier != null) ? endIdentifier : ExpressionTools.EMPTY_STRING; } /** * Returns the {@link Expression} that represents the CASE operand. * * @return The expression that was parsed representing the CASE operand */ public Expression getCaseOperand() { if (caseOperand == null) { caseOperand = buildNullExpression(); } return caseOperand; } /** * Returns the {@link Expression} that represents the ELSE operand. * * @return The expression that was parsed representing the ELSE operand */ public AbstractExpression getElseExpression() { if (elseExpression == null) { elseExpression = buildNullExpression(); } return elseExpression; } @Override public JPQLQueryBNF getQueryBNF() { return getQueryBNF(GeneralCaseExpressionBNF.ID); } /** * Returns the {@link Expression} that represents the WHEN clauses. * * @return The expression that was parsed representing the WHEN clauses */ public AbstractExpression getWhenClauses() { if (whenClauses == null) { whenClauses = buildNullExpression(); } return whenClauses; } /** * Determines whether the CASE operand was parsed. * * @return true if the CASE operand was parsed; false otherwise */ public boolean hasCaseOperand() { return caseOperand != null && !caseOperand.isNull(); } /** * Determines whether the identifier ELSE was parsed. * * @return true if the identifier ELSE was parsed; false * otherwise */ public boolean hasElse() { return elseIdentifier != null; } /** * Determines whether the ELSE expression was parsed. * * @return true if the ELSE expression was parsed; false * otherwise */ public boolean hasElseExpression() { return elseExpression != null && !elseExpression.isNull(); } /** * Determines whether the identifier END was parsed. * * @return true if the identifier END was parsed; false otherwise */ public boolean hasEnd() { return endIdentifier != null; } /** * Determines whether a whitespace was parsed after CASE. * * @return true if there was a whitespace after CASE; false * otherwise */ public boolean hasSpaceAfterCase() { return hasSpaceAfterCase; } /** * Determines whether a whitespace was parsed after the case operand. * * @return true if there was a whitespace after the case operand; false * otherwise */ public boolean hasSpaceAfterCaseOperand() { return hasSpaceAfterCaseOperand; } /** * Determines whether a whitespace was parsed after ELSE. * * @return true if there was a whitespace after ELSE; false * otherwise */ public boolean hasSpaceAfterElse() { return hasSpaceAfterElse; } /** * Determines whether a whitespace was parsed after the else expression. * * @return true if there was a whitespace after the else expression; * false otherwise */ public boolean hasSpaceAfterElseExpression() { return hasSpaceAfterElseExpression; } /** * Determines whether a whitespace was parsed after the WHEN clause. * * @return true if there was a whitespace after the WHEN * clause; false otherwise */ public boolean hasSpaceAfterWhenClauses() { return hasSpaceAfterWhenClauses; } /** * Determines whether the WHEN clauses were parsed. * * @return true if the WHEN clauses were parsed; * false otherwise */ public boolean hasWhenClauses() { return whenClauses != null && !whenClauses.isNull(); } @Override protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) { // 'CASE' if (parsingType == ParsingType.CASE) { return word.equalsIgnoreCase(WHEN) || word.equalsIgnoreCase(ELSE) || word.equalsIgnoreCase(END) || super.isParsingComplete(wordParser, word, expression); } // 'WHEN' if (parsingType == ParsingType.WHEN) { return word.equalsIgnoreCase(ELSE) || word.equalsIgnoreCase(END) || super.isParsingComplete(wordParser, word, expression); } // 'ELSE' return word.equalsIgnoreCase(END) || super.isParsingComplete(wordParser, word, expression); } @Override protected void parse(WordParser wordParser, boolean tolerant) { // Parse 'CASE' caseIdentifier = wordParser.moveForward(CASE); hasSpaceAfterCase = wordParser.skipLeadingWhitespace() > 0; // Parse case operand parsingType = ParsingType.CASE; if (!wordParser.startsWithIdentifier(WHEN)) { caseOperand = parse(wordParser, CaseOperandBNF.ID, tolerant); hasSpaceAfterCaseOperand = wordParser.skipLeadingWhitespace() > 0; } // Parse the WHEN clauses parsingType = ParsingType.WHEN; whenClauses = parse(wordParser, WhenClauseBNF.ID, tolerant); hasSpaceAfterWhenClauses = wordParser.skipLeadingWhitespace() > 0; // Parse 'ELSE' if (!tolerant || wordParser.startsWithIdentifier(ELSE)) { elseIdentifier = wordParser.moveForward(ELSE); hasSpaceAfterElse = wordParser.skipLeadingWhitespace() > 0; } // Parse the ELSE expression parsingType = ParsingType.ELSE; elseExpression = parse(wordParser, ElseExpressionBNF.ID, tolerant); hasSpaceAfterElseExpression = wordParser.skipLeadingWhitespace() > 0; // Parse 'END' if (!tolerant || wordParser.startsWithIdentifier(END)) { endIdentifier = wordParser.moveForward(END); } } @Override protected void toParsedText(StringBuilder writer, boolean actual) { // 'CASE' writer.append(actual ? caseIdentifier : CASE); if (hasSpaceAfterCase) { writer.append(SPACE); } // Case Operand if (caseOperand != null) { caseOperand.toParsedText(writer, actual); } if (hasSpaceAfterCaseOperand) { writer.append(SPACE); } // When clauses if (whenClauses != null) { whenClauses.toParsedText(writer, actual); } if (hasSpaceAfterWhenClauses) { writer.append(SPACE); } // 'ELSE' if (elseIdentifier != null) { writer.append(actual ? elseIdentifier : ELSE); } if (hasSpaceAfterElse) { writer.append(SPACE); } // Else expression if (elseExpression != null) { elseExpression.toParsedText(writer, actual); } if (hasSpaceAfterElseExpression) { writer.append(SPACE); } // 'END' if (endIdentifier != null) { writer.append(actual ? endIdentifier : END); } } /** * A enumeration used to determine how {@link CaseExpression#isParsingComplete(WordParser, String, Expression)} * should behaves. */ private enum ParsingType { CASE, ELSE, WHEN } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy