package org.jmeld.util.file.cmd;
import javax.swing.undo.*;
import java.util.*;
public abstract class AbstractCmd
extends AbstractUndoableEdit
{
private List<Command> commandList = new ArrayList<Command>();
private List<Command> finallyCommandList = new ArrayList<Command>();
protected boolean debug = true;
public void setDebug(boolean debug)
{
this.debug = debug;
}
public synchronized void execute()
throws Exception
{
commandList.clear();
finallyCommandList.clear();
createCommands();
for (Command command : commandList)
{
command.execute();
}
for (Command command : finallyCommandList)
{
command.execute();
}
}
protected abstract void createCommands()
throws Exception;
protected void addCommand(Command command)
{
commandList.add(command);
}
protected void addFinallyCommand(Command command)
{
finallyCommandList.add(command);
}
@Override
public synchronized void redo()
{
super.redo();
for (Command command : commandList)
{
command.redo();
}
for (Command command : finallyCommandList)
{
command.redo();
}
}
@Override
public synchronized void undo()
{
super.undo();
// Undo should be executed in the reverse order!
// Note: the commandList itself is reversed and that is OK because
// at the end of this method the commandList is cleared.
try
{
Collections.reverse(commandList);
for (Command command : commandList)
{
command.undo();
}
Collections.reverse(commandList);
Collections.reverse(finallyCommandList);
for (Command command : finallyCommandList)
{
command.undo();
}
Collections.reverse(finallyCommandList);
}
catch (Exception ex)
{
ex.printStackTrace();
throw new CannotRedoException();
}
}
public synchronized void discard()
{
Collections.reverse(commandList);
for (Command command : commandList)
{
command.discard();
}
commandList.clear();
Collections.reverse(finallyCommandList);
for (Command command : finallyCommandList)
{
command.discard();
}
finallyCommandList.clear();
}
abstract class Command
{
public abstract void execute()
throws Exception;
public void redo()
{
try
{
execute();
}
catch (Exception ex)
{
ex.printStackTrace();
throw new CannotRedoException();
}
}
public abstract void undo();
public void discard()
{
}
}
}