/***************************************************
* 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.actionprovider;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.converter.util.ConverterUtil;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.provider.IItemLabelProvider;
import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.papyrus.views.modelexplorer.actions.GenericTransformAction;
import org.eclipse.papyrus.views.modelexplorer.actions.GenericTransformer;
/**
* GenericTransformActionProvider class provides GenericTransformAction actions
* available for a given element.
*/
public class GenericTransformActionProvider extends
AbstractSubmenuActionProvider {
/** Group label */
private static final String TRANSFORM_INTO_LABEL = "Transform into";
/** The factories of appropriate EClass */
private Map<String, AdapterFactory> factories = new HashMap<String, AdapterFactory>();
/** The appropriate EClass for element's transformation */
private Set<EClassifier> eClassifiers = new HashSet<EClassifier>();
/**
* Adds all actions to transform an EObject
*/
@Override
public void fillContextMenu(IMenuManager menu) {
super.fillContextMenu(menu);
ISelection selection = getContext().getSelection();
if (selection instanceof IStructuredSelection
&& ((IStructuredSelection) selection).size() == 1) {
Object selectedElement = resolveSemanticObject(((IStructuredSelection) selection)
.getFirstElement());
if (selectedElement != null && selectedElement instanceof EObject) {
fillEClassifiers((EObject) selectedElement);
}
}
Collection<IAction> genericTransformActions = generateTransformActions(selection);
MenuManager submenuManager = new MenuManager(TRANSFORM_INTO_LABEL);
populateManager(submenuManager, genericTransformActions, null);
menu.add(submenuManager);
}
/**
* From an EObject we get the epackage corresponding to the resource
* extension of the file and get the imported epackage correspondant
*
* @param selectionEObject
*/
private void fillEClassifiers(EObject selectionEObject) {
Resource r = selectionEObject.eResource();
URI uri = r.getURI();
String extension = uri.fileExtension();
for (Object p : EPackage.Registry.INSTANCE.values()) {
if (p instanceof EPackage) {
EPackage pack = (EPackage) p;
if (pack.getNsPrefix() != null
&& extension.toLowerCase().equals(
pack.getNsPrefix().toLowerCase())) {
addClassifiers(pack, eClassifiers);
factories.put(pack.getNsURI(), GenericTransformer
.getFactory(pack.getNsURI()));
List<EPackage> packages = ConverterUtil
.computeRequiredPackages(pack);
for (EPackage pTmp : packages) {
addClassifiers(pTmp, eClassifiers);
factories.put(pTmp.getNsURI(), GenericTransformer
.getFactory(pTmp.getNsURI()));
}
break;
}
}
}
}
/**
* Register all classifiers contained in the package
*
* @param pack
* the package
* @param result
* results at which classifiers must be added
*/
private void addClassifiers(EPackage pack, Set<EClassifier> result) {
for (EClassifier c : pack.getEClassifiers()) {
result.add(c);
}
}
/**
* Generate the sorted list of transformation actions.
*
* @param descriptors
* the descriptors
* @param selection
* the selection
*
* @return the collection< i action>
*/
protected Collection<IAction> generateTransformActions(ISelection selection) {
List<IAction> transformActions = (List<IAction>) generateTransformActionsCore(selection);
Collections.<IAction> sort(transformActions, new Comparator<IAction>() {
public int compare(IAction a1, IAction a2) {
return a1.getText().compareTo(a2.getText());
}
});
return transformActions;
}
/**
* Generate transformation actions.
*
* @param descriptors
* the descriptors
* @param selection
* the selection
*
* @return the collection< i action>
*/
protected Collection<IAction> generateTransformActionsCore(
ISelection selection) {
Collection<IAction> actions = new ArrayList<IAction>();
if (eClassifiers != null) {
for (EClassifier descriptor : eClassifiers) {
Object selected = ((IStructuredSelection) selection)
.getFirstElement();
if (selected instanceof EObject) {
final EObject selectedElement = (EObject) selected;
if (descriptor instanceof EClass
&& selectedElement.eContainingFeature() != null) {
final EClass eclass = (EClass) descriptor;
EStructuralFeature containingFeature = selectedElement
.eContainingFeature();
// to be candidate an eclass has to have a common
// parent, to not be the selection
// and to not be abstract
EClass containgType = (EClass) containingFeature
.getEType();
if ((GenericTransformer.getAllSuperTypes(eclass)
.contains(containgType) || EcoreUtil.equals(
eclass, containgType))
&& !eclass.equals(selectedElement.eClass())
&& !eclass.isAbstract()) {
if (selection instanceof IStructuredSelection
&& ((IStructuredSelection) selection)
.size() == 1) {
AdapterFactory adapterFactory = factories
.get(eclass.getEPackage().getNsURI());
Action transformAction = new GenericTransformAction(
eclass, adapterFactory, selectedElement);
actions.add(transformAction);
if (adapterFactory != null) {
EObject tmpEobject = eclass.getEPackage()
.getEFactoryInstance().create(
eclass);
IItemLabelProvider provider = (IItemLabelProvider) adapterFactory
.adapt(tmpEobject,
IItemLabelProvider.class);
transformAction
.setImageDescriptor(ExtendedImageRegistry.INSTANCE
.getImageDescriptor(provider
.getImage(tmpEobject)));
}
}
}
}
}
}
}
return actions;
}
}