org.eclipse.persistence.jpa.jpql.parser.GroupByClause 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;
/**
* The GROUP BY construct enables the aggregation of values according to the properties of an
* entity class.
*
* BNF: groupby_clause ::= GROUP BY groupby_item {, groupby_item}*
*
* @version 2.5.1
* @since 2.3
* @author Pascal Filion
*/
public final class GroupByClause extends AbstractExpression {
/**
* The unique group by item or the collection of group by items.
*/
private AbstractExpression groupByItems;
/**
* Determines whether a whitespace was parsed after GROUP BY.
*/
private boolean hasSpace;
/**
* The actual GROUP BY identifier found in the string representation of the JPQL query.
*/
private String identifier;
/**
* Creates a new GroupByClause
.
*
* @param parent The parent of this expression
*/
public GroupByClause(AbstractExpression parent) {
super(parent, GROUP_BY);
}
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
@Override
public void acceptChildren(ExpressionVisitor visitor) {
getGroupByItems().accept(visitor);
}
@Override
protected void addChildrenTo(Collection children) {
children.add(getGroupByItems());
}
@Override
protected void addOrderedChildrenTo(List children) {
children.add(buildStringExpression(getText()));
if (hasSpace) {
children.add(buildStringExpression(SPACE));
}
if (groupByItems != null) {
children.add(groupByItems);
}
}
/**
* Creates a new {@link CollectionExpression} that will wrap the single group by item.
*
* @return The single group by item represented by a temporary collection
*/
public CollectionExpression buildCollectionExpression() {
List children = new ArrayList<>(1);
children.add((AbstractExpression) getGroupByItems());
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 ((groupByItems != null) && groupByItems.isAncestor(expression)) {
return getQueryBNF(GroupByItemBNF.ID);
}
return super.findQueryBNF(expression);
}
/**
* Returns the actual GROUP BY found in the string representation of the JPQL query, which
* has the actual case that was used.
*
* @return The GROUP BY identifier that was actually parsed
*/
public String getActualIdentifier() {
return identifier;
}
/**
* Returns the {@link Expression} that represents the list of group by items if any was parsed.
*
* @return The expression that was parsed representing the list of items
*/
public Expression getGroupByItems() {
if (groupByItems == null) {
groupByItems = buildNullExpression();
}
return groupByItems;
}
@Override
public JPQLQueryBNF getQueryBNF() {
return getQueryBNF(GroupByClauseBNF.ID);
}
/**
* Determines whether the list of items was parsed.
*
* @return true
if at least one item was parsed; false
otherwise
*/
public boolean hasGroupByItems() {
return groupByItems != null &&
!groupByItems.isNull();
}
/**
* Determines whether a whitespace was found after GROUP BY.
*
* @return true
if there was a whitespace after GROUP BY; false
otherwise
*/
public boolean hasSpaceAfterGroupBy() {
return hasSpace;
}
@Override
protected void parse(WordParser wordParser, boolean tolerant) {
// Parse 'GROUP BY'
identifier = wordParser.moveForwardIgnoreWhitespace(GROUP_BY);
hasSpace = wordParser.skipLeadingWhitespace() > 0;
// Group by items
groupByItems = parse(wordParser, GroupByItemBNF.ID, tolerant);
}
@Override
protected void toParsedText(StringBuilder writer, boolean actual) {
// 'GROUP BY'
writer.append(actual ? identifier : getText());
if (hasSpace) {
writer.append(SPACE);
}
// Group by items
if (groupByItems != null) {
groupByItems.toParsedText(writer, actual);
}
}
}