From 81a862147f0bc317f6f65ef155266f31bfa1f73f Mon Sep 17 00:00:00 2001 From: cletavernie Date: Fri, 27 Jul 2012 12:31:19 +0000 Subject: 386118: [EMF Facet] Papyrus should progressively support EMF Facet 0.2 https://bugs.eclipse.org/bugs/show_bug.cgi?id=386118 - Improve the resolution of EObjects in EMFHelper, to be able to handle EMF Facet 0.2 encapsulated TreeElements - Add a new Papyrus EMF Editor based on EMF Facet 0.2 (Extra plug-in). The previous editor, based en EMF Facet 0.1, is still available. - New utility methods added in EMFHelper --- .../META-INF/MANIFEST.MF | 8 +- .../plugin.xml | 11 +- .../infra/emf/editor/part/PapyrusEditor.java | 6 +- .../infra/emf/editor/part/PapyrusEditor2.java | 305 +++++++++++++++++++++ .../papyrus/infra/emf/editor/util/ActionUtil.java | 18 +- .../emf/embeddededitor/editor/EmbeddedEditor.java | 4 + .../META-INF/MANIFEST.MF | 2 + .../newchild/menu/AbstractCustomFillElement.java | 6 + .../infra/emf/newchild/menu/CustomFillElement.java | 2 + .../infra/emf/newchild/menu/FillNewChild.java | 42 ++- .../infra/emf/newchild/menu/FillerFactory.java | 1 + .../infra/emf/newchild/menu/MyCustomFiller.java | 4 +- .../META-INF/MANIFEST.MF | 3 +- .../strategy/SemanticEMFContentProvider.java | 5 +- .../eclipse/papyrus/infra/emf/utils/EMFHelper.java | 141 +++++++++- 15 files changed, 534 insertions(+), 24 deletions(-) create mode 100644 plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor2.java diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/META-INF/MANIFEST.MF index a0daea9223a..8281abc47c0 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/META-INF/MANIFEST.MF @@ -18,7 +18,13 @@ Require-Bundle: org.eclipse.ui, org.eclipse.emf.facet.infra.browser.uicore;bundle-version="0.1.0", org.eclipse.papyrus.views.properties;bundle-version="0.9.0", org.eclipse.papyrus.infra.widgets;bundle-version="0.9.0", - org.eclipse.emf.transaction;bundle-version="1.4.0" + org.eclipse.emf.transaction;bundle-version="1.4.0", + org.eclipse.emf.facet.efacet.core;bundle-version="0.2.0", + org.eclipse.emf.facet.custom.core;bundle-version="0.2.0", + org.eclipse.emf.facet.custom.ui;bundle-version="0.2.0", + org.eclipse.papyrus.infra.emf;bundle-version="0.9.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Eclipse-BuddyPolicy: dependent +Export-Package: org.eclipse.papyrus.infra.emf.editor.part, + org.eclipse.papyrus.infra.emf.editor.providers diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/plugin.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/plugin.xml index 4e5269bbe93..d2a34ed27c8 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/plugin.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/plugin.xml @@ -21,7 +21,16 @@ extensions="xmi" icon="icons/papyrus_model.png" id="org.eclipse.papyrus.emf.editor" - name="Papyrus EMF Editor"> + name="Papyrus EMF Editor (EMF Facet 0.1)"> + + diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor.java index 3939406c91c..ac3b8b43ccc 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor.java @@ -110,7 +110,7 @@ public class PapyrusEditor extends EcoreEditor implements ITabbedPropertySheetPa }); - Tree tree = new Tree(parent, SWT.BORDER | SWT.MULTI); + Tree tree = new Tree(parent, getTreeStyle() | SWT.MULTI); tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); selectionViewer = new TreeViewer(tree); @@ -168,6 +168,10 @@ public class PapyrusEditor extends EcoreEditor implements ITabbedPropertySheetPa updateProblemIndication(); } + protected int getTreeStyle() { + return SWT.BORDER; + } + @Override protected void initializeEditingDomain() { diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor2.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor2.java new file mode 100644 index 00000000000..96f6dcdc2fd --- /dev/null +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/part/PapyrusEditor2.java @@ -0,0 +1,305 @@ +package org.eclipse.papyrus.infra.emf.editor.part; + +import java.util.EventObject; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.emf.common.command.Command; +import org.eclipse.emf.common.command.CommandStack; +import org.eclipse.emf.common.command.CommandStackListener; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.presentation.EcoreEditor; +import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.edit.provider.ComposedAdapterFactory; +import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory; +import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory; +import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor; +import org.eclipse.emf.edit.ui.dnd.LocalTransfer; +import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter; +import org.eclipse.emf.facet.custom.core.ICustomizationCatalogManager; +import org.eclipse.emf.facet.custom.core.ICustomizationCatalogManagerFactory; +import org.eclipse.emf.facet.custom.core.ICustomizationManager; +import org.eclipse.emf.facet.custom.core.ICustomizationManagerFactory; +import org.eclipse.emf.facet.custom.metamodel.v0_2_0.custom.Customization; +import org.eclipse.emf.facet.custom.ui.ICustomizedContentProviderFactory; +import org.eclipse.emf.facet.custom.ui.IResolvingCustomizedLabelProviderFactory; +import org.eclipse.emf.transaction.TransactionalCommandStack; +import org.eclipse.emf.transaction.impl.TransactionalCommandStackImpl; +import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl; +import org.eclipse.jface.action.MenuManager; +import org.eclipse.jface.action.Separator; +import org.eclipse.jface.viewers.ILabelProvider; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.StructuredViewer; +import org.eclipse.jface.viewers.TreeViewer; +import org.eclipse.jface.viewers.ViewerFilter; +import org.eclipse.papyrus.infra.emf.editor.actions.MoDiscoDropAdapter; +import org.eclipse.papyrus.infra.widgets.editors.AbstractEditor; +import org.eclipse.papyrus.infra.widgets.editors.ICommitListener; +import org.eclipse.papyrus.infra.widgets.editors.StringEditor; +import org.eclipse.papyrus.infra.widgets.providers.PatternViewerFilter; +import org.eclipse.papyrus.views.properties.widgets.layout.GridData; +import org.eclipse.papyrus.views.properties.widgets.layout.PropertiesLayout; +import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Menu; +import org.eclipse.swt.widgets.Tree; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.views.properties.IPropertySheetPage; +import org.eclipse.ui.views.properties.tabbed.ITabbedPropertySheetPageContributor; +import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; + +/** + * An extended EMF editor + * + * This generic editor provides the following features : + * + * - EMF Facet browser customization + * - Papyrus customizable property view + * - Papyrus customizable new child + * + * @author Camille Letavernier + * + */ +public class PapyrusEditor2 extends EcoreEditor implements ITabbedPropertySheetPageContributor, CommandStackListener { + + public static final String PROPERTY_VIEW_ID = "CustomizablePropertyView"; //$NON-NLS-1$ + + /** + * The Property sheet page for this editor + */ + protected IPropertySheetPage iPropertySheetPage; + + @Override + public void createPages() { + // Creates the model from the editor input + // + createModel(); + + getContainer().setBackground(new Color(getContainer().getDisplay(), 255, 255, 255)); + getContainer().setBackgroundMode(SWT.INHERIT_DEFAULT); + + Composite gParent = new Composite(getContainer(), SWT.NONE); + gParent.setLayout(new FillLayout()); + + //SashForm parent = new SashForm(gParent, SWT.VERTICAL | SWT.V_SCROLL | SWT.H_SCROLL); + //parent.setLayout(new FillLayout()); + + Composite parent = new Composite(gParent, SWT.NONE); + parent.setLayout(new PropertiesLayout()); + + // Only creates the other pages if there is something that can be edited + // + if(!getEditingDomain().getResourceSet().getResources().isEmpty()) { + // Create a page for the selection tree view. + // + + final PatternViewerFilter filter = new PatternViewerFilter(); + filter.setShowIfHasVisibleParent(true); + + final StringEditor filterPattern = new StringEditor(parent, SWT.NONE, "Filter"); + filterPattern.addCommitListener(new ICommitListener() { + + public void commit(AbstractEditor editor) { + filter.setPattern((String)filterPattern.getValue()); + selectionViewer.refresh(); + } + + }); + + Tree tree = new Tree(parent, getTreeStyle() | SWT.MULTI); + tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + + selectionViewer = new TreeViewer(tree); + selectionViewer.setFilters(new ViewerFilter[]{ filter }); + setCurrentViewer(selectionViewer); + + initializeCustomizationCatalogManager(); + + IStructuredContentProvider contentProvider = createContentProvider(); + + ILabelProvider labelProvider = createLabelProvider(); + + editingDomain.getCommandStack().addCommandStackListener(this); + + selectionViewer.setContentProvider(contentProvider); + selectionViewer.setLabelProvider(labelProvider); + + selectionViewer.setInput(getTreeViewerInput()); + // selectionViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true); + + new AdapterFactoryTreeEditor(selectionViewer.getTree(), adapterFactory); + + createContextMenuFor(selectionViewer); + int pageIndex = addPage(gParent); + setPageText(pageIndex, "Model"); //$NON-NLS-1$ + + setActivePage(0); + + // Preview preview = new Preview(this); + // preview.createPartControl(parent); + // addPreview(preview); + + parent.layout(); + } + + // Ensures that this editor will only display the page's tab + // area if there are more than one page + // + getContainer().addControlListener(new ControlAdapter() { + + boolean guard = false; + + @Override + public void controlResized(ControlEvent event) { + if(!guard) { + guard = true; + hideTabs(); + guard = false; + } + } + }); + + if(getActionBarContributor() instanceof ActionBarContributor) { + ((ActionBarContributor)getActionBarContributor()).setEditingDomain(getEditingDomain()); + } + + updateProblemIndication(); + } + + protected Object getTreeViewerInput() { + List roots = new LinkedList(); + for(Resource resource : getResourceSet().getResources()) { + for(EObject rootEObject : resource.getContents()) { + roots.add(rootEObject); + } + } + return roots; + } + + protected int getTreeStyle() { + return SWT.BORDER; + } + + @Override + protected void initializeEditingDomain() { + // Create an adapter factory that yields item providers. + // + adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE); + + adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory()); + adapterFactory.addAdapterFactory(new EcoreItemProviderAdapterFactory()); + adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory()); + + // Create the command stack that will notify this editor as commands are executed. + // + TransactionalCommandStack commandStack = new TransactionalCommandStackImpl(); + + // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus. + // + commandStack.addCommandStackListener(new CommandStackListener() { + + public void commandStackChanged(final EventObject event) { + getContainer().getDisplay().asyncExec(new Runnable() { + + public void run() { + firePropertyChange(IEditorPart.PROP_DIRTY); + + // Try to select the affected objects. + // + Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand(); + if(mostRecentCommand != null) { + setSelectionToViewer(mostRecentCommand.getAffectedObjects()); + } + if(propertySheetPage != null && !propertySheetPage.getControl().isDisposed()) { + propertySheetPage.refresh(); + } + } + }); + } + }); + + // Create the editing domain with a special command stack. + // + editingDomain = new TransactionalEditingDomainImpl(adapterFactory, commandStack); + editingDomain.setResourceToReadOnlyMap(new HashMap()); + } + + @Override + protected void createContextMenuFor(StructuredViewer viewer) { + MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$ + contextMenu.add(new Separator("additions")); //$NON-NLS-1$ + contextMenu.setRemoveAllWhenShown(true); + contextMenu.addMenuListener(this); + Menu menu = contextMenu.createContextMenu(viewer.getControl()); + viewer.getControl().setMenu(menu); + + int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; + Transfer[] transfers = new Transfer[]{ LocalTransfer.getInstance() }; + viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer)); + viewer.addDropSupport(dndOperations, transfers, new MoDiscoDropAdapter(editingDomain, viewer)); + } + + @Override + public IPropertySheetPage getPropertySheetPage() { + if(iPropertySheetPage == null) { + iPropertySheetPage = new TabbedPropertySheetPage(this); + } + return iPropertySheetPage; + } + + protected ICustomizationManager getCustomizationManager() { + if(customizationManager == null) { + customizationManager = ICustomizationManagerFactory.DEFAULT.getOrCreateICustomizationManager(getResourceSet()); + } + return customizationManager; + } + + protected void initializeCustomizationCatalogManager() { + ICustomizationCatalogManager customCatalog = ICustomizationCatalogManagerFactory.DEFAULT.getOrCreateCustomizationCatalogManager(getResourceSet()); + List allCustomizations = customCatalog.getRegisteredCustomizations(); + for(Customization customization : allCustomizations) { + if(customization.isMustBeLoadedByDefault()) { + System.out.println("Apply default customization: " + customization.getName()); + getCustomizationManager().getManagedCustomizations().add(customization); + } + } + } + + protected IStructuredContentProvider createContentProvider() { + return ICustomizedContentProviderFactory.DEFAULT.createCustomizedTreeContentProvider(getCustomizationManager()); + } + + protected ResourceSet getResourceSet() { + return getEditingDomain().getResourceSet(); + } + + protected ILabelProvider createLabelProvider() { + return IResolvingCustomizedLabelProviderFactory.DEFAULT.createCustomizedLabelProvider(getCustomizationManager()); + } + + public void commandStackChanged(EventObject event) { + getViewer().refresh(); + } + + @Override + public void doSave(IProgressMonitor monitor) { + super.doSave(monitor); + } + + public String getContributorId() { + return PROPERTY_VIEW_ID; + } + + private ICustomizationManager customizationManager; +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/util/ActionUtil.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/util/ActionUtil.java index 2408b404a3e..4ac9ad61cbf 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/util/ActionUtil.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.editor/src/org/eclipse/papyrus/infra/emf/editor/util/ActionUtil.java @@ -16,10 +16,10 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import org.eclipse.core.runtime.IAdaptable; import org.eclipse.emf.ecore.EObject; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.papyrus.infra.emf.utils.EMFHelper; /** * Utility class for Actions @@ -45,9 +45,9 @@ public class ActionUtil { public static Collection getAdaptedSelection(Collection selection) { Collection newSelection = new LinkedList(); for(Object o : selection) { - if(o instanceof IAdaptable) { - EObject eObject = (EObject)((IAdaptable)o).getAdapter(EObject.class); - newSelection.add(eObject); + EObject adaptedEObject = EMFHelper.getEObject(o); + if(adaptedEObject != null) { + newSelection.add(adaptedEObject); } else { newSelection.add(o); } @@ -76,13 +76,9 @@ public class ActionUtil { Iterator it = currentSelection.iterator(); while(it.hasNext()) { Object object = it.next(); - if(object instanceof IAdaptable) { - EObject eObject = (EObject)((IAdaptable)object).getAdapter(EObject.class); - if(eObject != null) { - newSelection.add(eObject); - } else { - newSelection.add(object); - } + EObject adaptedEObject = EMFHelper.getEObject(object); + if(adaptedEObject != null) { + newSelection.add(adaptedEObject); } else { newSelection.add(object); } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.embeddededitor/src/org/eclipse/papyrus/infra/emf/embeddededitor/editor/EmbeddedEditor.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.embeddededitor/src/org/eclipse/papyrus/infra/emf/embeddededitor/editor/EmbeddedEditor.java index 9b02b2f68ae..7a37e8a086b 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.embeddededitor/src/org/eclipse/papyrus/infra/emf/embeddededitor/editor/EmbeddedEditor.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.embeddededitor/src/org/eclipse/papyrus/infra/emf/embeddededitor/editor/EmbeddedEditor.java @@ -292,4 +292,8 @@ public class EmbeddedEditor implements CommandStackListener, IMenuListener { public void addCommandStackListener(CommandStackListener listener) { editingDomain.getCommandStack().addCommandStackListener(listener); } + + public EditingDomain getEditingDomain() { + return editingDomain; + } } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/META-INF/MANIFEST.MF index 04b22c95a1f..52dd2dbba12 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/META-INF/MANIFEST.MF @@ -10,6 +10,8 @@ Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: J2SE-1.5 Export-Package: org.eclipse.papyrus.infra.emf.newchild, org.eclipse.papyrus.infra.emf.newchild.impl, + org.eclipse.papyrus.infra.emf.newchild.menu, + org.eclipse.papyrus.infra.emf.newchild.ncpolicy, org.eclipse.papyrus.infra.emf.newchild.runtime, org.eclipse.papyrus.infra.emf.newchild.util Require-Bundle: org.eclipse.core.runtime, diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/AbstractCustomFillElement.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/AbstractCustomFillElement.java index bf5c1c5325e..d16a7c4f5d7 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/AbstractCustomFillElement.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/AbstractCustomFillElement.java @@ -25,6 +25,8 @@ public abstract class AbstractCustomFillElement implements CustomFillElement { protected CustomFiller filler; + protected Object selectedObject; + public void setMenuItem(CustomFiller filler) { this.filler = filler; } @@ -33,6 +35,10 @@ public abstract class AbstractCustomFillElement implements CustomFillElement { this.group = group; } + public void setSelectedObject(Object selectedObject) { + this.selectedObject = selectedObject; + } + public abstract void fill(IMenuManager menuManager); } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/CustomFillElement.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/CustomFillElement.java index 0f0a4a824c3..20ca078e611 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/CustomFillElement.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/CustomFillElement.java @@ -24,4 +24,6 @@ public interface CustomFillElement extends FillElement { public void setParentGroup(FillMenuGroup group); + public void setSelectedObject(Object selectedObject); + } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillNewChild.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillNewChild.java index 3cad806dd37..4f8707f7da2 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillNewChild.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillNewChild.java @@ -13,8 +13,11 @@ package org.eclipse.papyrus.infra.emf.newchild.menu; import java.io.IOException; import java.text.Collator; +import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Comparator; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; @@ -24,6 +27,7 @@ import java.util.Set; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; @@ -69,7 +73,7 @@ public class FillNewChild extends FillMenu implements FillElement { //TODO : Extract that to a static instance, and load with extension point policyManager = new PolicyManager(); try { - NewchildConfiguration configuration = (NewchildConfiguration)EMFHelper.loadEMFModel(null, URI.createPlatformPluginURI("org.eclipse.papyrus.infra.emf.newchild/Model/NewchildConfiguration.xmi", true)); + NewchildConfiguration configuration = (NewchildConfiguration)EMFHelper.loadEMFModel(null, URI.createPlatformPluginURI("org.eclipse.papyrus.emf.facet.editor/newChild/NewchildConfiguration.xmi", true)); policyManager.addConfiguration(configuration); } catch (IOException ex) { Activator.log.error(ex); @@ -116,10 +120,35 @@ public class FillNewChild extends FillMenu implements FillElement { }); + // Collection allPackages = new HashSet(); + // + // allPackages.add(selectedEObject.eClass().getEPackage()); + // for(EClass eClass : selectedEObject.eClass().getEAllSuperTypes()) { + // EPackage ePackage = eClass.getEPackage(); + // allPackages.add(ePackage); + // } + + Collection allPackages = new HashSet(); + Collection packagesToExclude = Arrays.asList(new EPackage[]{ EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/MoDisco/infra/facet/0.8.incubation"), EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/emf/facet/efacet/0.1.incubation"), EPackage.Registry.INSTANCE.getEPackage("http://www.eclipse.org/EmfFacet/infra/facet/0.8.incubation") }); + + // Collection packagesToExclude = Collections.emptyList(); + + for(Object registeredPackage : EPackage.Registry.INSTANCE.values()) { + if(registeredPackage instanceof EPackage && !packagesToExclude.contains(registeredPackage)) { + EPackage ePackage = (EPackage)registeredPackage; + if(ePackage.getNsURI().contains("ocl")) { + continue; + } + allPackages.add(ePackage); + } + } + for(EStructuralFeature feature : features) { if(feature instanceof EReference && ((EReference)feature).isContainment()) { EClass type = (EClass)feature.getEType(); - List eClasses = EMFHelper.getSubclassesOf(type, true); + + List eClasses = EMFHelper.getSubclassesOf(type, true, allPackages); + Collections.sort(eClasses, new Comparator() { public int compare(EClass class1, EClass class2) { @@ -188,24 +217,33 @@ public class FillNewChild extends FillMenu implements FillElement { } private Layout getLayout(Map> instantiableClasses) { + //If the layout is not in automatic mode, return it if(menu.getLayout() != Layout.AUTO) { return menu.getLayout(); } + // + //Automatic layout + // + + //If there is 0 or 1 category, use a Flat Layout if(instantiableClasses.size() < 2) { return Layout.FLAT; } + //If there are more than 5 categories, use a Hierarchic layout if(instantiableClasses.size() > 5) { return Layout.HIERARCHICAL; } + //If at least one category contains more than 5 elements, use a Hierarchic layout for(List eClasses : instantiableClasses.values()) { if(eClasses.size() > 5) { return Layout.HIERARCHICAL; } } + //The case is simple enough (Few classes and few categories); use a Flat layout return Layout.FLAT; } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillerFactory.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillerFactory.java index 084c2187ebe..893d64caa8b 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillerFactory.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/FillerFactory.java @@ -50,6 +50,7 @@ public class FillerFactory { CustomFillElement filler = ClassLoaderHelper.newInstance(className, CustomFillElement.class); filler.setParentGroup(parentGroup); filler.setMenuItem((CustomFiller)menuItem); + filler.setSelectedObject(selectedObject); return filler; } diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/MyCustomFiller.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/MyCustomFiller.java index bc0fe9a475e..34b4f1a7160 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/MyCustomFiller.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.newchild/src/org/eclipse/papyrus/infra/emf/newchild/menu/MyCustomFiller.java @@ -15,7 +15,9 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.papyrus.infra.emf.newchild.runtime.DisabledContributionItem; import org.eclipse.papyrus.infra.emf.newchild.util.MenuHelper; - +/** + * Sample + */ public class MyCustomFiller extends AbstractCustomFillElement { @Override diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF index bf56b90eeae..c47f94bfbcf 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF @@ -24,7 +24,8 @@ Require-Bundle: org.eclipse.ui, org.eclipse.emf.facet.infra.browser.custom.core;bundle-version="0.2.0", org.eclipse.papyrus.infra.tools;bundle-version="0.9.0", org.eclipse.emf.transaction;bundle-version="1.4.0", - org.eclipse.emf.ecore.xmi + org.eclipse.emf.ecore.xmi, + org.eclipse.emf.facet.custom.metamodel;bundle-version="0.2.0" Bundle-RequiredExecutionEnvironment: J2SE-1.5 Bundle-ActivationPolicy: lazy Export-Package: org.eclipse.papyrus.infra.emf, diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java index a058fd7d16a..aba46dd5eed 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/strategy/SemanticEMFContentProvider.java @@ -80,7 +80,7 @@ public class SemanticEMFContentProvider extends CustomizableModelContentProvider protected static EObject[] getRoots(ResourceSet root) { List roots = new LinkedList(); - if (root != null) { + if(root != null) { for(Resource resource : root.getResources()) { roots.addAll(resource.getContents()); } @@ -120,7 +120,8 @@ public class SemanticEMFContentProvider extends CustomizableModelContentProvider @Override public boolean hasChildren(Object parent) { //May be expensive - return getChildren(parent).length > 0; + Object[] children = getChildren(parent); + return children != null && children.length > 0; } public boolean isValidValue(Object containerElement) { diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java index 50fa841c273..de6ed68c372 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/utils/EMFHelper.java @@ -13,13 +13,16 @@ package org.eclipse.papyrus.infra.emf.utils; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.emf.common.util.TreeIterator; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; @@ -36,6 +39,9 @@ import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.xmi.XMIResource; import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; import org.eclipse.emf.edit.domain.EditingDomain; +import org.eclipse.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EAttributeTreeElement; +import org.eclipse.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EObjectTreeElement; +import org.eclipse.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EReferenceTreeElement; import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.utils.ServiceUtilsForActionHandlers; import org.eclipse.papyrus.infra.emf.Activator; @@ -152,6 +158,20 @@ public class EMFHelper { * if the EObject could not be resolved */ public static EObject getEObject(final Object source) { + //Support for EMF 0.2 CustomizedTree: The TreeElements are EObjects, and do not implement IAdatapble. + if(source instanceof EObjectTreeElement) { + return ((EObjectTreeElement)source).getEObject(); + } + + if(source instanceof EAttributeTreeElement) { + return ((EAttributeTreeElement)source).getEAttribute(); + } + + if(source instanceof EReferenceTreeElement) { + return ((EReferenceTreeElement)source).getEReference(); + } + + //General case if(source instanceof EObject) { return (EObject)source; } else if(source instanceof IAdaptable) { @@ -292,17 +312,72 @@ public class EMFHelper { * The list of EClasses implementing or extending the given EClass */ public static List getSubclassesOf(final EClass type, final boolean concreteClassesOnly) { - List result = new LinkedList(); + Set result = new LinkedHashSet(); if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) { result.add(type); } EPackage ePackage = getRootPackage(type.getEPackage()); getSubclassesOf(type, ePackage, result, concreteClassesOnly); - return result; + return new LinkedList(result); + } + + /** + * Return the list of EClasses that are sub types + * of the given EClass + * + * @param type + * @param concreteClassesOnly + * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered + * @param packagesToBrowse + * The EPackages in which the EClasses should be retrieved + * @return + * The list of EClasses implementing or extending the given EClass + */ + public static List getSubclassesOf(final EClass type, final boolean concreteClassesOnly, Collection packagesToBrowse) { + Set result = new LinkedHashSet(); + if(!concreteClassesOnly || (!type.isAbstract() && !type.isInterface())) { + result.add(type); + } + + for(EPackage ePackage : packagesToBrowse) { + getSubclassesOf(type, ePackage, result, concreteClassesOnly); + } + + return new LinkedList(result); + } + + /** + * Return the list of EClasses that are sub types + * of the given EClass + * + * @param type + * @param concreteClassesOnly + * If true, only Concrete EClasses will be returned. Abstract and Interface EClasses will be filtered + * @param browseAllRegisteredPackages + * If true, all registered EPackages will be navigated to retrieve the matching EClasses. Otherwise, + * only the current EPackage will be used. + * @return + * The list of EClasses implementing or extending the given EClass + */ + public static List getSubclassesOf(final EClass type, final boolean concreteClassesOnly, final boolean browseAllRegisteredPackages) { + //If the current package is a dynamic package, it may not be registered (?). Add it directly + EPackage currentPackage = getRootPackage(type.getEPackage()); + + Set allPackages = new LinkedHashSet(); + allPackages.add(currentPackage); + + //FIXME // WARNING: This loop will load all EPackages. The first call is expensive. + Set allUris = new HashSet(EPackage.Registry.INSTANCE.keySet()); + + for(String nsURI : allUris) { + allPackages.add(EPackage.Registry.INSTANCE.getEPackage(nsURI)); + } + + return getSubclassesOf(type, concreteClassesOnly, allPackages); } - private static void getSubclassesOf(final EClass type, final EPackage fromPackage, final List result, final boolean concreteClassesOnly) { + private static void getSubclassesOf(final EClass type, final EPackage fromPackage, final Set result, final boolean concreteClassesOnly) { for(EClassifier classifier : fromPackage.getEClassifiers()) { if(classifier instanceof EClass) { EClass eClass = (EClass)classifier; @@ -417,13 +492,71 @@ public class EMFHelper { return false; //The property if not required } + /** + * Returns all objects of type T contained in the resource + * + * @param resource + * @param type + * @return + */ + public static Set allInstances(final Resource resource, Class type) { + TreeIterator iterator = resource.getAllContents(); + Set result = new LinkedHashSet(); + + while(iterator.hasNext()) { + EObject element = iterator.next(); + if(type.isInstance(element)) { + result.add(type.cast(element)); + } + } + + return result; + } + + /** + * Returns all the EPackages and nested EPackages contained in this resource + * + * @param resource + * @return + */ + public static Set getAllEPackages(final Resource resource) { + Set result = new LinkedHashSet(); + + for(EObject rootElement : resource.getContents()) { + if(rootElement instanceof EPackage) { + result.add((EPackage)rootElement); + result.addAll(getAllNestedPackages((EPackage)rootElement)); + } + } + + return result; + } + + /** + * Returns all packages nested in the given EPackage (recursively). Does not + * include the base EPackage. + * + * @param basePackage + * @return + */ + public static Set getAllNestedPackages(EPackage basePackage) { + Set result = new LinkedHashSet(); + + for(EPackage nestedPackage : basePackage.getESubpackages()) { + result.add(nestedPackage); + result.addAll(getAllNestedPackages(nestedPackage)); + } + + return result; + } + /** * * @param resource * a resource * * @return - * the list of the metamodel knows by the resource + * the list of the metamodels known by the resource */ public static Set getMetamodels(final Resource resource) { Set metamodels = new HashSet(); -- cgit v1.2.3