From d322e17b0de9d9092f0c8948d5a5943b22dd1251 Mon Sep 17 00:00:00 2001
From: Florian Hoelzl <hoelzl@fortiss.org>
Date: Tue, 8 Mar 2011 12:08:06 +0000
Subject: [PATCH] command stack service trial implementation

---
 .../trunk/META-INF/MANIFEST.MF                |   6 +-
 .../kernel/internal/CommandStackService.java  | 176 +++---------------
 2 files changed, 25 insertions(+), 157 deletions(-)

diff --git a/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF b/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
index 80f3df3c9..170081c08 100644
--- a/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
+++ b/org.fortiss.tooling.kernel/trunk/META-INF/MANIFEST.MF
@@ -12,9 +12,9 @@ Require-Bundle: org.eclipse.core.runtime;visibility:=reexport,
  org.conqat.ide.commons;bundle-version="2.7.0";visibility:=reexport,
  org.conqat.ide.commons.ui;bundle-version="2.7.0";visibility:=reexport,
  org.unicase.workspace,
- org.unicase.ecp.model;visibility:=reexport,
- org.unicase.ecpemfstorebridge,
- org.unicase.ui.common
+ org.unicase.ecp.model,
+ org.unicase.ui.common,
+ org.unicase.ecpemfstorebridge
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
 Bundle-ActivationPolicy: lazy
 Export-Package: org.fortiss.tooling.kernel,
diff --git a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
index 5c37766d1..f60a0e5cb 100644
--- a/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
+++ b/org.fortiss.tooling.kernel/trunk/src/org/fortiss/tooling/kernel/internal/CommandStackService.java
@@ -19,25 +19,21 @@ package org.fortiss.tooling.kernel.internal;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Stack;
 
 import org.conqat.ide.commons.ui.logging.LoggingUtils;
 import org.eclipse.core.runtime.IStatus;
-import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.BasicCommandStack;
 import org.eclipse.emf.common.notify.Notification;
 import org.eclipse.emf.common.notify.impl.AdapterImpl;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.edit.command.ChangeCommand;
-import org.eclipse.emf.edit.domain.EditingDomain;
 import org.fortiss.tooling.kernel.ToolingKernelActivator;
 import org.fortiss.tooling.kernel.services.ICommandStackService;
 import org.unicase.ecp.model.ECPWorkspaceManager;
 import org.unicase.ecp.model.NoWorkspaceException;
 import org.unicase.ecp.model.workSpaceModel.ECPProject;
-import org.unicase.ecp.model.workSpaceModel.ECPProjectListener;
 import org.unicase.ecp.model.workSpaceModel.ECPWorkspace;
 import org.unicase.ecp.model.workSpaceModel.WorkSpaceModelPackage;
-import org.unicase.workspace.ProjectSpace;
 
 /**
  * This class implements the {@link ICommandStackService} interface. We have to
@@ -59,7 +55,7 @@ public class CommandStackService implements ICommandStackService {
 	private ECPWorkspace workspace;
 
 	/** Stores the project command stacks. */
-	private Map<ECPProject, CommandStackInfo> commandStackMap = new HashMap<ECPProject, CommandStackInfo>();
+	private Map<ECPProject, BasicCommandStack> commandStackMap = new HashMap<ECPProject, BasicCommandStack>();
 
 	/** Constructor. */
 	public CommandStackService() {
@@ -75,14 +71,21 @@ public class CommandStackService implements ICommandStackService {
 		workspace.eAdapters().add(workspaceListener);
 
 		for (ECPProject project : workspace.getProjects()) {
-			addCommandStackInfo(project);
+			addCommandStack(project);
 		}
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void runAsCommand(EObject target, final Runnable runner) {
-		commandStackMap.get(getECPProject(target)).execute(target, runner);
+		ChangeCommand chgCommand = new ChangeCommand(target) {
+
+			@Override
+			protected void doExecute() {
+				runner.run();
+			}
+		};
+		commandStackMap.get(getECPProject(target)).execute(chgCommand);
 	}
 
 	/** {@inheritDoc} */
@@ -100,23 +103,18 @@ public class CommandStackService implements ICommandStackService {
 	/** {@inheritDoc} */
 	@Override
 	public void undo(EObject target) {
-		if (canUndo(target)) {
-			commandStackMap.get(getECPProject(target)).undo();
-		}
+		commandStackMap.get(getECPProject(target)).undo();
 	}
 
 	/** {@inheritDoc} */
 	@Override
 	public void redo(EObject target) {
-		if (canRedo(target)) {
-			commandStackMap.get(getECPProject(target)).redo();
-		}
+		commandStackMap.get(getECPProject(target)).redo();
 	}
 
 	/**
-	 * Creates the workspace listener, which registers the project listener on
-	 * added projects. It also unregisters the project listener from removed
-	 * projects.
+	 * Creates the workspace listener, which adds the command stacks for the
+	 * added projects. It also unregisters command stacks from removed projects.
 	 */
 	private void createWorkspaceListener() {
 		workspaceListener = new AdapterImpl() {
@@ -127,11 +125,11 @@ public class CommandStackService implements ICommandStackService {
 					if (msg.getEventType() == Notification.ADD
 							&& WorkSpaceModelPackage.eINSTANCE.getECPProject()
 									.isInstance(msg.getNewValue())) {
-						addCommandStackInfo((ECPProject) msg.getNewValue());
+						addCommandStack((ECPProject) msg.getNewValue());
 					} else if (msg.getEventType() == Notification.REMOVE
 							&& WorkSpaceModelPackage.eINSTANCE.getECPProject()
 									.isInstance(msg.getOldValue())) {
-						removeCommandStackInfo((ECPProject) msg.getOldValue());
+						removeCommandStack((ECPProject) msg.getOldValue());
 					}
 				}
 				super.notifyChanged(msg);
@@ -153,145 +151,15 @@ public class CommandStackService implements ICommandStackService {
 		return null;
 	}
 
-	/**
-	 * Stores project-specific information about the command stack of an
-	 * EMFStore proejct.
-	 */
-	private class CommandStackInfo {
-
-		/**
-		 * Stores the initial size of the operations list, which may be greater
-		 * than zero. This happens when uncommitted changes are in a project,
-		 * while the workbench is restarted, i.e., the command stack service
-		 * forgets, while the EMFStore workspace does not.
-		 */
-		private int initialOperationListSize = 0;
-
-		/** Stores the project undo stack. */
-		private final Stack<Command> undoStack = new Stack<Command>();
-
-		/** Stores the roject redo stack. */
-		private final Stack<Command> redoStack = new Stack<Command>();
-
-		/** Stores the ECP project. */
-		private final ECPProject ecpProject;
-
-		/** Stores the workspace project space. */
-		private ProjectSpace projectSpace;
-
-		/** Stores the editing domain. */
-		private EditingDomain editingDomain;
-
-		/** Stores the current command execution flag. */
-		private boolean inExecution = false;
-
-		/** Stores the project listener. */
-		private ECPProjectListener projectListener = new ECPProjectListener() {
-
-			@Override
-			public void projectDeleted() {
-				CommandStackService.this.removeCommandStackInfo(ecpProject);
-			}
-
-			@Override
-			public void projectChanged() {
-				updateCommandStackInfo();
-			}
-
-			@Override
-			public void modelelementDeleted(EObject eobject) {
-				// ignore for now
-			}
-		};
-
-		/** Constructor. */
-		public CommandStackInfo(ECPProject project) {
-			this.ecpProject = project;
-			this.projectSpace = (ProjectSpace) project.getRootObject();
-			project.addECPProjectListener(projectListener);
-			this.initialOperationListSize = projectSpace.getOperations().size();
-			this.editingDomain = project.getEditingDomain();
-		}
-
-		/** Perform redo. */
-		public void redo() {
-			Command cmd = redoStack.pop();
-			executeOnEMFStore(cmd);
-			undoStack.push(cmd);
-		}
-
-		/** Perform undo. */
-		public void undo() {
-			Command cmd = undoStack.pop();
-			projectSpace.undoLastOperation();
-			redoStack.push(cmd);
-		}
-
-		/** Returns whether undo is possible. */
-		public boolean canUndo() {
-			return !undoStack.isEmpty();
-		}
-
-		/** Returns whether redo is possible. */
-		public boolean canRedo() {
-			return !redoStack.isEmpty();
-		}
-
-		/** Executes the given command using the target's command stack. */
-		public void execute(EObject target, final Runnable runner) {
-			// sanity check
-			if (getECPProject(target) == ecpProject) {
-				ChangeCommand cmd = new ChangeCommand(target) {
-					@Override
-					protected void doExecute() {
-						CommandStackInfo.this.inExecution = true;
-						runner.run();
-						CommandStackInfo.this.inExecution = false;
-					}
-				};
-				executeOnEMFStore(cmd);
-				undoStack.push(cmd);
-				redoStack.clear();
-			}
-		}
-
-		/** Native command execution on EMFStore editing domain. */
-		private void executeOnEMFStore(Command cmd) {
-			editingDomain.getCommandStack().execute(cmd);
-		}
-
-		/** React to project changes and update the command stack. */
-		private void updateCommandStackInfo() {
-			int currentOperationListSize = projectSpace.getOperations().size();
-			if (currentOperationListSize == undoStack.size()
-					+ initialOperationListSize - 1) {
-				System.out.println("Und occured.");
-				redoStack.push(undoStack.pop());
-			} else if (currentOperationListSize == undoStack.size()
-					+ initialOperationListSize) {
-				System.out
-						.println("A push to the undo stack occured. Resetting redo stack. inExecution = "
-								+ inExecution);
-				redoStack.empty();
-			} else {
-				System.out
-						.println("Unknown project change received: undoStackSize = "
-								+ undoStack.size()
-								+ "; redoStackSize = "
-								+ redoStack.size()
-								+ "; operationsListSize = "
-								+ currentOperationListSize);
-			}
-		}
-	}
-
 	/** Adds the command stack for the given project. */
-	private void addCommandStackInfo(ECPProject project) {
-		commandStackMap.put(project, new CommandStackInfo(project));
+	private void addCommandStack(ECPProject project) {
+		BasicCommandStack cmdStack = (BasicCommandStack) project
+				.getEditingDomain().getCommandStack();
+		commandStackMap.put(project, cmdStack);
 	}
 
 	/** Removes the command stack for the given project. */
-	private void removeCommandStackInfo(ECPProject project) {
+	private void removeCommandStack(ECPProject project) {
 		commandStackMap.remove(project);
 	}
 }
-- 
GitLab