/*****************************************************************************
* Copyright (c) 2009 CEA LIST.
*
*
* 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:
* Fadoi LAKHAL Fadoi.Lakhal@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.clazz.custom.policies.itemsemantic;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.AbstractOperation;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EAnnotation;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.ReconnectRequest;
import org.eclipse.gmf.runtime.diagram.core.commands.DeleteCommand;
import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.commands.DestroyReferenceCommand;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyReferenceRequest;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.builders.NotificationBuilder;
import org.eclipse.papyrus.infra.widgets.toolbox.notification.popups.PopupNotification;
import org.eclipse.papyrus.uml.diagram.clazz.custom.command.CustomReorientContainmentLinkCommand;
import org.eclipse.papyrus.uml.diagram.clazz.custom.edit.part.CContainmentCircleEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.custom.helper.ContainmentHelper;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.AbstractionEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.CommentAnnotatedElementEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ConnectorDurationObservationEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ConnectorTimeObservationEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ConstraintConstrainedElementEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.DependencyBranchEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.DependencyEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.RealizationEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.TemplateBindingEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.UsageEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.policies.UMLBaseItemSemanticEditPolicy;
import org.eclipse.papyrus.uml.diagram.clazz.part.UMLVisualIDRegistry;
import org.eclipse.papyrus.uml.diagram.clazz.providers.UMLElementTypes;
import org.eclipse.swt.SWT;
import org.eclipse.uml2.uml.NamedElement;
public class CustomContainmentCircleItemSemanticEditPolicy extends UMLBaseItemSemanticEditPolicy {
public CustomContainmentCircleItemSemanticEditPolicy() {
super(UMLElementTypes.Node_3032);
// TODO Auto-generated constructor stub
}
/**
* Gets the destroy element command gen.
*
* @param req
* the req
* @return the destroy element command gen
*/
protected Command getDestroyElementCommandGen(DestroyElementRequest req) {
// copy of super.getDestroyElementCommand()
// with commented case of AddedLinkAddedPart wihich causes NPE
View view = (View)getHost().getModel();
CompositeTransactionalCommand cmd = new CompositeTransactionalCommand(getEditingDomain(), null);
cmd.setTransactionNestingEnabled(false);
for(Iterator<?> it = view.getTargetEdges().iterator(); it.hasNext();) {
Edge incomingLink = (Edge)it.next();
if(UMLVisualIDRegistry.getVisualID(incomingLink) == RealizationEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == AbstractionEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == UsageEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == DependencyEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == DependencyBranchEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == CommentAnnotatedElementEditPart.VISUAL_ID) {
DestroyReferenceRequest r = new DestroyReferenceRequest(incomingLink.getSource().getElement(), null, incomingLink.getTarget().getElement(), false);
cmd.add(new DestroyReferenceCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == ConstraintConstrainedElementEditPart.VISUAL_ID) {
DestroyReferenceRequest r = new DestroyReferenceRequest(incomingLink.getSource().getElement(), null, incomingLink.getTarget().getElement(), false);
cmd.add(new DestroyReferenceCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == TemplateBindingEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
/**
* if(UMLVisualIDRegistry.getVisualID(incomingLink) == AddedLinkEditPart.VISUAL_ID) {
* DestroyElementRequest r = new DestroyElementRequest(incomingLink.getElement(), false);
* cmd.add(new DestroyElementCommand(r));
* cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
* continue;
* }
**/
if(UMLVisualIDRegistry.getVisualID(incomingLink) == ConnectorTimeObservationEditPart.VISUAL_ID) {
DestroyReferenceRequest r = new DestroyReferenceRequest(incomingLink.getSource().getElement(), null, incomingLink.getTarget().getElement(), false);
cmd.add(new DestroyReferenceCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(incomingLink) == ConnectorDurationObservationEditPart.VISUAL_ID) {
DestroyReferenceRequest r = new DestroyReferenceRequest(incomingLink.getSource().getElement(), null, incomingLink.getTarget().getElement(), false);
cmd.add(new DestroyReferenceCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), incomingLink));
continue;
}
}
for(Iterator<?> it = view.getSourceEdges().iterator(); it.hasNext();) {
Edge outgoingLink = (Edge)it.next();
if(UMLVisualIDRegistry.getVisualID(outgoingLink) == RealizationEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(outgoingLink) == AbstractionEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(outgoingLink) == UsageEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(outgoingLink) == DependencyEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
continue;
}
if(UMLVisualIDRegistry.getVisualID(outgoingLink) == DependencyBranchEditPart.VISUAL_ID) {
DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
cmd.add(new DestroyElementCommand(r));
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
continue;
}
/**
* if(UMLVisualIDRegistry.getVisualID(outgoingLink) == AddedLinkEditPart.VISUAL_ID) {
* DestroyElementRequest r = new DestroyElementRequest(outgoingLink.getElement(), false);
* cmd.add(new DestroyElementCommand(r));
* cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
* continue;
* }
**/
}
EAnnotation annotation = view.getEAnnotation("Shortcut"); //$NON-NLS-1$
if(annotation == null) {
// there are indirectly referenced children, need extra commands: false
addDestroyShortcutsCommand(cmd, view);
// delete host element
/**
* cmd.add(new DestroyElementCommand(req));
**/
cmd.add(new DeleteCommand(getEditingDomain(), view));
} else {
cmd.add(new DeleteCommand(getEditingDomain(), view));
}
return getGEFWrapper(cmd.reduce());
}
/**
*
* {@inheritDoc}
*/
@Override
protected Command getDestroyElementCommand(DestroyElementRequest req) {
CompositeTransactionalCommand cmd = new CompositeTransactionalCommand(getEditingDomain(), null);
View circle = (View)getHost().getModel();
List<String> targetNames = new ArrayList<String>();
for(Object next : circle.getSourceEdges()) {
Edge outgoingLink = (Edge)next;
if(ContainmentHelper.isContainmentLink(outgoingLink)) {
targetNames.add(((NamedElement)outgoingLink.getTarget().getElement()).getName());
}
}
cmd.add(new AskToDeleteContainmentCommand(targetNames));
ICommandProxy command = (ICommandProxy)getDestroyElementCommandGen(req);
cmd.add(command.getICommand());
for(Object next : circle.getSourceEdges()) {
Edge outgoingLink = (Edge)next;
if(ContainmentHelper.isContainmentLink(outgoingLink)) {
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink));
//delete target view as it actually contained by the source object and will be deleted
cmd.add(new DeleteCommand(getEditingDomain(), outgoingLink.getTarget()));
// Important! Here we remove target
cmd.add(new DestroyElementCommand(new DestroyElementRequest(outgoingLink.getTarget().getElement(), true)));
ContainmentHelper.addDeleteOutgoingContainmentLinkViewCommands(getEditingDomain(), outgoingLink.getTarget(), cmd);
}
}
return getGEFWrapper(cmd.reduce());
}
/**
*
* {@inheritDoc}
*/
@Override
public Command getCommand(Request request) {
if(request instanceof ReconnectRequest) {
if(((ReconnectRequest)request).getTarget() instanceof CContainmentCircleEditPart) {
return getCustomReconnectRequest((ReconnectRequest)request);
}
}
return super.getCommand(request);
}
/**
*
* use the AbstractTransactionalCommand "CustomReorientLinkCommand" to change the owner of the target class
*/
public Command getCustomReconnectRequest(ReconnectRequest request) {
CompoundCommand cc = new CompoundCommand();
cc.add(new ICommandProxy(new CustomReorientContainmentLinkCommand(getEditingDomain(), request)));
return cc;
}
public static class AskToDeleteContainmentCommand extends AbstractOperation {
private List<String> myTargetNames;
public AskToDeleteContainmentCommand(List<String> targetNames) {
super("Show Question Dialog");
myTargetNames = targetNames;
}
@Override
public IStatus execute(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
String messageFormat = "You are about to delete a Containment Link - %s and its contained elements will be deleted as well. Are you sure you want to delete it?";
String message = String.format(messageFormat, getNamesString());
NotificationBuilder builder = NotificationBuilder.createYesNo(message);
int dialogResult = ((PopupNotification)builder.run()).getResult();
if(dialogResult == SWT.YES) {
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
private String getNamesString() {
String namesString = "";
Iterator<String> namesIterator = myTargetNames.iterator();
while(namesIterator.hasNext()) {
namesString += "'" + namesIterator.next() + "'";
if(namesIterator.hasNext()) {
namesString += ", ";
}
}
return namesString;
}
@Override
public IStatus redo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
return Status.OK_STATUS;
}
@Override
public IStatus undo(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
return Status.OK_STATUS;
}
}
}