blob: c14596c22c2e04c733b5af69d6e14199774c9ab8 [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 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.diagram.core.commands;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.AbstractTreeIterator;
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.CopyCommand.Helper;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.epf.common.CommonPlugin;
import org.eclipse.epf.diagram.core.DiagramCorePlugin;
import org.eclipse.epf.diagram.core.part.DiagramEditorInput;
import org.eclipse.epf.diagram.core.part.DiagramEditorInputProxy;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.command.DeleteMethodElementCommand;
import org.eclipse.epf.library.edit.command.INestedCommandProvider;
import org.eclipse.epf.library.edit.command.MethodElementAddCommand;
import org.eclipse.epf.library.edit.command.ResourceAwareCompoundCommand;
import org.eclipse.epf.library.edit.process.BreakdownElementWrapperItemProvider;
import org.eclipse.epf.library.edit.process.command.ActivityDropCommand;
import org.eclipse.epf.library.edit.process.command.CopyHelper;
import org.eclipse.epf.library.edit.process.command.ProcessDeepCopyCommand;
import org.eclipse.epf.library.edit.ui.IActionTypeProvider;
import org.eclipse.epf.library.edit.util.ActivityHandler;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.Process;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.edit.domain.TraceableAdapterFactoryEditingDomain;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorReference;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
/**
* @author Shilpa Toraskar
* @author Phong Nguyen Le
* @since 1.2
*/
public class NestedCommandProvider implements INestedCommandProvider {
private static final boolean DEBUG = DiagramCorePlugin.getDefault()
.isDebugging();
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.library.edit.command.INestedCommandProvider#createNestedCommand(org.eclipse.emf.common.command.Command)
*/
public Command createNestedCommand(Command command) {
if (command instanceof ActivityDropCommand) {
ActivityDropCommand cmd = (ActivityDropCommand) command;
if (IActionTypeProvider.COPY == cmd.getType())
return createNestedCommandForCopy(cmd);
else if (IActionTypeProvider.DEEP_COPY == cmd.getType())
return createNestedCommandForDeepCopy(cmd);
}
else if (command instanceof ProcessDeepCopyCommand) {
ProcessDeepCopyCommand cmd = (ProcessDeepCopyCommand) command;
Process deepCopy = null;
Collection<?> result = cmd.getResult();
if(!result.isEmpty()) {
deepCopy = (Process) result.iterator().next();
}
if(deepCopy != null) {
Collection<Activity> deepCopies = new ArrayList<Activity>();
deepCopies.add(deepCopy);
return createNestedCommandForDeepCopy(deepCopies, cmd.getTargetProcess(),
cmd.getCopyHelper(), cmd.getMethodConfiguration(), true);
}
}
return null;
}
/**
* Create nested command for Drag & Drop Copy
*
* @param command
* @return
*/
private Command createNestedCommandForCopy(ActivityDropCommand command) {
Collection<Resource> modifiedResources = ((ActivityDropCommand) command).getModifiedResources();
if (modifiedResources != null && !modifiedResources.isEmpty()) {
CompoundCommand cmd = new ResourceAwareCompoundCommand(
CompoundCommand.MERGE_COMMAND_ALL);
Helper copiedHelper = command.getActivityHandler().getCopyHelper();
Activity targetActivity = command.getActivity();
Process targetProc = TngUtil.getOwningProcess(targetActivity);
if (targetProc != null) {
try {
cmd.append(new CopyDiagramCommand(copiedHelper.values(),
copiedHelper, targetProc));
} catch (Exception ex) {
CommonPlugin.getDefault().getLogger().logError(ex);
if (DEBUG) {
ex.printStackTrace();
}
} finally {
}
}
if (!cmd.isEmpty()) {
return cmd;
}
}
return null;
}
/**
* Created nested command for Drag and Drop Deep copy
*
* @param command
* @return
*/
private Command createNestedCommandForDeepCopy(ActivityDropCommand command) {
ActivityHandler activityHandler = ((ActivityDropCommand) command)
.getActivityHandler();
if (activityHandler != null
&& !activityHandler.getDeepCopies().isEmpty()) {
return createNestedCommandForDeepCopy(activityHandler
.getDeepCopies(), activityHandler.getTargetProcess(),
activityHandler.getDeepCopyHelper(), activityHandler.getDeepCopyConfig(), false);
}
return null;
}
private Command createNestedCommandForDeepCopy(
Collection<Activity> deepCopies, final Process targetProc,
CopyHelper copyHelper, MethodConfiguration config,
boolean saveDiagram) {
CompoundCommand cmd;
if (saveDiagram) {
cmd = new ResourceAwareCompoundCommand(
CompoundCommand.MERGE_COMMAND_ALL) {
@Override
public void execute() {
super.execute();
// save diagram file
//
if (org.eclipse.epf.diagram.core.services.DiagramManager
.hasDiagramManager(targetProc)) {
org.eclipse.epf.diagram.core.services.DiagramManager mgr = org.eclipse.epf.diagram.core.services.DiagramManager
.getInstance(targetProc, this);
ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil
.getPersisterFor(targetProc.eResource())
.getFailSafePersister();
try {
Resource resource = mgr.getResource();
persister.save(resource);
persister.commit();
} catch (Exception e) {
DiagramCorePlugin.getDefault().getLogger()
.logError(e);
try {
persister.rollback();
} catch (Exception ex) {
DiagramCorePlugin.getDefault().getLogger()
.logError(ex);
}
} finally {
mgr.removeConsumer(this);
}
}
}
};
} else {
cmd = new ResourceAwareCompoundCommand(
CompoundCommand.MERGE_COMMAND_ALL);
}
for (Activity copyAct : deepCopies) {
Activity origAct = (Activity) copyHelper.getOriginal(copyAct);
Process srcProc = TngUtil.getOwningProcess(origAct);
Map<Activity, Activity> copyToOriginalMap = new HashMap<Activity, Activity>();
Iterator<BreakdownElement> copyTree = new AbstractTreeIterator<BreakdownElement>(
copyAct) {
@Override
protected Iterator<? extends BreakdownElement> getChildren(
Object object) {
if (object instanceof Activity) {
return ((Activity) object).getBreakdownElements()
.iterator();
}
return Collections.EMPTY_LIST.iterator();
}
};
while (copyTree.hasNext()) {
BreakdownElement e = copyTree.next();
if (e instanceof Activity) {
Object orig = copyHelper.getOriginal(e);
if (orig == null) {
System.out
.println("NestedCommandProvider.createNestedCommandForDeepCopy(): FATAL ERROR: could not find source activity of deep copy: " + e); //$NON-NLS-1$
} else {
copyToOriginalMap.put((Activity) e, (Activity) orig);
}
}
}
cmd.append(new CopyDiagramForDeepCopyCommand(copyToOriginalMap.keySet(),
copyToOriginalMap, srcProc, targetProc, copyHelper, config));
}
return !cmd.isEmpty() ? cmd : null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.library.edit.command.INestedCommandProvider#createRelatedObjects(java.util.Collection,
* org.eclipse.emf.common.command.Command)
*/
public Command createRelatedObjects(Collection createdElements,
Command createCommand) {
CompoundCommand cmd = new ResourceAwareCompoundCommand(
CompoundCommand.MERGE_COMMAND_ALL);
if (createCommand instanceof MethodElementAddCommand) {
MethodElementAddCommand meCommand = ((MethodElementAddCommand) createCommand);
Command addCommand = meCommand.getCommand();
if (addCommand instanceof AddCommand) {
EditingDomain ed = ((AddCommand) addCommand).getDomain();
if (((AddCommand)addCommand).getOwner() instanceof ProcessPackage) {
if (ed instanceof TraceableAdapterFactoryEditingDomain) {
Map copyToOriginalMap = ((TraceableAdapterFactoryEditingDomain) ed)
.getCopyToOriginalMap();
if (!copyToOriginalMap.isEmpty()) {
Collection affects = meCommand.getAffectedObjects();
for (Iterator iter = affects.iterator(); iter
.hasNext();) {
MethodElement element = (MethodElement) iter
.next();
if (element instanceof ProcessComponent) {
cmd.append(new CopyDiagramCommand(
copyToOriginalMap.keySet(),
copyToOriginalMap,
((ProcessComponent) element)
.getProcess()));
}
}
}
}
} else {
// Copy/paste within the process editor
if (ed instanceof TraceableAdapterFactoryEditingDomain) {
Map originalToCopyMap = ((TraceableAdapterFactoryEditingDomain) ed)
.getOriginalToClipboardMap();
Map copyToOriginalMap = new HashMap();
Object owner = ((AddCommand) addCommand).getOwner();
Process targetProc = TngUtil.getOwningProcess(owner);
if (targetProc != null) {
for (Iterator iter = originalToCopyMap.keySet()
.iterator(); iter.hasNext();) {
Object key = iter.next();
Object val = originalToCopyMap.get(key);
copyToOriginalMap.put(val, key);
}
cmd.append(new CopyDiagramCommand(copyToOriginalMap.keySet(),
copyToOriginalMap, targetProc));
}
}
}
}
}
if (!cmd.isEmpty()) {
return cmd;
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.epf.library.edit.command.INestedCommandProvider#removeRelatedObjects(java.util.Collection,
* org.eclipse.emf.common.command.Command)
*/
public Command removeRelatedObjects(Collection deletedElements,
Command deleteCommand) {
CompoundCommand cmd = new ResourceAwareCompoundCommand(
CompoundCommand.MERGE_COMMAND_ALL);
if(deleteCommand instanceof DeleteMethodElementCommand){
Command removeCommand = ((DeleteMethodElementCommand)deleteCommand).getCommand();
List<RemoveCommand> removeCommands = null;
if(removeCommand instanceof RemoveCommand){
removeCommands = Collections.singletonList((RemoveCommand)removeCommand);
}
else if(removeCommand instanceof CompoundCommand) {
removeCommands = new ArrayList<RemoveCommand>();
for (Command command : ((CompoundCommand)removeCommand).getCommandList()) {
if(command instanceof RemoveCommand) {
removeCommands.add((RemoveCommand) command);
}
}
}
if(removeCommands != null && !removeCommands.isEmpty()) {
Object owner = removeCommands.get(0).getOwner();
if(owner instanceof Activity) {
Process process = TngUtil.getOwningProcess((Activity)owner);
Collection<Activity> allElements = new HashSet<Activity>();
for (Iterator iter = deletedElements.iterator(); iter
.hasNext();) {
Object element = iter.next();
if (element instanceof Activity) {
Iterator iterator = new AbstractTreeIterator<Object>(element) {
private static final long serialVersionUID = 1L;
@Override
protected Iterator<? extends Object> getChildren(
Object object) {
if(object instanceof Activity) {
return ((Activity)object).getBreakdownElements().iterator();
}
else {
return Collections.emptyList().iterator();
}
}
};
while(iterator.hasNext()) {
Object e = iterator.next();
if(e instanceof Activity) {
allElements.add((Activity) e);
}
}
}
}
if(!allElements.isEmpty()){
cmd.append(new DeleteDiagramCommand(allElements, process));
}
for (RemoveCommand command : removeCommands) {
if(command.getOwner() instanceof Activity) {
DeleteDiagramNodeCommand deleteDiagramNodeCommand = new DeleteDiagramNodeCommand(
(Activity) command.getOwner(), command.getCollection());
if(deleteDiagramNodeCommand.canExecute()) {
cmd.append(deleteDiagramNodeCommand);
}
}
}
}
}
}
if(!deletedElements.isEmpty()){
for (Iterator iter = deletedElements.iterator(); iter.hasNext();) {
Object element = (Object) iter.next();
if(element instanceof ProcessComponent){
ProcessComponent pc = (ProcessComponent)element;
Process process = pc.getProcess();
closeDiagramEditors(process);
}
}
}
if(!cmd.isEmpty()){
return cmd;
}
return null;
}
/**
* Closes Diagram Editors if the owning process is deleted.
* @param process
*/
private void closeDiagramEditors(Process process) {
IWorkbenchPage workbenchPage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage();
IEditorReference[] editorReferences = workbenchPage
.getEditorReferences();
ArrayList<IEditorReference> editorsToClose = new ArrayList<IEditorReference>();
for (int i = 0; i < editorReferences.length; i++) {
IEditorReference editorRef = editorReferences[i];
IEditorInput editorInput;
try {
editorInput = editorRef.getEditorInput();
if (editorInput instanceof DiagramEditorInputProxy) {
DiagramEditorInput input = ((DiagramEditorInputProxy) editorInput)
.getDiagramEditorInput();
Object wrapper = input.getWrapper();
Object owningProcess = null;
if (wrapper != null) {
if (wrapper instanceof BreakdownElementWrapperItemProvider) {
owningProcess = TngUtil
.getOwningProcess(((BreakdownElementWrapperItemProvider) wrapper));
}
} else {
wrapper = input.getMethodElement();
if (wrapper instanceof BreakdownElement) {
owningProcess = TngUtil
.getOwningProcess(((BreakdownElement) wrapper));
}
}
if (owningProcess == owningProcess) {
editorsToClose.add(editorRef);
}
}
} catch (PartInitException e) {
DiagramCorePlugin.getDefault().getLogger().logError(e);
}
}
if(!editorsToClose.isEmpty()) {
IEditorReference[] refs = new IEditorReference[editorsToClose.size()];
editorsToClose.toArray(refs);
workbenchPage.closeEditors(refs, false);
}
}
}