In this page we will show the Papyrus capabilities to create and reintegrate submodels, also known as control mode.
As a model grows large in number of elements, it is convenient to split them into different physical resources i.e. files. Papyrus provides a feature to perform this splitting in a seamless fashion, allowing to move parts of the model to another resource. We call this create a submodel. This is specially helpful working in collaborative environments, since the Team features can be applied individually to the different resources i.e. make changes and commit them in only one part of the model.
To create a submodel:
Important: The selected element has not been moved just yet. The model editor will be dirty i.e. there will be an asterisk next to its name in the tab. In order to complete the submodel creation, you need to save your model.
The new resource is created in the chosen location with the chosen file name, whilst a green decorator is shown in the Model Explorer view of the parent model to indicate this element is in a submodel.
Note that, for a package, the dialog shows an option to have it be openable and editable in its own editor, independently of the package containing it (and the one containing that, etc.). This can be convenient, but it does mean that the package has to redundantly apply all of the profile applications applied to the packages containing it, so that stereotypes can properly be manipulated in the editor. This can result in inconsistencies if a profile definition changes over time and not all applications in all packages are kept up-to-date consistently with stereotype migrations. This option is available only for packages, because only they can have profile applications. For other kinds of elements, this option is disabled and the resources created for them will always open in the context of the containing model.
When this option is not selected, then the resulting submodel cannot be opened separately. Attempting to open it, usually by double-clicking it in the Project Explorer, will instead open the top-most independent submodel (or the root model package). Or, if that is already open, just activate its editor. This ensures that the nesting package context, and especially its profile applications, is always available to properly manage stereotypes.
Once a package has been stored in a submodel resource, the support for editing it independently can be added and removed at any time:
Important: These changes will only take permanent effect on the next save action. Until then, the resource on disk is not changed and so what happens when it is opened in an editor will not change.
In the Project Explorer view, the submodel resource is indicated by a filled blue note-paper decoration or a hollow blue decoration in the case that it is not an independently openable submodel.
To reintegrate a submodel into the main model:
The submodel is reintegrated into the main model resource.
Important: The submodel resources will be deleted only on save action.
This enhancement introduces a new variant of the controlled unit dubbed a 'shard' (as being a fragment of broken ceramic or glass that is a constituent of the whole on not generally handled). Thus Papyrus supports two modes of controlled unit:
*.emx
resource in the workspace, activates the context menu, and selects 'Import RSA Model/Profile'.*.emx
resource along with all of its *.efx
fragments. These latter are imported as 'shards'.*.di
resource that was imported from an *.efx
in the RSA model.The topology of sub-model units is implied by cross-resource containment in EMF: that is, containment references that have proxies for lazily resolved objects from other resources. As one of the benefits of the classic Papyrus sub-model unit is that it is independently openable and editable, it does not add a reference to its parent unit in an annotation as is done in RSA's fragments, because that would trigger loading of the parent unit chain by proxy resolution. Accordingly, in order to discover the connected graph of sub-unit resources at run-time, some agent is required that can provide independent off-line knowledge of it. This is naturally implemented on the WorkspaceModelIndex
framework.
A new ICrossReferenceIndex
API in the org.eclipse.papyrus.infra.emf
bundle provides for queries (asynchronous and synchronous, as usual) about:
Unlike sub-model units, shards additionally have annotations that reference the containing object in the parent resource, not unlike fragments in RSA. This is not a problem because they are not intended to be loaded independently of their parent units, anyways, but also has the benefit of enabling a tracing of the parent unit chain in cases where the full off-line index is not available:
The point of shard resources is that they cannot be loaded without the chain of parent resources storing their containing objects, so that in the case of UML resources, packages find all of the profile applications in their nesting packages to ensure that stereotype applications are properly resolved.
This loading of the parent unit chain, from the root unit(s) down, is ensured in two different ways, depending on the circumstances:
PapyrusMatchingStrategy
matches editor-inputs for shards with editor-inputs for their root unitsResourceSet
will demand-load the referenced resource. If this happens to be a shard, it needs to load it from the top unit down (this is the essence of
bug 458837 in which stereotype applications were lost by demand-loaded packages not knowing their profile applications). This is accomplished by a ShardResourceLocator
installed on the resource set. This API supports non-Eclipse applications via the on-demand cross-reference index discussed above.
Because now another index is introduced (Papyrus has had an index of external profile applications since the Mars release), it is prudent to do some refactoring to ensure as much as possible that performance doesn't suffer from the added burden.
Rather than have every index create background jobs for itself that react to resource changes and scan projects in the workspace, now a new IndexManager
provides a single point of control for these processes:
This improves throughput of the indexing process by eliminating multiple passes over resource deltas and resource trees in the workspace projects, but it does mean that asynchronous queries on any index will only be ready when all indices complete their processing of any deltas.
Because even the simplest use case of opening a model now depends on this new workspace-wide index, it is important to initialize that index as efficiently as possible. To that end, the WorkspaceModelIndex
framework now supports an extension of the IndexHandler
protocol which is a PersistentIndexHandler
. This protocol
Serializable
, so that it can be persisted when the workspace shuts downThe new CrossReferenceIndex
supports persistence and the older DecoratorModelIndex
is retrofitted for persistence, also.
As a consequence of both of the enhancements described above, consolidation of control and initialization from a persistent store, it is necessary for the IndexManager
to discover all available index instances when it starts up. This is accomplished by a new extension point org.eclipse.papyrus.infra.emf.index
on which IWorkspaceModelIndexProvider
s are registered that supply unique concrete WorkspaceModelIndex
instances. It is not required but probably advisable that all such instances be long-lived singletons.
As far as the manipulation of sub-units is concerned, they are still created in the same way as in the Neon release. The difference is that, after a model element is stored in its sub-unit resource, it needs to be tagged as a 'shard'. This is accomplished by the ShardResourceHelper
API. A helper is initialized with the model element that is the root of the shard sub-tree. It can add or remove the shard annotation directly or by providing Command
s for execution on the stack and can query the current shard-ness of the sub-unit. As long as the helper is in use, it maintains Adapter
s to track any changes to the object's containment and/or shard annotation. For this reason, it must be closed when no longer needed, to prevent memory leaks.
This enhancement introduces UI for manipulation of the 'shard' style of sub-unit resource, including:
A new protocol specializing the IControlModeParticipant
is introduced that participants may optionally implement to influence the UI workflows. The IControlCommandApprover
interface specifies two operations:
boolean canCreateSubModel(EObject)
: queries whether a model element that is to be made into a sub-unit can support independent opening and editing. The UML participant implements this to deny sub-model units for non-packages: they can only be created as shards. Thus, the warning dialog about limited support for non-package sub-units is no longer shownDiagnostic approveRequest(ControlModeRequest)
: gives participants an opportunity to veto a control or uncontrol request, with a message that is displayed to the userSo, the former of these APIs is used by the ControlModeManager
to determine the enablement of the check-box option for sub-models in the 'control resource' dialog and in the context menu (although, of course, in the latter case the action is enabled if a non-package element is controlled as a sub-model in order that it may be converted to a shard).
The latter API is used by the UI control/uncontrol command handlers to validate a request before attempting to survey the participants for commands and execute them.
The 'shard' structure is compatible with the Neon and Mars releases. It adds only an annotation that those versions of the software simply ignore. The back-reference to the parent unit will usually cause the parent units (and recursively up to the roots) to be loaded, which may help to emulate the Neon.1 and later behaviour. However, because a Neon.1 shard will not have redundant profile applications (a model imported from RSA in Mars or Neon would not have them, either) then there may be problems in handling of stereotype applications and potential data loss. If these resources must be edited with Mars or Neon versions of Papyrus, then it is recommended either always to open them at the root unit explicitly or even to opt for the classic sub-model unit structure (except for non-packages, which effectively always were defective shards anyways).