/***************************************************************************** * 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 * Tatiana Fesenko (CEA LIST) - 318000 [Class Diagram] Refactor the creation / move / drag and drop behavior of the ContainmentLink * *****************************************************************************/ package org.eclipse.papyrus.uml.diagram.clazz.custom.command; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gef.EditPart; import org.eclipse.gef.commands.CompoundCommand; import org.eclipse.gef.editparts.AbstractGraphicalEditPart; import org.eclipse.gmf.runtime.common.core.command.CommandResult; 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.AbstractTransactionalCommand; import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientReferenceRelationshipRequest; import org.eclipse.gmf.runtime.emf.type.core.requests.ReorientRelationshipRequest; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.View; 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.ClassEditPart; import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ContainmentSubLinkEditPart; import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.PackageEditPart; import org.eclipse.uml2.uml.PackageableElement; /** * The Class AddedLinkReorientCommand is used to reorient a containment link. */ public class ContainmentLinkReorientCommand extends AbstractTransactionalCommand { /** The reorient direction. */ private final int reorientDirection; /** The old end. */ private final EObject oldEnd; /** The new end. */ private final EObject newEnd; /** The my target edit part. */ private EditPart myTargetEditPart; /** The old end visual parent. */ private EObject oldEndVisualParent; /** * Instantiates a new containment link reorient command. * * @param req * the req * @param editPartTarget * the edit part target */ public ContainmentLinkReorientCommand(ReorientReferenceRelationshipRequest req, EditPart editPartTarget) { super(req.getEditingDomain(), req.getLabel(), null); myTargetEditPart = editPartTarget; reorientDirection = req.getDirection(); final EObject oldEndView; if(reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE) { oldEndView = ((Edge)req.getParameter(ContainmentHelper.KEY_CONNECTION_VIEW)).getSource(); } else if(reorientDirection == ReorientRelationshipRequest.REORIENT_TARGET) { oldEndView = ((Edge)req.getParameter(ContainmentHelper.KEY_CONNECTION_VIEW)).getTarget(); } else { throw new IllegalStateException(); } oldEndVisualParent = ((View)oldEndView.eContainer()).getElement(); oldEnd = req.getOldRelationshipEnd(); newEnd = req.getNewRelationshipEnd(); } /** * @see org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand#doExecuteWithResult(org.eclipse.core.runtime.IProgressMonitor, * org.eclipse.core.runtime.IAdaptable) * * @param monitor * @param info * @return * @throws ExecutionException */ @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { if(!canExecute()) { throw new ExecutionException("Invalid arguments in reorient link command"); //$NON-NLS-1$ } if(reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE) { return reorientSource(); } if(reorientDirection == ReorientRelationshipRequest.REORIENT_TARGET) { return reorientTarget(); } throw new IllegalStateException(); } /** * @see org.eclipse.core.commands.operations.AbstractOperation#canExecute() * * @return */ public boolean canExecute() { if(reorientDirection == ReorientRelationshipRequest.REORIENT_SOURCE) { return canReorientSource(); } if(reorientDirection == ReorientRelationshipRequest.REORIENT_TARGET) { return canReorientTarget(); } return false; } /** * Can reorient source. * * @return true, if successful */ protected boolean canReorientSource() { return false; } /** * Can reorient target. * * @return true, if successful */ protected boolean canReorientTarget() { if(!(oldEnd instanceof PackageableElement && newEnd instanceof PackageableElement)) { return false; } if(getNewTarget().equals(getOldTarget().getOwner())) { return false; } if(EcoreUtil.isAncestor(getNewTarget(), getOldTarget())) { return false; } return newEnd != null; } /** * Reorient source. * * @return the command result * @throws ExecutionException * the execution exception */ protected CommandResult reorientSource() throws ExecutionException { throw new ExecutionException("Cannot reorient a source of Containment link"); } /** * Reorient target. * * @return the command result * @throws ExecutionException * the execution exception */ protected CommandResult reorientTarget() throws ExecutionException { EObject source = getOldTarget().getOwner(); EObject moveOldTargetTo = getOldTargetOwner(); EObject moveNewTargetTo = source; ContainmentHelper helper = new ContainmentHelper(getEditingDomain()); helper.move(getOldTarget(), moveOldTargetTo); helper.move(getNewTarget(), moveNewTargetTo); deleteOldLinkEditPart(); return CommandResult.newOKCommandResult(); } /** * Delete old link edit part. * * @return true, if successful */ private boolean deleteOldLinkEditPart() { if(myTargetEditPart instanceof ClassEditPart || myTargetEditPart instanceof PackageEditPart) { CompoundCommand cc = new CompoundCommand(); for(Object currentLink : ((AbstractGraphicalEditPart)myTargetEditPart).getTargetConnections()) { if(currentLink instanceof ContainmentSubLinkEditPart) { ContainmentSubLinkEditPart addedLinkEP = (ContainmentSubLinkEditPart)currentLink; if((addedLinkEP.getSource() instanceof CContainmentCircleEditPart)) { if(((CContainmentCircleEditPart)addedLinkEP.getSource()).getSourceConnections().size() == 1) { cc.add(new ICommandProxy(new DeleteCommand(getEditingDomain(), (View)addedLinkEP.getSource().getModel()))); } cc.add(new ICommandProxy(new DeleteCommand(getEditingDomain(), addedLinkEP.getNotationView()))); } } } cc.execute(); } return true; } /** * Gets the old source. * * @return the old source */ private PackageableElement getOldSource() { return (PackageableElement)oldEnd; } /** * Gets the new source. * * @return the new source */ private PackageableElement getNewSource() { return (PackageableElement)newEnd; } /** * Gets the old target. * * @return the old target */ private PackageableElement getOldTarget() { return (PackageableElement)oldEnd; } /** * Gets the new target. * * @return the new target */ private PackageableElement getNewTarget() { return (PackageableElement)newEnd; } /** * Gets the old target owner. * * @return the old target owner */ private EObject getOldTargetOwner() { return oldEndVisualParent; } }