001package org.biopax.paxtools.command;
002
003import org.biopax.paxtools.controller.PropertyEditor;
004import org.biopax.paxtools.model.BioPAXElement;
005import org.biopax.paxtools.model.Model;
006
007import java.util.Set;
008import java.util.Stack;
009
010/**
011 * This is a class for manipulating a BioPAX model via undoable commands
012 */
013
014public class CommandManager
015{
016        private Stack<Command> undoStack = new Stack<Command>();
017        private Stack<Command> redoStack = new Stack<Command>();
018        private Model model;
019
020
021        public CommandManager(Model model)
022        {
023                this.model = model;
024        }
025
026        public void addProperty(BioPAXElement bpe, PropertyEditor editor, Object value)
027        {
028                recordAndRun(editor.isMultipleCardinality() ?
029                             new PropertyAddCommand(bpe, editor, value) :
030                             new PropertySetCommand(bpe, editor, value));
031
032        }
033
034
035        public void removeProperty(BioPAXElement bpe, PropertyEditor editor, Object value)
036        {
037                recordAndRun(new PropertyRemoveCommand(bpe, editor, value));
038        }
039
040
041        public void addObjects(Set<BioPAXElement> bpes)
042        {
043                recordAndRun(new AddCommand(model, bpes));
044        }
045
046        public void removeObjects(Set<BioPAXElement> bpes)
047        {
048                recordAndRun(new RemoveCommand(model, bpes));
049        }
050
051        private void recordAndRun(Command command)
052        {
053                command.redo();
054                undoStack.add(command);
055                if (!redoStack.isEmpty())
056                {
057                        redoStack.clear();
058                }
059        }
060
061        public void undo()
062        {
063                Command command = undoStack.pop();
064                command.undo();
065                redoStack.add(command);
066        }
067
068        public void redo()
069        {
070                Command command = redoStack.pop();
071                command.redo();
072                undoStack.add(command);
073
074        }
075
076
077        public boolean canUndo()
078        {
079                return !undoStack.isEmpty();
080        }
081
082        public boolean canRedo()
083        {
084                return !redoStack.isEmpty();
085        }
086}