Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrschnekenbu2012-04-11 16:08:15 +0000
committerrschnekenbu2012-04-11 16:08:15 +0000
commitd3b33262b70743dc69515423e8adcd282ceb447a (patch)
tree738e1ddb06d4dfd5e34ddf24053f0b8dd1f189a5
parent644229771ed87e60b047511f3f732a260e5ab0b1 (diff)
downloadorg.eclipse.papyrus-d3b33262b70743dc69515423e8adcd282ceb447a.tar.gz
org.eclipse.papyrus-d3b33262b70743dc69515423e8adcd282ceb447a.tar.xz
org.eclipse.papyrus-d3b33262b70743dc69515423e8adcd282ceb447a.zip
ASSIGNED - bug 374636: [SYSML][Model Explorer] Copy / paste of a part does not create the corresponding association
https://bugs.eclipse.org/bugs/show_bug.cgi?id=374636 - added some behavior to the paste command and paste manager: looking for additional elements will also be completed by the PropertyPartEditHelperAdvice to copy associated association.
-rw-r--r--plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/helper/PartPropertyEditHelperAdvice.java198
-rw-r--r--plugins/uml/org.eclipse.papyrus.pastemanager/src/org/eclipse/papyrus/pastemanager/command/PapyrusDuplicateWrapperCommand.java2
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.menu/src/org/eclipse/papyrus/uml/menu/command/PasteElementCommand.java5
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/ElementEditHelperAdvice.java7
4 files changed, 209 insertions, 3 deletions
diff --git a/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/helper/PartPropertyEditHelperAdvice.java b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/helper/PartPropertyEditHelperAdvice.java
index 0ef6b79b321..3582ba1d647 100644
--- a/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/helper/PartPropertyEditHelperAdvice.java
+++ b/plugins/sysml/org.eclipse.papyrus.sysml.service.types/src/org/eclipse/papyrus/sysml/service/types/helper/PartPropertyEditHelperAdvice.java
@@ -14,20 +14,33 @@
*****************************************************************************/
package org.eclipse.papyrus.sysml.service.types.helper;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
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.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CommandResult;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.commands.DuplicateEObjectsCommand;
import org.eclipse.gmf.runtime.emf.type.core.IElementMatcher;
import org.eclipse.gmf.runtime.emf.type.core.commands.ConfigureElementCommand;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DuplicateElementsRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.GetEditContextRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.papyrus.sysml.blocks.Block;
+import org.eclipse.papyrus.sysml.service.types.Activator;
import org.eclipse.papyrus.sysml.service.types.element.SysMLElementTypes;
import org.eclipse.papyrus.sysml.service.types.matcher.BlockMatcher;
+import org.eclipse.papyrus.sysml.service.types.matcher.PartPropertyMatcher;
import org.eclipse.papyrus.uml.service.types.utils.ElementUtil;
import org.eclipse.papyrus.uml.service.types.utils.NamedElementHelper;
import org.eclipse.uml2.uml.AggregationKind;
@@ -41,6 +54,9 @@ import org.eclipse.uml2.uml.UMLFactory;
/** SysML Property Part edit helper advice */
public class PartPropertyEditHelperAdvice extends AbstractEditHelperAdvice {
+ /** duplicate constant from copy command service */
+ private static final String ADDITIONAL_DUPLICATED_ELEMENTS = "Additional_Duplicated_Elements";
+
/**
* Check if the creation context is a {@link Block}.
*
@@ -72,6 +88,118 @@ public class PartPropertyEditHelperAdvice extends AbstractEditHelperAdvice {
return isApproved;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ICommand getBeforeDuplicateCommand(DuplicateElementsRequest request) {
+ Object targetContainer = request.getParameter("Target_Owner");
+ // additional element should be a set of elements that will be duplicated. If this is null, the request will be ignored.
+ if(!(targetContainer instanceof EObject)) {
+ return super.getBeforeDuplicateCommand(request);
+ }
+ Property partToBeDuplicated = getDuplicatedPart(request);
+ if(partToBeDuplicated == null) {
+ return super.getBeforeDuplicateCommand(request);
+ }
+
+ Property newPart = (Property)request.getAllDuplicatedElementsMap().get(partToBeDuplicated);
+ if(newPart == null) {
+ Activator.log.debug("Trying to create a command for a new part which has not been created yet");
+ return super.getBeforeDuplicateCommand(request);
+ }
+
+ // check association has not be duplicated yet
+ Association originalAssociation = partToBeDuplicated.getAssociation();
+ Association newAssociation = (Association)request.getAllDuplicatedElementsMap().get(originalAssociation);
+ if(newAssociation != null && newAssociation.equals(newPart.getAssociation())) {
+ return super.getBeforeDuplicateCommand(request);
+ }
+
+ TransactionalEditingDomain editingDomain = getEditingDomain(partToBeDuplicated);
+ if(editingDomain == null) {
+ return super.getBeforeDuplicateCommand(request);
+ }
+
+ Package targetPackage = getTargetContainer((EObject)targetContainer, partToBeDuplicated, newPart, request.getAllDuplicatedElementsMap());
+ return new DuplicatePapyrusAssociationCommand(editingDomain, "Duplicate Association for part", originalAssociation, request.getAllDuplicatedElementsMap(), targetPackage);
+ }
+
+ /**
+ * Computes the target container for the new association
+ *
+ * @param targetContainer
+ * the target container of the association creation request
+ * @param partToBeDuplicated
+ * the part which was duplicated
+ * @param newPart
+ * the new part linked to the association
+ * @param allDuplicatedElementsMap
+ * the map of all duplicated elements
+ * @return the target {@link Package} for the new association or <code>null</code> if no package was found
+ */
+ protected Package getTargetContainer(EObject targetContainer, Property partToBeDuplicated, Property newPart, Map allDuplicatedElementsMap) {
+
+ // 1. look if the new part has a nearest package
+ // 2. look if the part to be duplicated has a package which has a copy
+ // 3. if target container == package => this can be the place where the association could be placed
+ // 4. look for the nearest package of the target container
+
+ Package result = newPart.getNearestPackage();
+ if(result != null) {
+ return result;
+ }
+
+ Package originalPackage = partToBeDuplicated.getNearestPackage();
+ // look for its equivalent in the list of duplicated objects
+ Object o = allDuplicatedElementsMap.get(originalPackage);
+ if(o instanceof Package) {
+ return (Package)o;
+ }
+
+ if(targetContainer instanceof Package) {
+ return ((Package)targetContainer);
+ }
+
+ if(targetContainer instanceof Element) {
+ return ((Element)targetContainer).getNearestPackage();
+ }
+
+ return null;
+ }
+
+ /**
+ * Get the editing domain from an {@link EObject}
+ *
+ * @param eObject
+ * @return
+ */
+ protected TransactionalEditingDomain getEditingDomain(EObject eObject) {
+ EditingDomain editingDomain = AdapterFactoryEditingDomain.getEditingDomainFor(eObject);
+ if(editingDomain instanceof TransactionalEditingDomain) {
+ return (TransactionalEditingDomain)editingDomain;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the Part to be duplicated
+ *
+ * @return the Part to be duplicated or <code>null</code> if this is not a part
+ */
+ protected Property getDuplicatedPart(DuplicateElementsRequest request) {
+ List<Object> elementsToBeDuplicated = request.getElementsToBeDuplicated();
+ if(elementsToBeDuplicated == null || elementsToBeDuplicated.isEmpty()) {
+ return null;
+ }
+ Object firstElement = elementsToBeDuplicated.get(0); // there should be only one element here
+ if(!(firstElement instanceof Property)) {
+ return null;
+ }
+ PartPropertyMatcher matcher = new PartPropertyMatcher();
+ return matcher.matches((Property)firstElement) ? (Property)firstElement : null;
+ }
+
/** Complete creation process by setting name and default aggregation */
@Override
protected ICommand getBeforeConfigureCommand(final ConfigureRequest request) {
@@ -133,4 +261,74 @@ public class PartPropertyEditHelperAdvice extends AbstractEditHelperAdvice {
}
};
}
+
+
+ /**
+ * Command to duplicate an association and place it in a new container.
+ */
+ public class DuplicatePapyrusAssociationCommand extends DuplicateEObjectsCommand {
+
+ /** association to be duplicated */
+ private final Association associationToDuplicate;
+
+ /** target container */
+ private Package targetContainer;
+
+
+ /**
+ * Constructs a new duplicate EObjects command with the specified label and
+ * list of EObjects. Also sets the list of affected files to be the files,
+ * where the targetContainer is stored. Target container specifies the
+ * eObject into which the duplicated eObjects will be added.
+ *
+ * @param editingDomain
+ * the editing domain through which model changes are made
+ * @param label
+ * The label for the new command.
+ * @param originalAssociation
+ * <code>Association</code> to be duplicated.
+ * @param allDuplicatedObjectsMap
+ * An empty map to be populated with the duplicated objects.
+ * @param targetContainer
+ * target package
+ */
+ public DuplicatePapyrusAssociationCommand(TransactionalEditingDomain editingDomain, String label, Association originalAssociation, Map allDuplicatedObjectsMap, Package targetContainer) {
+ super(editingDomain, label, Collections.singletonList(originalAssociation), allDuplicatedObjectsMap, targetContainer);
+ this.associationToDuplicate = originalAssociation;
+ this.targetContainer = targetContainer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor progressMonitor, IAdaptable info) throws ExecutionException {
+ // Remove elements whose container is getting copied.
+ // ClipboardSupportUtil.getCopyElements(getObjectsToBeDuplicated());
+
+ // Perform the copy and update the references.
+ EcoreUtil.Copier copier = new EcoreUtil.Copier();
+ copier.putAll(getAllDuplicatedObjectsMap());
+ copier.copy(associationToDuplicate);
+ copier.copyReferences();
+
+ Association newAssociation = (Association)copier.get(associationToDuplicate);
+ if(newAssociation == null) {
+ return CommandResult.newErrorCommandResult("Impossible to find the copied association");
+ }
+
+ // note: can be executed only if targetcontainer is instanceof package, this means that there is no need to tests for null targetContainer
+ newAssociation.setPackage(targetContainer);
+ String associationName = NamedElementHelper.getDefaultNameWithIncrementFromBase("Association", targetContainer.eContents()); //$NON-NLS-1$
+ newAssociation.setName(associationName);
+ return CommandResult.newOKCommandResult(getAllDuplicatedObjectsMap());
+ }
+
+ @Override
+ public boolean canExecute() {
+ // should add some tests here? no need to test containement feature like previous, Table has no owner...
+ return targetContainer instanceof Package;
+ }
+ }
+
}
diff --git a/plugins/uml/org.eclipse.papyrus.pastemanager/src/org/eclipse/papyrus/pastemanager/command/PapyrusDuplicateWrapperCommand.java b/plugins/uml/org.eclipse.papyrus.pastemanager/src/org/eclipse/papyrus/pastemanager/command/PapyrusDuplicateWrapperCommand.java
index 536a48a98c7..121eb39cec2 100644
--- a/plugins/uml/org.eclipse.papyrus.pastemanager/src/org/eclipse/papyrus/pastemanager/command/PapyrusDuplicateWrapperCommand.java
+++ b/plugins/uml/org.eclipse.papyrus.pastemanager/src/org/eclipse/papyrus/pastemanager/command/PapyrusDuplicateWrapperCommand.java
@@ -40,6 +40,7 @@ import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.LayoutConstraint;
import org.eclipse.gmf.runtime.notation.Shape;
import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.core.utils.BusinessModelResolver;
import org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.service.edit.service.IElementEditService;
@@ -202,6 +203,7 @@ public class PapyrusDuplicateWrapperCommand extends AbstractTransactionalCommand
DuplicateElementsRequest request = new DuplicateElementsRequest(Collections.singletonList(object));
request.setAllDuplicatedElementsMap(duplicatedElementsMap);
request.setParameter(PapyrusDuplicateWrapperCommand.ADDITIONAL_DUPLICATED_ELEMENTS, duplicatedExternalElements);
+ request.setParameter("Target_Owner", BusinessModelResolver.getInstance().getBusinessModel(container));
IElementEditService service = ElementEditServiceUtils.getCommandProvider(object);
ICommand command = service.getEditCommand(request);
if(command != null) {
diff --git a/plugins/uml/org.eclipse.papyrus.uml.menu/src/org/eclipse/papyrus/uml/menu/command/PasteElementCommand.java b/plugins/uml/org.eclipse.papyrus.uml.menu/src/org/eclipse/papyrus/uml/menu/command/PasteElementCommand.java
index eafdcac4e12..ea56a7389dc 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.menu/src/org/eclipse/papyrus/uml/menu/command/PasteElementCommand.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.menu/src/org/eclipse/papyrus/uml/menu/command/PasteElementCommand.java
@@ -193,7 +193,7 @@ public class PasteElementCommand extends AbstractCommand {
}
}
- ICommand externalObjectsDuplicateCommand = getExternalObjectsDuplicateCommand(duplicatedObjects);
+ ICommand externalObjectsDuplicateCommand = getExternalObjectsDuplicateCommand(duplicatedObjects, targetOwner);
if(externalObjectsDuplicateCommand != null && command != null) {
command.compose(externalObjectsDuplicateCommand);
}
@@ -286,7 +286,7 @@ public class PasteElementCommand extends AbstractCommand {
*
* @return the list of external objects to duplicate or an empty list if not elements are found to add.
*/
- protected ICommand getExternalObjectsDuplicateCommand(Map duplicatedElementsMap) {
+ protected ICommand getExternalObjectsDuplicateCommand(Map duplicatedElementsMap, EObject targetOwner) {
CompositeCommand result = new CompositeCommand("Duplicate Diagrams");
Set<Object> duplicatedExternalElements = new HashSet<Object>();
@@ -296,6 +296,7 @@ public class PasteElementCommand extends AbstractCommand {
DuplicateElementsRequest request = new DuplicateElementsRequest(Collections.singletonList(object));
request.setAllDuplicatedElementsMap(duplicatedElementsMap);
request.setParameter("Additional_Duplicated_Elements", duplicatedExternalElements);
+ request.setParameter("Target_Owner", targetOwner);
IElementEditService service = ElementEditServiceUtils.getCommandProvider(object);
ICommand command = service.getEditCommand(request);
if(command != null) {
diff --git a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/ElementEditHelperAdvice.java b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/ElementEditHelperAdvice.java
index 30fdaf18174..bd375c5c075 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/ElementEditHelperAdvice.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.service.types/src/org/eclipse/papyrus/uml/service/types/helper/advice/ElementEditHelperAdvice.java
@@ -76,7 +76,7 @@ public class ElementEditHelperAdvice extends AbstractEditHelperAdvice {
/*
* Test if the moving element is going to be in a new resource
*/
- if(!eResource.equals(containerEResource) && !AdapterFactoryEditingDomain.isControlled(sourceEObject)) {
+ if(!containerEResource.equals(eResource) && !AdapterFactoryEditingDomain.isControlled(sourceEObject)) {
/*
* Move related diagrams
*/
@@ -154,6 +154,11 @@ public class ElementEditHelperAdvice extends AbstractEditHelperAdvice {
}
protected ICommand getMoveDiagramsCommand(EObject container, EObject sourceEObject) {
+
+ // in case of copy/paste context (usage of MoveCommand also), the source object does not have a resource
+ if(sourceEObject.eResource() == null) {
+ return null;
+ }
/*
* Get all diagram from source EObject (its diagram and its descendant)
*/

Back to the top