package org.eclipse.uml2.diagram.statemachine.part; import java.io.IOException; import java.util.Collection; import java.util.Collections; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.eclipse.emf.common.command.Command; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.common.util.WrappedException; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.util.FeatureMap; import org.eclipse.emf.edit.command.AddCommand; import org.eclipse.emf.edit.command.CommandParameter; import org.eclipse.emf.edit.command.SetCommand; import org.eclipse.emf.edit.domain.EditingDomain; import org.eclipse.emf.edit.provider.IWrapperItemProvider; import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.gmf.runtime.emf.core.GMFEditingDomainFactory; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.viewers.ILabelProvider; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Tree; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.model.WorkbenchLabelProvider; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.UMLFactory; import org.eclipse.uml2.uml.UMLPackage; public class SelectStateMachineDialog extends Dialog { public SelectStateMachineDialog(Shell parentShell) { super(parentShell); setShellStyle(getShellStyle() | SWT.RESIZE); } @Override protected Control createDialogArea(Composite parent) { getShell().setText(CustomMessages.SelectStateMachineDialog_Title); createViewer(parent); return parent; } @Override protected Control createButtonBar(Composite parent) { Control buttonBar = super.createButtonBar(parent); setOkButtonEnabled(false); return buttonBar; } public URI getSelectedModelElementURI() { Resource resource = mySelectedModelElement.eResource(); return resource.getURI().appendFragment(resource.getURIFragment(mySelectedModelElement)); } private void createViewer(Composite parent) { treeViewer = new TreeViewer(parent, SWT.SINGLE | SWT.V_SCROLL | SWT.BORDER); GridData layoutData = new GridData(GridData.FILL_BOTH); layoutData.heightHint = 300; layoutData.widthHint = 300; treeViewer.getTree().setLayoutData(layoutData); treeViewer.setContentProvider(new ModelElementsTreeContentProvider()); treeViewer.setLabelProvider(new ModelElementsTreeLabelProvider()); treeViewer.setInput(ResourcesPlugin.getWorkspace().getRoot()); treeViewer.addFilter(new ModelFilesFilter()); treeViewer.addSelectionChangedListener(new OkButtonEnabler()); Tree tree = treeViewer.getTree(); MenuManager menuManager = new MenuManager(); Menu menu = menuManager.createContextMenu(tree); menuManager.addMenuListener(new IMenuListener() { public void menuAboutToShow(IMenuManager manager) { NewStateMachineAction newStateMachineAction = new NewStateMachineAction(); if (!(mySelectedModelElement instanceof Package)) { newStateMachineAction.setEnabled(false); } manager.add(newStateMachineAction); } }); menuManager.setRemoveAllWhenShown(true); tree.setMenu(menu); } private void setOkButtonEnabled(boolean enabled) { getButton(IDialogConstants.OK_ID).setEnabled(enabled); } private boolean isValidModelFile(IFile file) { String fileExtension = file.getFullPath().getFileExtension(); return "uml".equals(fileExtension); //$NON-NLS-1$ } private EObject mySelectedModelElement; private EditingDomain myEditingDomain = GMFEditingDomainFactory.INSTANCE.createEditingDomain(); private TreeViewer treeViewer; private class NewStateMachineAction extends Action { public NewStateMachineAction() { super(CustomMessages.SelectStateMachineDialog_CreateStateMachineAction_Title); } @Override public void run() { Command addCommand = AddCommand.create(myEditingDomain, mySelectedModelElement, UMLPackage.Literals.PACKAGE__PACKAGED_ELEMENT, UMLFactory.eINSTANCE.createStateMachine(), CommandParameter.NO_INDEX); myEditingDomain.getCommandStack().execute(addCommand); Collection<?> result = addCommand.getResult(); if (result.isEmpty()) { return; } Object createdElement = result.iterator().next(); Command setCommand = SetCommand.create(myEditingDomain, createdElement, UMLPackage.Literals.NAMED_ELEMENT__NAME, CustomMessages.SelectStateMachineDialog_CreateStateMachineAction_DefaultName); myEditingDomain.getCommandStack().execute(setCommand); treeViewer.setSelection(new StructuredSelection(createdElement), true); try { mySelectedModelElement.eResource().save(null); } catch (IOException ioe) { UMLDiagramEditorPlugin.getInstance().logError("Unable to save modified model: " + mySelectedModelElement.eResource().getURI().toString(), ioe); //$NON-NLS-1$ ioe.printStackTrace(); } }; } private class OkButtonEnabler implements ISelectionChangedListener { public void selectionChanged(SelectionChangedEvent event) { if (event.getSelection() instanceof IStructuredSelection) { IStructuredSelection selection = (IStructuredSelection) event.getSelection(); if (selection.size() == 1) { Object selectedElement = selection.getFirstElement(); if (selectedElement instanceof IWrapperItemProvider) { selectedElement = ((IWrapperItemProvider) selectedElement).getValue(); } if (selectedElement instanceof FeatureMap.Entry) { selectedElement = ((FeatureMap.Entry) selectedElement).getValue(); } if (selectedElement instanceof EObject) { mySelectedModelElement = (EObject) selectedElement; setOkButtonEnabled(mySelectedModelElement != null && mySelectedModelElement.eClass() == UMLPackage.Literals.STATE_MACHINE); return; } } } mySelectedModelElement = null; setOkButtonEnabled(false); } } private class ModelElementsTreeContentProvider implements ITreeContentProvider { public Object[] getChildren(Object parentElement) { Object[] result = myWorkbenchContentProvider.getChildren(parentElement); if (result != null && result.length > 0) { return result; } if (parentElement instanceof IFile) { IFile modelFile = (IFile) parentElement; IPath resourcePath = modelFile.getFullPath(); ResourceSet resourceSet = myEditingDomain.getResourceSet(); try { Resource modelResource = resourceSet.getResource(URI.createPlatformResourceURI(resourcePath.toString(), true), true); return myAdapterFctoryContentProvier.getChildren(modelResource); } catch (WrappedException e) { UMLDiagramEditorPlugin.getInstance().logError("Unable to load resource: " + resourcePath.toString(), e); //$NON-NLS-1$ } return Collections.EMPTY_LIST.toArray(); } return myAdapterFctoryContentProvier.getChildren(parentElement); } public Object getParent(Object element) { Object parent = myWorkbenchContentProvider.getParent(element); if (parent != null) { return parent; } if (element instanceof EObject) { EObject eObject = (EObject) element; if (eObject.eContainer() == null && eObject.eResource().getURI().isFile()) { String path = eObject.eResource().getURI().path(); return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(path)); } return myAdapterFctoryContentProvier.getParent(eObject); } return null; } public boolean hasChildren(Object element) { if (element instanceof IFile) { return isValidModelFile((IFile) element); } return myWorkbenchContentProvider.hasChildren(element) || myAdapterFctoryContentProvier.hasChildren(element); } public Object[] getElements(Object inputElement) { Object[] elements = myWorkbenchContentProvider.getElements(inputElement); return elements; } public void dispose() { myWorkbenchContentProvider.dispose(); myAdapterFctoryContentProvier.dispose(); } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { myWorkbenchContentProvider.inputChanged(viewer, oldInput, newInput); myAdapterFctoryContentProvier.inputChanged(viewer, oldInput, newInput); } private ITreeContentProvider myWorkbenchContentProvider = new WorkbenchContentProvider(); private AdapterFactoryContentProvider myAdapterFctoryContentProvier = new AdapterFactoryContentProvider(UMLDiagramEditorPlugin.getInstance().getItemProvidersAdapterFactory()); } private class ModelElementsTreeLabelProvider implements ILabelProvider { public Image getImage(Object element) { Image result = myWorkbenchLabelProvider.getImage(element); return result != null ? result : myAdapterFactoryLabelProvider.getImage(element); } public String getText(Object element) { String result = myWorkbenchLabelProvider.getText(element); return result != null && result.length() > 0 ? result : myAdapterFactoryLabelProvider.getText(element); } public void addListener(ILabelProviderListener listener) { myWorkbenchLabelProvider.addListener(listener); myAdapterFactoryLabelProvider.addListener(listener); } public void dispose() { myWorkbenchLabelProvider.dispose(); myAdapterFactoryLabelProvider.dispose(); } public boolean isLabelProperty(Object element, String property) { return myWorkbenchLabelProvider.isLabelProperty(element, property) || myAdapterFactoryLabelProvider.isLabelProperty(element, property); } public void removeListener(ILabelProviderListener listener) { myWorkbenchLabelProvider.removeListener(listener); myAdapterFactoryLabelProvider.removeListener(listener); } private WorkbenchLabelProvider myWorkbenchLabelProvider = new WorkbenchLabelProvider(); private AdapterFactoryLabelProvider myAdapterFactoryLabelProvider = new AdapterFactoryLabelProvider(UMLDiagramEditorPlugin.getInstance().getItemProvidersAdapterFactory()); } private class ModelFilesFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { if (element instanceof IContainer) { return true; } if (element instanceof IFile) { IFile file = (IFile) element; return isValidModelFile(file); } return true; } } }