From a127a49f7d12a9819cca53f4fbac4ca4cb329034 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Mon, 2 May 2016 09:59:20 +0000
Subject: [PATCH] Extended DummyTopLevelElement to behave like ModelContext but
 without any fixed storage. Undo/redo is working fine. refs 2567

---
 .../handler/TutorialDefinitionHandler.java    |   2 +-
 .../kernel/internal/DummyTopLevelElement.java | 111 +++++++++++++++---
 2 files changed, 97 insertions(+), 16 deletions(-)

diff --git a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/handler/TutorialDefinitionHandler.java b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/handler/TutorialDefinitionHandler.java
index 5933408ae..b2bcb706f 100644
--- a/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/handler/TutorialDefinitionHandler.java
+++ b/org.fortiss.tooling.kernel.ui/trunk/src/org/fortiss/tooling/kernel/ui/internal/handler/TutorialDefinitionHandler.java
@@ -44,7 +44,7 @@ public final class TutorialDefinitionHandler extends ModelElementHandlerBase<Tut
 	/** {@inheritDoc} */
 	@Override
 	public String getName(TutorialDefinition element) {
-		return element.getName();
+		return "Tutorial";
 	}
 
 	/** {@inheritDoc} */
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/DummyTopLevelElement.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/DummyTopLevelElement.java
index d142bcc9f..e5ac435de 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/DummyTopLevelElement.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/DummyTopLevelElement.java
@@ -17,13 +17,25 @@ $Id$
 +--------------------------------------------------------------------------*/
 package org.fortiss.tooling.kernel.internal;
 
+import static org.fortiss.tooling.kernel.utils.LoggingUtils.error;
+
+import java.util.EventObject;
+import java.util.LinkedList;
+import java.util.List;
+
 import org.eclipse.core.runtime.Assert;
 import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.command.AbstractCommand;
 import org.eclipse.emf.common.command.CommandStackListener;
 import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.common.util.URI;
 import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.fortiss.tooling.kernel.ToolingKernelActivator;
 import org.fortiss.tooling.kernel.extension.data.ITopLevelElement;
+import org.fortiss.tooling.kernel.internal.storage.eclipse.AutoUndoCommandStack;
 import org.fortiss.tooling.kernel.model.IIdLabeled;
 import org.fortiss.tooling.kernel.service.IPersistencyService;
 
@@ -37,15 +49,32 @@ import org.fortiss.tooling.kernel.service.IPersistencyService;
  * @version $Rev$
  * @ConQAT.Rating YELLOW Hash: 64D330706835D3C03BC7487F87364627
  */
-final class DummyTopLevelElement implements ITopLevelElement {
+final class DummyTopLevelElement implements ITopLevelElement, CommandStackListener {
 
 	/** Stores the root element. */
 	private final EObject root;
 
+	/** The editing domain used for this model. */
+	private final TransactionalEditingDomain editingDomain;
+
+	/** The transactional command stack. */
+	private final AutoUndoCommandStack transactionalCommandStack;
+
+	/** Stores the command stack listener for this context. */
+	private final List<CommandStackListener> listeners = new LinkedList<CommandStackListener>();
+
 	/** Constructor. */
 	public DummyTopLevelElement(EObject root) {
 		Assert.isNotNull(root);
 		this.root = root;
+
+		editingDomain = TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain();
+
+		Resource res =
+				editingDomain.getResourceSet().createResource(URI.createURI("dummy://dummy"));
+		transactionalCommandStack = new AutoUndoCommandStack(editingDomain);
+		transactionalCommandStack.addCommandStackListener(this);
+		runAsNonDirtyingCommand(() -> res.getContents().add(root));
 	}
 
 	/** {@inheritDoc} */
@@ -54,52 +83,95 @@ final class DummyTopLevelElement implements ITopLevelElement {
 		return root;
 	}
 
-	/** {@inheritDoc} */
+	/** Runs the given runnable as a command. */
 	@Override
-	public void runAsCommand(Runnable runner) {
-		runner.run();
-	}
+	public void runAsCommand(final Runnable runnable) {
+		transactionalCommandStack.execute(new AbstractCommand() {
 
-	/** {@inheritDoc} */
-	@Override
-	public void runAsNonDirtyingCommand(Runnable runner) {
-		runner.run();
+			@Override
+			public boolean canExecute() {
+				return true;
+			}
+
+			@Override
+			public void execute() {
+				runnable.run();
+			}
+
+			@Override
+			public void redo() {
+				// we do nothing here, as redo is handled by our command stack.
+			}
+		});
+	}
+
+	/** Runs the given runnable as a command that does not make the model dirty. */
+	@Override
+	public void runAsNonDirtyingCommand(final Runnable runnable) {
+		try {
+			transactionalCommandStack.executeNonDirtyingNonUndoing(new AbstractCommand() {
+				@Override
+				public void execute() {
+					runnable.run();
+				}
+
+				@Override
+				public boolean canExecute() {
+					return true;
+				}
+
+				@Override
+				public void redo() {
+					// we do nothing here, as redo is handled by our command stack.
+				}
+
+				/** {@inheritDoc} */
+				@Override
+				public boolean canUndo() {
+					return false;
+				}
+			});
+		} catch(Exception e) {
+			e.printStackTrace();
+			error(ToolingKernelActivator.getDefault(),
+					"Problem with synchronizing library and model!", e);
+		}
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void addCommandStackListener(CommandStackListener listener) {
-		// ignore
+		listeners.add(listener);
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void removeCommandStackListener(CommandStackListener listener) {
-		// ignore
+		listeners.remove(listener);
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public boolean canUndo() {
-		return false;
+		return transactionalCommandStack.canUndo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public boolean canRedo() {
-		return false;
+		return transactionalCommandStack.canRedo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void undo() {
-		// ignore
+		transactionalCommandStack.undo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void redo() {
-		// ignore
+		transactionalCommandStack.redo();
 	}
 
 	/** {@inheritDoc} */
@@ -169,4 +241,13 @@ final class DummyTopLevelElement implements ITopLevelElement {
 	public ResourceSet getResourceSet() {
 		return null;
 	}
+
+	/** {@inheritDoc} */
+	@Override
+	public void commandStackChanged(EventObject event) {
+		EventObject eo = new EventObject(this);
+		for(CommandStackListener l : listeners) {
+			l.commandStackChanged(eo);
+		}
+	}
 }
-- 
GitLab