package com.sap.ide.refactoring.core.execution; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.command.CommandStack; import org.eclipse.emf.ecore.resource.ResourceSet; import com.sap.ide.refactoring.core.RefactoringCoreException; /** * Helper class used undo/redo sequences of commands. * * Used by the {@link RefactoringCommandExecutor} to be able to not just undo a single * refactoring command, but to also undo all automatically triggered subsequent commands (e.g. pretty printing * or reference re-evalautions) * * @author Stephan Erb (d049157) * */ public class CommandUndoRedoHelper { private final ResourceSet connection; public CommandUndoRedoHelper(ResourceSet connection) { this.connection = connection; } public void undoRefactoring(CommandHandle handle) throws RefactoringCoreException { undoRefactoring(handle, new NullProgressMonitor()); } public void undoRefactoring(CommandHandle handle, IProgressMonitor pm) throws RefactoringCoreException { if (handle == null) { return; } CommandStack stack = connection.getCommandStack(); pm.beginTask("Undoing Commands", stack.getUndoStack().size()); CommandHandle lastUndoneCmd = null; while (stack.canUndo() && !handle.equals(lastUndoneCmd)) { lastUndoneCmd = peekUndoStack(); stack.undo(); pm.worked(1); } pm.done(); if (lastUndoneCmd == null) { throw new RefactoringCoreException("There was no command to undo"); } if (lastUndoneCmd != handle) { throw new RefactoringCoreException("Unable to undrefactoring command." + "Expected <" + handle.getDescription() + "> somehwere in the Undo stack. But last und-doable command was <" + lastUndoneCmd.getDescription() +">"); } } public CommandHandle peekUndoStack() { CommandStack stack = connection.getCommandStack(); if (stack.canUndo()) { return stack.getUndoStack().get(stack.getUndoStack().size()-1); } else { return null; } } public void redoRefactoring(CommandHandle handle) throws RefactoringCoreException { redoRefactoring(handle, new NullProgressMonitor()); } public void redoRefactoring(CommandHandle handle, IProgressMonitor pm) throws RefactoringCoreException { CommandStack stack = connection.getCommandStack(); pm.beginTask("Re-applying Commands", stack.getRedoStack().size()); CommandHandle lastRedoneCmd = null; while (stack.canRedo() && !handle.equals(lastRedoneCmd)) { lastRedoneCmd = peekRedoStack(); stack.redo(); pm.worked(1); }; pm.done(); if (lastRedoneCmd == null) { throw new RefactoringCoreException("There was no command to redo"); } if (lastRedoneCmd != handle) { throw new RefactoringCoreException("Unable to re-apply refactoring command." + "Expected <" + handle.getDescription() + "> ontop of the Redo stack. But last re-doable command was <" + lastRedoneCmd.getDescription() +">"); } } public CommandHandle peekRedoStack() { CommandStack stack = connection.getCommandStack(); if (stack.canRedo()) { return stack.getRedoStack().get(stack.getRedoStack().size()-1); } else { return null; } } }