//------------------------------------------------------------------------------ // 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.core.commands.ExecutionException; import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.command.AbstractCommand; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EModelElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.edit.command.CopyCommand.Helper; import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain; import org.eclipse.epf.diagram.core.DiagramCorePlugin; import org.eclipse.epf.diagram.core.bridge.BridgeHelper; import org.eclipse.epf.diagram.core.services.DiagramHelper; import org.eclipse.epf.diagram.core.services.DiagramManager; import org.eclipse.epf.diagram.core.services.DiagramService; import org.eclipse.epf.diagram.model.NamedNode; import org.eclipse.epf.diagram.model.NodeContainer; import org.eclipse.epf.diagram.model.util.TxUtil; import org.eclipse.epf.library.edit.command.IResourceAwareCommand; import org.eclipse.epf.library.edit.util.IDiagramManager; import org.eclipse.epf.uma.Activity; import org.eclipse.epf.uma.MethodElement; import org.eclipse.epf.uma.Process; import org.eclipse.gmf.runtime.notation.Diagram; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.uml2.uml.ActivityParameterNode; import org.eclipse.uml2.uml.ActivityPartition; import org.eclipse.uml2.uml.StructuredActivityNode; /** * * It does copy the diagram for the activity * * @author Shilpa Toraskar * @author Phong Nguyen Le * @since 1.2 */ public class CopyDiagramCommand extends AbstractCommand implements IResourceAwareCommand { private Collection<?> elements; private Map<EObject, EObject> copyToOriginalMap; private Collection<Diagram> copiedElements; private static final boolean DEBUG = DiagramCorePlugin.getDefault() .isDebugging(); private Process targetProcess; private DiagramManager mgr; private InternalTransactionalEditingDomain domain; private Map<EObject, EObject> originalToCopyMap; private CopyDiagramCommand(Collection<?> elements, Process targetProcess) { this.elements = elements; this.targetProcess = targetProcess; // get diagram manager and domain mgr = DiagramManager.getInstance(targetProcess, this); domain = mgr.getEditingDomain(); } public CopyDiagramCommand(Collection<?> elements, Helper copyHelper, Process targetProcess) { this(elements, targetProcess); this.originalToCopyMap = copyHelper; } public CopyDiagramCommand(Collection<?> elements, Map<EObject, EObject> copyToOriginalMap, Process targetProcess) { this(elements, targetProcess); this.copyToOriginalMap = copyToOriginalMap; } /* * (non-Javadoc) * * @see org.eclipse.emf.common.command.Command#execute() */ public void execute() { try { TxUtil.runInTransaction(domain, new Runnable() { public void run() { doExecute(); } }); } catch (ExecutionException e) { DiagramCorePlugin.getDefault().getLogger().logError(e); } } /* * (non-Javadoc) * * @see org.eclipse.emf.common.command.Command#redo() */ public void redo() { execute(); } protected Map<?, ?> getCopyToOriginalMap() { if(copyToOriginalMap == null && originalToCopyMap != null) { copyToOriginalMap = new HashMap<EObject, EObject>(); for (Map.Entry<EObject, EObject> entry : originalToCopyMap.entrySet()) { copyToOriginalMap.put(entry.getValue(), entry.getKey()); } } return copyToOriginalMap; } private void doExecute() { if (copiedElements == null) { copiedElements = new ArrayList<Diagram>(); } else { copiedElements.clear(); } DiagramService diagramSvc = new DiagramService(); try { for (Object e : elements) { Object orig = getCopyToOriginalMap().get(e); if (orig != null && orig instanceof Activity && e != null && e instanceof Activity) { Activity copyActivity = (Activity) e; Activity origActivity = (Activity) orig; Collection<Diagram> diagrams = diagramSvc.getDiagrams(origActivity); if (diagrams != null && !diagrams.isEmpty()) { for (Diagram diagram : diagrams) { if (diagram != null) { // copy the diagram Diagram diagramCopy = (Diagram) DiagramHelper .copyDiagram(domain, diagram); // update children references updateReferences(diagramCopy); // associate with the activity int diagramType = DiagramHelper .getDiagramType(diagramCopy); mgr.associate(diagramCopy, diagramType, (Activity) copyActivity); copiedElements.add(diagramCopy); } } } } } } catch (Exception ex) { DiagramCorePlugin.getDefault().getLogger().logError(ex); if (DEBUG) { ex.printStackTrace(); } } finally { diagramSvc.dispose(); } } /** * Update eAnnotations references * * @param copy */ public void updateReferences(Diagram copy) { int diagramType = DiagramHelper.getDiagramType(copy); List<Object> children = new ArrayList<Object>(); // collect all children first e.g. for ActivityPartition // we don't have partition into partition so just getting one level sub-children // are enough for now. for (Iterator<?> itor = copy.getChildren().iterator(); itor.hasNext();) { Node node = (Node) itor.next(); EObject obj = node.getElement(); children.add(node); if (obj instanceof ActivityPartition){ children.addAll(node.getChildren()); } } for (Iterator<?> itor = children.iterator(); itor.hasNext();) { Node node = (Node) itor.next(); EObject obj = node.getElement(); if (diagramType == IDiagramManager.ACTIVITY_DIAGRAM) { if (obj instanceof StructuredActivityNode || obj instanceof ActivityParameterNode) { EModelElement modelElement = (EModelElement) obj; MethodElement me = BridgeHelper .getMethodElementFromAnnotation(modelElement, targetProcess.eResource().getResourceSet()); Object mappedMethodElement = getCopiedElement(me); if (mappedMethodElement != null) { BridgeHelper.addEAnnotation(modelElement, (MethodElement) mappedMethodElement); } } } else if (diagramType == IDiagramManager.ACTIVITY_DETAIL_DIAGRAM) { if (obj instanceof NodeContainer) { NodeContainer nodeContainer = (NodeContainer) obj; // do mapping for nodecontainer MethodElement me = nodeContainer.getLinkedElement(); Object mappedMethodElement = getCopiedElement(me); if (mappedMethodElement != null) { nodeContainer .setLinkedElement((MethodElement) mappedMethodElement); } // do mapping for its children List<?> nodes = nodeContainer.getNodes(); for (int i = 0; i < nodes.size(); i++) { NamedNode namedNode = (NamedNode) nodes.get(i); me = namedNode.getLinkedElement(); mappedMethodElement = getCopiedElement(me); if (mappedMethodElement != null) { namedNode .setLinkedElement((MethodElement) mappedMethodElement); } } } } else if (diagramType == IDiagramManager.WORK_PRODUCT_DEPENDENCY_DIAGRAM) { if (obj instanceof NamedNode) { NamedNode namedNode = (NamedNode) obj; MethodElement me = namedNode.getLinkedElement(); Object mappedMethodElement = getCopiedElement(me); if (mappedMethodElement != null) { namedNode .setLinkedElement((MethodElement) mappedMethodElement); } } } } } /** * Get copied element from the map * * @param element * @return */ private Object getCopiedElement(Object element) { if(originalToCopyMap == null && copyToOriginalMap != null) { originalToCopyMap = new HashMap<EObject, EObject>(); for (Map.Entry<EObject, EObject> entry : copyToOriginalMap.entrySet()) { originalToCopyMap.put(entry.getValue(), entry.getKey()); } } return originalToCopyMap != null ? originalToCopyMap.get(element) : null; } /* * (non-Javadoc) * * @see org.eclipse.emf.common.command.AbstractCommand#prepare() */ protected boolean prepare() { return true; } /* * (non-Javadoc) * * @see org.eclipse.emf.common.command.AbstractCommand#undo() */ public void undo() { if (!(copiedElements == null || copiedElements.isEmpty())) { try { TxUtil.runInTransaction(domain, new Runnable() { public void run() { try { for (Diagram diagram : copiedElements) { mgr.getResource().getContents() .remove(diagram.getElement()); mgr.getResource().getContents().remove(diagram); } } catch (CoreException e) { throw new WrappedException(e); } } }); copiedElements.clear(); } catch (Exception ex) { DiagramCorePlugin.getDefault().getLogger().logError(ex); if (DEBUG) { ex.printStackTrace(); } } } } /* * (non-Javadoc) * * @see org.eclipse.epf.library.edit.command.IResourceAwareCommand#getModifiedResources() */ public Collection<Resource> getModifiedResources() { if (copiedElements == null || copiedElements.isEmpty()) { // command is not executed yet return Collections.emptyList(); } HashSet<Resource> modifiedResources = new HashSet<Resource>(); for (Diagram diagram : copiedElements) { if(diagram != null && diagram.eResource() != null) modifiedResources.add(diagram.eResource()); } return modifiedResources; } /* * (non-Javadoc) * * @see org.eclipse.emf.common.command.AbstractCommand#dispose() */ public void dispose() { if (mgr != null) mgr.removeConsumer(this); super.dispose(); } }