diff options
author | Eike Stepper | 2021-02-02 11:46:26 +0000 |
---|---|---|
committer | Eike Stepper | 2021-02-02 11:46:26 +0000 |
commit | 53249c2fc2ef90c5f07aaf09e405aec5514b4d04 (patch) | |
tree | 825ceab9307170cb2352e6f69b18e84aa0bddceb | |
parent | a19bff87d338c698adb273f31f70b96e57515b46 (diff) | |
download | cdo-53249c2fc2ef90c5f07aaf09e405aec5514b4d04.tar.gz cdo-53249c2fc2ef90c5f07aaf09e405aec5514b4d04.tar.xz cdo-53249c2fc2ef90c5f07aaf09e405aec5514b4d04.zip |
[570839] [UI] Reopen CDOLob editors after a restart
https://bugs.eclipse.org/bugs/show_bug.cgi?id=570839
5 files changed, 471 insertions, 245 deletions
diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/plugin.xml b/plugins/org.eclipse.emf.cdo.explorer.ui/plugin.xml index 3ac78026e1..c51de2bf2c 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/plugin.xml +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/plugin.xml @@ -855,6 +855,9 @@ <factory id="org.eclipse.emf.cdo.explorer.ui.checkouts.CDOModelEditorInput.ElementFactory" class="org.eclipse.emf.cdo.explorer.ui.checkouts.CDOModelEditorInput$ElementFactory"/> + <factory + id="org.eclipse.emf.cdo.explorer.ui.checkouts.CDOCheckoutLobEditorInput.ElementFactory" + class="org.eclipse.emf.cdo.explorer.ui.checkouts.CDOCheckoutLobEditorInput$ElementFactory"/> </extension> <extension point="org.eclipse.emf.cdo.ui.editorOpeners"> diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutLobEditorInput.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutLobEditorInput.java new file mode 100644 index 0000000000..8253e62282 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/CDOCheckoutLobEditorInput.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2020 Eike Stepper (Loehne, 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; + +import org.eclipse.emf.cdo.eresource.CDOFileResource; +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.internal.ui.editor.CDOLobEditorInput; +import org.eclipse.emf.cdo.internal.ui.editor.CDOLobStorage; +import org.eclipse.emf.cdo.view.CDOView; + +import org.eclipse.net4j.util.ObjectUtil; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; +import org.eclipse.net4j.util.ui.GlobalPartAdapter; + +import org.eclipse.emf.common.util.URI; + +import org.eclipse.core.runtime.IAdaptable; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IEditorReference; +import org.eclipse.ui.IElementFactory; +import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPersistableElement; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPart; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.PartInitException; + +/** + * A text editor will consult {@link CDOLobStorage} for this input. + * + * @author Eike Stepper + */ +public class CDOCheckoutLobEditorInput extends CDOLobEditorInput implements IPersistableElement +{ + protected static final String URI_TAG = "uri"; + + protected static final String COMMIT_ON_SAVE_TAG = "commitOnSave"; + + public CDOCheckoutLobEditorInput(URI uri) + { + this(uri, false); + } + + public CDOCheckoutLobEditorInput(URI uri, boolean commitOnSave) + { + super(getFile(uri), commitOnSave); + setURI(uri); + } + + @Override + public IPersistableElement getPersistable() + { + return this; + } + + @Override + public void saveState(IMemento memento) + { + URI uri = getURI(); + memento.putString(URI_TAG, uri == null ? null : uri.toString()); + memento.putBoolean(COMMIT_ON_SAVE_TAG, isCommitOnSave()); + } + + @Override + public String getFactoryId() + { + return ElementFactory.ID; + } + + public static IEditorPart openEditor(IWorkbenchPage page, String editorID, URI uri) throws PartInitException + { + for (IEditorReference editorReference : page.getEditorReferences()) + { + if (!ObjectUtil.equals(editorReference.getId(), editorID)) + { + continue; + } + + IEditorInput editorInput = editorReference.getEditorInput(); + if (!(editorInput instanceof CDOCheckoutLobEditorInput)) + { + continue; + } + + CDOCheckoutLobEditorInput lobInput = (CDOCheckoutLobEditorInput)editorInput; + if (!lobInput.getURI().equals(uri)) + { + continue; + } + + IEditorPart editor = editorReference.getEditor(true); + page.activate(editor); + return editor; + } + + IEditorInput lobInput = new CDOCheckoutLobEditorInput(uri, true); + return page.openEditor(lobInput, editorID); + } + + private static CDOFileResource<?> getFile(URI uri) + { + String id = uri.authority(); + CDOCheckout checkout = CDOExplorerUtil.getCheckout(id); + if (checkout != null) + { + checkout.open(); + + CDOView view = checkout.getView(); + if (!view.isHistorical()) + { + view = checkout.openTransaction(); + } + + CDOResourceNode node = view.getResourceNode(uri.path()); + if (node instanceof CDOFileResource) + { + return (CDOFileResource<?>)node; + } + } + + return null; + } + + static + { + new GlobalPartAdapter() + { + @Override + public void partClosed(IWorkbenchPartReference partRef) + { + IWorkbenchPart part = partRef.getPart(false); + if (part instanceof IEditorPart) + { + IEditorPart editor = (IEditorPart)part; + + IEditorInput input = editor.getEditorInput(); + if (input instanceof CDOCheckoutLobEditorInput) + { + CDOCheckoutLobEditorInput lobInput = (CDOCheckoutLobEditorInput)input; + + CDOView view = lobInput.getResource().cdoView(); + CDOCheckout checkout = CDOExplorerUtil.getCheckout(view); + if (checkout == null || checkout.getView() != view) + { + LifecycleUtil.deactivate(view); + } + } + } + } + }; + } + + /** + * @author Eike Stepper + */ + public static class ElementFactory implements IElementFactory + { + public static final String ID = "org.eclipse.emf.cdo.explorer.ui.checkouts.CDOCheckoutLobEditorInput.ElementFactory"; + + public ElementFactory() + { + } + + @Override + public IAdaptable createElement(IMemento memento) + { + URI uri = URI.createURI(memento.getString(URI_TAG)); + boolean commitOnSave = memento.getBoolean(COMMIT_ON_SAVE_TAG); + return new CDOCheckoutLobEditorInput(uri, commitOnSave); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/OpenWithActionProvider.java b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/OpenWithActionProvider.java index 18d682bdf1..95c8179b9f 100644 --- a/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/OpenWithActionProvider.java +++ b/plugins/org.eclipse.emf.cdo.explorer.ui/src/org/eclipse/emf/cdo/explorer/ui/checkouts/actions/OpenWithActionProvider.java @@ -21,17 +21,15 @@ 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.explorer.ui.checkouts.CDOCheckoutLobEditorInput; import org.eclipse.emf.cdo.internal.explorer.CDOExplorerURIHandler; import org.eclipse.emf.cdo.internal.ui.dialogs.EditObjectDialog; -import org.eclipse.emf.cdo.internal.ui.editor.CDOLobEditorInput; import org.eclipse.emf.cdo.transaction.CDOTransaction; import org.eclipse.emf.cdo.ui.CDOEditorOpener; import org.eclipse.emf.cdo.ui.CDOEditorUtil; import org.eclipse.emf.cdo.util.CDOUtil; -import org.eclipse.emf.cdo.view.CDOView; import org.eclipse.net4j.util.ObjectUtil; -import org.eclipse.net4j.util.om.OMPlatform; import org.eclipse.net4j.util.ui.UIUtil; import org.eclipse.emf.common.command.BasicCommandStack; @@ -49,10 +47,7 @@ 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.IEditorPart; -import org.eclipse.ui.IPartListener; import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.PartInitException; import org.eclipse.ui.navigator.CommonActionProvider; import org.eclipse.ui.navigator.ICommonActionConstants; @@ -65,8 +60,6 @@ import org.eclipse.ui.navigator.ICommonViewerWorkbenchSite; */ public class OpenWithActionProvider extends CommonActionProvider { - private static final boolean OMIT_LOB_HANDLER_URI = OMPlatform.INSTANCE.isProperty("org.eclipse.emf.cdo.explorer.ui.omitLobHandlerURI"); - private ICommonViewerWorkbenchSite viewSite; private OpenAction openAction; @@ -276,28 +269,6 @@ public class OpenWithActionProvider extends CommonActionProvider 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); - } } } else if (resourceLeaf instanceof CDOFileResource) @@ -305,62 +276,11 @@ public class OpenWithActionProvider extends CommonActionProvider String editorID = CDOEditorUtil.getEffectiveEditorID(resourceLeaf); if (editorID != null) { - CDOView view = resourceLeaf.cdoView(); - CDOCheckout checkout = CDOExplorerUtil.getCheckout(view); - CDOTransaction tx = view.isHistorical() ? null : checkout != null ? checkout.openTransaction() : view.getSession().openTransaction(view.getBranch()); - CDOResourceLeaf txLeaf = tx == null ? resourceLeaf : tx.getObject(resourceLeaf); + URI uri = CDOExplorerURIHandler.createURI(resourceLeaf); try { - CDOLobEditorInput editorInput = (CDOLobEditorInput)CDOEditorUtil.createLobEditorInput(txLeaf, true); - - if (checkout != null && !OMIT_LOB_HANDLER_URI) - { - editorInput.setURI(CDOExplorerURIHandler.createURI(checkout, txLeaf)); - } - - IEditorPart editor = page.openEditor(editorInput, editorID); - - page.addPartListener(new IPartListener() - { - @Override - public void partClosed(IWorkbenchPart part) - { - if (part == editor) - { - if (tx != null) - { - tx.close(); - } - - editor.getSite().getPage().removePartListener(this); - } - } - - @Override - public void partActivated(IWorkbenchPart part) - { - // Do nothing. - } - - @Override - public void partBroughtToTop(IWorkbenchPart part) - { - // Do nothing. - } - - @Override - public void partDeactivated(IWorkbenchPart part) - { - // Do nothing. - } - - @Override - public void partOpened(IWorkbenchPart part) - { - // Do nothing. - } - }); + CDOCheckoutLobEditorInput.openEditor(page, editorID, uri); } catch (PartInitException ex) { @@ -409,133 +329,6 @@ public class OpenWithActionProvider extends CommonActionProvider 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 */ @@ -599,39 +392,4 @@ public class OpenWithActionProvider extends CommonActionProvider 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); - // } - // } } diff --git a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/CDOExplorerURIHandler.java b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/CDOExplorerURIHandler.java index 3b09c8df6e..bc46524b68 100644 --- a/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/CDOExplorerURIHandler.java +++ b/plugins/org.eclipse.emf.cdo.explorer/src/org/eclipse/emf/cdo/internal/explorer/CDOExplorerURIHandler.java @@ -219,6 +219,17 @@ public abstract class CDOExplorerURIHandler<NODE extends CDOResourceNode> extend return null; } + public static URI createURI(CDOResourceNode node) + { + CDOCheckout checkout = CDOExplorerUtil.getCheckout(node); + if (checkout == null) + { + return null; + } + + return createURI(checkout, node); + } + public static URI createURI(CDOCheckout checkout, CDOResourceNode node) { String scheme = getScheme(node); diff --git a/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/GlobalPartAdapter.java b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/GlobalPartAdapter.java new file mode 100644 index 0000000000..04285fce0e --- /dev/null +++ b/plugins/org.eclipse.net4j.util.ui/src/org/eclipse/net4j/util/ui/GlobalPartAdapter.java @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2021 Eike Stepper (Loehne, 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.net4j.util.ui; + +import org.eclipse.net4j.util.collection.ConcurrentArray; +import org.eclipse.net4j.util.internal.ui.bundle.OM; + +import org.eclipse.ui.IPageListener; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IWindowListener; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartReference; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.PlatformUI; + +import java.util.function.Consumer; + +/** + * @author Eike Stepper + * @since 3.10 + */ +public class GlobalPartAdapter implements IWindowListener, IPageListener, IPartListener2 +{ + private static final ConcurrentArray<GlobalPartAdapter> adapters = new ConcurrentArray<GlobalPartAdapter>() + { + @Override + protected GlobalPartAdapter[] newArray(int length) + { + return new GlobalPartAdapter[length]; + } + }; + + public GlobalPartAdapter() + { + adapters.add(this); + } + + public void dispose() + { + adapters.remove(this); + } + + @Override + public void windowActivated(IWorkbenchWindow window) + { + // Subclasses may override. + } + + @Override + public void windowDeactivated(IWorkbenchWindow window) + { + // Subclasses may override. + } + + @Override + public void windowClosed(IWorkbenchWindow window) + { + // Subclasses may override. + } + + @Override + public void windowOpened(IWorkbenchWindow window) + { + // Subclasses may override. + } + + @Override + public void pageActivated(IWorkbenchPage page) + { + // Subclasses may override. + } + + @Override + public void pageClosed(IWorkbenchPage page) + { + // Subclasses may override. + } + + @Override + public void pageOpened(IWorkbenchPage page) + { + // Subclasses may override. + } + + @Override + public void partActivated(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partBroughtToTop(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partClosed(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partDeactivated(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partOpened(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partHidden(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partVisible(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + @Override + public void partInputChanged(IWorkbenchPartReference partRef) + { + // Subclasses may override. + } + + private static void notifyAdapters(Consumer<GlobalPartAdapter> consumer) + { + GlobalPartAdapter[] array = adapters.get(); + if (array != null) + { + for (int i = 0; i < array.length; i++) + { + GlobalPartAdapter adapter = array[i]; + + try + { + consumer.accept(adapter); + } + catch (Exception ex) + { + OM.LOG.error(ex); + } + } + } + } + + static + { + IPartListener2 partListener = new IPartListener2() + { + @Override + public void partOpened(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partOpened(partRef)); + } + + @Override + public void partClosed(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partClosed(partRef)); + } + + @Override + public void partActivated(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partActivated(partRef)); + } + + @Override + public void partDeactivated(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partDeactivated(partRef)); + } + + @Override + public void partBroughtToTop(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partBroughtToTop(partRef)); + } + + @Override + public void partHidden(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partHidden(partRef)); + } + + @Override + public void partVisible(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partVisible(partRef)); + } + + @Override + public void partInputChanged(IWorkbenchPartReference partRef) + { + notifyAdapters(a -> a.partInputChanged(partRef)); + } + }; + + IPageListener pageListener = new IPageListener() + { + @Override + public void pageOpened(IWorkbenchPage page) + { + page.addPartListener(partListener); + notifyAdapters(a -> a.pageOpened(page)); + } + + @Override + public void pageClosed(IWorkbenchPage page) + { + page.removePartListener(partListener); + notifyAdapters(a -> a.pageClosed(page)); + } + + @Override + public void pageActivated(IWorkbenchPage page) + { + notifyAdapters(a -> a.pageActivated(page)); + } + }; + + IWindowListener windowListener = new IWindowListener() + { + @Override + public void windowOpened(IWorkbenchWindow window) + { + window.addPageListener(pageListener); + notifyAdapters(a -> a.windowOpened(window)); + } + + @Override + public void windowClosed(IWorkbenchWindow window) + { + window.removePageListener(pageListener); + notifyAdapters(a -> a.windowOpened(window)); + } + + @Override + public void windowActivated(IWorkbenchWindow window) + { + notifyAdapters(a -> a.windowClosed(window)); + } + + @Override + public void windowDeactivated(IWorkbenchWindow window) + { + notifyAdapters(a -> a.windowDeactivated(window)); + } + }; + + IWorkbench workbench = PlatformUI.getWorkbench(); + workbench.addWindowListener(windowListener); + } +} |