org.eclipse.persistence.jpa.jpql.parser.UpdateItem 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
The 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.WordParser;
/**
* The new_value
specified for an update operation must be compatible in type with the
* field to which it is assigned.
*
* BNF: update_item ::= [identification_variable.]{state_field | single_valued_association_field} = new_value
*
* @see UpdateClause
*
* @version 2.5
* @since 2.3
* @author Pascal Filion
*/
public final class UpdateItem extends AbstractExpression {
/**
* Determines whether the equal sign was parsed or not.
*/
private boolean hasEqualSign;
/**
* Determines whether a whitespace was parsed after the equal sign or not.
*/
private boolean hasSpaceAfterEqualSign;
/**
* Determines whether a whitespace was parsed before the equal sign or not
*/
private boolean hasSpaceAfterStateFieldPathExpression;
/**
* The expression representing the new value.
*/
private AbstractExpression newValue;
/**
* The expression representing the state field to have its value updated.
*/
private AbstractExpression stateFieldExpression;
/**
* Creates a new UpdateItem
.
*
* @param parent The parent of this expression
*/
public UpdateItem(AbstractExpression parent) {
super(parent);
}
@Override
public void accept(ExpressionVisitor visitor) {
visitor.visit(this);
}
@Override
public void acceptChildren(ExpressionVisitor visitor) {
getStateFieldPathExpression().accept(visitor);
getNewValue().accept(visitor);
}
@Override
protected void addChildrenTo(Collection children) {
children.add(getStateFieldPathExpression());
children.add(getNewValue());
}
@Override
protected void addOrderedChildrenTo(List children) {
// State field expression
if (stateFieldExpression != null) {
children.add(stateFieldExpression);
}
if (hasSpaceAfterStateFieldPathExpression) {
children.add(buildStringExpression(SPACE));
}
// '='
if (hasEqualSign) {
children.add(buildStringExpression(EQUAL));
}
if (hasSpaceAfterEqualSign) {
children.add(buildStringExpression(SPACE));
}
// New value
if (newValue != null) {
children.add(newValue);
}
}
@Override
public JPQLQueryBNF findQueryBNF(Expression expression) {
if ((stateFieldExpression != null) && stateFieldExpression.isAncestor(expression)) {
return getQueryBNF(UpdateItemStateFieldPathExpressionBNF.ID);
}
if ((newValue != null) && newValue.isAncestor(expression)) {
return getQueryBNF(NewValueBNF.ID);
}
return super.findQueryBNF(expression);
}
/**
* Returns the {@link Expression} representing the new value, which is the new value of the property.
*
* @return The expression for the new value
*/
public Expression getNewValue() {
if (newValue == null) {
newValue = buildNullExpression();
}
return newValue;
}
@Override
public JPQLQueryBNF getQueryBNF() {
return getQueryBNF(UpdateItemBNF.ID);
}
/**
* Returns the {@link Expression} representing the state field path expression, which is the
* property that should get updated.
*
* @return The expression for the state field path expression
*/
public Expression getStateFieldPathExpression() {
if (stateFieldExpression == null) {
stateFieldExpression = buildNullExpression();
}
return stateFieldExpression;
}
/**
* Determines whether the equal sign was parsed or not.
*
* @return true
if the equal sign was parsed; false
otherwise
*/
public boolean hasEqualSign() {
return hasEqualSign;
}
/**
* Determines whether the new value section of the query was parsed.
*
* @return true
the new value was parsed; false
if nothing was parsed
*/
public boolean hasNewValue() {
return newValue != null &&
!newValue.isNull();
}
/**
* Determines whether a whitespace was parsed after the equal sign or not.
*
* @return true
if there was a whitespace after the equal sign; false
otherwise
*/
public boolean hasSpaceAfterEqualSign() {
return hasSpaceAfterEqualSign;
}
/**
* Determines whether a whitespace was parsed after the state field path expression not.
*
* @return true
if there was a whitespace after the state field path expression;
* false
otherwise
*/
public boolean hasSpaceAfterStateFieldPathExpression() {
return hasSpaceAfterStateFieldPathExpression;
}
/**
* Determines whether the state field was parsed.
*
* @return true
the state field was parsed; false
otherwise
*/
public boolean hasStateFieldPathExpression() {
return stateFieldExpression != null &&
!stateFieldExpression.isNull();
}
@Override
protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
return word.equals(EQUAL) ||
super.isParsingComplete(wordParser, word, expression);
}
@Override
protected void parse(WordParser wordParser, boolean tolerant) {
// Parse state field
if (tolerant) {
stateFieldExpression = parse(wordParser, UpdateItemStateFieldPathExpressionBNF.ID, tolerant);
}
else {
stateFieldExpression = new StateFieldPathExpression(this, wordParser.word());
stateFieldExpression.parse(wordParser, tolerant);
}
hasSpaceAfterStateFieldPathExpression = wordParser.skipLeadingWhitespace() > 0;
// Parse '='
hasEqualSign = wordParser.startsWith(EQUAL);
if (hasEqualSign) {
wordParser.moveForward(1);
hasSpaceAfterEqualSign = wordParser.skipLeadingWhitespace() > 0;
if (stateFieldExpression != null) {
hasSpaceAfterStateFieldPathExpression = true;
}
}
// Parse new value
newValue = parse(wordParser, NewValueBNF.ID, tolerant);
if (!hasSpaceAfterEqualSign && (newValue != null)) {
hasSpaceAfterEqualSign = true;
}
}
@Override
protected void toParsedText(StringBuilder writer, boolean actual) {
// State field expression
if (stateFieldExpression != null) {
stateFieldExpression.toParsedText(writer, actual);
}
if (hasSpaceAfterStateFieldPathExpression) {
writer.append(SPACE);
}
// '='
if (hasEqualSign) {
writer.append(EQUAL);
}
if (hasSpaceAfterEqualSign) {
writer.append(SPACE);
}
// New value
if (newValue != null) {
newValue.toParsedText(writer, actual);
}
}
}