org.eclipse.persistence.jpa.jpql.parser.AbstractConditionalClause Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of eclipselink Show documentation
Show all versions of eclipselink Show documentation
EclipseLink build based upon Git transaction f2b9fc5
/*
* 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.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.WordParser;
/**
* Conditional expressions are composed of other conditional expressions, comparison operations,
* logical operations, path expressions that evaluate to boolean values, boolean literals, and
* boolean input parameters. Arithmetic expressions can be used in comparison expressions.
* Arithmetic expressions are composed of other arithmetic expressions, arithmetic operations, path
* expressions that evaluate to numeric values, numeric literals, and numeric input parameters.
* Arithmetic operations use numeric promotion. Standard bracketing () for ordering expression
* evaluation is supported.
*
* BNF: expression ::= identifier conditional_expression
*
* @see HavingClause
* @see OnClause
* @see StartWithClause
* @see WhereClause
*
* @version 2.5
* @since 2.3
* @author Pascal Filion
*/
public abstract class AbstractConditionalClause extends AbstractExpression {
/**
* The expression representing the composition of the conditional expressions.
*/
private AbstractExpression conditionalExpression;
/**
* Determines whether a whitespace was parsed after the identifier.
*/
private boolean hasSpaceAfterIdentifier;
/**
* The actual identifier found in the string representation of the JPQL query.
*/
private String identifier;
/**
* Creates a new AbstractConditionalClause
.
*
* @param parent The parent of this expression
* @param identifier The identifier of this conditional clause
*/
protected AbstractConditionalClause(AbstractExpression parent, String identifier) {
super(parent, identifier);
}
@Override
public void acceptChildren(ExpressionVisitor visitor) {
getConditionalExpression().accept(visitor);
}
@Override
protected final void addChildrenTo(Collection children) {
children.add(getConditionalExpression());
}
@Override
protected final void addOrderedChildrenTo(List children) {
// Identifier
children.add(buildStringExpression(getText()));
// Space
if (hasSpaceAfterIdentifier) {
children.add(buildStringExpression(SPACE));
}
// Conditional Expression
if (conditionalExpression != null) {
children.add(conditionalExpression);
}
}
/**
* Creates a new {@link CollectionExpression} that will wrap the single select item.
*
* @return The single select item represented by a temporary collection
*/
public CollectionExpression buildCollectionExpression() {
List children = new ArrayList<>(1);
children.add((AbstractExpression) getConditionalExpression());
List commas = new ArrayList<>(1);
commas.add(Boolean.FALSE);
List spaces = new ArrayList<>(1);
spaces.add(Boolean.FALSE);
return new CollectionExpression(this, children, commas, spaces, true);
}
@Override
public JPQLQueryBNF findQueryBNF(Expression expression) {
if ((conditionalExpression != null) && conditionalExpression.isAncestor(expression)) {
return getQueryBNF(ConditionalExpressionBNF.ID);
}
return super.findQueryBNF(expression);
}
/**
* 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 final String getActualIdentifier() {
return identifier;
}
/**
* Returns the expression representing the composition of the conditional expressions.
*
* @return The actual conditional expression
*/
public final Expression getConditionalExpression() {
if (conditionalExpression == null) {
conditionalExpression = buildNullExpression();
}
return conditionalExpression;
}
/**
* Returns the JPQL identifier of this expression.
*
* @return The JPQL identifier
*/
public final String getIdentifier() {
return getText();
}
/**
* Determines whether the conditional expression was parsed.
*
* @return true
if there is a conditional expression; false
otherwise
*/
public final boolean hasConditionalExpression() {
return conditionalExpression != null &&
!conditionalExpression.isNull();
}
/**
* Determines whether a whitespace was parsed after the identifier or not.
*
* @return true
if there was a whitespace after the identifier; false
* otherwise
*/
public final boolean hasSpaceAfterIdentifier() {
return hasSpaceAfterIdentifier;
}
@Override
protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
return wordParser.character() == RIGHT_PARENTHESIS ||
super.isParsingComplete(wordParser, word, expression);
}
@Override
protected final void parse(WordParser wordParser, boolean tolerant) {
// Parse the identifier
identifier = wordParser.moveForward(getText());
hasSpaceAfterIdentifier = wordParser.skipLeadingWhitespace() > 0;
// Parse the conditional expression
conditionalExpression = parse(wordParser, ConditionalExpressionBNF.ID, tolerant);
}
@Override
protected boolean shouldSkipLiteral(AbstractExpression expression) {
return false;
}
@Override
protected final void toParsedText(StringBuilder writer, boolean actual) {
writer.append(actual ? identifier : getText());
if (hasSpaceAfterIdentifier) {
writer.append(SPACE);
}
if (conditionalExpression != null) {
conditionalExpression.toParsedText(writer, actual);
}
}
}