/*******************************************************************************
* Copyright (c) 2009 BestSolution.at and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
*******************************************************************************/
package org.eclipse.emf.example.library.service.internal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import java.util.List;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStack;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.command.CommandParameter;
import org.eclipse.emf.edit.command.OverrideableCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.example.library.service.ISavePoint;
import org.eclipse.emf.example.library.service.ISavePointEditingDomain;
public class SavePointEditingDomain implements EditingDomain, ISavePointEditingDomain {
private EditingDomain wrappedDomain;
private List<SavePoint> savePoints;
private boolean skipEvent;
public static class SavePoint implements ISavePoint {
private String name;
private int count;
private SavePointEditingDomain domain;
private boolean disposed;
SavePoint(SavePointEditingDomain domain, String name) {
this.domain = domain;
this.name = name;
}
public void dispose() {
disposed = true;
domain.removeSavePoint(this);
}
public void rollback() {
domain.rollbackToSavePoint(this);
}
public boolean canRollback() {
return ! disposed;
}
}
private CommandStackListener stackListener = new CommandStackListener() {
public void commandStackChanged(EventObject event) {
if( savePoints != null && ! skipEvent ) {
for( SavePoint p : savePoints ) {
p.count++;
}
}
}
};
public SavePointEditingDomain(EditingDomain wrappedDomain) {
this.wrappedDomain = wrappedDomain;
}
public Command createCommand(Class<? extends Command> commandClass,
CommandParameter commandParameter) {
return wrappedDomain.createCommand(commandClass, commandParameter);
}
public Command createOverrideCommand(OverrideableCommand command) {
return wrappedDomain.createOverrideCommand(command);
}
public Resource createResource(String fileNameURI) {
return wrappedDomain.createResource(fileNameURI);
}
public Collection<?> getChildren(Object object) {
return wrappedDomain.getChildren(object);
}
public Collection<Object> getClipboard() {
return wrappedDomain.getClipboard();
}
public CommandStack getCommandStack() {
return new CommandStack() {
public void addCommandStackListener(CommandStackListener listener) {
wrappedDomain.getCommandStack().addCommandStackListener(listener);
}
public boolean canRedo() {
return wrappedDomain.getCommandStack().canRedo();
}
public boolean canUndo() {
return wrappedDomain.getCommandStack().canUndo();
}
public void execute(Command command) {
wrappedDomain.getCommandStack().execute(command);
}
public void flush() {
wrappedDomain.getCommandStack().flush();
}
public Command getMostRecentCommand() {
return wrappedDomain.getCommandStack().getMostRecentCommand();
}
public Command getRedoCommand() {
return wrappedDomain.getCommandStack().getRedoCommand();
}
public Command getUndoCommand() {
return wrappedDomain.getCommandStack().getUndoCommand();
}
public void redo() {
try {
skipEvent = true;
wrappedDomain.getCommandStack().redo();
if( savePoints != null ) {
for( SavePoint p : savePoints ) {
p.count++;
}
}
} finally {
skipEvent = false;
}
}
public void removeCommandStackListener(CommandStackListener listener) {
wrappedDomain.getCommandStack().removeCommandStackListener(listener);
}
public void undo() {
try {
skipEvent = true;
wrappedDomain.getCommandStack().undo();
if( savePoints != null ) {
ArrayList<SavePoint> points = new ArrayList<SavePoint>(savePoints);
for( SavePoint p : points ) {
p.count--;
if( p.count == 0 ) {
p.dispose();
}
}
}
} finally {
skipEvent = false;
}
}
};
}
public Collection<?> getNewChildDescriptors(Object object, Object sibling) {
return wrappedDomain.getNewChildDescriptors(object, sibling);
}
public boolean getOptimizeCopy() {
return wrappedDomain.getOptimizeCopy();
}
public Object getParent(Object object) {
return wrappedDomain.getParent(object);
}
public ResourceSet getResourceSet() {
return wrappedDomain.getResourceSet();
}
public Object getRoot(Object object) {
return wrappedDomain.getRoot(object);
}
public List<?> getTreePath(Object object) {
return wrappedDomain.getTreePath(object);
}
public boolean isControllable(Object object) {
return wrappedDomain.isControllable(object);
}
public boolean isReadOnly(Resource resource) {
return wrappedDomain.isReadOnly(resource);
}
public Resource loadResource(String fileNameURI) {
return wrappedDomain.loadResource(fileNameURI);
}
public void setClipboard(Collection<Object> clipboard) {
wrappedDomain.setClipboard(clipboard);
}
public TreeIterator<?> treeIterator(Object object) {
return wrappedDomain.treeIterator(object);
}
private boolean rollbackToSavePoint(SavePoint savepoint) {
if( savePoints != null ) {
if( savepoint != null ) {
int steps = savepoint.count;
CommandStack stack = getCommandStack();
if( steps > 0 ) {
for( int i = 0; i < steps; i++ ) {
if( stack.canUndo() ) {
stack.undo();
} else {
return false;
}
}
return true;
}
}
}
return false;
}
public ISavePoint addSavePoint(String savepoint) {
if( savePoints == null ) {
savePoints = new ArrayList<SavePoint>();
getCommandStack().addCommandStackListener(stackListener);
}
SavePoint p;
if( (p = getSavePoint(savepoint)) == null ) {
p = new SavePoint(this,savepoint);
savePoints.add(p);
}
return p;
}
private void removeSavePoint(SavePoint savepoint) {
if( savePoints != null ) {
savePoints.remove(savepoint);
if( savePoints.size() == 0 ) {
savePoints = null;
getCommandStack().removeCommandStackListener(stackListener);
}
}
}
public SavePoint getSavePoint(String savepoint) {
if( savePoints != null ) {
for( SavePoint p : savePoints ) {
if( p.name.equals(savepoint) ) {
return p;
}
}
}
return null;
}
}