Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions org.openmbee.mpspi/src/org/openmbee/mpspi/MPAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,19 +62,17 @@ public enum ReloadResult {
NEED_REACTIVATE
}

public enum DoResult implements UndoResult, RedoResult {
UNSUPPORTED, DONE, ERROR, NEED_REACTIVATE, EMPTY_STACK
}

/**
* reload the model
* @throws MPException
*/
ReloadResult reload() throws MPException;

public enum UndoResult {
UNSUPPORTED,
DONE,
ERROR,
NEED_REACTIVATE,
EMPTY_STACK
}

public interface UndoResult {}

/**
* reload the last modification
Expand All @@ -87,6 +85,14 @@ public enum UndoResult {
* */
void storeTransaction() throws MPException;

public interface RedoResult {}


/**
* Revert the last undo transaction
* */
RedoResult redo() throws MPException;

/**
* Return the resource that has been loaded.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
*
*/
package org.openmbee.mpspi.exceptions;

/**
* @author mzeshan
*
*/
public class MPRedoException extends MPFatalException {
/**
*
*/
private static final long serialVersionUID = 6684692097946706048L;

public MPRedoException(String message) {
super(message);
}

public MPRedoException(String message, Throwable cause) {
super(message, cause);
}

}
56 changes: 50 additions & 6 deletions org.openmbee.mpspi/src/org/openmbee/mpspi/svc/MPBaseAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.openmbee.mpspi.exceptions.MPException;
import org.openmbee.mpspi.exceptions.MPRedoException;
import org.openmbee.mpspi.exceptions.MPUndoException;
import org.openmbee.mpspi.exceptions.MPUnsupportedOperationException;
import org.openmbee.mpspi.modifier.MPModifier;
Expand Down Expand Up @@ -45,7 +46,7 @@ private boolean isTransactionEnabled() {

protected void setTransaction(boolean flag) {
if (flag) {
mpCommandLog = new ArrayList<MPCommand>();
mpCommandLog = new ArrayList<MPCommand>();
undoCommandLog = new Stack<List<MPCommand>>();
} else {
mpCommandLog = null;
Expand Down Expand Up @@ -97,28 +98,71 @@ protected void commit() throws MPException {
for (MPCommand mpc : mpCommandLog) {
mpc.execute();
}
redoStack.clear();
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public UndoResult undo() throws MPException {
if (undoLogs.isEmpty())
return UndoResult.EMPTY_STACK;
return DoResult.EMPTY_STACK;

try {
Stack<List<MPCommand>> undoLog = undoLogs.pop();
Object redoObject = undoLog.clone();
while (!undoLog.isEmpty()) {
List<MPCommand> undo = undoLog.pop();
for (MPCommand mpCommand : undo) {
mpCommand.undo();
}
}
return UndoResult.DONE;
redoStack.add((Stack) redoObject);
return DoResult.DONE;
} catch (Exception e) {
// clear the undo stack and throw exception
clearUndoStack();
throw new MPUndoException("Unable to revert, Please reload the model without saving." , e);
throw new MPUndoException("Unable to revert, Please reload the model without saving.", e);
}
}

private Stack<Stack<List<MPCommand>>> redoStack = new Stack<Stack<List<MPCommand>>>();;

@Override
public RedoResult redo() throws MPException {
if (redoStack.isEmpty())
return DoResult.EMPTY_STACK;
try {
Stack<List<MPCommand>> redoLog = redoStack.pop();
Object tmp = redoLog.clone();
Stack<List<MPCommand>> undoObject = null;
if (tmp instanceof Stack<?>) {
@SuppressWarnings("unchecked")
// This cast is safe as it keeps the same type used internally
Stack<List<MPCommand>> tmp2 = (Stack<List<MPCommand>>) tmp;
undoObject = tmp2;
}

if (undoObject == null)
throw new IllegalStateException();

while (!redoLog.isEmpty()) {
List<MPCommand> redo = redoLog.pop();
for (MPCommand mpCommand : redo) {
mpCommand.execute();
}
}
undoLogs.push(undoObject);
return DoResult.DONE;
} catch (Exception e) {
// clear the redo stack and throw exception
clearRedoStack();
throw new MPRedoException("Unable to perform redo operation, Please reload the model without saving.", e);
}
}

private void clearRedoStack() {
redoStack.clear();
}

public void doSet(EObject target, EStructuralFeature feature, Object value, Object oldValue) {
if (isTransactionEnabled()) {
mpCommandLog.add(new MPCommand.Set(target, feature, value, oldValue, false));
Expand Down Expand Up @@ -263,12 +307,12 @@ public void removeByIdx(EObject eObj, EStructuralFeature feature, int index) thr
public void set(EObject eObj, EStructuralFeature feature, Object value) throws MPException {
MPModifier m = mpModifierMap.get(feature);
if (m != null) {
Object oldValue = get(eObj, feature);
Object oldValue = get(eObj, feature);
m.set(eObj, feature, value, oldValue);
} else {
if (MPUtil.isVirtual(feature))
return;
Object oldValue = get(eObj, feature);
Object oldValue = get(eObj, feature);
doSet(eObj, feature, value, oldValue);
}
}
Expand Down