Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
Papyrus/Neon Work Description/Improvements/Canonical Edit Policy
Dropless Canonical Edit Policy
This document describes the design of an enhancement in the Neon release in which the synchronization of canonical diagram views with the model no longer relies on the drag-and-drop infrastructure.
Contents
Contents
Requirements
In the Mars release, a new PapyrusCanonicalEditPolicy
was introduced that replaces
GMF's standard canonical edit policy (the EditPolicyRoles.CANONICAL_ROLE
). The key
design point of this policy was its delegation to the diagram's specific drag-and-drop policy
to create views of existing elements. As indicated by
bug 477384, this does have the side-effect
of limiting the customizability of drag-and-drop in the diagrams. In particular, the canonical
synchronization implemented by the CanonicalEditPolicy
expects the drop edit policy
to do nothing (or very little) more than create a view of an existing element. This restricts
the amount of intelligent dropping of elements to create related new elements in various scenarios,
without also going to lengths to constrain what kinds of elements the canonical edit policy will
attempt to visualize.
Accordingly, the primary requirements for the Neon implementation of the canonical edit policy are:
- R1: the
PapyrusCanonicalEditPolicy
WON'T depend on the diagram's drag-and-drop edit policy to create new views of model elements - R2: the
PapyrusCanonicalEditPolicy
SHALL simply useCreateRequest
s to create new views for elements as directly as possible, according to the specific visual element types of each diagram- R2.1: the diagrams SHOULD publish information about their specific visual element types in some reusable form that other components (such as drag-and-drop, itself) may likewise rely on
Design
The core issue addressed by the Mars design was that a generic edit policy such as the
PapyrusCanonicalEditPolicy
had no means to determine the specific visual element types
(in particular, visual IDs) of the views that it needed to create for semantic elements in
any given diagram. These specific element types are required to formulate the
CreateRequest
s that ultimately are satisfied by the diagram's particular
ViewProvider
. The solution in the Mars release was to delegate to the diagram's
generated DragDropEditPolicy
by transforming CreateRequest
to
DropObjectsRequest
s (encapsulated in a wrapper to pass them through the customizable
drop policy with its pluggable strategies, but that's a minor detail). This worked because
each diagram actually substitutes a custom drop edit policy implementation that is specifically
coded to be aware of the mapping of semantic element types to visual element types in each
parent view that can visualize each semantic element within the context of the particular diagram.
Accordingly, the new design for Neon hoists this knowledge of the diagram's specific visual element
types out of the drop edit policy and into a new GMF-style service that the generic
PapyrusCanonicalEditPolicy
can query to determine the visual element types that it
should request.
The PapyrusCanonicalEditPolicy
uses a new VisualTypeService
to query the
following diagram-specific information that it needs to formulate CreateRequest
s to
create new views for the semantic elements that it needs to visualize:
- the most appropriate view type (visual ID in generated diagrams, but generally some string type code) for an element to be visualized as a child
Node
of some parentView
(which could be the diagram surface or some shape or compartment) - the most appropriate view type (visual ID or string) for an element to be visualized as an
Edge
in theDiagram
- the element type corresponding to a view type (visual ID or string, as obtained from one of the two previous queries) specific to a particular
Diagram
Thus the dependence on the diagram-specific drop edit policies is removed, as the canonical edit
policy now has independent access to the visual type information that it needs, specific to each
diagram. The generic CommonDiagramDragDropEditPolicy
is also updated to use the new
VisualTypeService
to implement the previously abstract API methods that the diagrams'
custom subclasses implemented to provide this same visual type information. As a result, diagrams
that don't need special drop behaviour but only need drag-and-drop to create new views can be
somewhat simplified.
Code Generation
A new code generation template is added in the org.eclipse.papyrus.def
bundle that
generates the diagram's contribution of a concrete implementation of the
IVisualTypeProvider
. The implementations of the provider API methods simply delegate
to static APIs that are also generated for each diagram:
-
getNodeType
andgetLinkType
methods delegate to the corresponding APIs of the generated visual ID registry (usually namedUMLVisualIDRegistry
) -
getElementType
delegates to the generated element-types enumeration (usually namedUMLElementTypes
Because the APIs that the visual type provider delegates to are static, there is no way in the
existing GMF/Papyrus frameworks to plug them into the core diagram layer without an intermediate
object like the visual type provider. The generated UMLElementTypes
classes do all
include a TYPED_INSTANCE
field implementing a DiagramElementTypes
interface,
but this, too, is a static API, so it has to be injected by code into any class that needs it. There
is no facility for injecting these into a core component like the
PapyrusCanonicalEditPolicy
. Besides that the DiagramElementTypes
API
doesn't provide all that is needed in this scenario. So, the alternatives are to create a new
template for generation of subclasses of the PapyrusCanonicalEditPolicy
in each diagram
(which would obviate the need for the VisualTypeService
) or create a new template for
generation of visual type providers. The latter seems a cleaner design, separating out the concern
of diagram-specific visual ID discovery into a reusable component that may be of service to other
clients than just the PapyrusCanonicalEditPolicy
(such as, in fact, the
CommonDiagramDragDropEditPolicy
).
Because there is now a new generated visual type provider class, the GMFGen model for a diagram
needs to be able to specify the name of the generated class, if necessary, and also a custom subclass
for overrides of the generated default behaviour. This is a common pattern, especially in the
edit-parts and edit-policies models. These use cases are satisfied by the addition of the
GenVisualTypeProvider
class in Papyrus's GMFGen extension model on the one hand and
by registration of a higher-priority custom provider on the other (as is done for
edit-part providers, for example).
The GenVisualTypeProvider
optionally specifies a provider class name; the default value
is "UMLVisualTypeProvider"
. Static methods are defined that obtain, respectively, the
simple and the qualified name of the visual type provider class for a diagram. This accounts for
the absence of a GenVisualTypeProvider
element in the GMFGen model (it is an optional
extension element) to provide the defaults even in that case. Thus, none of the existing UML
diagrams' GMFGen models need changes to generate the new provider class.
Deprecations
ICreationTargetStrategy
The custom drop edit policies of some of the diagrams are rather particular about what an element
needs to be dropped on in order to add it to the diagram. For example, some connections cannot just
be dropped anywhere in the diagram but only on a particular shape (perhaps one of its ends). In
the State Machine Diagram, a region that is not the first region visualized in a composite state must
be dropped onto some other region in order to partition the space that it occupies in two. To
account for these cases, the Mars design included pluggable ICreationTargetStrategy
extensions. These allowed the diagrams to re-direct the drop operation from the obvious target
(the edit-part of the parent element) to some other edit-part. This mechanism is now no longer
necessary, because the PapyrusCanonicalEditPolicy
knows a priori which parent view
must contain the node that it is trying to create, and the diagrams' view providers know how to
create the child views (note that edges are a simpler case because they are all owned by the root
diagram view).
Accordingly, the ICreationTargetStrategy
API is deprecated in Neon and all
implementations in the UML diagrams are deleted (the framework still delegates to these strategies
if they happen to exist). The special case of regions in a diagram might have needed this target
strategy but it is easily handled in the custom creation strategies for state machine compartment
and state compartment using GEF's own getTargetEditPart(Request)
protocol, for the
case of the CreateRequest
.
CanonicalDropObjectsRequest
The Mars design delegated to the diagrams' generated drop edit policies. This required a mechanism
to sidestep the CustomizableDropEditPolicy
installed by the core Papyrus diagram layer
to override the diagrams' generated policies, because it would not be desirable to let pluggable
drop strategies interfere with the straightforward drop behaviour needed for view synchronization.
The solution was similar to protocol encapsulation in networking: wrap the
DropObjectsRequest
in a CanonicalDropObjectsRequest
which the
CustomizableDropEditPolicy
recognized. On receiving the wrapper, the customizable
policy would simply unwrap the DropObjectsRequest
within it and forward that to the
default drop policy provided by the diagram.
None of this encapsulation is needed in Neon, so the CanonicalDropObjectsRequest
class
is deprecated and the CustomizableDropEditPolicy
no longer recognizes it.
Limitations
All of the UML diagrams are regenerated in Neon to plug in their visual type providers. However, the SysML 1.1 diagrams in the main Papyrus repository cannot be generated (they do not use GMFGen models) and, more importantly, they do not use visual ID registries as the UML diagrams do. They prefer the use of non-integer view types, using integer visual IDs only for elements inherited from the UML diagrams that they extend. So, a different pattern of delegation to existing SysML-specific view-type registries and the inherited UML visual type providers is devised in the SysML diagrams to implement their specific visual type providers.