org.eclipse.persistence.jpa.jpql.tools.model.query.UpdateClauseStateObject 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 774c696
/*******************************************************************************
* Copyright (c) 2011, 2014 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 v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Oracle - initial API and implementation
*
******************************************************************************/
package org.eclipse.persistence.jpa.jpql.tools.model.query;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.ListIterator;
import org.eclipse.persistence.jpa.jpql.parser.InternalUpdateClauseBNF;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.tools.model.IListChangeListener;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ListIterable;
import org.eclipse.persistence.jpa.jpql.utility.iterable.SnapshotCloneListIterable;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.*;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.*;
/**
* This is the UPDATE
clause of the UPDATE
statement.
*
* An UPDATE
statement provides bulk operations over sets of entities of a
* single entity class (together with its subclasses, if any). Only one entity abstract schema type
* may be specified in the UPDATE
clause.
*
*
BNF: update_clause ::= UPDATE abstract_schema_name [[AS] identification_variable] SET update_item {, update_item}*
*
* @see UpdateClause
*
* @version 2.5
* @since 2.4
* @author Pascal Filion
*/
@SuppressWarnings({"nls", "unused"}) // unused used for the import statement: see bug 330740
public class UpdateClauseStateObject extends AbstractModifyClauseStateObject
implements ListHolderStateObject {
/**
* The list of {@link UpdateItemStateObject} that represent the update items.
*/
private List items;
/**
* Notify the list of {@link StateObject StateObjects} representing the update items.
*/
public static final String UPDATE_ITEMS_LIST = "items";
/**
* Creates a new UpdateClauseStateObject
.
*
* @param parent The parent of this state object, which cannot be null
* @exception NullPointerException The given parent cannot be null
*/
public UpdateClauseStateObject(UpdateStatementStateObject parent) {
super(parent);
}
/**
* {@inheritDoc}
*/
public void accept(StateObjectVisitor visitor) {
visitor.visit(this);
}
/**
* {@inheritDoc}
*/
@Override
protected void addChildren(List children) {
super.addChildren(children);
children.addAll(items);
}
/**
* Adds a new UPDATE
item to this clause.
*
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem() {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param paths The paths of the value to update
* @param newValue The {@link StateObject} representing the new value
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(ListIterator paths, StateObject newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPaths(paths);
updateItem.setNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param paths The paths of the value to update
* @param newValue The string representation of the new value to parse and to convert into a
* {@link StateObject} representation
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(ListIterator paths, String newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPaths(paths);
updateItem.parseNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param path The path of the value to update
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(String path) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPath(path);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param path The path of the value to update
* @param newValue The {@link StateObject} representing the new value
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(String path, StateObject newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPath(path);
updateItem.setNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param path The path of the value to update
* @param newValue The string representation of the new value to parse and to convert into a
* {@link StateObject} representation
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(String path, String newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPath(path);
updateItem.parseNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param paths The paths of the value to update
* @param newValue The {@link StateObject} representing the new value
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(String[] paths, StateObject newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPaths(paths);
updateItem.setNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* Adds a new UPDATE
item to this clause.
*
* @param paths The paths of the value to update
* @param newValue The string representation of the new value to parse and to convert into a
* {@link StateObject} representation
* @return The newly added {@link UpdateItemStateObject}
*/
public UpdateItemStateObject addItem(String[] paths, String newValue) {
UpdateItemStateObject updateItem = new UpdateItemStateObject(this);
updateItem.setPaths(paths);
updateItem.parseNewValue(newValue);
addItem(updateItem);
return updateItem;
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public UpdateItemStateObject addItem(UpdateItemStateObject item) {
getChangeSupport().addItem(this, items, UPDATE_ITEMS_LIST, parent(item));
return item;
}
/**
* {@inheritDoc}
*/
public void addItems(List items) {
getChangeSupport().addItems(this, this.items, UPDATE_ITEMS_LIST, parent(items));
}
/**
* {@inheritDoc}
*/
public void addListChangeListener(String listName, IListChangeListener listener) {
getChangeSupport().addListChangeListener(listName, listener);
}
/**
* Determines whether the children of this {@link StateObject} are equivalent to the children
* of the given one, i.e. the information of the {@link StateObject StateObjects} is the same.
*
* @param stateObject The {@link StateObject} to compare its children to this one's children
* @return true
if both have equivalent children; false
otherwise
*/
protected boolean areChildrenEquivalent(UpdateClauseStateObject stateObject) {
int size = itemsSize();
if (size != stateObject.itemsSize()) {
return false;
}
for (int index = size; --index >= 0; ) {
StateObject child1 = getItem(index);
StateObject child2 = stateObject.getItem(index);
if (!child1.isEquivalent(child2)) {
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
public boolean canMoveDown(UpdateItemStateObject item) {
return getChangeSupport().canMoveDown(items, item);
}
/**
* {@inheritDoc}
*/
public boolean canMoveUp(UpdateItemStateObject item) {
return getChangeSupport().canMoveUp(items, item);
}
/**
* {@inheritDoc}
*/
@Override
public UpdateClause getExpression() {
return (UpdateClause) super.getExpression();
}
/**
* {@inheritDoc}
*/
@Override
public String getIdentifier() {
return UPDATE;
}
/**
* {@inheritDoc}
*/
public UpdateItemStateObject getItem(int index) {
return items.get(index);
}
/**
* {@inheritDoc}
*/
@Override
public UpdateStatementStateObject getParent() {
return (UpdateStatementStateObject) super.getParent();
}
/**
* {@inheritDoc}
*/
public boolean hasItems() {
return !items.isEmpty();
}
/**
* {@inheritDoc}
*/
@Override
protected void initialize() {
super.initialize();
items = new ArrayList();
}
/**
* {@inheritDoc}
*/
@Override
public boolean isEquivalent(StateObject stateObject) {
return super.isEquivalent(stateObject) &&
areChildrenEquivalent((UpdateClauseStateObject) stateObject);
}
/**
* Determines whether the identification variable has been defined.
*
* @return true
if the identification variable has been specified; false
* otherwise, which means it has been generated based on the abstract schema name
*/
public boolean isIdentificationVariableDefined() {
return !getIdentificationVariableStateObject().isVirtual();
}
/**
* {@inheritDoc}
*/
public ListIterable items() {
return new SnapshotCloneListIterable(items);
}
/**
* {@inheritDoc}
*/
public int itemsSize() {
return items.size();
}
/**
* {@inheritDoc}
*/
public UpdateItemStateObject moveDown(UpdateItemStateObject item) {
getChangeSupport().moveDown(this, items, UPDATE_ITEMS_LIST, item);
return item;
}
/**
* {@inheritDoc}
*/
public UpdateItemStateObject moveUp(UpdateItemStateObject item) {
getChangeSupport().moveUp(this, items, UPDATE_ITEMS_LIST, item);
return item;
}
/**
* Parses the given fragment, which represents a single update item, and creates the {@link
* StateObject} equivalent.
*
* @param jpqlFragment The portion of the query representing a single update item
*/
public void parse(String jpqlFragment) {
UpdateItemStateObject stateObject = buildStateObject(jpqlFragment, InternalUpdateClauseBNF.ID);
addItem(stateObject);
}
/**
* {@inheritDoc}
*/
public void removeItem(UpdateItemStateObject stateObject) {
getChangeSupport().removeItem(this, this.items, UPDATE_ITEMS_LIST, stateObject);
}
/**
* {@inheritDoc}
*/
public void removeItems(Collection items) {
getChangeSupport().removeItems(this, this.items, UPDATE_ITEMS_LIST, items);
}
/**
* {@inheritDoc}
*/
public void removeListChangeListener(String listName, IListChangeListener listener) {
getChangeSupport().removeListChangeListener(listName, listener);
}
/**
* Keeps a reference of the {@link UpdateClause parsed object} object, which should only be
* done when this object is instantiated during the conversion of a parsed JPQL query into
* {@link StateObject StateObjects}.
*
* @param expression The {@link UpdateClause parsed object} representing an UPDATE
* clause
*/
public void setExpression(UpdateClause expression) {
super.setExpression(expression);
}
/**
* {@inheritDoc}
*/
@Override
protected void toTextInternal(Appendable writer) throws IOException {
super.toTextInternal(writer);
writer.append(SPACE);
writer.append(SET);
writer.append(SPACE);
toStringItems(writer, items, true);
}
}