diff options
author | Christian W. Damus | 2016-07-13 19:05:54 +0000 |
---|---|---|
committer | Christian W. Damus | 2016-07-13 19:51:04 +0000 |
commit | ddfb7b0caefdd1be212db31bde24b8a9feb225de (patch) | |
tree | 5c350c81ea1a9fb2985bb62195c06ff50a7a5174 /plugins/infra/ui | |
parent | f68c766e5c5df1bb5c08fd65bc6f5464d3a58208 (diff) | |
download | org.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.tar.gz org.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.tar.xz org.eclipse.papyrus-ddfb7b0caefdd1be212db31bde24b8a9feb225de.zip |
Bug 496299: Controlled Units as Integral Fragments
https://bugs.eclipse.org/bugs/show_bug.cgi?id=496299
Implement a new mode of controlled unit in Papyrus dubbed "shards".
A shard is like any other sub-unit created up to and including the
Neon release, except that it cannot be opened independently in the
editor. The Papyrus editor, when asked to open a "shard", will
instead open the root resource of the model. Likewise, the editor
matcher normalizes editor inputs to the root resource of any shard.
The graph of shard dependencies is inferred from a new workspace-
wide index of cross-resource containment references, when it is
available. Otherwise, the linkage of shards to their parent
references is parsed on-the-fly from the shard annotation's
reference (with a relatively efficient XML parsing that terminates
after reading only a few lines of the XMI text).
A new ResourceLocator is implemented to provide a pluggable hook for
resource loading (including proxy resolution), to ensure when loading
a shard resource that its parent resource chain is first loaded from
the top down to ensure that all context of profile applications is
available before loading the shard, itself, which may have stereotype
applications that depend on those profile applications. The
CoreMultiDiagramEditor installs this resource locator on the ModelSet;
other applications (including in a non-Eclipse context) can make
similar use of it.
Some additional fixes are required in other core components to make
the loading of referenced sharded models as in bug 458837 work:
* the SemanticUMLContentProvider did not detect the final resolution
of containment proxies that changes what looks look a model root
object into just another intermediate element in the content tree.
Besides that it would schedule a large number of redundant
UI refreshes asynchronously (deferred) on the UI thread
* the DiModel and NotationModel would load their adjuncts to the *.uml
resource when that resource is created, not after it has been loaded.
This is much too early and ends up causing the transactional editing
domain to detect the attachment of a resource's contents at the end
of loading as an attempt to edit the model during a read-only
transaction, which logs an exception and bombs the UI action.
Instead, these models now have snippets that load the *.di and
*.notation resources after the semantic resource has been loaded.
* the new model snippets required an additional fix in the loading
of IModels to handle contributions of snippets and dependencies to
models that are overridden by other IModels registered under the
same ID, such as is the case with the NotationModel and the
CSSNotationModel, which latter needs the snippet declared by the
former
* the IModels additionally need to ensure that they start snippets
on loading of an existing model even when it is already found to
be loaded in the ModelSet (as happens often in JUnit tests)
* the AbstractModelFixture in the JUnit test framework is updated to
ensure that the ModelSet is properly initialized, with its own
snippets started and its IModels loaded and their snippets started
* the basic uncontrol command now removes the shard annotation from
the uncontrolled element/resource, if there was one. Because this
bundle now supports a new feature (that being shards), it seems
appropriate to bump its minor version number
General-purpose changes in the core workspace model index framework
that improve overall performance, of particular significance in large
and highly fragmented models:
Implement persistent storage of the workspace model index at workspace
save to support quick start-up without parsing the entire workspace.
Consolidation of indices:
* run a single pool of indexing jobs and a single resource change
listener to trigger (re)-indexing of files
* all indices matching any given file process it
* includes a new extension point from which all indices are loaded
into the shared index manager to initialize them and do the work
(cherry-picked from streams/2.0-maintenance)
Change-Id: Ifd65a71c57134b69d873f17139f3cedbf11c5ba5
Diffstat (limited to 'plugins/infra/ui')
4 files changed, 93 insertions, 25 deletions
diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF index 405a6b4eafb..d3f993e710c 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/META-INF/MANIFEST.MF @@ -32,10 +32,11 @@ Require-Bundle: org.eclipse.papyrus.infra.core;bundle-version="[2.0.0,3.0.0)";vi org.eclipse.emf.edit.ui;bundle-version="[2.12.0,3.0.0)", org.eclipse.papyrus.infra.widgets;bundle-version="[2.0.0,3.0.0)";visibility:=reexport, org.eclipse.ui.views;bundle-version="[3.8.0,4.0.0)";visibility:=reexport, - org.eclipse.papyrus.infra.emf;bundle-version="[2.0.0,3.0.0)", - org.eclipse.papyrus.infra.widgets.toolbox;bundle-version="[1.2.0,2.0.0)" + org.eclipse.papyrus.infra.emf;bundle-version="[2.0.1,3.0.0)", + org.eclipse.papyrus.infra.widgets.toolbox;bundle-version="[1.2.0,2.0.0)", + org.eclipse.papyrus.infra.tools;bundle-version="[2.0.1,3.0.0)" Bundle-Vendor: %providerName -Bundle-Version: 1.2.0.qualifier +Bundle-Version: 1.4.0.qualifier Eclipse-BuddyPolicy: dependent Bundle-ManifestVersion: 2 Bundle-Activator: org.eclipse.papyrus.infra.ui.Activator diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml index f6a01ae6b41..a4c1a625ebe 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/pom.xml @@ -7,7 +7,7 @@ <version>0.0.1-SNAPSHOT</version> </parent> <artifactId>org.eclipse.papyrus.infra.ui</artifactId> - <version>1.2.0-SNAPSHOT</version> + <version>1.4.0-SNAPSHOT</version> <packaging>eclipse-plugin</packaging> <description>Plugin dedicated to manage generic menus and actions, linked to EMF but not to UML nor GMF technologies.</description> </project> diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java index b6a33a1dca9..6c6d7b1f228 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/editor/CoreMultiDiagramEditor.java @@ -12,7 +12,7 @@ * Christian W. Damus (CEA) - bug 410346 * Christian W. Damus (CEA) - bug 431953 (pre-requisite refactoring of ModelSet service start-up) * Christian W. Damus (CEA) - bug 437217 - * Christian W. Damus - bugs 469464, 469188, 485220 + * Christian W. Damus - bugs 469464, 469188, 485220, 496299 * *****************************************************************************/ @@ -36,7 +36,6 @@ import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.SubMonitor; import org.eclipse.emf.common.notify.AdapterFactory; -import org.eclipse.emf.common.ui.URIEditorInput; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; @@ -71,6 +70,8 @@ import org.eclipse.papyrus.infra.core.services.ServiceMultiException; import org.eclipse.papyrus.infra.core.services.ServiceStartKind; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.core.utils.ServiceUtils; +import org.eclipse.papyrus.infra.emf.resource.ICrossReferenceIndex; +import org.eclipse.papyrus.infra.emf.resource.ShardResourceLocator; import org.eclipse.papyrus.infra.ui.Activator; import org.eclipse.papyrus.infra.ui.contentoutline.ContentOutlineRegistry; import org.eclipse.papyrus.infra.ui.editor.IReloadableEditor.DirtyPolicy; @@ -84,14 +85,13 @@ import org.eclipse.papyrus.infra.ui.multidiagram.actionbarcontributor.CoreCompos import org.eclipse.papyrus.infra.ui.services.EditorLifecycleManager; import org.eclipse.papyrus.infra.ui.services.internal.EditorLifecycleManagerImpl; import org.eclipse.papyrus.infra.ui.services.internal.InternalEditorLifecycleManager; +import org.eclipse.papyrus.infra.ui.util.EditorUtils; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorActionBarContributor; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorSite; -import org.eclipse.ui.IFileEditorInput; -import org.eclipse.ui.IURIEditorInput; import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchActionConstants; @@ -149,7 +149,7 @@ public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implemen */ protected ISaveAndDirtyService saveAndDirtyService; - private final List<IPropertySheetPage> propertiesPages = new LinkedList<IPropertySheetPage>(); + private final List<IPropertySheetPage> propertiesPages = new LinkedList<>(); private final List<Runnable> closeActions = new ArrayList<>(); @@ -253,12 +253,12 @@ public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implemen /** * Editor reload listeners. */ - private CopyOnWriteArrayList<IEditorReloadListener> reloadListeners = new CopyOnWriteArrayList<IEditorReloadListener>(); + private CopyOnWriteArrayList<IEditorReloadListener> reloadListeners = new CopyOnWriteArrayList<>(); /** * A pending reload operation (awaiting next activation of the editor). */ - private final AtomicReference<DeferredReload> pendingReload = new AtomicReference<DeferredReload>(); + private final AtomicReference<DeferredReload> pendingReload = new AtomicReference<>(); public CoreMultiDiagramEditor() { super(); @@ -586,30 +586,37 @@ public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implemen servicesRegistry.add(EditorLifecycleManager.class, 1, lifecycleManager, ServiceStartKind.LAZY); // Start servicesRegistry - URI uri; - IEditorInput input = getEditorInput(); - if (input instanceof IFileEditorInput) { - uri = URI.createPlatformResourceURI(((IFileEditorInput) input).getFile().getFullPath().toString(), true); - } else if (input instanceof URIEditorInput) { - uri = ((URIEditorInput) input).getURI(); - } else { - uri = URI.createURI(((IURIEditorInput) input).getURI().toString()); - } + URI uri = EditorUtils.getResourceURI(getEditorInput()); try { // Start the ModelSet first, and load if from the specified File. // Also start me so that I may be retrieved from the registry by other services - List<Class<?>> servicesToStart = new ArrayList<Class<?>>(1); + List<Class<?>> servicesToStart = new ArrayList<>(1); servicesToStart.add(ModelSet.class); servicesToStart.add(IMultiDiagramEditor.class); servicesRegistry.startServicesByClassKeys(servicesToStart); resourceSet = servicesRegistry.getService(ModelSet.class); + + // Install shard resource handling + new ShardResourceLocator(resourceSet); + + // Resolve a possible shard URI + uri = EditorUtils.resolveShardRoot( + ICrossReferenceIndex.getInstance(resourceSet), uri); + + // Load it up resourceSet.loadModels(uri); // start remaining services servicesRegistry.startRegistry(); + + // In case of a shard + String name = uri.lastSegment(); + if (!name.equals(getPartName())) { + setPartName(name); + } } catch (ModelMultiException e) { try { // with the ModelMultiException it is still possible to open the @@ -625,7 +632,6 @@ public class CoreMultiDiagramEditor extends AbstractMultiPageSashEditor implemen // throw new PartInitException("could not initialize services", e); } - // Get required services try { diff --git a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java index e476a005dd1..acc7299b2e1 100644 --- a/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java +++ b/plugins/infra/ui/org.eclipse.papyrus.infra.ui/src/org/eclipse/papyrus/infra/ui/util/EditorUtils.java @@ -1,5 +1,5 @@ /***************************************************************************** - * Copyright (c) 2008, 2013 CEA LIST and others. + * Copyright (c) 2008, 2016 CEA LIST, Christian W. Damus, and others. * * * All rights reserved. This program and the accompanying materials @@ -12,14 +12,17 @@ * <a href="mailto:thomas.szadel@atosorigin.com">Thomas Szadel</a>: Code simplification and NPE * management. * Christian W. Damus (CEA LIST) - API for determining URI of a resource in an editor + * Christian W. Damus - bug 496299 * *****************************************************************************/ package org.eclipse.papyrus.infra.ui.util; import java.util.ArrayList; import java.util.List; +import java.util.Set; import org.eclipse.core.resources.IFile; +import org.eclipse.core.runtime.CoreException; import org.eclipse.emf.common.ui.URIEditorInput; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.Resource; @@ -35,6 +38,8 @@ import org.eclipse.papyrus.infra.core.services.ServiceException; import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException; import org.eclipse.papyrus.infra.core.services.ServicesRegistry; import org.eclipse.papyrus.infra.core.utils.DiResourceSet; +import org.eclipse.papyrus.infra.emf.resource.ICrossReferenceIndex; +import org.eclipse.papyrus.infra.emf.resource.ShardResourceHelper; import org.eclipse.papyrus.infra.ui.Activator; import org.eclipse.papyrus.infra.ui.editor.CoreMultiDiagramEditor; import org.eclipse.papyrus.infra.ui.editor.IMultiDiagramEditor; @@ -48,6 +53,10 @@ import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; +import com.google.common.collect.Iterables; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + /** * Set of utility methods for the CoreEditor. <br> * WARNING : Some of these methods rely on @@ -81,7 +90,7 @@ public class EditorUtils { if (page == null) { return null; } - List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>(); + List<IMultiDiagramEditor> list = new ArrayList<>(); for (IEditorReference editorRef : page.getEditorReferences()) { IEditorPart editorPart = editorRef.getEditor(false); if (editorPart instanceof IMultiDiagramEditor) { @@ -109,7 +118,7 @@ public class EditorUtils { if (openedEditors == null) { return new IMultiDiagramEditor[0]; } - List<IMultiDiagramEditor> list = new ArrayList<IMultiDiagramEditor>(openedEditors.length); + List<IMultiDiagramEditor> list = new ArrayList<>(openedEditors.length); for (IMultiDiagramEditor editorPart : openedEditors) { if (editorPart.getEditorInput() instanceof IFileEditorInput && diFile.equals(((IFileEditorInput) editorPart.getEditorInput()).getFile())) { @@ -719,4 +728,56 @@ public class EditorUtils { return result; } + + /** + * Resolves the root resource URI from the URI of a resource that may be a + * shard or may be an independent model unit. + * + * @param index + * the shard index to consult + * @param resourceURI + * a resource URI + * + * @return the root, which may just be the input resource URI if it is a root + * + * @see ShardResourceHelper + * @see ICrossReferenceIndex#getRoots(URI) + * @since 1.3 + */ + public static URI resolveShardRoot(ICrossReferenceIndex index, URI resourceURI) { + URI result; + + try { + Set<URI> roots = index.getRoots(resourceURI); + + // TODO: Handle case of multiple roots + result = Iterables.getFirst(roots, resourceURI); + } catch (CoreException e) { + Activator.log.log(e.getStatus()); + result = resourceURI; + } + + return result; + } + + /** + * Asynchronously resolves the root resource URI from the URI of a resource that + * may be a shard or may be an independent model unit. + * + * @param index + * the shard index to consult + * @param resourceURI + * a resource URI + * + * @return the root, which may just be the input resource URI if it is a root + * + * @see ShardResourceHelper + * @see ICrossReferenceIndex#getRootsAsync(URI) + * @since 1.3 + */ + public static ListenableFuture<URI> resolveShardRootAsync(ICrossReferenceIndex index, URI resourceURI) { + // TODO: Handle case of multiple roots + return Futures.transform(index.getRootsAsync(resourceURI), + (Set<URI> roots) -> Iterables.getFirst(roots, resourceURI)); + } } |