blob: 8a04a020085f66c0824c7d52149589807794339d [file] [log] [blame]
/*
* Copyright (c) 2011, 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.tools.model.query;
import java.io.IOException;
import java.util.List;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSingleEncapsulatedExpression;
/**
* This {@link StateObject} represents a JPQL expression that has a JPQL identifier followed by
* an encapsulated expression with parenthesis.
*
* <div><p><b>BNF:</b> <code>expression ::= &lt;identifier&gt;(expression)</code></p></div>
*
* @see org.eclipse.persistence.jpa.jpql.parser.AbstractSingleEncapsulatedExpression AbstractSingleEncapsulatedExpression
*
* @version 2.4
* @since 2.4
* @author Pascal Filion
*/
@SuppressWarnings("nls")
public abstract class AbstractSingleEncapsulatedExpressionStateObject extends AbstractEncapsulatedExpressionStateObject {
/**
* The {@link StateObject} representing the encapsulated expression.
*/
private StateObject stateObject;
/**
* Notifies the encapsulated {@link StateObject} has changed.
*/
public static final String STATE_OBJECT_PROPERTY = "stateObject";
/**
* Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
*
* @param parent The parent of this state object, which cannot be <code>null</code>
* @exception NullPointerException The given parent cannot be <code>null</code>
*/
protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent) {
super(parent);
}
/**
* Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
*
* @param parent The parent of this state object, which cannot be <code>null</code>
* @param stateObject The {@link StateObject} representing the encapsulated expression
* @exception NullPointerException The given parent cannot be <code>null</code>
*/
protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent,
StateObject stateObject) {
super(parent);
this.stateObject = parent(stateObject);
}
/**
* Creates a new <code>AbstractSingleEncapsulatedExpressionStateObject</code>.
*
* @param parent The parent of this state object, which cannot be <code>null</code>
* @param jpqlFragment The portion of the query representing the encapsulated expression
* @exception NullPointerException The given parent cannot be <code>null</code>
*/
protected AbstractSingleEncapsulatedExpressionStateObject(StateObject parent,
String jpqlFragment) {
super(parent);
parse(jpqlFragment);
}
@Override
protected void addChildren(List<StateObject> children) {
super.addChildren(children);
if (stateObject != null) {
children.add(stateObject);
}
}
@Override
public AbstractSingleEncapsulatedExpression getExpression() {
return (AbstractSingleEncapsulatedExpression) super.getExpression();
}
/**
* Returns the unique identifier of the {@link org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF
* JPQLQueryBNF} that will determine how to parse the encapsulated expression.
*
* @return The non-<code>null</code> ID of the BNF
*/
protected abstract String getQueryBNFId();
/**
* Returns the encapsulated {@link StateObject}.
*
* @return The encapsulated {@link StateObject}
*/
public StateObject getStateObject() {
return stateObject;
}
/**
* Determines whether the {@link StateObject} representing the encapsulated expression is present
* or not.
*
* @return <code>true</code> if the encapsulated {@link StateObject} is not <code>null</code>;
* <code>false</code> otherwise
*/
public boolean hasStateObject() {
return getStateObject() != null;
}
@Override
public boolean isEquivalent(StateObject stateObject) {
if (super.isEquivalent(stateObject)) {
AbstractSingleEncapsulatedExpressionStateObject encapsulated = (AbstractSingleEncapsulatedExpressionStateObject) stateObject;
return areEquivalent(stateObject, encapsulated.stateObject);
}
return false;
}
/**
* Parses the given JPQL fragment, which represents the encapsulated expression, and creates the
* {@link StateObject}.
*
* @param jpqlFragment The portion of the query representing the encapsulated expression
*/
public void parse(String jpqlFragment) {
StateObject stateObject = buildStateObject(jpqlFragment, getQueryBNFId());
setStateObject(stateObject);
}
/**
* Sets the given {@link StateObject} to represent the new encapsulated expression.
*
* @param stateObject The new encapsulated {@link StateObject}
*/
protected void setStateObject(StateObject stateObject) {
StateObject oldStateObject = this.stateObject;
this.stateObject = parent(stateObject);
firePropertyChanged(STATE_OBJECT_PROPERTY, oldStateObject, stateObject);
}
@Override
protected void toTextEncapsulatedExpression(Appendable writer) throws IOException {
if (stateObject != null) {
stateObject.toString(writer);
}
}
}