| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation and others. |
| // 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: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.edit.command; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.command.CommandStack; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.edit.command.AddCommand; |
| import org.eclipse.emf.edit.command.RemoveCommand; |
| import org.eclipse.emf.edit.command.SetCommand; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.epf.library.edit.TngAdapterFactory; |
| |
| /** |
| * Manages the execution of editing commands with full support for dirty flag, |
| * undo and redo. |
| * |
| * @author Phong Nguyen Le |
| * @since 1.0 |
| */ |
| public class ActionManager implements IActionManager { |
| |
| protected static final Map RESOURCE_TO_MODIFIERS_MAP = new HashMap(); |
| |
| private EditingDomain editingDomain; |
| |
| private FullyRevertibleCommandStack commandStack; |
| |
| public ActionManager() { |
| commandStack = createCommandStack(); |
| editingDomain = new AdapterFactoryEditingDomain( |
| TngAdapterFactory.INSTANCE |
| .getNavigatorView_ComposedAdapterFactory(), |
| commandStack); |
| } |
| |
| protected FullyRevertibleCommandStack createCommandStack() { |
| return new FullyRevertibleCommandStack(this); |
| } |
| |
| protected void registerAsModifierOf(EObject object) { |
| Resource resource = object.eResource(); |
| if (resource == null) |
| return; |
| registerAsModifierOf(resource); |
| } |
| |
| protected void registerAsModifierOf(Resource resource) { |
| synchronized (RESOURCE_TO_MODIFIERS_MAP) { |
| Set mods = (Set) RESOURCE_TO_MODIFIERS_MAP.get(resource); |
| if (mods == null) { |
| mods = new HashSet(); |
| RESOURCE_TO_MODIFIERS_MAP.put(resource, mods); |
| } |
| mods.add(this); |
| } |
| } |
| |
| protected void unregisterAsModifier() { |
| synchronized (RESOURCE_TO_MODIFIERS_MAP) { |
| for (Iterator iter = getModifiedResources().iterator(); iter |
| .hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| Set mods = (Set) RESOURCE_TO_MODIFIERS_MAP.get(resource); |
| if (mods != null) { |
| mods.remove(this); |
| if (mods.isEmpty()) { |
| // save the resource before it removed from |
| // RESOURCE_TO_MODIFIERS_MAP |
| // |
| save(resource); |
| RESOURCE_TO_MODIFIERS_MAP.remove(resource); |
| } |
| } |
| } |
| } |
| } |
| |
| public boolean doAction(int actionType, EObject object, |
| EStructuralFeature feature, Object value, int index) { |
| Command cmd = null; |
| Object oldValue = null; |
| switch (actionType) { |
| case ADD: { |
| if (index >= 0) { |
| cmd = new AddCommand(editingDomain, object, feature, value, |
| index); |
| } else { |
| cmd = new AddCommand(editingDomain, object, feature, value); |
| } |
| break; |
| } |
| case ADD_MANY: { |
| if (index >= 0) { |
| cmd = new AddCommand(editingDomain, object, feature, |
| (Collection) value, index); |
| } else { |
| cmd = new AddCommand(editingDomain, object, feature, |
| (Collection) value); |
| } |
| break; |
| } |
| case REMOVE: { |
| cmd = new RemoveCommand(editingDomain, object, feature, value); |
| break; |
| } |
| case REMOVE_MANY: { |
| cmd = new RemoveCommand(editingDomain, object, feature, |
| (Collection) value); |
| break; |
| } |
| case SET: { |
| oldValue = object.eGet(feature); |
| if ((oldValue != null && !oldValue.equals(value)) |
| || (oldValue == null && value != null)) { |
| cmd = new SetCommand(editingDomain, object, feature, value); |
| } |
| break; |
| } |
| } |
| if (cmd != null) { |
| return commandStack.doExecute(cmd); |
| } |
| return false; |
| } |
| |
| public void undo() { |
| commandStack.undo(); |
| } |
| |
| public void redo() { |
| commandStack.redo(); |
| } |
| |
| public boolean undoAll() { |
| boolean b = commandStack.undoAll(); |
| unregisterAsModifier(); |
| // fireNotifyChanged(null); |
| return b; |
| } |
| |
| public void saveIsDone() { |
| commandStack.saveIsDone(); |
| unregisterAsModifier(); |
| // fireNotifyChanged(null); |
| } |
| |
| public boolean isSaveNeeded() { |
| boolean ret = commandStack.isSaveNeeded(); |
| if (!ret) |
| return false; |
| if (getModifiedResources().isEmpty()) |
| return false; |
| return ret; |
| } |
| |
| public void dispose() { |
| commandStack.flush(); |
| } |
| |
| public Collection getModifiedResources() { |
| synchronized (RESOURCE_TO_MODIFIERS_MAP) { |
| Collection modifiedResources = new HashSet(); |
| for (Iterator iter = RESOURCE_TO_MODIFIERS_MAP.entrySet() |
| .iterator(); iter.hasNext();) { |
| Map.Entry entry = (Map.Entry) iter.next(); |
| Set mods = (Set) entry.getValue(); |
| if (mods.contains(this)) { |
| modifiedResources.add(entry.getKey()); |
| } |
| } |
| return modifiedResources; |
| } |
| } |
| |
| // public void fireNotifyChanged(Notification notification) { |
| // changeNotifier.fireNotifyChanged(notification); |
| // } |
| // |
| // public void addListener(INotifyChangedListener notifyChangedListener) { |
| // changeNotifier.add(notifyChangedListener); |
| // } |
| // |
| // public void removeListener(INotifyChangedListener notifyChangedListener) |
| // { |
| // changeNotifier.remove(notifyChangedListener); |
| // } |
| |
| /** |
| * Does nothing here, subclass should implement to provide saving the |
| * resource before it got removed from RESOURCE_TO_MODIFIERS_MAP |
| * |
| * @param resource |
| */ |
| protected void save(Resource resource) { |
| } |
| |
| public CommandStack getCommandStack() { |
| return commandStack; |
| } |
| |
| public boolean execute(IResourceAwareCommand cmd) { |
| if (cmd != null) { |
| return commandStack.doExecute(cmd); |
| } |
| return false; |
| } |
| |
| } |