org.eclipse.emf.cdo.explorer.ui.checkouts.actions.OpenWithActionProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.emf.cdo.explorer.ui.checkouts.actions.OpenWithActionProvider.java

Source

/*
 * Copyright (c) 2015, 2016 Eike Stepper (Berlin, Germany) and others.
 * 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.explorer.ui.checkouts.actions;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceFolder;
import org.eclipse.emf.cdo.eresource.CDOResourceLeaf;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.explorer.ui.bundle.OM;
import org.eclipse.emf.cdo.internal.ui.dialogs.EditObjectDialog;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.ui.CDOEditorOpener;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.net4j.util.ObjectUtil;
import org.eclipse.net4j.util.ui.UIUtil;

import org.eclipse.emf.common.command.BasicCommandStack;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.navigator.CommonActionProvider;
import org.eclipse.ui.navigator.ICommonActionConstants;
import org.eclipse.ui.navigator.ICommonActionExtensionSite;
import org.eclipse.ui.navigator.ICommonMenuConstants;
import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite;

/**
 * @author Eike Stepper
 */
public class OpenWithActionProvider extends CommonActionProvider {
    // private static final String WORKBENCH_PART_KEY = IWorkbenchPart.class.getName();
    //
    // private static final Map<IEditorPart, Pair<CDOView, Pair<CDOResourceLeaf, String>>> VIEWS = new
    // HashMap<IEditorPart, Pair<CDOView, Pair<CDOResourceLeaf, String>>>();
    //
    // private static final Map<Pair<CDOResourceLeaf, String>, Object> EDITORS = new HashMap<Pair<CDOResourceLeaf,
    // String>, Object>();
    //
    // private static final Object EDITOR_OPENING = new Object();
    //
    // private static final IPartListener2 PART_LISTENER = new PartListener();
    //
    // private static final IPageListener PAGE_LISTENER = new PageListener();
    //
    // private static final IWindowListener WINDOW_LISTENER = new WindowListener();
    //
    // static
    // {
    // IWorkbench workbench = UIUtil.getWorkbench();
    // for (IWorkbenchWindow window : workbench.getWorkbenchWindows())
    // {
    // window.addPageListener(PAGE_LISTENER);
    //
    // for (IWorkbenchPage page : window.getPages())
    // {
    // page.addPartListener(PART_LISTENER);
    // }
    // }
    //
    // workbench.addWindowListener(WINDOW_LISTENER);
    // }

    private ICommonViewerWorkbenchSite viewSite;

    private OpenAction openAction;

    public OpenWithActionProvider() {
    }

    @Override
    public void init(ICommonActionExtensionSite aConfig) {
        if (aConfig.getViewSite() instanceof ICommonViewerWorkbenchSite) {
            viewSite = (ICommonViewerWorkbenchSite) aConfig.getViewSite();
            openAction = new OpenAction(viewSite.getPage());
        }
    }

    @Override
    public void fillActionBars(IActionBars actionBars) {
        if (viewSite == null) {
            return;
        }

        Object selectedElement = getSelectedElement();

        openAction.selectionChanged(selectedElement);
        if (openAction.isEnabled()) {
            actionBars.setGlobalActionHandler(ICommonActionConstants.OPEN, openAction);
        }
    }

    @Override
    public void fillContextMenu(IMenuManager menu) {
        if (viewSite == null) {
            return;
        }

        Object selectedElement = getSelectedElement();

        openAction.selectionChanged(selectedElement);
        if (openAction.isEnabled()) {
            menu.insertAfter(ICommonMenuConstants.GROUP_OPEN, openAction);
            addOpenWithMenu(menu, selectedElement);
        }
    }

    private void addOpenWithMenu(IMenuManager menu, Object selectedElement) {
        EObject openableElement = getOpenableElement(selectedElement);
        if (openableElement != null) {
            CDOObject cdoObject = CDOUtil.getCDOObject(openableElement);
            CDOResourceLeaf resourceLeaf = getResourceLeaf(cdoObject);
            if (resourceLeaf instanceof CDOResource) {
                CDOResource resource = (CDOResource) resourceLeaf;
                URI uri = resource.getURI();

                CDOCheckout checkout = CDOExplorerUtil.getCheckout(cdoObject);
                if (checkout != null) {
                    CDOEditorOpener[] editorOpeners = CDOEditorOpener.Registry.INSTANCE.getEditorOpeners(uri);
                    if (editorOpeners.length != 0) {
                        IMenuManager submenu = new MenuManager("Open With", ICommonMenuConstants.GROUP_OPEN_WITH);
                        submenu.add(new GroupMarker(ICommonMenuConstants.GROUP_TOP));

                        for (CDOEditorOpener editorOpener : editorOpeners) {
                            OpenWithAction action = new OpenWithAction(viewSite.getPage(), cdoObject, editorOpener);
                            submenu.add(action);
                        }

                        submenu.add(new GroupMarker(ICommonMenuConstants.GROUP_ADDITIONS));
                        menu.appendToGroup(ICommonMenuConstants.GROUP_OPEN, submenu);
                    }
                }
            }
        }
    }

    private Object getSelectedElement() {
        IStructuredSelection selection = (IStructuredSelection) getContext().getSelection();
        if (selection.size() == 1) {
            return selection.getFirstElement();
        }

        return null;
    }

    private static EObject getOpenableElement(Object element) {
        if (element instanceof EObject) {
            EObject eObject = (EObject) element;
            CDOCheckout checkout = CDOExplorerUtil.getCheckout(eObject);
            if (checkout != null && !(eObject instanceof CDOResourceFolder)) {
                return eObject;
            }
        }

        return null;
    }

    private static CDOResourceLeaf getResourceLeaf(CDOObject cdoObject) {
        if (cdoObject instanceof CDOResourceLeaf) {
            return (CDOResourceLeaf) cdoObject;
        }

        if (cdoObject instanceof CDOResourceFolder) {
            return null;
        }

        return cdoObject.cdoResource();
    }

    // private static IEditorInput createEditorInput(String editorID, CDOCheckout checkout, CDOResourceLeaf resourceLeaf)
    // {
    // if (CDOEditorUtil.EDITOR_ID.equals(editorID))
    // {
    // return CDOEditorUtil.createEditorInput(editorID, resourceLeaf, false, true);
    // }
    //
    // String path = resourceLeaf.getPath();
    // URI uri = checkout.createResourceURI(path);
    // return new URIEditorInput(uri);
    // }
    //
    // private static void openEditor(final IWorkbenchPage page, final CDOObject object, final CDOResourceLeaf
    // resourceLeaf,
    // final String editorID, final Pair<CDOResourceLeaf, String> key)
    // {
    // new Job("Open")
    // {
    // @Override
    // protected IStatus run(IProgressMonitor monitor)
    // {
    // final CDOCheckout checkout = CDOExplorerUtil.getCheckout(object);
    // final CDOView view = checkout.openView();
    //
    // final CDOResourceLeaf contextualLeaf = view.getObject(resourceLeaf);
    // final IEditorInput editorInput = createEditorInput(editorID, checkout, contextualLeaf);
    //
    // Shell shell = page.getWorkbenchWindow().getShell();
    // if (!shell.isDisposed())
    // {
    // shell.getDisplay().asyncExec(new Runnable()
    // {
    // public void run()
    // {
    // try
    // {
    // IEditorPart editor = page.openEditor(editorInput, editorID);
    // if (editor != null)
    // {
    // registerEditor(editor, view, key);
    // }
    // }
    // catch (Exception ex)
    // {
    // OM.LOG.error(ex);
    // }
    // }
    // });
    // }
    //
    // return Status.OK_STATUS;
    // }
    // }.schedule();
    // }

    public static void openEditor(IWorkbenchPage page, ComposedAdapterFactory adapterFactory, EObject object,
            String editorOpenerID) {
        if (page == null) {
            page = UIUtil.getActiveWorkbenchPage();
        }

        if (object == null) {
            throw new IllegalArgumentException("object is null");
        }

        if (editorOpenerID == null && !(object instanceof CDOResourceNode)) {
            if (adapterFactory == null) {
                // This must be an unwanted second call through the global open action registration.
                return;
            }

            Shell shell = page.getWorkbenchWindow().getShell();
            if (editObject(shell, adapterFactory, object)) {
                return;
            }
        }

        CDOObject cdoObject = CDOUtil.getCDOObject(object);

        CDOResourceLeaf resourceLeaf = getResourceLeaf(cdoObject);
        if (resourceLeaf instanceof CDOResource) {
            CDOCheckout checkout = CDOExplorerUtil.getCheckout(cdoObject);
            if (checkout != null) {
                URI uri = resourceLeaf.getURI();

                if (!(object instanceof CDOResourceNode)) {
                    StringBuilder builder = new StringBuilder();
                    CDOIDUtil.write(builder, cdoObject.cdoID());

                    String fragment = builder.toString();
                    uri = uri.appendFragment(fragment);
                }

                CDOEditorOpener[] editorOpeners = CDOEditorOpener.Registry.INSTANCE
                        .getEditorOpeners(uri.trimFragment());
                String defaultEditorOpenerID = editorOpeners.length != 0 ? editorOpeners[0].getID() : null;

                CDOID objectID = cdoObject.cdoID();
                String lastEditorOpenerID = checkout.getEditorOpenerID(objectID);

                if (editorOpenerID == null) {
                    editorOpenerID = lastEditorOpenerID;
                }

                if (editorOpenerID == null) {
                    editorOpenerID = defaultEditorOpenerID;
                }

                if (editorOpenerID != null) {
                    CDOEditorOpener editorOpener = CDOEditorOpener.Registry.INSTANCE
                            .getEditorOpener(editorOpenerID);
                    if (editorOpener != null) {
                        if (!ObjectUtil.equals(editorOpenerID, lastEditorOpenerID)) {
                            checkout.setEditorOpenerID(objectID, editorOpenerID);
                        }

                        if (cdoObject instanceof CDOResourceNode) {
                            uri = uri.trimFragment();
                        }

                        editorOpener.openEditor(page, uri);
                    }
                } else {
                    // Pair<CDOResourceLeaf, String> key = Pair.create(resourceLeaf, editorOpenerID);
                    //
                    // synchronized (EDITORS)
                    // {
                    // Object editor = EDITORS.get(key);
                    // if (editor != null)
                    // {
                    // if (editor != EDITOR_OPENING)
                    // {
                    // page.activate((IEditorPart)editor);
                    // }
                    //
                    // return;
                    // }
                    //
                    // EDITORS.put(key, EDITOR_OPENING);
                    // }
                    //
                    // openEditor(page, cdoObject, resourceLeaf, editorOpenerID, key);
                }
            }
        }
    }

    public static boolean editObject(Shell shell, ComposedAdapterFactory adapterFactory, EObject object) {
        boolean edited = false;

        if (!(object instanceof CDOResourceNode)) {
            CDOCheckout checkout = CDOExplorerUtil.getCheckout(object);
            if (checkout != null) {
                EditingDomain editingDomain = new AdapterFactoryEditingDomain(adapterFactory,
                        new BasicCommandStack());
                ResourceSet resourceSet = editingDomain.getResourceSet();
                CDOTransaction transaction = checkout.openTransaction(resourceSet);

                try {
                    EObject txObject = transaction.getObject(object);

                    int result = new EditObjectDialog(shell, adapterFactory, txObject).open();
                    edited = true;

                    if (result == EditObjectDialog.OK) {
                        transaction.commit();
                    }
                } catch (Exception ex) {
                    OM.LOG.error(ex);
                } finally {
                    transaction.close();
                }
            }
        }

        return edited;
    }

    // private static void registerEditor(IEditorPart editor, CDOView view, Pair<CDOResourceLeaf, String> key)
    // {
    // view.properties().put(WORKBENCH_PART_KEY, editor);
    //
    // synchronized (EDITORS)
    // {
    // EDITORS.put(key, editor);
    // }
    //
    // synchronized (VIEWS)
    // {
    // VIEWS.put(editor, Pair.create(view, key));
    // }
    // }
    //
    // /**
    // * @author Eike Stepper
    // */
    // private static final class WindowListener implements IWindowListener
    // {
    // public void windowOpened(IWorkbenchWindow window)
    // {
    // window.addPageListener(PAGE_LISTENER);
    // }
    //
    // public void windowClosed(IWorkbenchWindow window)
    // {
    // window.removePageListener(PAGE_LISTENER);
    // }
    //
    // public void windowActivated(IWorkbenchWindow window)
    // {
    // // Do nothing
    // }
    //
    // public void windowDeactivated(IWorkbenchWindow window)
    // {
    // // Do nothing
    // }
    // }
    //
    // /**
    // * @author Eike Stepper
    // */
    // private static final class PageListener implements IPageListener
    // {
    // public void pageOpened(IWorkbenchPage page)
    // {
    // page.addPartListener(PART_LISTENER);
    // }
    //
    // public void pageClosed(IWorkbenchPage page)
    // {
    // page.removePartListener(PART_LISTENER);
    // }
    //
    // public void pageActivated(IWorkbenchPage page)
    // {
    // // Do nothing
    // }
    // }
    //
    // /**
    // * @author Eike Stepper
    // */
    // private static final class PartListener implements IPartListener2
    // {
    // public void partOpened(IWorkbenchPartReference partRef)
    // {
    // }
    //
    // public void partClosed(IWorkbenchPartReference partRef)
    // {
    // IWorkbenchPart part = partRef.getPart(false);
    // if (part != null)
    // {
    // Pair<CDOView, Pair<CDOResourceLeaf, String>> pair;
    // synchronized (VIEWS)
    // {
    // pair = VIEWS.remove(part);
    // }
    //
    // if (pair != null)
    // {
    // CDOView view = pair.getElement1();
    // view.close();
    //
    // Pair<CDOResourceLeaf, String> key = pair.getElement2();
    // synchronized (EDITORS)
    // {
    // EDITORS.remove(key);
    // }
    // }
    // }
    // }
    //
    // public void partVisible(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    //
    // public void partHidden(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    //
    // public void partActivated(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    //
    // public void partDeactivated(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    //
    // public void partBroughtToTop(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    //
    // public void partInputChanged(IWorkbenchPartReference partRef)
    // {
    // // Do nothing
    // }
    // }

    /**
     * @author Eike Stepper
     */
    private static class OpenAction extends Action {
        public static final String ID = OM.BUNDLE_ID + ".OpenAction"; //$NON-NLS-1$

        private final IWorkbenchPage page;

        private EObject openableElement;

        public OpenAction(IWorkbenchPage page) {
            super("Open");
            setId(ID);
            setToolTipText("Edit this resource");
            this.page = page;
        }

        public void selectionChanged(Object selectedElement) {
            openableElement = getOpenableElement(selectedElement);
            setEnabled(openableElement != null);
        }

        @Override
        public void run() {
            openEditor(page, null, openableElement, null);
        }
    }

    /**
     * @author Eike Stepper
     */
    private static class OpenWithAction extends Action {
        public static final String ID = OM.BUNDLE_ID + ".OpenWithAction"; //$NON-NLS-1$

        private final IWorkbenchPage page;

        private EObject openableElement;

        private CDOEditorOpener editorOpener;

        public OpenWithAction(IWorkbenchPage page, EObject openableElement, CDOEditorOpener editorOpener) {
            setId(ID);
            setText(editorOpener.getName());
            setImageDescriptor(editorOpener.getIcon());
            setToolTipText("Edit this resource");

            this.page = page;
            this.openableElement = openableElement;
            this.editorOpener = editorOpener;
        }

        @Override
        public void run() {
            openEditor(page, null, openableElement, editorOpener.getID());
        }
    }

    // /**
    // * @author Eike Stepper
    // */
    // private static class OpenFileAction extends Action
    // {
    // public static final String ID = OM.BUNDLE_ID + ".OpenFileAction"; //$NON-NLS-1$
    //
    // private final IWorkbenchPage page;
    //
    // private EObject openableElement;
    //
    // private String editorID;
    //
    // public OpenFileAction(IWorkbenchPage page, EObject openableElement, String editorID)
    // {
    // setId(ID);
    //
    // this.page = page;
    // this.openableElement = openableElement;
    // this.editorID = editorID;
    //
    // IEditorDescriptor editorDescriptor = PlatformUI.getWorkbench().getEditorRegistry().findEditor(editorID);
    // setText(editorDescriptor.getLabel());
    // setImageDescriptor(editorDescriptor.getImageDescriptor());
    //
    // setToolTipText("Edit this resource");
    // }
    //
    // @Override
    // public void run()
    // {
    // openEditor(page, null, openableElement, editorID);
    // }
    // }
}