Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF5
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/DelagatingCommandStack.java55
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCommandStack.java (renamed from plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/ICompareCommandStack.java)2
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCopyCommand.java (renamed from plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/ICompareCopyCommand.java)2
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java (renamed from plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyAllNonConflictingCommand.java)5
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java (renamed from plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyCommand.java)5
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java33
-rw-r--r--plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java611
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java8
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java8
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/RedoAction.java6
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/UndoAction.java6
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java13
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java15
-rw-r--r--plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/EMFCompareEditingDomain.java403
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/AbstractTestCompareCommandStack.java562
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/CommandStackTestSuite.java25
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/MockCompareCommand.java134
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareCommandStack.java32
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareSideCommandStack.java193
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestDualCompareCommandStack.java32
-rw-r--r--plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java3
22 files changed, 1720 insertions, 438 deletions
diff --git a/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
index 49539d015..907755b68 100644
--- a/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.edit/META-INF/MANIFEST.MF
@@ -8,7 +8,10 @@ Bundle-Activator: org.eclipse.emf.compare.provider.EMFCompareEditPlugin$Implemen
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: J2SE-1.5
-Export-Package: org.eclipse.emf.compare.commands,
+Export-Package: org.eclipse.emf.compare.command,
+ org.eclipse.emf.compare.command.impl,
+ org.eclipse.emf.compare.domain,
+ org.eclipse.emf.compare.domain.impl,
org.eclipse.emf.compare.provider,
org.eclipse.emf.compare.provider.spec
Require-Bundle: org.eclipse.core.runtime,
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/DelagatingCommandStack.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/DelagatingCommandStack.java
new file mode 100644
index 000000000..bd59e8522
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/DelagatingCommandStack.java
@@ -0,0 +1,55 @@
+package org.eclipse.emf.compare.command;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.command.CommandStackListener;
+
+public abstract class DelagatingCommandStack implements CommandStack {
+
+ protected abstract CommandStack delegate();
+
+ public void execute(Command command) {
+ delegate().execute(command);
+ }
+
+ public boolean canUndo() {
+ return delegate().canUndo();
+ }
+
+ public void undo() {
+ delegate().undo();
+ }
+
+ public boolean canRedo() {
+ return delegate().canRedo();
+ }
+
+ public Command getUndoCommand() {
+ return delegate().getUndoCommand();
+ }
+
+ public Command getRedoCommand() {
+ return delegate().getRedoCommand();
+ }
+
+ public Command getMostRecentCommand() {
+ return delegate().getMostRecentCommand();
+ }
+
+ public void redo() {
+ delegate().redo();
+ }
+
+ public void flush() {
+ delegate().flush();
+ }
+
+ public void addCommandStackListener(CommandStackListener listener) {
+ delegate().addCommandStackListener(listener);
+ }
+
+ public void removeCommandStackListener(CommandStackListener listener) {
+ delegate().removeCommandStackListener(listener);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/ICompareCommandStack.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCommandStack.java
index 61f40fcad..b3a81f393 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/ICompareCommandStack.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCommandStack.java
@@ -8,7 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.util;
+package org.eclipse.emf.compare.command;
import org.eclipse.emf.common.command.CommandStack;
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/ICompareCopyCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCopyCommand.java
index 90790db4c..508bc7f92 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/ICompareCopyCommand.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/ICompareCopyCommand.java
@@ -8,7 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
-package org.eclipse.emf.compare.commands;
+package org.eclipse.emf.compare.command;
import org.eclipse.emf.common.command.Command;
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyAllNonConflictingCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java
index afac8c747..dd9453115 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyAllNonConflictingCommand.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyAllNonConflictingCommand.java
@@ -8,7 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
-package org.eclipse.emf.compare.commands;
+package org.eclipse.emf.compare.command.impl;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
@@ -22,6 +22,7 @@ import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceSource;
import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.command.ICompareCopyCommand;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.edit.command.ChangeCommand;
@@ -63,7 +64,7 @@ public class CopyAllNonConflictingCommand extends ChangeCommand implements IComp
/**
* {@inheritDoc}
*
- * @see org.eclipse.emf.compare.commands.ICompareCopyCommand#isLeftToRight()
+ * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
*/
public boolean isLeftToRight() {
return leftToRight;
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyCommand.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java
index 8dded1584..b0a06da7b 100644
--- a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/commands/CopyCommand.java
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/command/impl/CopyCommand.java
@@ -8,7 +8,7 @@
* Contributors:
* Obeo - initial API and implementation
*******************************************************************************/
-package org.eclipse.emf.compare.commands;
+package org.eclipse.emf.compare.command.impl;
import static org.eclipse.emf.compare.utils.EMFComparePredicates.hasState;
@@ -21,6 +21,7 @@ import java.util.List;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.compare.Diff;
import org.eclipse.emf.compare.DifferenceState;
+import org.eclipse.emf.compare.command.ICompareCopyCommand;
import org.eclipse.emf.ecore.change.util.ChangeRecorder;
import org.eclipse.emf.edit.command.ChangeCommand;
@@ -62,7 +63,7 @@ public class CopyCommand extends ChangeCommand implements ICompareCopyCommand {
/**
* {@inheritDoc}
*
- * @see org.eclipse.emf.compare.commands.ICompareCopyCommand#isLeftToRight()
+ * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
*/
public boolean isLeftToRight() {
return leftToRight;
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java
new file mode 100644
index 000000000..325b2bf55
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/ICompareEditingDomain.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.domain;
+
+import java.util.List;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.command.ICompareCommandStack;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ *
+ */
+public interface ICompareEditingDomain {
+
+ void dispose();
+
+ ICompareCommandStack getCommandStack();
+
+ Command createCopyCommand(Diff diff, boolean leftToRight);
+
+ Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight);
+
+}
diff --git a/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java
new file mode 100644
index 000000000..6b55ad3c4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.edit/src/org/eclipse/emf/compare/domain/impl/EMFCompareEditingDomain.java
@@ -0,0 +1,611 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.domain.impl;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableCollection;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.command.BasicCommandStack;
+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.notify.Notifier;
+import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.command.DelagatingCommandStack;
+import org.eclipse.emf.compare.command.ICompareCommandStack;
+import org.eclipse.emf.compare.command.ICompareCopyCommand;
+import org.eclipse.emf.compare.command.impl.CopyAllNonConflictingCommand;
+import org.eclipse.emf.compare.command.impl.CopyCommand;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.ecore.change.util.ChangeRecorder;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class EMFCompareEditingDomain implements ICompareEditingDomain {
+
+ private final ChangeRecorder fChangeRecorder;
+
+ private final ImmutableCollection<Notifier> fNotifiers;
+
+ private final ICompareCommandStack fCommandStack;
+
+ public EMFCompareEditingDomain(Notifier left, Notifier right, Notifier ancestor,
+ ICompareCommandStack commandStack) {
+ if (ancestor == null) {
+ fNotifiers = ImmutableList.of(left, right);
+ } else {
+ fNotifiers = ImmutableList.of(left, right, ancestor);
+ }
+
+ fCommandStack = commandStack;
+
+ fChangeRecorder = new ChangeRecorder();
+ fChangeRecorder.setResolveProxies(false);
+ }
+
+ public static ICompareEditingDomain create(Notifier left, Notifier right, Notifier ancestor) {
+ return create(left, right, ancestor, new BasicCommandStack());
+ }
+
+ public static ICompareEditingDomain create(Notifier left, Notifier right, Notifier ancestor,
+ CommandStack commandStack) {
+ return create(left, right, ancestor, commandStack, null);
+ }
+
+ public static ICompareEditingDomain create(Notifier left, Notifier right, Notifier ancestor,
+ CommandStack leftCommandStack, CommandStack rightCommandStack) {
+
+ final ICompareCommandStack commandStack;
+
+ if (leftCommandStack == null && rightCommandStack != null) {
+ commandStack = new CompareCommandStack(rightCommandStack);
+ } else if (leftCommandStack != null && rightCommandStack == null) {
+ commandStack = new CompareCommandStack(leftCommandStack);
+ } else if (leftCommandStack instanceof BasicCommandStack
+ && rightCommandStack instanceof BasicCommandStack) {
+ commandStack = new DualCompareCommandStack((BasicCommandStack)leftCommandStack,
+ (BasicCommandStack)rightCommandStack);
+ } else {
+ commandStack = new CompareCommandStack(new BasicCommandStack());
+ }
+
+ return new EMFCompareEditingDomain(left, right, ancestor, commandStack);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.eclipse.emf.compare.domain.ICompareEditingDomain#dispose()
+ */
+ public void dispose() {
+ fChangeRecorder.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.eclipse.emf.compare.domain.ICompareEditingDomain#getCommandStack()
+ */
+ public ICompareCommandStack getCommandStack() {
+ return fCommandStack;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.eclipse.emf.compare.domain.ICompareEditingDomain#createCopyCommand(org.eclipse.emf.compare.Diff, boolean)
+ */
+ public Command createCopyCommand(Diff diff, boolean leftToRight) {
+ ImmutableSet<Notifier> notifiers = ImmutableSet.<Notifier> builder().add(
+ diff.getMatch().getComparison()).addAll(fNotifiers).build();
+ return new CopyCommand(fChangeRecorder, notifiers, Collections.singletonList(diff), leftToRight);
+ }
+
+ /**
+ * {@inheritDoc}
+ * @see org.eclipse.emf.compare.domain.ICompareEditingDomain#createCopyAllNonConflictingCommand(java.util.List, boolean)
+ */
+ public Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight) {
+ ImmutableSet.Builder<Notifier> notifiersBuilder = ImmutableSet.builder();
+ for (Diff diff : differences) {
+ notifiersBuilder.add(diff.getMatch().getComparison());
+ }
+ ImmutableSet<Notifier> notifiers = notifiersBuilder.addAll(fNotifiers).build();
+
+ return new CopyAllNonConflictingCommand(fChangeRecorder, notifiers, differences, leftToRight);
+ }
+
+ public static class DualCompareCommandStack implements ICompareCommandStack {
+
+ private final BasicCommandStack leftCommandStack;
+
+ private final BasicCommandStack rightCommandStack;
+
+ private final List<BasicCommandStack> commandStackStack;
+
+ private int top;
+
+ private BasicCommandStack mostRecentCommandStack;
+
+ private int saveIndex = -1;
+
+ public DualCompareCommandStack(BasicCommandStack leftCommandStack, BasicCommandStack rightCommandStack) {
+ this.leftCommandStack = Preconditions.checkNotNull(leftCommandStack);
+ this.rightCommandStack = Preconditions.checkNotNull(rightCommandStack);
+ this.commandStackStack = newArrayList();
+ this.top = -1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#execute(org.eclipse.emf.common.command.Command)
+ */
+ public void execute(Command command) {
+ // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
+ // side lists.
+ if (command instanceof ICompareCopyCommand) {
+ final BasicCommandStack commandStack;
+ final ICompareCopyCommand compareCommand = (ICompareCopyCommand)command;
+ if (compareCommand.isLeftToRight()) {
+ commandStack = rightCommandStack;
+ } else {
+ commandStack = leftCommandStack;
+ }
+ commandStack.execute(compareCommand);
+
+ // Clear the list past the top.
+ //
+ Iterator<BasicCommandStack> commandStacks = commandStackStack.listIterator(top + 1);
+ while (commandStacks.hasNext()) {
+ commandStacks.next();
+ commandStacks.remove();
+ }
+
+ // Record the successfully executed command.
+ //
+ mostRecentCommandStack = commandStack;
+ commandStackStack.add(commandStack);
+ ++top;
+
+ // This is kind of tricky.
+ // If the saveIndex was in the redo part of the command list which has now been wiped out,
+ // then we can never reach a point where a save is not necessary, not even if we undo all the
+ // way back to the beginning.
+ //
+ if (saveIndex >= top) {
+ // This forces isSaveNeded to always be true.
+ //
+ saveIndex = -2;
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#canUndo()
+ */
+ public boolean canUndo() {
+ return top != -1 && commandStackStack.get(top).canUndo();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#undo()
+ */
+ public void undo() {
+ if (canUndo()) {
+ BasicCommandStack commandStack = commandStackStack.get(top--);
+ commandStack.undo();
+ mostRecentCommandStack = commandStack;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#canRedo()
+ */
+ public boolean canRedo() {
+ return top < commandStackStack.size() - 1;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#getUndoCommand()
+ */
+ public Command getUndoCommand() {
+ return top == -1 || top == commandStackStack.size() ? null : commandStackStack.get(top)
+ .getUndoCommand();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#getRedoCommand()
+ */
+ public Command getRedoCommand() {
+ return top + 1 >= commandStackStack.size() ? null : commandStackStack.get(top + 1)
+ .getRedoCommand();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#getMostRecentCommand()
+ */
+ public Command getMostRecentCommand() {
+ if (mostRecentCommandStack != null) {
+ return mostRecentCommandStack.getMostRecentCommand();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#redo()
+ */
+ public void redo() {
+ if (canRedo()) {
+ BasicCommandStack commandStack = commandStackStack.get(++top);
+ commandStack.redo();
+ mostRecentCommandStack = commandStack;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#flush()
+ */
+ public void flush() {
+ Iterator<BasicCommandStack> commands = commandStackStack.listIterator();
+ while (commands.hasNext()) {
+ commands.next();
+ commands.remove();
+ }
+ commandStackStack.clear();
+ top = -1;
+ saveIndex = -1;
+ mostRecentCommandStack = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#addCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
+ */
+ public void addCommandStackListener(CommandStackListener listener) {
+ leftCommandStack.addCommandStackListener(listener);
+ rightCommandStack.addCommandStackListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#removeCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
+ */
+ public void removeCommandStackListener(CommandStackListener listener) {
+ leftCommandStack.removeCommandStackListener(listener);
+ rightCommandStack.removeCommandStackListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#isLeftSaveNeeded()
+ */
+ public boolean isLeftSaveNeeded() {
+ return leftCommandStack.isSaveNeeded();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#isRightSaveNeeded()
+ */
+ public boolean isRightSaveNeeded() {
+ return rightCommandStack.isSaveNeeded();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#leftSaveIsDone()
+ */
+ public void leftSaveIsDone() {
+ leftCommandStack.saveIsDone();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#rightSaveIsDone()
+ */
+ public void rightSaveIsDone() {
+ rightCommandStack.saveIsDone();
+ }
+
+ }
+
+ public static class CompareCommandStack extends DelagatingCommandStack implements ICompareCommandStack {
+
+ private final CompareSideCommandStack rightCommandStack;
+
+ private final CompareSideCommandStack leftCommandStack;
+
+ private final CommandStack delegate;
+
+ public CompareCommandStack(CommandStack delegate) {
+ this.delegate = delegate;
+ this.rightCommandStack = new CompareSideCommandStack();
+ this.leftCommandStack = new CompareSideCommandStack();
+ }
+
+ /**
+ * @return the delegate
+ */
+ @Override
+ protected CommandStack delegate() {
+ return delegate;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.BasicCommandStack#execute(org.eclipse.emf.common.command.Command)
+ */
+ @Override
+ public void execute(Command command) {
+ // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
+ // side lists.
+ if (command instanceof ICompareCopyCommand) {
+ ICompareCopyCommand compareCommand = (ICompareCopyCommand)command;
+ if (compareCommand.isLeftToRight()) {
+ rightCommandStack.executed(compareCommand);
+ } else {
+ leftCommandStack.executed(compareCommand);
+ }
+ }
+ super.execute(command);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.BasicCommandStack#undo()
+ */
+ @Override
+ public void undo() {
+ // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
+ // side lists.
+ if (canUndo()) {
+ if (getUndoCommand() instanceof ICompareCopyCommand) {
+ ICompareCopyCommand compareCommand = (ICompareCopyCommand)getUndoCommand();
+ if (compareCommand.isLeftToRight()) {
+ rightCommandStack.undone();
+ } else {
+ leftCommandStack.undone();
+ }
+ }
+ }
+ super.undo();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.BasicCommandStack#redo()
+ */
+ @Override
+ public void redo() {
+ // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
+ // side lists.
+ if (canRedo()) {
+ if (getRedoCommand() instanceof ICompareCopyCommand) {
+ ICompareCopyCommand compareCommand = (ICompareCopyCommand)getRedoCommand();
+ if (compareCommand.isLeftToRight()) {
+ rightCommandStack.redone();
+ } else {
+ leftCommandStack.redone();
+ }
+ }
+ }
+ super.redo();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.CommandStack#flush()
+ */
+ @Override
+ public void flush() {
+ rightCommandStack.flushed();
+ leftCommandStack.flushed();
+ super.flush();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#isLeftSaveNeeded()
+ */
+ public boolean isLeftSaveNeeded() {
+ return leftCommandStack.isSaveNeeded();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#isRightSaveNeeded()
+ */
+ public boolean isRightSaveNeeded() {
+ return rightCommandStack.isSaveNeeded();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#leftSaveIsDone()
+ */
+ public void leftSaveIsDone() {
+ leftCommandStack.saveIsDone();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCommandStack#rightSaveIsDone()
+ */
+ public void rightSaveIsDone() {
+ rightCommandStack.saveIsDone();
+ }
+ }
+
+ public static class CompareSideCommandStack {
+
+ private final List<ICompareCopyCommand> commandList;
+
+ private int top;
+
+ private Command mostRecentCommand;
+
+ private int saveIndex = -1;
+
+ public CompareSideCommandStack() {
+ commandList = newArrayList();
+ top = -1;
+ }
+
+ public void executed(ICompareCopyCommand command) {
+ // If the command is executable, record and execute it.
+ //
+ if (command != null) {
+ if (command.canExecute()) {
+ // Clear the list past the top.
+ //
+ Iterator<ICompareCopyCommand> commands = commandList.listIterator(top + 1);
+ while (commands.hasNext()) {
+ commands.next();
+ commands.remove();
+ }
+
+ // Record the successfully executed command.
+ //
+ mostRecentCommand = command;
+ commandList.add(command);
+ ++top;
+
+ // This is kind of tricky.
+ // If the saveIndex was in the redo part of the command list which has now been wiped
+ // out,
+ // then we can never reach a point where a save is not necessary, not even if we undo
+ // all the way back to the beginning.
+ //
+ if (saveIndex >= top) {
+ // This forces isSaveNeded to always be true.
+ //
+ saveIndex = -2;
+ }
+ }
+ }
+ }
+
+ public void undone() {
+ Command command = commandList.get(top--);
+ mostRecentCommand = command;
+ }
+
+ public void redone() {
+ Command command = commandList.get(++top);
+ mostRecentCommand = command;
+ }
+
+ public void flushed() {
+ // Clear the list.
+ //
+ Iterator<ICompareCopyCommand> commands = commandList.listIterator();
+ while (commands.hasNext()) {
+ commands.next();
+ commands.remove();
+ }
+ commandList.clear();
+ top = -1;
+ saveIndex = -1;
+ mostRecentCommand = null;
+ }
+
+ /**
+ * Called after a save has been successfully performed.
+ */
+ public void saveIsDone() {
+ // Remember where we are now.
+ //
+ saveIndex = top;
+ }
+
+ /**
+ * Returns whether the model has changes since {@link #saveIsDone} was call the last.
+ *
+ * @return whether the model has changes since <code>saveIsDone</code> was call the last.
+ */
+ public boolean isSaveNeeded() {
+ // Only if we are at the remembered index do we NOT need to save.
+ //
+ // return top != saveIndex;
+
+ if (saveIndex < -1) {
+ return true;
+ }
+
+ if (top > saveIndex) {
+ for (int i = top; i > saveIndex; --i) {
+ if (!(commandList.get(i) instanceof AbstractCommand.NonDirtying)) {
+ return true;
+ }
+ }
+ } else {
+ for (int i = saveIndex; i > top; --i) {
+ if (!(commandList.get(i) instanceof AbstractCommand.NonDirtying)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public Command getUndoCommand() {
+ return top == -1 || top == commandList.size() ? null : (Command)commandList.get(top);
+ }
+
+ public Command getRedoCommand() {
+ return top + 1 >= commandList.size() ? null : (Command)commandList.get(top + 1);
+ }
+
+ public Command getMostRecentCommand() {
+ return mostRecentCommand;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
index 6f69328aa..d17c8c680 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/EMFCompareContentMergeViewer.java
@@ -27,12 +27,12 @@ import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Diff;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.EMFCompareColor;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColor;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.ICompareColorProvider;
import org.eclipse.emf.compare.rcp.ui.mergeviewer.IMergeViewerItem;
@@ -93,7 +93,7 @@ public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer im
private EMFCompareColor fColors;
- private final EMFCompareEditingDomain fEditingDomain;
+ private final ICompareEditingDomain fEditingDomain;
private final DynamicObject fDynamicObject;
@@ -108,7 +108,7 @@ public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer im
fComparison = (Comparison)cc.getProperty(EMFCompareConstants.COMPARE_RESULT);
- fEditingDomain = (EMFCompareEditingDomain)getCompareConfiguration().getProperty(
+ fEditingDomain = (ICompareEditingDomain)getCompareConfiguration().getProperty(
EMFCompareConstants.EDITING_DOMAIN);
}
@@ -124,7 +124,7 @@ public abstract class EMFCompareContentMergeViewer extends ContentMergeViewer im
/**
* @return the fEditingDomain
*/
- protected final EMFCompareEditingDomain getEditingDomain() {
+ protected final ICompareEditingDomain getEditingDomain() {
return fEditingDomain;
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
index 3acd3b5e8..d19e44fa2 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/text/EMFCompareTextMergeViewer.java
@@ -24,12 +24,12 @@ import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CommandStackListener;
import org.eclipse.emf.compare.AttributeChange;
import org.eclipse.emf.compare.Comparison;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.DynamicObject;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.RedoAction;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.UndoAction;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.AttributeChangeNode;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.ToolBarManager;
@@ -46,7 +46,7 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer implements Comman
private static final String BUNDLE_NAME = EMFCompareTextMergeViewer.class.getName();
- private final EMFCompareEditingDomain fEditingDomain;
+ private final ICompareEditingDomain fEditingDomain;
private DynamicObject fDynamicObject;
@@ -60,7 +60,7 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer implements Comman
*/
public EMFCompareTextMergeViewer(Composite parent, CompareConfiguration configuration) {
super(parent, configuration);
- fEditingDomain = (EMFCompareEditingDomain)getCompareConfiguration().getProperty(
+ fEditingDomain = (ICompareEditingDomain)getCompareConfiguration().getProperty(
EMFCompareConstants.EDITING_DOMAIN);
fEditingDomain.getCommandStack().addCommandStackListener(this);
setContentProvider(new EMFCompareTextMergeViewerContentProvider(configuration));
@@ -217,7 +217,7 @@ public class EMFCompareTextMergeViewer extends TextMergeViewer implements Comman
toolBarManager.appendToGroup("navigation", contributionPreviousDiff);
// This is called from the super-constructor, fEditingDomain is not set yet.
- final EMFCompareEditingDomain domain = (EMFCompareEditingDomain)getCompareConfiguration()
+ final ICompareEditingDomain domain = (ICompareEditingDomain)getCompareConfiguration()
.getProperty(EMFCompareConstants.EDITING_DOMAIN);
final UndoAction undoAction = new UndoAction(domain);
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/RedoAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/RedoAction.java
index 8227f1232..c9514c48a 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/RedoAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/RedoAction.java
@@ -1,7 +1,7 @@
package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;
import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.jface.action.Action;
@@ -9,9 +9,9 @@ import org.eclipse.jface.action.Action;
* An redo action is implemented by using the {@link org.eclipse.emf.common.command.CommandStack}.
*/
public class RedoAction extends Action {
- protected EMFCompareEditingDomain domain;
+ protected ICompareEditingDomain domain;
- public RedoAction(EMFCompareEditingDomain domain) {
+ public RedoAction(ICompareEditingDomain domain) {
super(EMFEditUIPlugin.INSTANCE.getString("_UI_Redo_menu_item", new Object[] {"" })); //$NON-NLS-1$ //$NON-NLS-2$
this.domain = domain;
update();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/UndoAction.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/UndoAction.java
index 208ea5797..282f41ed9 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/UndoAction.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/contentmergeviewer/util/UndoAction.java
@@ -1,7 +1,7 @@
package org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util;
import org.eclipse.emf.common.command.Command;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.jface.action.Action;
@@ -9,9 +9,9 @@ import org.eclipse.jface.action.Action;
* An undo action is implemented by using the {@link org.eclipse.emf.common.command.CommandStack}.
*/
public class UndoAction extends Action {
- protected EMFCompareEditingDomain domain;
+ protected ICompareEditingDomain domain;
- public UndoAction(EMFCompareEditingDomain domain) {
+ public UndoAction(ICompareEditingDomain domain) {
super(EMFEditUIPlugin.INSTANCE.getString("_UI_Undo_menu_item", new Object[] {"" })); //$NON-NLS-1$ //$NON-NLS-2$
this.domain = domain;
update();
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
index bf1988bc5..e0af46c44 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/handler/AbstractCompareHandler.java
@@ -31,10 +31,11 @@ import org.eclipse.emf.compare.CompareFactory;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.EMFCompare;
import org.eclipse.emf.compare.Match;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.EMFCompareIDE;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.EMFCompareStructureMergeViewer;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
import org.eclipse.emf.compare.match.DefaultComparisonFactory;
import org.eclipse.emf.compare.match.DefaultEqualityHelperFactory;
import org.eclipse.emf.compare.match.DefaultMatchEngine;
@@ -61,7 +62,7 @@ public abstract class AbstractCompareHandler extends AbstractHandler {
Notifier left, Notifier right, Notifier origin) {
CompareEditorInput input = null;
- EMFCompareEditingDomain editingDomain = createEMFCompareEditingDomain(part, left, right, origin);
+ ICompareEditingDomain editingDomain = createEMFCompareEditingDomain(part, left, right, origin);
final CompareConfiguration configuration = new CompareConfiguration();
// never use id in EObjects comparison
@@ -90,7 +91,7 @@ public abstract class AbstractCompareHandler extends AbstractHandler {
return text;
}
- private EMFCompareEditingDomain createEMFCompareEditingDomain(final IWorkbenchPart activePart,
+ private ICompareEditingDomain createEMFCompareEditingDomain(final IWorkbenchPart activePart,
final Notifier left, final Notifier right, Notifier origin) {
EditingDomain delegatingEditingDomain = getDelegatingEditingDomain(activePart, left, right);
@@ -99,7 +100,7 @@ public abstract class AbstractCompareHandler extends AbstractHandler {
delegatingCommandStack = delegatingEditingDomain.getCommandStack();
}
- return new EMFCompareEditingDomain(left, right, origin, delegatingCommandStack);
+ return EMFCompareEditingDomain.create(left, right, origin, delegatingCommandStack);
}
private EditingDomain getDelegatingEditingDomain(final IWorkbenchPart activePart, Notifier left,
@@ -169,13 +170,13 @@ public abstract class AbstractCompareHandler extends AbstractHandler {
private AdapterFactory adapterFactory;
- private EMFCompareEditingDomain editingDomain;
+ private ICompareEditingDomain editingDomain;
/**
* @param configuration
*/
public EMFCompareEditorInput(CompareConfiguration configuration, EMFCompare comparator,
- EMFCompareEditingDomain editingDomain, AdapterFactory adapterFactory, Notifier left,
+ ICompareEditingDomain editingDomain, AdapterFactory adapterFactory, Notifier left,
Notifier right, Notifier origin) {
super(configuration);
this.comparator = comparator;
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
index d34dbd063..47e8a8895 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/structuremergeviewer/EMFCompareStructureMergeViewer.java
@@ -34,8 +34,10 @@ import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.compare.Comparison;
import org.eclipse.emf.compare.Match;
-import org.eclipse.emf.compare.commands.CopyAllNonConflictingCommand;
-import org.eclipse.emf.compare.commands.CopyCommand;
+import org.eclipse.emf.compare.command.impl.CopyAllNonConflictingCommand;
+import org.eclipse.emf.compare.command.impl.CopyCommand;
+import org.eclipse.emf.compare.domain.ICompareEditingDomain;
+import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.EMFCompareIDE;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareConstants;
import org.eclipse.emf.compare.ide.ui.internal.EMFCompareIDEUIPlugin;
@@ -46,7 +48,6 @@ import org.eclipse.emf.compare.ide.ui.internal.actions.group.GroupActionMenu;
import org.eclipse.emf.compare.ide.ui.internal.actions.save.SaveComparisonModelAction;
import org.eclipse.emf.compare.ide.ui.internal.contentmergeviewer.util.CompareConfigurationExtension;
import org.eclipse.emf.compare.ide.ui.internal.structuremergeviewer.provider.ComparisonNode;
-import org.eclipse.emf.compare.ide.ui.internal.util.EMFCompareEditingDomain;
import org.eclipse.emf.compare.ide.ui.logical.EMFSynchronizationModel;
import org.eclipse.emf.compare.scope.IComparisonScope;
import org.eclipse.emf.ecore.EObject;
@@ -77,7 +78,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
private Object fRoot;
- private EMFCompareEditingDomain editingDomain;
+ private ICompareEditingDomain editingDomain;
/**
* The difference filter that will be applied to the structure viewer. Note that this will be initialized
@@ -174,7 +175,7 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
if (input instanceof ComparisonNode) {
// FIXME: should not get ComparisonNode here. Should prepare a ICompareInpupt in EditorInput
// and compute here the diff (see SaveablesCompareEditorInput)
- editingDomain = (EMFCompareEditingDomain)getCompareConfiguration().getProperty(
+ editingDomain = (ICompareEditingDomain)getCompareConfiguration().getProperty(
EMFCompareConstants.EDITING_DOMAIN);
editingDomain.getCommandStack().addCommandStackListener(this);
@@ -203,10 +204,10 @@ public class EMFCompareStructureMergeViewer extends DiffTreeViewer implements Co
final ResourceSet rightResourceSet = (ResourceSet)scope.getRight();
final ResourceSet originResourceSet = (ResourceSet)scope.getOrigin();
- editingDomain = (EMFCompareEditingDomain)getCompareConfiguration().getProperty(
+ editingDomain = (ICompareEditingDomain)getCompareConfiguration().getProperty(
EMFCompareConstants.EDITING_DOMAIN);
if (editingDomain == null) {
- editingDomain = new EMFCompareEditingDomain(leftResourceSet, rightResourceSet,
+ editingDomain = EMFCompareEditingDomain.create(leftResourceSet, rightResourceSet,
originResourceSet);
getCompareConfiguration().setProperty(EMFCompareConstants.EDITING_DOMAIN, editingDomain);
}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/EMFCompareEditingDomain.java b/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/EMFCompareEditingDomain.java
deleted file mode 100644
index 834d39396..000000000
--- a/plugins/org.eclipse.emf.compare.ide.ui/src/org/eclipse/emf/compare/ide/ui/internal/util/EMFCompareEditingDomain.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2012 Obeo.
- * 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:
- * Obeo - initial API and implementation
- *******************************************************************************/
-package org.eclipse.emf.compare.ide.ui.internal.util;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.eclipse.emf.common.command.AbstractCommand;
-import org.eclipse.emf.common.command.BasicCommandStack;
-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.notify.Notifier;
-import org.eclipse.emf.compare.Diff;
-import org.eclipse.emf.compare.commands.CopyAllNonConflictingCommand;
-import org.eclipse.emf.compare.commands.CopyCommand;
-import org.eclipse.emf.compare.commands.ICompareCopyCommand;
-import org.eclipse.emf.ecore.change.util.ChangeRecorder;
-
-/**
- * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
- */
-public class EMFCompareEditingDomain {
-
- private final ChangeRecorder fChangeRecorder;
-
- private final ImmutableCollection<Notifier> fNotifiers;
-
- private final CompareCommandStack fCommandStack;
-
- public EMFCompareEditingDomain(Notifier left, Notifier right, Notifier ancestor) {
- this(left, right, ancestor, null);
- }
-
- public EMFCompareEditingDomain(Notifier left, Notifier right, Notifier ancestor, CommandStack commandStack) {
- if (ancestor == null) {
- fNotifiers = ImmutableList.of(left, right);
- } else {
- fNotifiers = ImmutableList.of(left, right, ancestor);
- }
-
- if (commandStack == null) {
- fCommandStack = new CompareCommandStack(new BasicCommandStack());
- } else {
- fCommandStack = new CompareCommandStack(commandStack);
- }
-
- fChangeRecorder = new ChangeRecorder();
- fChangeRecorder.setResolveProxies(false);
- }
-
- public void dispose() {
- fChangeRecorder.dispose();
- }
-
- public ICompareCommandStack getCommandStack() {
- return fCommandStack;
- }
-
- public Command createCopyCommand(Diff diff, boolean leftToRight) {
- ImmutableSet<Notifier> notifiers = ImmutableSet.<Notifier> builder().add(
- diff.getMatch().getComparison()).addAll(fNotifiers).build();
- return new CopyCommand(fChangeRecorder, notifiers, Collections.singletonList(diff), leftToRight);
- }
-
- public Command createCopyAllNonConflictingCommand(List<? extends Diff> differences, boolean leftToRight) {
- ImmutableSet.Builder<Notifier> notifiersBuilder = ImmutableSet.builder();
- for (Diff diff : differences) {
- notifiersBuilder.add(diff.getMatch().getComparison());
- }
- ImmutableSet<Notifier> notifiers = notifiersBuilder.addAll(fNotifiers).build();
-
- return new CopyAllNonConflictingCommand(fChangeRecorder, notifiers, differences, leftToRight);
- }
-
- private static class CompareCommandStack implements ICompareCommandStack {
-
- private final CompareSideCommandStack rightCommandList;
-
- private final CompareSideCommandStack leftCommandList;
-
- private final CommandStack delegate;
-
- public CompareCommandStack(CommandStack delegate) {
- this.delegate = delegate;
- this.rightCommandList = new CompareSideCommandStack();
- this.leftCommandList = new CompareSideCommandStack();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.BasicCommandStack#execute(org.eclipse.emf.common.command.Command)
- */
- public void execute(Command command) {
- // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
- // side lists.
- if (command instanceof ICompareCopyCommand) {
- ICompareCopyCommand compareCommand = (ICompareCopyCommand)command;
- if (compareCommand.isLeftToRight()) {
- rightCommandList.executed(compareCommand);
- } else {
- leftCommandList.executed(compareCommand);
- }
- }
- delegate.execute(command);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.BasicCommandStack#undo()
- */
- public void undo() {
- // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
- // side lists.
- if (canUndo()) {
- if (getUndoCommand() instanceof ICompareCopyCommand) {
- ICompareCopyCommand compareCommand = (ICompareCopyCommand)getUndoCommand();
- if (compareCommand.isLeftToRight()) {
- rightCommandList.undone();
- } else {
- leftCommandList.undone();
- }
- }
- }
- delegate.undo();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.BasicCommandStack#redo()
- */
- public void redo() {
- // should do that AFTER delegate.execute, but in this this case, notifiers will not see change in
- // side lists.
- if (canRedo()) {
- if (getRedoCommand() instanceof ICompareCopyCommand) {
- ICompareCopyCommand compareCommand = (ICompareCopyCommand)getRedoCommand();
- if (compareCommand.isLeftToRight()) {
- rightCommandList.redone();
- } else {
- leftCommandList.redone();
- }
- }
- }
- delegate.redo();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#canUndo()
- */
- public boolean canUndo() {
- return delegate.canUndo();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#canRedo()
- */
- public boolean canRedo() {
- return delegate.canRedo();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#getUndoCommand()
- */
- public Command getUndoCommand() {
- return delegate.getUndoCommand();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#getRedoCommand()
- */
- public Command getRedoCommand() {
- return delegate.getRedoCommand();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#getMostRecentCommand()
- */
- public Command getMostRecentCommand() {
- return delegate.getMostRecentCommand();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#flush()
- */
- public void flush() {
- rightCommandList.flushed();
- leftCommandList.flushed();
- delegate.flush();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#addCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
- */
- public void addCommandStackListener(CommandStackListener listener) {
- delegate.addCommandStackListener(listener);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.common.command.CommandStack#removeCommandStackListener(org.eclipse.emf.common.command.CommandStackListener)
- */
- public void removeCommandStackListener(CommandStackListener listener) {
- delegate.removeCommandStackListener(listener);
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.util.ICompareCommandStack#isLeftSaveNeeded()
- */
- public boolean isLeftSaveNeeded() {
- return leftCommandList.isSaveNeeded();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.util.ICompareCommandStack#isRightSaveNeeded()
- */
- public boolean isRightSaveNeeded() {
- return rightCommandList.isSaveNeeded();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.util.ICompareCommandStack#leftSaveIsDone()
- */
- public void leftSaveIsDone() {
- leftCommandList.saveIsDone();
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.compare.ide.ui.internal.util.ICompareCommandStack#rightSaveIsDone()
- */
- public void rightSaveIsDone() {
- rightCommandList.saveIsDone();
- }
- }
-
- private static class CompareSideCommandStack {
-
- private final List<ICompareCopyCommand> commandList;
-
- private int top;
-
- private Command mostRecentCommand;
-
- private int saveIndex = -1;
-
- public CompareSideCommandStack() {
- commandList = newArrayList();
- top = -1;
- }
-
- public void executed(ICompareCopyCommand command) {
- // If the command is executable, record and execute it.
- //
- if (command != null) {
- if (command.canExecute()) {
- // Clear the list past the top.
- //
- Iterator<ICompareCopyCommand> commands = commandList.listIterator(top + 1);
- while (commands.hasNext()) {
- commands.next();
- commands.remove();
- }
-
- // Record the successfully executed command.
- //
- mostRecentCommand = command;
- commandList.add(command);
- ++top;
-
- // This is kind of tricky.
- // If the saveIndex was in the redo part of the command list which has now been wiped
- // out,
- // then we can never reach a point where a save is not necessary, not even if we undo
- // all the way back to the beginning.
- //
- if (saveIndex >= top) {
- // This forces isSaveNeded to always be true.
- //
- saveIndex = -2;
- }
- }
- }
- }
-
- public void undone() {
- Command command = commandList.get(top--);
- mostRecentCommand = command;
- }
-
- public void redone() {
- Command command = commandList.get(++top);
- mostRecentCommand = command;
- }
-
- public void flushed() {
- // Clear the list.
- //
- Iterator<ICompareCopyCommand> commands = commandList.listIterator();
- while (commands.hasNext()) {
- commands.next();
- commands.remove();
- }
- commandList.clear();
- top = -1;
- saveIndex = -1;
- mostRecentCommand = null;
- }
-
- /**
- * Called after a save has been successfully performed.
- */
- public void saveIsDone() {
- // Remember where we are now.
- //
- saveIndex = top;
- }
-
- /**
- * Returns whether the model has changes since {@link #saveIsDone} was call the last.
- *
- * @return whether the model has changes since <code>saveIsDone</code> was call the last.
- */
- public boolean isSaveNeeded() {
- // Only if we are at the remembered index do we NOT need to save.
- //
- // return top != saveIndex;
-
- if (saveIndex < -1) {
- return true;
- }
-
- if (top > saveIndex) {
- for (int i = top; i > saveIndex; --i) {
- if (!(commandList.get(i) instanceof AbstractCommand.NonDirtying)) {
- return true;
- }
- }
- } else {
- for (int i = saveIndex; i > top; --i) {
- if (!(commandList.get(i) instanceof AbstractCommand.NonDirtying)) {
- return true;
- }
- }
- }
-
- return false;
- }
-
- public Command getUndoCommand() {
- return top == -1 || top == commandList.size() ? null : (Command)commandList.get(top);
- }
-
- public Command getRedoCommand() {
- return top + 1 >= commandList.size() ? null : (Command)commandList.get(top + 1);
- }
-
- public Command getMostRecentCommand() {
- return mostRecentCommand;
- }
- }
-
-}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/AbstractTestCompareCommandStack.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/AbstractTestCompareCommandStack.java
new file mode 100644
index 000000000..7de3334f8
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/AbstractTestCompareCommandStack.java
@@ -0,0 +1,562 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.emf.compare.command.ICompareCommandStack;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public abstract class AbstractTestCompareCommandStack {
+
+ private ICompareCommandStack commandStack;
+
+ private MockCompareCommand leftToRight1;
+
+ private MockCompareCommand leftToRight2;
+
+ private MockCompareCommand leftToRight3;
+
+ private MockCompareCommand leftToRight4;
+
+ private MockCompareCommand rightToLeft1;
+
+ private MockCompareCommand rightToLeft2;
+
+ private MockCompareCommand rightToLeft3;
+
+ private MockCompareCommand rightToLeft4;
+
+ @Before
+ public void before() {
+ commandStack = createCommandStack();
+
+ leftToRight1 = new MockCompareCommand(true);
+ leftToRight2 = new MockCompareCommand(true);
+ leftToRight3 = new MockCompareCommand(true);
+ leftToRight4 = new MockCompareCommand(true);
+
+ rightToLeft1 = new MockCompareCommand(false);
+ rightToLeft2 = new MockCompareCommand(false);
+ rightToLeft3 = new MockCompareCommand(false);
+ rightToLeft4 = new MockCompareCommand(false);
+ }
+
+ /**
+ * @return the commandStack
+ */
+ protected abstract ICompareCommandStack createCommandStack();
+
+ @Test
+ public void testInitState() {
+ assertEquals(null, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTROnce() {
+ commandStack.execute(leftToRight1);
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTROnceUndo() {
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTROnceUndoRedo() {
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.redo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwice() {
+ commandStack.execute(leftToRight2);
+ commandStack.execute(leftToRight1);
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndo() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight2, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndoTwice() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.undo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndoTwiceRedo() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.undo();
+ commandStack.redo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight2, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndoTwiceRedoTwice() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.undo();
+ commandStack.redo();
+ commandStack.redo();
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight2, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndoExecuteLTR() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.execute(leftToRight3);
+
+ assertEquals(leftToRight3, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight3, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRTwiceUndoExecuteLTRUndo() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.execute(leftToRight3);
+ commandStack.undo();
+
+ assertEquals(leftToRight3, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight3, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLOnce() {
+ commandStack.execute(rightToLeft1);
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLOnceUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLOnceUndoRedo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.undo();
+ commandStack.redo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwice() {
+ commandStack.execute(rightToLeft2);
+ commandStack.execute(rightToLeft1);
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+
+ assertEquals(rightToLeft2, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft2, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndoTwice() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndoTwiceRedo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.undo();
+ commandStack.redo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft2, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndoTwiceRedoTwice() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.undo();
+ commandStack.redo();
+ commandStack.redo();
+
+ assertEquals(rightToLeft2, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft2, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndoExecuteRTL() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.execute(rightToLeft3);
+
+ assertEquals(rightToLeft3, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft3, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLTwiceUndoExecuteRTLUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.execute(rightToLeft3);
+ commandStack.undo();
+
+ assertEquals(rightToLeft3, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft3, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRExecuteRTL() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(rightToLeft1);
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteLTRExecuteRTLUndo() {
+ commandStack.execute(leftToRight1);
+ commandStack.execute(rightToLeft1);
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight1, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoRedo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.redo();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteLTR() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(leftToRight2);
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight2, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertTrue(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteRTL() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(rightToLeft2);
+
+ assertEquals(rightToLeft2, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(rightToLeft2, commandStack.getUndoCommand());
+ assertFalse(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteRTLUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+
+ assertEquals(rightToLeft2, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft2, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteRTLUndoUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(rightToLeft2);
+ commandStack.undo();
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteLTRUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight2, commandStack.getRedoCommand());
+ assertEquals(rightToLeft1, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertTrue(commandStack.canUndo());
+ assertTrue(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+
+ @Test
+ public void testExecuteRTLExecuteLTRUndoExecuteLTRUndoUndo() {
+ commandStack.execute(rightToLeft1);
+ commandStack.execute(leftToRight1);
+ commandStack.undo();
+ commandStack.execute(leftToRight2);
+ commandStack.undo();
+ commandStack.undo();
+
+ assertEquals(rightToLeft1, commandStack.getMostRecentCommand());
+ assertEquals(rightToLeft1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertTrue(commandStack.canRedo());
+ assertFalse(commandStack.canUndo());
+ assertFalse(commandStack.isLeftSaveNeeded());
+ assertFalse(commandStack.isRightSaveNeeded());
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/CommandStackTestSuite.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/CommandStackTestSuite.java
new file mode 100644
index 000000000..4aea29309
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/CommandStackTestSuite.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+@RunWith(Suite.class)
+@SuiteClasses(value = {TestCompareCommandStack.class, TestCompareSideCommandStack.class,
+ TestDualCompareCommandStack.class, })
+public class CommandStackTestSuite {
+
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/MockCompareCommand.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/MockCompareCommand.java
new file mode 100644
index 000000000..cafc0bc35
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/MockCompareCommand.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.compare.command.ICompareCopyCommand;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class MockCompareCommand implements ICompareCopyCommand {
+
+ private final boolean leftToRight;
+
+ public MockCompareCommand(boolean leftToRight) {
+ this.leftToRight = leftToRight;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#canExecute()
+ */
+ public boolean canExecute() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#execute()
+ */
+ public void execute() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#canUndo()
+ */
+ public boolean canUndo() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#undo()
+ */
+ public void undo() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#redo()
+ */
+ public void redo() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#getResult()
+ */
+ public Collection<?> getResult() {
+ return new ArrayList<Object>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#getAffectedObjects()
+ */
+ public Collection<?> getAffectedObjects() {
+ return new ArrayList<Object>();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#getLabel()
+ */
+ public String getLabel() {
+ return MockCompareCommand.class.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#getDescription()
+ */
+ public String getDescription() {
+ return MockCompareCommand.class.getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#dispose()
+ */
+ public void dispose() {
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.common.command.Command#chain(org.eclipse.emf.common.command.Command)
+ */
+ public Command chain(Command command) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.command.ICompareCopyCommand#isLeftToRight()
+ */
+ public boolean isLeftToRight() {
+ return leftToRight;
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareCommandStack.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareCommandStack.java
new file mode 100644
index 000000000..cb41f68b4
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareCommandStack.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.compare.command.ICompareCommandStack;
+import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain.CompareCommandStack;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TestCompareCommandStack extends AbstractTestCompareCommandStack {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.tests.command.AbstractTestCompareCommandStack#createCommandStack()
+ */
+ @Override
+ protected ICompareCommandStack createCommandStack() {
+ return new CompareCommandStack(new BasicCommandStack());
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareSideCommandStack.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareSideCommandStack.java
new file mode 100644
index 000000000..95d23daa1
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestCompareSideCommandStack.java
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain.CompareSideCommandStack;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TestCompareSideCommandStack {
+
+ private MockCompareCommand leftToRight1;
+
+ private MockCompareCommand leftToRight2;
+
+ private CompareSideCommandStack commandStack;
+
+ private MockCompareCommand leftToRight3;
+
+ private MockCompareCommand leftToRight4;
+
+ @Before
+ public void before() {
+ commandStack = new CompareSideCommandStack();
+ leftToRight1 = new MockCompareCommand(true);
+ leftToRight2 = new MockCompareCommand(true);
+ leftToRight3 = new MockCompareCommand(true);
+ leftToRight4 = new MockCompareCommand(true);
+ }
+
+ @Test
+ public void testInitState() {
+ assertEquals(null, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertFalse(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedOnce() {
+ commandStack.executed(leftToRight1);
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedOnceUndo() {
+ commandStack.executed(leftToRight1);
+ commandStack.undone();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertFalse(commandStack.isSaveNeeded());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testExecutedOnceUndoTwice() {
+ commandStack.executed(leftToRight1);
+ commandStack.undone();
+ commandStack.undone();
+ }
+
+ @Test
+ public void testExecutedOnceUndoRedo() {
+ commandStack.executed(leftToRight1);
+ commandStack.undone();
+ commandStack.redone();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwice() {
+ commandStack.executed(leftToRight2);
+ commandStack.executed(leftToRight1);
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwiceUndo() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight2, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwiceUndoTwice() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.undone();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight1, commandStack.getRedoCommand());
+ assertEquals(null, commandStack.getUndoCommand());
+ assertFalse(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwiceUndoTwiceRedo() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.undone();
+ commandStack.redone();
+
+ assertEquals(leftToRight1, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight2, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwiceUndoTwiceRedoTwice() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.undone();
+ commandStack.redone();
+ commandStack.redone();
+
+ assertEquals(leftToRight2, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight2, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test
+ public void testExecutedTwiceUndoExecuted() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.executed(leftToRight3);
+
+ assertEquals(leftToRight3, commandStack.getMostRecentCommand());
+ assertEquals(null, commandStack.getRedoCommand());
+ assertEquals(leftToRight3, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+
+ @Test(expected = IndexOutOfBoundsException.class)
+ public void testExecutedTwiceUndoExecutedRedo() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.executed(leftToRight3);
+ commandStack.redone();
+ }
+
+ @Test
+ public void testExecutedTwiceUndoExecutedUndo() {
+ commandStack.executed(leftToRight1);
+ commandStack.executed(leftToRight2);
+ commandStack.undone();
+ commandStack.executed(leftToRight3);
+ commandStack.undone();
+
+ assertEquals(leftToRight3, commandStack.getMostRecentCommand());
+ assertEquals(leftToRight3, commandStack.getRedoCommand());
+ assertEquals(leftToRight1, commandStack.getUndoCommand());
+ assertTrue(commandStack.isSaveNeeded());
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestDualCompareCommandStack.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestDualCompareCommandStack.java
new file mode 100644
index 000000000..5306d5199
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/command/TestDualCompareCommandStack.java
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright (c) 2012 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.tests.command;
+
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.compare.command.ICompareCommandStack;
+import org.eclipse.emf.compare.domain.impl.EMFCompareEditingDomain.DualCompareCommandStack;
+
+/**
+ * @author <a href="mailto:mikael.barbero@obeo.fr">Mikael Barbero</a>
+ */
+public class TestDualCompareCommandStack extends AbstractTestCompareCommandStack {
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.compare.tests.command.AbstractTestCompareCommandStack#createCommandStack()
+ */
+ @Override
+ protected ICompareCommandStack createCommandStack() {
+ return new DualCompareCommandStack(new BasicCommandStack(), new BasicCommandStack());
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
index 85633e262..c8b68de07 100644
--- a/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.tests/src/org/eclipse/emf/compare/tests/suite/AllTests.java
@@ -15,6 +15,7 @@ import junit.framework.Test;
import junit.textui.TestRunner;
import org.eclipse.emf.compare.ComparePackage;
+import org.eclipse.emf.compare.tests.command.CommandStackTestSuite;
import org.eclipse.emf.compare.tests.conflict.ConflictDetectionTest;
import org.eclipse.emf.compare.tests.diff.DiffUtilTest;
import org.eclipse.emf.compare.tests.diff.URIDistanceTest;
@@ -50,7 +51,7 @@ import org.junit.runners.Suite.SuiteClasses;
MultipleMergeTest.class, PostProcessorTest.class, IndividualMergeTest.class,
IndividualMergeOutOfScopeValuesTest.class, ProximityComparisonTest.class,
DynamicInstanceComparisonTest.class, URIDistanceTest.class, FragmentationTest.class,
- AllEditTests.class })
+ AllEditTests.class, CommandStackTestSuite.class, })
public class AllTests {
/**
* Standalone launcher for all of compare's tests.

Back to the top