Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Papyrus/Neon Work Description/Improvements/Bundle Dependencies

< Papyrus‎ | Neon Work Description
Revision as of 18:57, 8 January 2016 by Give.a.damus.gmail.com (Talk | contribs) (Various internal API considerations)

Architectural Issues in Papyrus Bundle Dependencies — Infra Layer

This document captures the problems of bundle dependencies in the "infra layer" bundles of Papyrus.[1] In particular, the focus is on invalid dependencies:

  • dependencies on bundles in higher layers, causing layer dependency cycles in the aggregate
  • dependencies on non-Papyrus technologies associated with other layers (e.g., org.eclipse.uml2.uml which should be used only within the UML layer or org.eclipse.gef which should be used only within the GEF3 Diagrams layer
  • dependencies on UI in bundles that should be deployable in a headless environment

Illegal UI dependencies

In core bundles

  • org.eclipse.papyrus.infra.constraints
    • org.eclipse.ui — usage of IStructuredSelection is baked into the constraint API
    • org.eclipse.papyrus.infra.widgets — for ConstraintTypeContentProvider which doesn't belong in this bundle
  • org.eclipse.papyrus.infra.core
    • org.eclipse.ui.ide
    • org.eclipse.ui.views.properties.tabbed
    • org.eclipse.emf.edit.ui
    • org.eclipse.papyrus.infra.core.sasheditor.di
  • org.eclipse.papyrus.infra.emf
    • org.eclipse.ui
    • org.eclipse.emf.edit.ui
    • org.eclipse.papyrus.emf.facet.custom.ui
    • org.eclipse.papyrus.infra.services.labelprovider
  • org.eclipse.papyrus.infra.emf.readonly
    • org.eclipse.ui
    • org.eclipse.papyrus.infra.gmfdiag.commands
    • org.eclipse.papyrus.infra.tools — for access to a UI-thread executor
  • org.eclipse.papyrus.infra.extendedtypes.emf — this bundle should probably just be renamed as org.eclipse.papyrus.infra.extendedtypes.ui
    • org.eclipse.ui
    • org.eclipse.papyrus.views.properties
  • org.eclipse.papyrus.infra.constraints
    • org.eclipse.ui
    • org.eclipse.papyrus.infra.widgets
  • org.eclipse.papyrus.infra.elementtypesconfigurations
    • org.eclipse.ui
  • org.eclipse.papyrus.infra.elementtypesconfigurations.emf
    • org.eclipse.ui
    • org.eclipse.papyrus.views.properties
  • org.eclipse.papyrus.infra.elementtypesconfigurations.invarianttypes
    • org.eclipse.ui — used only for the AbstractUIPlugin class, which isn't necessary
  • org.eclipse.papyrus.infra.extendedtypes
    • org.eclipse.ui
    • org.eclipse.gmf.runtime.common.ui.services
  • org.eclipse.papyrus.infra.onefile
    • org.eclipse.ui
    • org.eclipse.ui.ide
    • org.eclipse.ui.navigator
    • org.eclipse.ui.navigator.resources
    • org.eclipse.ltk.ui.refactoring
  • org.eclipse.papyrus.infra.sync
    • org.eclipse.ui — only for the AbstractUIPlugin, which isn't necessary
  • org.eclipse.papyrus.infra.tools
    • org.eclipse.ui

There is also the case of the org.eclipse.papyrus.infra.widgets.toolbox plug-in, which presents a few different problems:

  • the name is very odd. This bundle is not a toolbox for building widgets. In fact, it is mostly a notification system like that provided by the Mylyn project, which is not in the least suggested by the bundle name
  • clients that wish to post notifications to the user may well need to do so from non-UI code, so the dependency on this UI bundle is problematic. There should be a generic notification API in the core (non-UI) layer for which this bundle provides the UI presentation (in the absence of which, perhaps, notifications go to stdout or log or some other destination)

In services bundles

  • org.eclipse.papyrus.infra.services.controlmode
    • org.eclipse.emf.edit.ui
    • org.eclipse.papyrus.infra.widgets.toolbox
    • especially because it defines a core API for control-mode invocation and participants, this bundle should be partitioned into separate core and UI components
  • org.eclipse.papyrus.infra.services.edit
    • org.eclipse.ui — only to provide a class implementing ISelectionStatusValidator
  • org.eclipse.papyrus.infra.services.markerlistener
    • org.eclipse.ui — marker changes often don't occur on the UI thread and reacting to them should not require the UI
    • org.eclipse.gmf.runtime.common.ui
    • org.eclipse.emf.edit.ui
  • org.eclipse.papyrus.infra.services.resourceloading
    • org.eclipse.ui.ide
    • org.eclipse.papyrus.infra.core.sasheditor.di
    • org.eclipse.papyrus.infra.widgets.toolbox - because there is no core notification API, only the API in this UI bundle
    • org.eclipse.gmf.runtime.diagram.common.ui
    • headless clients should be able to use the on-demand-loading ModelSet and take advantage of the smart resource unloading facilities
  • org.eclipse.papyrus.infra.services.validation
    • org.eclipse.ui — headless clients should be able to invoke validation
    • org.eclipse.emf.edit.ui
    • org.eclipse.papyrus.infra.widgets
    • org.eclipse.papyrus.infra.services.decoration
  • org.eclipse.papyrus.services.viewersearch
    • org.eclipse.ui - only for the AbstractUIPlugin class, which is not necessary

Illegal UML Dependencies

In core bundles

  • org.eclipse.papyrus.infra.elementtypesconfigurations.emf
    • org.eclipse.uml2.uml
    • org.eclipse.uml2.uml.edit
  • org.eclipse.papyrus.infra.extendedtypes.editor
    • org.eclipse.uml2.uml.edit — not needed because of delegation to adapter-factory registry
  • org.eclipse.papyrus.infra.newchild
    • org.eclipse.papyrus.uml.tools — for the SemanticUMLContentProvider

In services bundles

  • org.eclipse.papyrus.infra.services.resourceloading
    • org.eclipse.papyrus.uml.tools - for access to the semantic model via UmlModel

Illegal GMF/GEF Dependencies

In core bundles

Note that the GMF Run-time component's architecture has two distinct personalities: an extension of the EMF run-time's editing capabilities historically named the MSL ("Model Services Layer", references to which still may linger in the Javadocs and other comments in the code) and the GEF-based diagram editor implementation and related frameworks and services. This latter has the dependency on the GEF3 APIs specifically and is what should not be referenced by the Infra layer bundles (for the transitive GEF requirement). The EMF editing services (MSL) layer of the GMF Run-time is permitted in the Infra layer, especially for such components as the Element Types Registry.

  • org.eclipse.papyrus.infra.core
    • org.eclipse.gef
  • org.eclipse.papyrus.infra.core.sasheditor
    • org.eclipse.gef — the GEF editor delegate needs to be factored out into the diagrams layer
  • org.eclipse.papyrus.infra.emf
    • org.eclipse.gmf.runtime.notation
  • org.eclipse.papyrus.infra.emf.readonly
    • org.eclipse.papyrus.infra.gmfdiag.commands
  • org.eclipse.papyrus.infra.hyperlink
    • org.eclipse.gmf.runtime.notation
  • org.eclipse.papyrus.infra.newchild
    • org.eclipse.papyrus.infra.gmfdiag.commands

In services bundles

  • org.eclipse.papyrus.infra.services.resourceloading
    • org.eclipse.gef
    • org.eclipse.gmf.runtime.notation
    • org.eclipse.gmf.runtime.diagram.ui
    • org.eclipse.papyrus.infra.gmfdiag.common
  • org.eclipse.papyrus.infra.services.validation
    • org.eclipse.gmf.runtime.emf.commands.core — only so that the validation commands can be AbstractTransactionalCommands (a kind of GMF ICommand). There should be no need for them to be that; they can just be AbstractEMFOperations or not even commands at all (why do they need to be undoable?)

Other suspicious dependencies

In core bundles

  • org.eclipse.papyrus.infra.emf
    • org.eclipse.papyrus.emf.facet.custom.core
    • org.eclipse.gmf.runtime.common.core — seems odd in a bundled named "emf"
    • org.eclipse.gmf.runtime.emf.commands.core — likewise
    • org.eclipse.gmf.runtime.emf.type.core — likewise
  • org.eclipse.papyrus.infra.extendedtypes.emf
    • org.eclipse.papyrus.views.properties.model

In services bundles

  • org.eclipse.papyrus.infra.services.resourceloading.preferences
    • should be renamed as org.eclipse.papyrus.infra.services.resourceloading.ui because the preference page is only one small part of the UI. Other UI-dependent APIs would be moved into this bundle

Evolution Strategies

Dependencies on UI

This is the simplest case. Simply divide the bundle into two, a "core" bundle and a "ui" bundle. In many cases, this would simply amount to creating a new bundle for the UI bits, leaving the core bits in the current bundle, on the assumption that this has the least impact on clients (UI content often being not intended as API, but merely contributions of menu actions etc. to the platform UI).

Note that, where UI classes and non-UI classes reside in the same package, moving the UI classes into a new bundle implies changing their package name. We should not employ the discouraged OSGi capability of splitting packages.

A common problem in Papyrus APIs that should be "core" (headless) is the need to post asynchronous execution of tasks to defer reactions to changes in the UI (in the case that there is a UI and that updates do need to be deferred). For this purpose, a root Papyrus plug-in (org.eclipse.papyrus.core or probably org.eclipse.papyrus.tools) should define an API for obtaining a shared executor that posts tasks on the UI thread, and the org.eclipse.papyrus.ui bundle should provide that executor (via an OSGi service is probably the best mechanism).

Dependencies on UML

A common dependency on the Papyrus UML Layer is for access to the semantic model, either as the simple root model element (via UmlModel) or for presentation of a tree of model content (SemanticUMLContentProvider). Both of these ought to be available in a generic fashion via some service that can provide:

  • what is/are the root(s) of the EMF-based semantic model content
  • a SemanticEMFContentProvider best suited to presenting the semantic model content

The ILanguageService API should be expanded to provide these facilities. In particular,

  • an ILanguage can provide the IModel that matches its semantic content. If that IModel is an IEMFModel that, with a new API, can provide its model roots as EObjects, then clients can use that to get the model roots
  • an IModel can be adapted to a new factory interface for ITreeContentProviders that can accept the ModelSet as input (hence making this a responsibility of the IModel). When such a content provider is a SemanticEMFContentProvider, it can be used to populate the various Papyrus tree viewers accordingly. Adaptation would be required to plug in the factory from a UI bundle
  • the SemanticService in the org.eclipse.papyrus.infra.services.semantic bundle could be expanded to synthesize these new capabilities (it already provides all contents of all resources as the "semantic" model, which often is not what clients really need)

Other Considerations

Deprecated APIs

This is an opportunity, with the version 2.0, to remove some deprecated APIs from certain core components. In particular,

  • IFile and other workspace resource assumptions in deprecated APIs in the IModel and ModelSet. Very few bundles should have any dependency on org.eclipse.core.resources
  • the IReadOnlyHandler interface and related deprecated APIs in the read-only framework

Internal APIs

Most packages in the Papyrus bundles are exported as public API (not internal), although the intent probably was not to publish them as frozen stable API.

to be completed

Bundle Activators

This is a special case of the internal API problem discussed above, but with particular insidious twists:

  • almost all Papyrus plug-ins export their activator classes as public API
  • almost all of these have the same name, Activator
  • a lot of code references the bundle activator to use the LogHelper for logging exceptions and other problems
  • consequently, whenever a compilation unit is refactored from one bundle to another, it often happens that it can still see the activator that it used formerly and so it continues to do so without the user noticing. A relatively benign result is that the user's log messages are a bit confusing because they are tagged with the wrong bundle ID. More serious problems arise when extension points move and the utilities that read them, being initialized with a bundle namespace via Activator.PLUGIN_ID, now use the wrong namespace and no longer find any extensions

Recommendations:

  • all bundle activators should be moved to an internal package. Possibly even one that isn't even exported at all, so that it cannot be used as API by other bundles, although the restriction warning really ought to be sufficient to alert developers when refactorings go awry
  • APIs that load contributions from an extension point should never be initialized by clients with the namespace in which the extension point is defined. The extension point API should know that for itself and internalize it. For example:
    • the ExtensionServicesRegistry should be hard-coded to use the org.eclipse.papyrus.infra.core namespace
    • the CreationCommandRegistry should be hard-coded to use the org.eclipse.papyrus.infra.ui namespace
    • etc.

Traceability

Bugzilla

This effort is tracked in bugzilla under bug 485220.

Gerrit

Several Gerrit reviews propose changes to implement the dependency refactorings:

  • Change 63777 illustrates the impact of removing UI-dependent APIs from the org.eclipse.papyrus.infra.tools bundle to org.eclipse.papyrus.infra.ui

Footnotes

  1. Excluding the infra.gmfdiag, infra.nattable, and infra.viewpoints layers, which are not actually core-infrastructural. They should simply be named diagram, nattable, and viewpoints, respectively.

Back to the top