Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorptessier2010-04-21 13:30:21 +0000
committerptessier2010-04-21 13:30:21 +0000
commit6f70f62ec787c2e890203a45694b83415860f02b (patch)
treee399a5c1475ad5d6d576ac5509913292abb3f89a /plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java
parent0a1d990c323df7ca9d79f3d21352b3870a513a16 (diff)
downloadorg.eclipse.papyrus-6f70f62ec787c2e890203a45694b83415860f02b.tar.gz
org.eclipse.papyrus-6f70f62ec787c2e890203a45694b83415860f02b.tar.xz
org.eclipse.papyrus-6f70f62ec787c2e890203a45694b83415860f02b.zip
first integration
Diffstat (limited to 'plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java')
-rw-r--r--plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java489
1 files changed, 489 insertions, 0 deletions
diff --git a/plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java b/plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java
new file mode 100644
index 00000000000..eb134660fd9
--- /dev/null
+++ b/plugins/core/org.eclipse.papyrus.modelexplorer/src/org/eclipse/papyrus/modelexplorer/actions/GenericTransformer.java
@@ -0,0 +1,489 @@
+/***************************************************
+ * Copyright (c) 2010 Atos Origin.
+
+ *
+ * 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:
+ * Atos Origin - Initial API and implementation
+ *
+ ****************************************************/
+package org.eclipse.papyrus.modelexplorer.actions;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.draw2d.geometry.Point;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EStructuralFeature.Setting;
+import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gef.EditPart;
+import org.eclipse.gef.commands.Command;
+import org.eclipse.gef.commands.CommandStack;
+import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
+import org.eclipse.gef.requests.GroupRequest;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.ui.services.editor.EditorService;
+import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewRefactorHelper;
+import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
+import org.eclipse.gmf.runtime.diagram.ui.commands.ICommandProxy;
+import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramEditDomain;
+import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
+import org.eclipse.gmf.runtime.diagram.ui.requests.DropObjectsRequest;
+import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.Edge;
+import org.eclipse.gmf.runtime.notation.LayoutConstraint;
+import org.eclipse.gmf.runtime.notation.Location;
+import org.eclipse.gmf.runtime.notation.Node;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.papyrus.core.utils.EditorUtils;
+import org.eclipse.papyrus.modelexplorer.Activator;
+import org.eclipse.papyrus.modelexplorer.commands.EObjectInheritanceCopyCommand;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * The Class GenericTransformer. Permits to transform an eobject of eclass to
+ * another eclass
+ */
+public class GenericTransformer {
+
+ /** The factories to create eObjects */
+ private static HashMap<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>();
+
+ /** extension to recover factories */
+ private static final String EXT_FACTORIES = "org.eclipse.emf.edit.itemProviderAdapterFactories";
+
+ /** title of the warning dialog */
+ private static final String WARNING_TITLE = "Problems during transformation";
+
+ /** message of the warning dialog */
+ private static final String WARNING_MSG = "It seems the transformation you want to perform can't be executed";
+
+ /** command to execute the whole transformation */
+ private CompositeCommand globalCommand;
+
+ /** element to transform */
+ private EObject element;
+
+ /** views referencing the element */
+ private Set<View> referencingViews = new HashSet<View>();
+
+ /** command to execute the model transformation */
+ private EObjectInheritanceCopyCommand commandModel;
+
+ /** whether the graphical edit parts must also be transformed */
+ private boolean graphCopy = true;
+
+ /** the command to import new graphical edit parts */
+ private ImporterCommand importerCommand;
+
+ /**
+ * Instantiates a new generic transformer.
+ *
+ * @param currentNode
+ * the current node
+ */
+ public GenericTransformer(AbstractGraphicalEditPart currentNode) {
+ this(currentNode, true);
+ }
+
+ /**
+ * Instantiates a new generic transformer. and specify if we have to perform
+ * graphical copy
+ *
+ * @param currentNode
+ * the current node
+ * @param graphCopy
+ * the graph copy
+ */
+ public GenericTransformer(AbstractGraphicalEditPart currentNode,
+ boolean graphCopy) {
+ this.graphCopy = graphCopy;
+ if (currentNode != null) {
+ Object model = currentNode.getModel();
+ if (model instanceof View) {
+ this.element = ((View) model).getElement();
+ }
+ }
+ }
+
+ /**
+ * Instantiates a new generic transformer.
+ *
+ * @param currentEobject
+ * the current eobject
+ */
+ public GenericTransformer(EObject currentEobject) {
+ this.element = currentEobject;
+ }
+
+ /**
+ * Transform the element to the given eclass.
+ *
+ * @param eclass
+ * the targeted eclass
+ */
+ public void transform(EClass eclass) {
+
+ IWorkbenchPage page = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage();
+ IEditorPart editor = page.getActiveEditor();
+ CommandStack stack = (CommandStack) editor
+ .getAdapter(CommandStack.class);
+ globalCommand = new CompositeCommand("Generic Transformation");
+
+ if (graphCopy) {
+ if (element != null) {
+ EReference[] features = { NotationPackage.eINSTANCE
+ .getView_Element() };
+ Collection<?> views = EMFCoreUtil.getReferencers(element,
+ features);
+ for (Object view : views) {
+ if (view instanceof View) {
+ referencingViews.add((View) view);
+ }
+ }
+ }
+ }
+ if (stack != null) {
+ // maybe extension point for stereotypes
+ EObject model = (EObject) AdapterFactoryEditingDomain
+ .unwrap(element);
+ // get mixed editing domain to do transaction
+ TransactionalEditingDomain domain = EditorUtils
+ .getTransactionalEditingDomain();
+ commandModel = new EObjectInheritanceCopyCommand(model, eclass,
+ domain);
+ globalCommand.add(commandModel);
+ if (graphCopy) {
+ importerCommand = new ImporterCommand(domain);
+ if (importerCommand.canExecute()) {
+ globalCommand.add(importerCommand);
+ }
+
+ }
+ if (globalCommand.canExecute()) {
+ try {
+ // drop caches about input element
+ ECrossReferenceAdapter cross = ECrossReferenceAdapter
+ .getCrossReferenceAdapter(element);
+ if (cross != null) {
+ cross.unsetTarget(element);
+ }
+ stack.execute(new ICommandProxy(globalCommand));
+ } catch (Exception e) {
+ MessageDialog.openWarning(Display.getDefault()
+ .getActiveShell(), WARNING_TITLE, WARNING_MSG);
+ e.printStackTrace();
+ }
+ } else {
+ MessageDialog.openWarning(
+ Display.getDefault().getActiveShell(), WARNING_TITLE,
+ WARNING_MSG);
+ }
+ }
+ }
+
+ /**
+ * The Class ImporterCommand. permits to add the importer in the compound
+ * command
+ */
+ private class ImporterCommand extends AbstractTransactionalCommand {
+
+ /**
+ * Constructor.
+ *
+ * @param domain
+ * transactional editing domain
+ */
+ public ImporterCommand(TransactionalEditingDomain domain) {
+ super(domain, "Import graphical nodes", null);
+ }
+
+ /**
+ * Execute the command
+ *
+ * @param monitor
+ * progress monitor
+ * @param info
+ * the info
+ * @return the command result
+ * @throws ExecutionException
+ */
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor,
+ IAdaptable info) throws ExecutionException {
+ graphCopy(null, commandModel.getResultEobject());
+ return CommandResult.newOKCommandResult();
+ }
+
+ /**
+ * Graph copy, make a drag and drop of the new object on all diagrams
+ *
+ * @param diagramDomain
+ * the mixed domain
+ * @param target
+ * the target
+ * @param globalCommand2
+ * @param graphElement
+ * the graph element
+ * @param oldLocation
+ * the old location
+ * @param editpart
+ * the editpart
+ */
+ private void graphCopy(IDiagramEditDomain domain, EObject target) {
+ for (View graphElement : referencingViews) {
+ View parent = ViewUtil.getContainerView(graphElement);
+ if (parent == null || graphElement.getDiagram() == null) {
+ // this is an orphaned view. Skip it
+ continue;
+ }
+ IWorkbenchPage page = PlatformUI.getWorkbench()
+ .getActiveWorkbenchWindow().getActivePage();
+ // Get the edit part of the diagram containing the view.
+ DiagramEditPart diagramEditPart = null;
+ IEditorPart activeEditorPart = page.getActiveEditor();
+ if (activeEditorPart instanceof IDiagramWorkbenchPart) {
+ if (graphElement.getDiagram().equals(
+ ((IDiagramWorkbenchPart) activeEditorPart)
+ .getDiagram())) {
+ diagramEditPart = ((IDiagramWorkbenchPart) activeEditorPart)
+ .getDiagramEditPart();
+ }
+ }
+ if (diagramEditPart == null) {
+ // search in other editor parts than the active one
+ List<?> editorParts = EditorService.getInstance()
+ .getRegisteredEditorParts();
+ for (Object editorPart : editorParts) {
+ if (editorPart instanceof IDiagramWorkbenchPart) {
+ if (graphElement.getDiagram().equals(
+ ((IDiagramWorkbenchPart) editorPart)
+ .getDiagram())) {
+ diagramEditPart = ((IDiagramWorkbenchPart) editorPart)
+ .getDiagramEditPart();
+ }
+ }
+ }
+ }
+
+ if (diagramEditPart != null) {
+ EditPart containerPart = (EditPart) diagramEditPart
+ .getViewer().getEditPartRegistry().get(parent);
+ // create the new transformed view
+ DropObjectsRequest req = new DropObjectsRequest();
+ req.setObjects(Collections.singletonList(target));
+ if (graphElement instanceof Node) {
+ LayoutConstraint constraint = ((Node) graphElement)
+ .getLayoutConstraint();
+ if (constraint instanceof Location) {
+ Location location = (Location) constraint;
+ req.setLocation(new Point(location.getX(), location
+ .getY()));
+ }
+ }
+ if (req.getLocation() == null) {
+ req.setLocation(new Point());
+ }
+ Command partCreationCmd = containerPart.getCommand(req);
+ partCreationCmd.execute();
+ View newView = null;
+ if (partCreationCmd instanceof ICommandProxy) {
+ CommandResult res = ((ICommandProxy) partCreationCmd)
+ .getICommand().getCommandResult();
+ Object newValue = res.getReturnValue();
+ if (newValue instanceof Collection<?>) {
+ for (Object value : (Collection<?>) newValue) {
+ if (value instanceof ViewDescriptor) {
+ newView = (View) ((ViewDescriptor) value)
+ .getAdapter(View.class);
+ }
+ }
+ } else if (newValue instanceof ViewDescriptor) {
+ newView = (View) ((ViewDescriptor) newValue)
+ .getAdapter(View.class);
+ }
+ }
+ // with ViewRefactorHelper, copy view properties on the old
+ // one
+ if (newView != null) {
+ ViewTransformerHelper helper = new ViewTransformerHelper(
+ diagramEditPart.getDiagramPreferencesHint());
+ helper.copyMixedViewFeatures(graphElement, newView);
+ }
+ // delete the old view
+ GroupRequest deleteReq = new GroupRequest(
+ RequestConstants.REQ_DELETE);
+ EditPart oldPart = (EditPart) diagramEditPart.getViewer()
+ .getEditPartRegistry().get(graphElement);
+ Command partDeletionCmd = oldPart.getCommand(deleteReq);
+ partDeletionCmd.execute();
+ }
+ }
+
+ }
+
+ }
+
+ /**
+ * ViewTransformerHelper allow to refactor a view to copy properties from
+ * another view
+ */
+ private static class ViewTransformerHelper extends ViewRefactorHelper {
+
+ /**
+ * Constructor.
+ *
+ * @param preferencesHint
+ * the diagram preferences hint
+ */
+ public ViewTransformerHelper(PreferencesHint preferencesHint) {
+ super(preferencesHint);
+ }
+
+ /**
+ * Copy common features from a view to another
+ *
+ * @param oldView
+ * the old view to copy from
+ * @param newView
+ * the new view to copy to
+ */
+ public void copyMixedViewFeatures(View oldView, View newView) {
+ if (oldView instanceof Diagram && newView instanceof Diagram) {
+ copyDiagramFeatures((Diagram) oldView, (Diagram) newView);
+ } else if (oldView instanceof Node && newView instanceof Node) {
+ copyNodeFeatures((Node) oldView, (Node) newView);
+ } else if (oldView instanceof Edge && newView instanceof Edge) {
+ copyEdgeFeatures((Edge) oldView, (Edge) newView);
+ } else {
+ copyViewFeatures(oldView, newView);
+ }
+ }
+
+ }
+
+ /**
+ * Gets all the super types.
+ *
+ * @param class1
+ * the class
+ *
+ * @return super types
+ */
+ public static HashSet<EClass> getAllSuperTypes(EClass class1) {
+ HashSet<EClass> results = new HashSet<EClass>();
+ results.addAll(class1.getEAllSuperTypes());
+ return results;
+ }
+
+ /**
+ * Gets the factory from uri.
+ *
+ * @param uri
+ * the uri
+ *
+ * @return the factory
+ */
+ public static AdapterFactory getFactory(String uri) {
+ AdapterFactory factory = factories.get(uri);
+ if (factory == null) {
+ IConfigurationElement[] extensions = Platform
+ .getExtensionRegistry().getConfigurationElementsFor(
+ EXT_FACTORIES);
+ for (IConfigurationElement e : extensions) {
+ if (uri.equals(e.getAttribute("uri"))) {
+ try {
+ factory = (AdapterFactory) e
+ .createExecutableExtension("class");
+ if (factory != null) {
+ factories.put(uri, factory);
+ }
+ } catch (CoreException e1) {
+ // do nothing
+ }
+ }
+ }
+ }
+ return factory;
+ }
+
+ /**
+ * Checks if a transformation is possible.
+ *
+ * @param eclass
+ * the eclass
+ *
+ * @return the multi status
+ */
+ public MultiStatus isTransformationPossible(EClass eclass) {
+ MultiStatus result = new MultiStatus(Activator.PLUGIN_ID, 0,
+ "Type incompatibility", null);
+ if (element != null) {
+ Collection<Setting> usages = EObjectInheritanceCopyCommand
+ .getUsages(element);
+ if (usages != null) {
+ for (EStructuralFeature.Setting nonNavigableInverseReference : usages) {
+ EStructuralFeature structuralFeature = nonNavigableInverseReference
+ .getEStructuralFeature();
+ if (!(nonNavigableInverseReference.getEObject() instanceof View)) {
+ boolean compatible = EObjectInheritanceCopyCommand
+ .isCompatible(structuralFeature.getEType(),
+ eclass);
+ if (!compatible) {
+ String econtainer = structuralFeature.eContainer() instanceof EClassifier ? ((EClassifier) structuralFeature
+ .eContainer()).getName()
+ + " ( "
+ + nonNavigableInverseReference.getEObject()
+ .toString() + " )"
+ : structuralFeature.eContainer().toString();
+ Status s = new Status(
+ Status.WARNING,
+ Activator.PLUGIN_ID,
+ String.format(
+ "an element typed %s references your selection, we can not assign instead of your selection an object typed %s",
+ econtainer, eclass.getName()));
+ result.add(s);
+ }
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+}

Back to the top