Skip to main content
aboutsummaryrefslogblamecommitdiffstats
blob: 830db10e47786c2af7111bb0ab8d9d82379e81fc (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13


                                                     
   








                                                                         
                                                         












                                                       
                                         






























                                                                                     









                                                                                       
                                                      

                                                                                       










































                                                                                                                       
           
                              
                                       







                                                                                     
           
                              
                                       
                            
                                     
            
                                                                                              
                                            
                                           
                                                               

                                                                            





                                                   
           
                                 
                                          






                                                            
           
                         
                                          


                                               
                                                                                                            
                                                             
                                                                                           

                                                                                

                                               

                                                                                                         


                                                                                   



                                          
                                     
                                                                 
                                                                                               
                                                                      
                                                                                                                                
                                                                                                 
                                                         
                                         
                                                                               
                                                                    



                                                                            
                                                          

                                                                           
                                                                                                                                 
                                                             



                                                                                         
                                                                                                                                      


                                                             
                                                                                                                              











                                                                                  
                   
                                 
                                                           






                                                                            
                   
                                  
                                               
                               
                                       


                                              

                                                                                                                                   





                                                                                      
                   
                                        
                                               
                                 
                                         

                                         
                                                
                                      
                                               
                                   
                                           

                                                                                    
                                                                     
                                                                                       
                                                                                           


                                                                             
                                                                                                                            


                                                                                         


                                                                                                                                         

                                          
                                                               
                                                                                            
                                                                                                                      



                                                                                                                                                   




                                                          

                                                                                                                                           


                                                                                           



                                                                                                                           
                                                                                                                      

                                                  
                                                                         




                                                                                                 

                                                                                                                                        
                                                                                        



                                                                                                                                          

                                                                  

                                                                                                                             



                                                                                                    
                                                               
                                                                                                                                                       


                                                                                                     

                                                                                                                                           
















                                                                                                 
                   
                                          
                                                           






                                                                                
                   
                                  
                                                        
                                  
                                                      

                                                                                





                                                                                           








                                                                    
           
                         

                                









                                                                        
           
                      

                              



                                                              
                                       
                                                                                                                                         

                                                                         
                                              

                                                                                                                 












                                                                                     
           
                         

                                 


                                                                     
                                                                                                            
                                       
                                                                                   

                                                                                                         
                                                                                                                                     
                                                                                                            
                                                                                                                                                       



                                                                                                                                                                                                                                                                                       









                                                                       
/***************************************************
 * 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.views.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.IStatus;
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.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.infra.emf.utils.EMFHelper;
import org.eclipse.papyrus.views.modelexplorer.Activator;
import org.eclipse.papyrus.views.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 = (TransactionalEditingDomain) EMFHelper.resolveEditingDomain(model);
			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
		 */
		@Override
		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(org.eclipse.gef.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 = EMFHelper.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(IStatus.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