| =Papyrus-Sirius Developer Guides= |
| Basically, the developement rules are the same than for Papyrus. |
| ==Java Code Style== |
| The recommendation are almost the same than for Papyrus. We reuse its Code Style configurations for '''Clean Up''' and '''Formatter'''. |
| Concerning the '''Code Templates''', we did these changes: |
| * Comment > Files : we register the Papyrus default file header |
| * Comment > Types : we removed the @{user} |
| * Comment > Modules : we removed the @{user} |
| * Code > Constructor, we removed the todo |
| |
| These 3 templates files are stored into the git org.eclipse.papyrus-sirius, into the folder '''releng-sirius/templates'''. |
| |
| ==Plug-in Preferences== |
| We provide pre-configured preferences files to copy in the .settings folder (it is a hidden folder by default) in each new plugin. There are 6 files to copy: |
| * org.eclipse.core.resources.prefs |
| * org.eclipse.core.runtime.prefs |
| * org.eclipse.jdt.core.prefs |
| * org.eclipse.jdt.ui.prefs |
| * org.eclipse.pde.api.tools.prefs |
| * org.eclipse.pde.prefs |
| These preferences files can be copied from '''releng-sirius/preferences''' into the '''.setting''' folder of your new plugin. |
| |
| ==Eclipse.ini== |
| Add your user name as vmargs argument like that in order to get a nice file header for the new creted file: |
| |
| |
| ''-vmargs'' |
| |
| ''-Duser.name=John Doe (Company) <john.doe@company.com>'' |
| |
| ==Manifest.ini== |
| Rules: |
| *we avoid to use '''Import Package''' |
| *each dependency is defined with a min and max values |
| *the dependencies are sorted by alphabetical order |
| |
| |
| = Architecture of Papyrus-Sirius = |
| This framework has been developed to be used only when a sirius diagram is opened. |
| |
| ==Git Architecture== |
| *'''plugins/editor''' |
| **'''org.eclipse.papyrus.sirius.editor''': plugin handling sirius diagram views and session management |
| **'''modelexplorer''':contains code allowing to display and use sirius diagram in the papyrus model explorer |
| **'''properties''': contains code to visualize the properties of sirius diagrams |
| **'''representation''': contains the code to create sirius diagram views |
| **'''representation.architecture''': contains the code to create specific sirius diagram |
| **'''representation.edit''': plugin defining sirius diagram prototype |
| **'''sirius''': plugin containing sirius services to handle session |
| |
| |
| *'''plugins/uml/''' |
| **'''org.eclipse.papyrus.sirius.uml''': contains Papyrus Architecture contributions for UML and Sirius: elementTypes and EMF-Facet customization for Sirius Diagram |
| **'''org.eclipse.papyrus.sirius.uml.diagram.architecture''': contains the UML Sirius diagram contributions for the Papyrus Architecture Framework |
| **'''org.eclipse.papyrus.sirius.uml.diagram.clazz''': contains class diagram description and services |
| **'''org.eclipse.papyrus.sirius.uml.diagram.common''': contains all the common services that can be used by all diagrams |
| **'''org.eclipse.papyrus.sirius.uml.diagram.sequence''': contains sequence diagram description and services |
| **'''org.eclipse.papyrus.sirius.uml.diagram.statemachine''': contains statemachine diagram description and services |
| **'''org.eclipse.papyrus.sirius.uml.diagram.textedit''': contains customization to use Papyrus XText grammar inside Papyrus Sirius Diagram |
| |
| = odesign file conception rules = |
| The Papyrus user is used to non-synchronized diagrams. Hence, while developing the Sirius Diagram, we must consider them as not synchronized by default. We advise you to set the Sirius synchronization preferences to false and to show the synchronization marker to always display the status (synchronized/unsynchronized) of the diagram. |
| |
| [[File:../../../image/dev/Sirius_Diagram_Synchonization_Preference.png]] |
| |
| To ease development and review, we decided to follow conception rules for odesign file: |
| *structure of the odesign: |
| **almost all elements are organized by alphabetical order (following the label displayed in the odesign editor) |
| |
| *''id'' field rules: |
| ** doesn't contents space |
| ** contains the name of the semantic element |
| ** tool for creation must be named following this pattern ''CreateXXXTool'' |
| ** tool for semantic drop must be named following this pattern ''SemanticXXXDrop'' |
| ** tool for graphical drop must be named following this pattern ''GraphicalXXXDrop'' |
| ** mapping representing a label node must be suffixed with ''LabelNode'' |
| ** mapping representing a compartment node must be named like this: ''parentMappingName'' + ''ElementNames''(plural form) + ''Compartment'', example: '''CD_ClassAttributesCompartment''' |
| |
| *''label expression'' field rule: |
| ** create an optional layer, applied by default, named '''AppliedStereotypeLayer''', |
| ** create an optional layer named '''QualifiedNameLayer''', |
| ** declares the Sirius Service '''org.eclipse.papyrus.sirius.uml.diagram.common.core.services.UMLLabelService''', |
| *** this service uses the previous layer to build a label with/without the applied stereotypes and the qualified name of the element |
| *** this service uses the internationalization feature provided by Papyrus |
| ***this service build complex label like : '<<keyword>> <appliedStereotype> labelOfTheElement', where 'labelOfTheElement' can also be a specific construction, like for UML Property: 'name: type [0..*]', |
| ** for nodes used inside a ''Compartment List'', we want a single line label, so we use the service method '''buildSingleLineLabel(Element element, DDiagram diagram)''', |
| ** for others figures, we want a multiline label, so we use '''buildMultilineLabel(Element element, DDiagram diagram)''', |
| **this service uses the internationalization feature provided by Papyrus |
| |
| *''icon'' rules: |
| **the path of the icon of semantic UML element must be something like '''/org.eclipse.uml2.uml.edit/icons/full/obj16/xxx.yyy''' each time it exists. We must avoid duplicate icons when it is not necessary. |
| |
| *''node'' rules: |
| ** Nodes must be defined as ''Unsynchronizable'', documented exceptions are allowed. |
| ** The field ''semantic candidates expression'' must be filled (avoiding eAllContents). |
| *** Typically for ClassDiagram, the expression returns all Constraints found in the Package (diagram background) and in its sub-elements to avoid that a Constraint disappears after creating a ContextLink (ContextLink changes the containments of the Constraint). |
| ** All nodes containing objects must have compartments, these compartments are synchronized when they represent the contents of a feature. |
| ** Each semantic element represented as a node must have its own mapping (we want to avoid reuse at this level,e.g. Interface and Class have their own mapping). |
| ** Nodes must be defined at root level (or in a fake container for validation purposes). We avoid defining nodes inside another nodes. We want to avoid to reuse a mapping defined inside another element. The fake containers be named like this : '''DIAGRAM_TRIGRAM + _SHARED_ + xxx'''. In ClassDiagram '''xxx''' represents the name of the owningFeature, ie '''CD_SHARED_OwnedAttribute'''. |
| |
| *''edge'' rules: |
| ** all edges must be declared ''Unsynchronizable'' (documented exceptions are allowed). |
| ** the field ''semantic candidates expression'' must be filled (avoiding eAllContents) and provides owned edges (and sometimes indirectly) by the element represented by the diagram background. |
| |
| *''palette'' rules: |
| ** the palette description is given by two folders, one for nodes, named '''Nodes''', one for edges, named '''Edges'''. |
| ** in these folders, the tools should be sorted alphabetically, but the organization also depends on the frequency of use of each element. |
| |
| *''reconnect'' rules: |
| **The reconnect tools are defined in a folder called ''Relationships''. |
| **The id of each tool follows this pattern: ''ReconnectXXXSource'' for the tool reconnecting the source of an XXX element, and ''ReconnectXXXTarget'' for a the tool reconnecting its target. |
| **The reconnect tool must also update the containment of the reconnected link when required. We decided that the owner of a link is given by its source (the source itself, or its nearest ''Package'' or an other element, depending of the containement feature of the link). |
| |
| *'drop' rules: |
| **There are 2 kinds of drop : the semantic drop (from the ModelExplorer) and the graphical drop (inside the diagram). |
| **The drop tools are defined inside 2 folders : the ''SemanticDrop'' folder and the ''GraphicalDrop'' folder. |
| **The id of each tool follows this patten : ''SemanticXXXDrop'' or ''GraphicalXXXDrop''. |
| **Only one semantic drop per semantic element is accepted, the tool can work on several mapping (in ClassDiagram, '''SemanticPrimitiveTypeDrop''', works with 2 mappings representing a '''PrimitiveType'''. |
| **Only one graphical drop per semantic element is accepted. |
| **The ''precondition'' rule must check the type of dropped element with self.oclIsTypeof(uml::XXX), to ensure that only one drop tool can be activated for the element. |
| |
| *''edition'' rules: |
| **The tools used for edition are described in the folder ''F2_Edition''. |
| **The id of these tools follows this pattern: ''metaclassName'' + ''_'' + ''editedFeature'' + ''_'' + ''EditionTool'', example : '''Comment_body_EditionTool''' and '''NamedElement_name_EditionTool'''. |
| |
| *''delete'' rules: |
| **delete actions are defined in the folder ''DeleteActions'' |
| **the odesign declares the java service '''org.eclipse.papyrus.sirius.uml.diagram.common.services.SemanticDeletionService#''' in charge of the semantic deletion |
| **each diagram must provide a Delete action using the previous service with the call '''element.deleteElement(elementView)''' |
| |
| *''validation'' rules: |
| **the *.odesign files must be valid (using EMF Validation) |
| |
| |
| *Sirius Services rules: |
| Developing the class diagram it appeared that it is often easier to call a java service instead of writing aql rules. As we created the same methods for each semantic element, we follow a common pattern for the naming of these methods. Each method must be prefixed by the managed metaclass (see '''org.eclipse.papyrus.sirius.uml.diagram.clazz.services.ClassDiagramServices'''). For the ''UML::Abstraction'' we have these methods: |
| **abstraction_getSemanticCandidates(EObject) |
| **abstraction_canReconnectSource(Element, Element) |
| **abstraction_canReconnectTarget(Element, Element) |
| **abstraction_reconnectSource(Element, Element, Element) |
| **abstraction_reconnectTarget(Element, Element, Element) |
| **association_getSemanticCandidates(EObject) |
| |
| NB: Currently these methods, for each UML Element, are in the ClassDiagramServices. In the future, we will probably create a java class for each semantic element, and the '''ClassDiagramServices''' will delegate to these classes. This point is still open for a discussion, because we are also thinking about a connection to the Papyrus Edition Service and it could be redundant. |
| |
| = Sirius viewpoint = |
| |
| Each new diagram contribution is added in a new plugin, which contains the description of the mapping, the filters and the tools available for this diagram. |
| |
| For more information about viewpoint description, you can have a look at the sirius documentation available here: |
| https://www.eclipse.org/sirius/doc/specifier/general/Specifying_Viewpoints.html |
| |
| Note that each viewpoint shall reuse: |
| * The common layer which is a mandatory layer defining the common concept of all diagrams (Bendpoint for example). |
| * The common tool, for deletion, etc. |
| * Common and specific java services. |
| |
| = Adding a new diagram to the architecture file = |
| |
| The editor provided to edit the DocumentStructureTemplate metamodel is not exactly the version generated by EMF. We customized it in order to use a TransactionalEditingDomain (to ease the Papyrus integration). |
| |
| When we add a new Sirius diagram, we shall create a new Sirius diagram prototype: |
| |
| [[File:../../../image/dev/1_ViewCreation.png]] |
| |
| Once the Sirius Diagram Prototype has been created, it shall be defined as in the following picture: |
| |
| [[File:../../../image/dev/5_DefineRepresentation.png]] |
| |
| To be able to reference the corresponding Diagram Description, it shall first be loaded in order to reference it. This can be done as in the following image: |
| |
| [[File:../../../image/dev/2_LoadViewpoint.png]] |
| |
| And select the corresponding *.odesign file using the Browse Workspace: |
| |
| [[File:../../../image/dev/2_SelectOdesign.png]] |
| |
| Once the Sirius Diagram Prototype has been created. We shall select on which viewpoint this representation shall be allowed. To do this, select the viewpoint and add a Representation Kinds: |
| |
| [[File:../../../image/dev/4_AddRespresentation.png]] |
| |
| And simply select the diagram prototype that was created on the previous step. |
| |
| [[File:../../../image/dev/3_RegisterRepresentation.png]] |
| |
| This shall be done for both Analysis and Design viewpoint. |
| |
| == Adding the creation command== |
| |
| In the org.eclipse.papyrus.sirius.editor.representation.architecture plugin, a new class extending the AbstractCreateSiriusDiagramEditorCommand shall be created. This class will manage the condition of the creation of the diagram and the action to execute before creating it depending on the context. |
| |
| For example, a sequence diagram can be created directly under an interaction without prior action, but if we want to create it under a Model, an interaction shall be created before and defined as the root of the diagram. |
| |
| = Sirius session management = |
| ==Initialization== |
| We created the Papyrus service '''org.eclipse.papyrus.sirius.editor.internal.sessions.SessionService''' initialized during Papyrus' launch. This service is in charge creating the Sirius Session and attaching it to the edited semantic resource (uml file). This way a Sirius Session will always be accesible even if the user didn't yet created a Sirius diagram. |
| |
| == EditingDomain == |
| To use the same transactional editing domain as other Papyrus services, we had to override the default Sirius Session and its creation process. This is done by the '''PapyrusSessionFactory''' which creates the '''PapyrusSession''' (which is just a Sirius session with the Papyrus TransactionalEditingDomain). |
| |
| For new services using session, it is recommanded to use the SessionService provided in the org.eclipse.papyrus.sirius.editor plugin. |
| = API To find creatable Sirius Diagram Prototype = |
| From a selected EObject, we want to find all SiriusDiagramViewPrototype and store them into a list: |
| |
| <source> |
| List<ViewPrototype> data = new ArrayList<>(); |
| for (final ViewPrototype proto : PolicyChecker.getFor(selection).getPrototypesFor(selection)) { |
| if (proto instanceof SiriusDiagramViewPrototype && proto.getRepresentationKind() instanceof SiriusDiagramPrototype) { |
| final SiriusDiagramViewPrototype siriusPrototype = (SiriusDiagramViewPrototype) proto; |
| |
| //additional check not yet done by the PolicyChecker |
| if (siriusPrototype.canInstantianteOn(selection)) { |
| data.add(proto); |
| } |
| } |
| }</source> |
| |
| |
| = Common Diagram = |
| == How to get the semantic EObject from a Sirius EditPart== |
| Initially, for an Editpart selected in a Sirius Diagram, the method '''org.eclipse.papyrus.infra.emf.utils.EMFHelper.getEObject(Object)''' returns as EObject the Sirius diagram element representation (from the Sirius DDiagram metamodel) instead of the semantic EObject. We get this problem, because Sirius uses an intermediate metamodel (DDiagram) between the semantic element and the GMF metamodel. Consequently, the selection in the ModelExplorer and the displayed property view were never synchronized with a Sirius Diagram. |
| |
| To solve this problem, our class '''org.eclipse.papyrus.sirius.editor.Activator''' contributes to the OSGi Service '''EObjectResolverService''' defined by the Papyrus plugin '''org.eclipse.papyrus.infra.emf'''. Our resolver is the class '''org.eclipse.papyrus.sirius.editor.internal.emf.SiriusEditPartEObjectResolver'''. |
| |
| == ModelExplorer Synchronization with a Papyrus Sirius Diagram == |
| The selection of the ModelExplorer is propagated to the Papyrus Sirius Diagram editor (class '''org.eclipse.papyrus.sirius.editor.internal.editor.NestedSiriusDiagramViewEditor''') using the interface '''org.eclipse.papyrus.infra.widgets.util.IRevealSemanticElement'''. |
| |
| |
| == Common concepts == |
| |
| === Bendpoints === |
| |
| Benpoints mapping is used to draw a Benpoint node at the intersection of edges when the Benpoints filter is activated. |
| |
| === Refresh provider === |
| |
| In some sirius diagrams, for several purpose (region management, bendpoints and sequence diagram reorder), the post refresh behavior of sirius diagrams have been overriden. |
| |
| To override this behavior, we have used the following extension point org.eclipse.sirius.refreshExtensionProvider. |
| |
| === Common services === |
| |
| * PapyrusSiriusTabbarContributor allows to enable or deactivate tools in the sirius tabbar. |
| |
| [[File:../../../image/dev/6_SiriusTabbar.png]] |
| |
| * AbstractDiagramServices is used to manage Label node label, node creation and node drag and drop tools. |
| |
| * AddElementToDiagramServices handles precondition for creation tool. |
| |
| * LabelServices handles direct edition of labels. |
| |
| * TooltipServices helps to provide a tooltip for each tools of the palette. |
| |
| * DeleteFromModelHandler handles the deletion of semantic element. |
| |
| = Class Diagram = |
| |
| The class diagram code is located in the |
| org.eclipse.papyrus.sirius.uml.diagram.clazz plugin. |
| |
| == Services== |
| |
| * ClassDiagramServices handles services used by tools of the class diagram for creation, reconnection, etc. |
| |
| == Description == |
| |
| The diagram description is located in the papyrus_class.odesign: |
| |
| The Class layer defines all the mapping and tools specific to the class diagram: |
| * NodeContainer, Node, Edge and BorderedNode mapping. |
| * The style of each node |
| * The Nodes tool section define the Nodes palette tools behavior, which are mostly creation tools. |
| * The Edges tool section define the Edges palette tools behavior, which are mostly creation tools. |
| * The Features tool section define the drag and drop from model and from representations, tools for the label edition and tools for deletion. |
| * The Relationships tool section define the reconnection tools and some deletion tools. |
| |
| = State Machine Diagram = |
| |
| The State Machine diagram code is located in the |
| org.eclipse.papyrus.sirius.uml.diagram.statemachine plugin. |
| |
| == Services == |
| |
| To handle the specific behavior of Region, since both VerticalStack or HorizontalStack children presentations could not handle the mixed behavior of region (sometimes vertical and sometimes horizontal). Hence, the Freeform children presentation is used combined to a manageRegionPresentation and setChildRepresentation method that allows to chose between either horizontal and vertical. |
| |
| == Description == |
| |
| The diagram description is located in the papyrus_statemachine.odesign: |
| |
| The State Machine layer defines all the mapping and tools specific to the state machine diagram: |
| * NodeContainer, Node, Edge and BorderedNode mapping. |
| * The style of each node. |
| * The Nodes tool section define the Nodes palette tools behavior (mostly creation tools), drag and drop from model or from representation tools, label edition tools and deletion tools. |
| * The Edges tool section define the Edges palette tools behavior (mostly creation tools) and reconnection tools. |
| |
| = Sequence Diagram = |
| |
| The Sequence diagram code is located in the |
| org.eclipse.papyrus.sirius.uml.diagram.sequence plugin. |
| |
| == Services == |
| |
| * Each services available in org.eclipse.papyrus.sirius.uml.diagram.sequence.services refers to one kind of element and handles the creation, reconnection and precondition for tools linked to this element. |
| |
| * ReorderSequenceRegistry, ReorderService and RefreshSequenceExtensionProvider are used to handle the reordering of all the diagram when moving elements. |
| |
| == Description == |
| |
| The diagram description is located in the papyrus_sequence.odesign: |
| |
| The Sequence layer defines all the mapping and tools specific to the Sequence diagram: |
| * InstanceRole, NodeContainer, Node, Edge, BorederedNode, Execution, State, CombinedFragment, InteractionUse and ObservationPoint mapping. |
| * The style of each mapping. |
| * The Nodes tool section define the Nodes palette tools behavior (mostly creation tools) and label edition tools. |
| * The Edges tool section define the Edges palette tools behavior (mostly creation tools). |
| * The Tools tool section define reconnection tools, reodering tools, label edition tools and deletion tools. |
| |
| = Xtext integration = |
| |
| Code in org.eclipse.papyrus.sirius.uml.diagram.textedit override classic editpart to add an xtext parser on each label edition. |
| |
| = Tests = |
| ==How to ensure new plugins/features are well configured?== |
| Each new feature must be added as extra requirements in the pom.xml of the plugin '''org.eclipse.papyrus.sirius.bundles.tests''' to ensure that all plugins provided by the new feature is well configured (about.xml, min/max for dependencies ...) |
| |
| == Test coverage == |
| The common method to create new tests for sirius diagram is located in org.eclipse.papyrus.sirius.junit.utils. In this plugin, the SiriusDiagramEditorFixture provide all the method to load model, ope session, tests tools that will be used in the several test case. |
| |
| Each specific diagram is tested in a specific plugin. Those tests include: |
| * Diagram creation |
| * Diagram deletion |
| * Creation tools tests |
| * Drag and Drop tools tests |
| * Deletion |
| |
| Each test should check the state of the tested diagram (synchronized/unsynchronized), to ensure that the test is executed on the expected diagram configuration. |
| |
| = ClassDiagram = |
| ==AssociationClass== |
| This element is quite difficult to represent. Its representation is composed with two edges and one node: |
| * '''CD_AssociationClass_Link''', a link with the same behavior than '''CD_Association'''. This link is ''Unsynchronizable'' |
| * '''CD_AssociationClass_Node''', a node with the same behavior than '''CD_Class'''. This node can only be owned by the diagram background. This node is ''Synchronized'' in order to appear automatically when a '''CD_AssociationClass_Link''' is represented on the diagram. |
| * '''CD_AssociationClass_NodeToLink''', this link relies the two previous elements. It is also ''Synchronized'' in order to appear automatically when a '''CD_AssociationClass_Link''' is represented on the diagram. |
| |
| The '''AssociationClass''' is owned by the nearest '''Package''' of the source. |
| The '''AssociationClass''' owns 2 '''Property''' referenced by the feature ''memberEnds''. |
| * the first '''Property''' (index 0) is typed by the target of the '''AssociationClass''', |
| * the second '''Property''' (index 1) is typed by the source of the '''AssociationClass'''. |