To ease the development on Papyrus, each member of the team works with basically the same configuration.
One way to manage this is using the Eclipse Installer (by Oomph) to manage your Papyrus development workbench.
The Eclipse Installer provides a set-up model for Papyrus, making it easier than ever to get a complete Eclipse workbench up and running for development on the Papyrus source code. Just download the Oomph Installer from the linked wiki page and follow the simple wizard to create your IDE and import the Papyrus source projects that you want to work on.
Pick any product you like on the first page, but be sure it's the latest release of that product for the Papyrus stream you're working on. For example, if you're working on the Luna service stream of Papyrus, you need the Luna release of Eclipse. On the second page, expand Eclipse.org / Papyrus to see the various components that you can import to work on. Pick any combination of the leaf-level sub-(sub-)projects, even all of them if you like. In the third page where you specify variables such as install location, workspace location, git clone, etc. be sure to choose "Luna" for the Target Platform. This ensures that you will be set up to work on Papyrus Luna (SR1), which is the only development stream currently supported by the setup model (until Mars development gets under way).
Contributing your changes is easy because Oomph will clone the Papyrus Git repository for you and configure Gerrit push.
Amongst possibly other details, the setup model configures:
Please raise bugs if you see any problems in the setup configuration.
Follow the following link for a step by step installation guide:
When you first launch the Eclipse Installer, it will show the default "simple mode" installer presentation:
You can choose to proceed from here, picking for example the "Eclipse IDE for Committers" package to install, which is the minimal configuration, and later using Oomph to import the Papyrus sources into the workspace (box 1 in the screenshot). However, you may as well select all of the Papyrus content that you need in your development environment now to set everything up in one go. To do that, switch to the "advanced mode": open the dialog tray by clicking on the button (box 2) and select "Advanced Mode..." (box 3). Now you should see the dialog reconfigured as shown below:
Again, the simplest option is to start with the "Eclipse IDE for Committers" package because the setup model will add everything else you need for working on Papyrus's various code and models.
On the second page, pick whatever Papyrus components you need to import into the workspace:
Note: At a minimum, you must select the top-level "Papyrus" project node for import, to get the correct tooling installed for working with the source and to bring the nightly builds into your PDE Target.
If you need to work on and test the Papyrus setup model, itself, then you should also import the "Papyrus / Developer / Oomph Setup" project (selected in the screenshot above) to configure the workbench to load the Papyrus setup model from your Git checkout instead of from the central Git repository via HTTP.
Next, tell Oomph where to check out the Papyrus repository, where to install Eclipse, and where to create the workspace:
Note that exactly how this page looks will depend on the options you choose for how to manage installation and workspace locations, and whether you have previously used Oomph to install other Eclipse instances (I have).
Note also that if you do not see the target platform that you need in the 'Target Platform' pick-list (for example, Neon to start working on the Papyrus Neon branch that is the master at the time of this writing), then you can just type the name into the field.
The last page summarizes the steps that Oomph will follow to start the installation:
After the newly installed Eclipse instance starts up, it will complete the setup by performing the rest of the tasks that have to be done in the workspace that didn't exist initially. These include the git checkout, importing projects from the checkout into the workspace, creating working sets, Mylyn queries, and more. Once these steps have completed, you will be ready to start working on the Papyrus code.
If you used Oomph's "simple mode" to create your Eclipse workspace, or if you need to make changes to what Papyrus bits you have imported (even for setting up the set-up model redirection), you can do this at any time by launching the Oomph installer wizard from within the Eclipse workbench. Note that you will first have to make the Oomph setup actions available in the toolbar be enabling the preference:
This launches essentially the same wizard as the "advanced mode" of the Oomph Installer.
Following is a description of the basic configuration:
-Dosgi.requiredJavaVersion=1.8 -Xms768m -Xmx1024m -XX:+CMSClassUnloadingEnabled
Oomph includes a way to manage the version changes between two releases as illustrated as following:
As of late February 2016 in the Neon development cycle, the Papyrus Main plug-ins and features and the Developer Tools are configured for PDE API Tooling and Oomph Version Management validation. One of the value-added capabilities of Oomph is flagging plug-ins and features that aren't included in any other feature, and thus appear to be slipping through a crack in the release. This only works when the workspace has all of the plug-in and feature projects of Papyrus imported.
If your workspace only has a subset of the Papyrus projects imported, then you can tell Oomph that this check is not appropriate by configuring the "check mode" in the Preferences:
The Hudson builds are currently implemented with Maven, using Tycho to build Eclipse-compatible artifacts. Therefore, all active plug-in and feature projects have Maven POM files describing them. There is a proposal under consideration to implement Maven Nature provided by M2Eclipse in the Papyrus source projects, to more closely align the Hudson build environment with the developer's local build environment in the Eclipse workbench.
An initial analysis of what would be involved in this change, both in terms of actually implementing the Maven Nature and its impact on Papyrus developers' daily workflow, is captured in this document:
If you are not using Oomph to set your environment you will need to fetch the code manually.
The Papyrus code and some documents are located in a Git repository. In the website http://git.eclipse.org/c/papyrus/org.eclipse.papyrus.git you will find the most recent activity information of the repository and, at the bottom of the page, you will find the URIs of the Git repository (e.g., http://git.eclipse.org/gitroot/papyrus/org.eclipse.papyrus.git).
Follow this quick tutorial if you never used Git before and want to know how to import the source files of one or more Papyrus plugins in your Eclipse workspace.
The following tutorial will focus on the main repository but every repository in the papyrus constellation can be found in the Papyrus project developer resources page.
To retrieve the papyrus code:
First, you will have to clone the Git repository.
Select the clone by URI.
As you can see, you have access to a number of ways to import the Git repository. Select the way you prefer and enter the corresponding address.
You then have to select the branches you want to import.
Then, at the moment of the creation, you will be asked which branch you want to be created by default.
Once you already have a cloned Git repository, you have to add it to your "Git repository" view.
To allow the user to commit anything Git will have to know your id and email. As such you can enter those variables in Preferences>Team>Git>Configuration and add the two entries:
If you do not have an ssh key yet, you can generate one using PuTTYgen ( http://the.earth.li/~sgtatham/putty/latest/x86/puttygen.exe ). Select Key>SSH-2 RSA key in 2048 bits in length and just click generate. It is important to know that the key is generated by the random movements of the mouse inside the window, so don't wait for it to generate itself. then, save both keys in your .ssh folder.
Save your private key and your public key with the corresponding buttons. It is preferable to protect your key by adding a pass-phrase to it that will be asked every time you use it as a precaution. You should get two keys by the time this is finished: xxxx.pub (for your public key) and xxxx (for your private one). PuTTy may name your keys with its owned extensions but ignore it and rename them accordingly.
To clone the repository:
For the configuration:
If you want to check your info:
For the ssh key, just type the following command:
The steps are essentially the same as with PuTTY: generate the key, say where to save it and enter a pass-phrase. You can then test your new pair by entering ssh-keygen -y -f [private key name], you will be prompt for the pass-phrase (if any) and your public key will pop up.
Furthermore your will have to add the ssh key (if you want to commit via ssh) to Preferences>General>Network Connection>SSH2 by setting the path to your .ssh folder and adding the name of your key to the private keys list.
As an example here is what this should look like when viewed inside your eclipse's Preferences page:
It is forbidden to modify the GUI. Only important bug fixes should be merged. Creation of a branch (tag) for the release
Its forbidden to merge contribution. Only by the project Chief for critical bugs.
See the chapter Papyrus Developer Guide > Contributing to Papyrus > Code Contributions and Reviews.
Find here a quick tutorial on CQs:
Contribution Questionnaires (CQs) are a big part of the IP (Intellectual Property) checking of a project. They allow the Eclipse IP Team to quickly know what third party code a project depends on and see if it is compliant with the EPL (Eclipse Public License). Eclipse Projects are expected to take necessary precautions to mitigate intellectual property risk to adopters. The integration of the provided code must come with the confidence that it can legally be distributed under the agreed-to terms, i.e. the EPL.
You must be a committer to see those but they can be found when logging into your Eclipse account and going to the project's page. There you will have access to three different menus providing the following:
1- The page used to create a CQ 2- A list of all active and previously used CQs 3- A list of all active and previously used jars
Considering that there is no existing CQ for the code you are contributing, you will need to create your own. To that end you will need to search the existing CQs to see if the code already possesses a CQ declaring its fair use under the EPL. If you are lucky, which you should be in most cases, there will be a CQ for the third party code you are using, as illustrated in (1) and you just have to select the correct version, and/or tool, for you and depend directly onto it. This particular process is called Piggy Backing (PB). If there are no existing CQs then the work of proof reading and getting into contact with the owner of the code begins (which should of course have been done BEFORE asking for a CQ). You will also get to, instead of selecting and existing one, name the CQ yourself ! (yay !)
Once selected, or created, you will then proceed to the creation of the CQ.
In our example the CQ is created as a Piggy Back of the original 13111 CQ (1). Its name will therefore show that (2). Once you are content with the look of your new CQ you can then proceed to officially create it. Once create a request will be sent to the IP team in order to review the CQ and a PMC will have to validate it.
Once a CQ is created you can follow the link to see it in the CQ bugzilla: IPZilla. There you will have be able to check the associated information:
1- The name of the CQ 2- The number of the Piggy Backed CQ 3- Your CQ's number 4- The project associated to the CQ 5- The compliance level of the Project. Type B - Full IP Due Diligence (License, Provenance, Scanning)
The Papyrus Code Templates, Java Cleanup and Java Formatter files are available under the Papyrus repository in the folder releng/templates/ and should be used for all your development on Papyrus.
The note explains how to install the templates in your environment.
//
and the $
.Bad code:
String fileName = "aFileName"; String message = "The file " + fileName + " can't be found";
This message is splitted in 2 strings. It is not good, because the translator doesn't know what he is translating and the order of the words can change from english to another language, so we recommand:
Good code:
String fileName = "aFileName"; String message = NLS.bind("The file {0} can't be found", fileName);
In this message, there is only one string to translate, the translator, can move the {0} to the good location in the new language.
The method String#format
should work fine too.
Left Click -> Source-> Externalize Strings...:
Give a nice name to the string
In plugin.xml, you should do the same thing, from the Overview tab. The output folder shouldn't changed:
Set the field
translatable to true
:
These rules apply to all plug-ins and features developed for the Papyrus Eclipse project, and distributed under the EPL licence.
plugin.xml:
/***************************************************************************** * Copyright (c) 2016 CEA LIST and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * Name (SOCIETY) Email - Initial API and implementation * *****************************************************************************/
Each plug-in contributed within the Papyrus project must be accompanied with a Test plug-in (And their associated Feature). Each test plug-in must at least contain a test class so that it can be included to the build/test infrastructure. Of course, the more tests it actually contains, the better...
The test plug-ins and features must follow the same rules as the other Papyrus plug-ins.
Most of these rules are checked automatically when running the Papyrus tests. If you want to check them locally, use the plug-in org.eclipse.papyrus.bundles.tests ( Run as > Junit plug-in test or use the *.launch file from this plug-in). This plug-in can be retrieved on the Papyrus Git repository: http://git.eclipse.org/c/papyrus/org.eclipse.papyrus.git/tree/tests/junit/plugins/developer/org.eclipse.papyrus.bundles.tests
All new plugins contributed to Papyrus should follow a submition process describe here. The goal of this submition process is to allows all commiters to review the new plugin before it is added to the main development trunk. The goals of this process are:
allows to choose altogether the definitive plugin name, its target repository (core, uml, ...) and to check that coding rules are respected.
This is a draft proposal, subject to changes.
This list contains all points that should be verified before committing the plugin in the repository:
This page explains:
All papyrus plugin should start with the same prefix:
org.eclipse.papyrus
So you want to propose a new plugin. You need to give it a name.
All papyrus plugins should start with the same prefix:
org.eclipse.papyrus
But this is not enough. The next step is to decide where your plugin should be located:
The trunk and the branches have the same structure. Here we will only describe the trunk structure.
The trunk contains the following folders:
These folders can also contains subfolders.
This folder contains sub folders. All plugins in the sub folders form the main Papyrus distribution.
folder | plugin prefixes | description |
plugins/core | org.eclipse.papyrus. core.*'''''' | |
plugins/uml | org.eclipse.papyrus. uml.* | All plugins related to UML diagrams and UML should be located in this repository, except plugins related to a particular profile |
plugins/uml | org.eclipse.papyrus. uml.diagram.* | Plugins related to common UML diagrams are located in this repository. The naming scheme include 'diagram' namespace. |
plugins/developer | To be moved in extraplugins or in developer ? | |
plugins/others | org.eclipse.papyrus.??? | Plugins that do no feet in other repositories |
plugins/sysml | org.eclipse.papyrus. sysml.* | All plugins related to sysml UML profile |
This folders contains subfolders, each one dedicated to a kind of test:
Each subfolder mimic the same structure as the trunk. The names of the plugins are usually the same name as the tested plugin, suffixed with the type of test.
folder | plugin prefixes | description |
tests/junit | org.eclipse.papyrus' .*.tests' | This folder mimic the trunk folder. It containt Plugin for junit tests.
The plugins have the same name as the plugin they test, with the suffix .tests |
tests/recipes | org.eclipse.papyrus' .*.recipetest' | This folder mimic the trunk folder. It containt Plugin for recipes tests.
The plugins have the same name as the plugin they test, with the suffix .recipetest |
tests/swbot | org.eclipse.papyrus' .*' | ???? |
There is two kind of examples:
The folder contains subfolders for each kind of examples.
folder | plugin prefixes | description |
examples/user | org.eclipse.papyrus. example.user.* | Plugins providing examples for Papyrus end user (ex: models) |
examples/dev/core | org.eclipse.papyrus. example.core.* | Plugins related to core and providing examples for developer or customizer. |
examples/dev/uml | org.eclipse.papyrus. example.uml.* | Plugins related to UML and providing examples for developer or customizer. |
examples/dev/others | org.eclipse.papyrus. example.???.* | Plugins providing examples that do not fit in other folders. |
The following table try to resume the actual existing folders, their purpose, and eventually the proposed refactoring:
folder | plugin prefixes | description |
required actions |
plugins/core | org.eclipse.papyrus. core.*'''''' | ||
plugins/uml | org.eclipse.papyrus. uml.* | All plugins related to UML diagrams and UML should be locate in this repository, except plugins related to a particular profile | |
plugins/uml/diagram | org.eclipse.papyrus .uml.diagram.* | All plugins related to UML diagrams. | |
plugins/developer | Move to extraplugins ? | ||
plugins/marte | org.eclipse.papyrus. marte.* | All plugins related to marte UML profile | Delete from plugins. Marte stuff is in extraplugins/marte |
plugins/others | org.eclipse.papyrus.??? | Plugins that do no feet in other repository |
oep.outline --> extraplugins oep.profile --> uml |
plugins/sysml | org.eclipse.papyrus. sysml.* | All plugins related to sysml UML profile | |
plugins/profile-tool | ??? | clarify this repository, its purpose, and its naming scheme. Move to UML ? | |
incoming | org.eclipse.papyrus' .*' |
New plugins that should be added to Papyrus. See Build_Process. Plugins in this repository should follow the naming scheme of there targeted repository. |
|
extraplugins | org.eclipse.papyrus' .*' |
This repository contains plugins providing some extra functionalities to Papyrus. For example:
|
|
examples | org.eclipse.papyrus. examples.* |
Examples for Papyrus users. |
Need to separate user examples from developers examples. |
examples | org.eclipse.papyrus. examples.* |
Examples for Papyrus developpers / customizers. This repository contains some plugins illustrating how to use some Papyrus functionalities, or how to extends Papyrus. |
|
tests/junit/plugins tests/junit/extraplugins |
sameNameAsTestedPlugin .tests |
These repositories contain the same hierarchies as in plugins. The test plugins should have the name of its tested plugin, suffixed with ".tests" |
|
tests/recipes/plugins tests/recipes/extraplugins |
sameNameAsTestedPlugin.recipetest | These repositories contain the same hierarchies as in plugins.
The recipetest plugins should have the name of its tested plugin, suffixed with ".recipetest" |
|
tests/swbot | ??? | please complete |
Documentation for the finished functionalities of Papyrus should be accessible online via the info center, in the documentation embedded in Eclipse platform and in the documentation plugins themselves. Such distributed documentation should be coherent throughout those platforms. As such, the documentation should be stored in plugin format inside the Papyrus documentation repository in the main and extra folders.
There will not be any documentation on finished and/or published features in wiki pages. The wiki pages will only be used to discuss and exchange ideas on feature currently in development. Any finished feature's documentation should be removed from those pages and published in plugin form in the papyrus' git repository.
Documentation should follow these recommendations Eclipse Doc Style, but keep particularly in mind the following ones:
Root Folder
|
Please be aware that there is a discussion on releasing the developer documentation directly from the git repository through the usage of maven site plugin. The proposition is to maintain the documentation only in the source code repository and have a mechanism to publish it directly. If you have any idea or requirements, do not hesitate to contact us via the [mdt-papyrus.dev@eclipse.org developer mailing list].
The following steps should help you create your own documentation plugin and integrate it as a publishable item if needed.
Create a new plugin with the following tree content.
Notice that there is a main-toc.xml to provide the skeleton for the future book. Then several mediawiki pages are to be created, one for every topic treated. Of course, as your wikimedia pages will be illustrated don't forget to add your screenshots in a images folder.
Here is the plugin you will have to add to your pom.xml (as long as it is not already inherited from the parent pom.xml).
<plugin> <groupId>org.eclipse.mylyn.docs</groupId> <artifactId>org.eclipse.mylyn.wikitext.core.maven</artifactId> <configuration> <sourceFolder>src/site/mediawiki</sourceFolder> <outputFolder>${project.build.directory}/generated-eclipse-help</outputFolder> <copyrightNotice>${help.copyrightNotice}</copyrightNotice> <title>${help.documentTitle}</title> <multipleOutputFiles>false</multipleOutputFiles> <navigationImages>true</navigationImages> <formatOutput>true</formatOutput> <htmlFilenameFormat>$1.html</htmlFilenameFormat> <xmlFilenameFormat>$1-toc.xml</xmlFilenameFormat> <helpPrefix>target/site/generated-eclipse-help</helpPrefix> <stylesheetUrls> <param>styles/main.css</param> </stylesheetUrls> </configuration> <executions> <execution> <goals> <goal>eclipse-help</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.eclipse.mylyn.docs</groupId> <artifactId>org.eclipse.mylyn.wikitext.mediawiki.core</artifactId> <version>${mylyn.wikitext.version}</version> </dependency> </dependencies> </plugin>
As is illustrated below, adding the MyLyn mediawiki maven plugin to the pom.xml enables the creation of the target folder containing automatically generated eclipse documentation when building the project.
Your plugin will contains a site directory that will hold your mediawiki documentation with it embedded resources such as images. The mediawiki files will be processed by a maven wiki plugin and will generate a toc file and the corresponding html file in the output folder. If you want more information, please have a look to the mylyn wiki page.
You will then have to create a new TOC file that will reference the generated TOC files
Content of the myplugin-main-toc.xml file :
<?xml version='1.0' encoding='utf-8' ?> <toc label="Using tables" link_to="../org.eclipse.papyrus.infra.doc/toc.xml#PapyrusDocCustom"> <topic label="Using tables" > <link toc="target/site/generated-eclipse-help/tablemetamodeldocumentation-toc.xml"/> <anchor id="tableMetamodel"/> <link toc="target/site/generated-eclipse-help/tableUserDoc-toc.xml"/> <anchor id="tableUserDoc"/> </topic> </toc>
link_to add the contribution to the PapyrusDocCustom anchor (defined in the main papyrus documentation plugin's org.eclipse.papyrus.infra.doc toc.xml).
warning: paths are related to the root of the plugin.
The generated TOC (through the build, e.g. tablemetamodeldocumentation-toc in our example) is referenced by the hand-written one (which we called main-toc.xml). An anchor is also added in the generated ones, so the documentation can be extended by another contribution.
Then, add all images embedded in the documentation in the same folder as the mediawiki and all generated files. Do not forget to add all files (the folder resource in the example) to the build.properties file.
Finally, the tocs should be referenced in the extensions of the plugin.
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.4"?> <plugin> <extension point="org.eclipse.help.toc"> <toc file="target/site/generated-eclipse-help/myplugin-main-toc.xml" primary="false"/> <toc file="target/site/generated-eclipse-help/myplugin-generated-toc.xml" primary="false"/> </extension> </plugin>
Now that your documentation is ready to be published, you need to add your doc plugin in the modules of the pom.xml of the root documentation folder (in our case plugins/doc/pom.xml).
<?xml version="1.0" encoding="UTF-8"?> <project> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>org.eclipse.papyrus</artifactId> <groupId>org.eclipse.papyrus</groupId> <version>1.1.0-SNAPSHOT</version> <relativePath>../../releng/top-pom-main.xml</relativePath> </parent> <artifactId>org.eclipse.papyrus.plugins.doc</artifactId> <packaging>pom</packaging> <modules> <module>org.eclipse.papyrus.cdo.ui.doc</module> <module>org.eclipse.papyrus.copypaste.ui.doc</module> ... <module>org.eclipse.papyrus.myplugin.doc</module> </modules> </project>
If you want the new documentation to be released with the Papyrus doc plugins that will serve as the basic released documentation for the next info center (i.e. http://help.eclipse.org/[version]/index.jsp), it will need to be added in org.eclipse.papyrus.doc.feature/feature.xml
<plugin id="org.eclipse.papyrus.infra.nattable.doc" download-size="0" install-size="0" version="0.0.0" unpack="false"/>
You should execute an Eclipse RCP obtained from your initial platform, and your documentation should be accessible through the help menu.
You could also execute a full local release of Papyrus by running a mvn clean install -f ./releng/main/pom.xml -Dtycho.localArtifacts=ignore
from the root of your papyrus git repository.
When adding a task to the buzilla, the following grammar should be used:
The category helps to filter the bugs for developers. There are already some existing categories: General, XXX Diagram, Common, Property View, etc.
As a reminder, the lifecycle of bugs is located here: Bugzilla Use
Using Gerrit, you can contribute to the Papryrus project, even if you aren't a committer. If you have not cloned the repository yet please follow the tutorial of Papyrus Developer Guide > Getting the code > Papyrus Git Tutorial.
This step is your average account creation, and it will require you to visit a mail sent URL to validate the account.
This can be done (by visitiing the following link: http://projects.eclipse.org/user/login/sso) once logged in by clicking on Contributor License Agreement and following all the instruction on this same page.
The id and password , just as your sign-in information on the eclipse website, are the mail address you used to create the eclipse account and the associated password, no need to create a new one.
Because you're not an official Papyrus commiter, you can't just commit your code on the papyrus git repository; you have to submit your contribution via the commit refs/for/master branch.
You can configure EGit for push on that particular branch:
N.B. : you can also choose to modify the origin remote.
You now have to configure the repository URI :
If you're experiencing problems, please verify that you're pushing on refs/for/master (Or refs/drafts/master for hidden review)
git remote add sshGerrit ssh://[committer_id]@git.eclipse.org:29418/papyrus/org.eclipse.papyrus
A good way to do this is to open the Git perspective inside your eclipse window as it will have all the necessary views to achieve what you want to do in this case. The first step is to verify that your local branches have a remote assigned and that it is the remote you want to push on, as the mechanism of commit and push of egit will select this one by default. This can be done easily by clicking on the branch in your Git repository interface and selecting the "Configure Branch" option.
Or by editing the Preferences>Team>Git>Configuration "Repository Settings" and defining which default remote your branch will be attached to.
Once this is done you will have to create, or amend, the commit by going to the "Git Staging" tab. there you will have all the changes detected by EGit (it might be a little messy and full of files you didn't even touch, as is the case in this image, but don't pay it attention as your changes will be there as well) and drag the wanted files from Unstaged Changes to Staged Changes . then edit the commit message:
If you only need to amend a commit EGit provides a fast way to edit the message with the "amend previous commit", "add signed off by" and "add Change Id" buttons.
The first commit on a Bug won't have a change-id as this will be created when the commit is pushed and accepted by Gerrit. The change-id can be retrieved by visiting the pushed commit on Gerrit. With EGit the "amend previous commit" button should fill the new commit's message with the previous fields. It is important to know that the Change-Id must be separated from the commit message by a blank line, so that it will be identified from the rest of the message and your push to gerrit will update the existing one.
Once all this is done, don't forget to link the gerrit page inside a comment in the related Bugzilla page. This little update will make things easier for the users and even serve you as a reminder to close or update the Bugzilla status !
Gerrit & Bugzilla are now synchronized. A reference from Bugzilla to the Gerrit contribution is now automatically added as soon as the contribution is proposed, and another comment is added when the contribution is accepted (merged). Note that this synchronization can only happen if the Contribution contains the Bug ID in the commit message (‘' Bug 123456': ....’). Also note that by default, Mylyn/Bugzilla only writes the bug number (Without the ‘Bug’ prefix), which doesn’t trigger the automatic synchronization.
The editor used in this section is Cygwin ( http://www.cygwin.com/), to which we added the specific git packages: git-completion, gui, svn and fast version control system. To install them choose a site, such as mirrors.kernel.org To make the display more comfortable and easier to read, it is preferable to run the following command: git config --global color.ui true, if it is not already enabled, so that you will have access to all the nice colors. Also, if you are allergic to VI, try installing another editor, like nano.
This hook will automaticaly insert Gerrit Change-Id in your commit message
scp -p -P 29418 username@git.eclipse.org:hooks/commit-msg .git/hooks/
see also Install the commit-msg hook in your repository.
Having created an empty file (using the touch command) inside the git repository, git sees it as a modification and therefore the git status command shows the file as untracked. We add it to the index of the next commit using git add [file name] and as you can see by the second git status the file testGerrit.txt is in the "Changes to be committed". The next step is to create the commit itself. For this purpose we run the git commit -m "[your commit message]" --signoff command. This command decompose itself in 3:
Before pushing on gerrit it is preferable to update your local branch from the remote as that should prevent merge conflicts if your change is accepted and merged.
Then, we push the commit onto Gerrit. It will signal you if the build incorporating your changes has failed and allow your code to be reviewed before being merged. Instead of pushing to the actual branch, your local is based on, Gerrit uses "magic branches", effectively virtual branches, for the purpose of reviewing the code and pushing it, or not depending on the review, on the actual git remote. Those are identified with the "refs/for/[remote]" tag.
You will be able to see your contribution by opening Gerrit's web interface ( http://git.eclipse.org/r). Filters can be applied in the search fieldbox. Useful ones in this case are:
And this is what your commit details will look like:
Please keep in mind that, for the following steps ("second push" and "third push"), we are in the Gerrit situation where the contribution has not yet been merged. Amended commits are actually entirely new commits, and the previous commit is removed from the project history. If you amend a commit that other developers have based their work on it will look like the basis of their work has vanished from the project history and that is a tricky situation to recover from.
Now lets say that you want to add modifications to the project you are working on. In this case we just create a new file "testGerritMod.txt". As a newly created file, a "git status" tells us that it is added to the untracked list, that is the not yet committed files. We add the new file to the index and create a new commit as usual and adding the Change-Id to our message in order to signify gerrit that it is a modification of our first commit. As a reminder, remember to put an empty line between the commit message and the footer containing the Change-Id.
But the problem is that we did not amend the first commit but created a new and different commit altogether without deleting the first one. Therefore we try to have two commits with the same Change-Id and that is just not possible. The push order gets rejected. Time for a squash, that is a rebase -i, of our two commits: git rebase -i HEAD~2 which means that we get the last two commits (~2) done from our local branch (HEAD). We then get an editor in which we choose how to fuse the commits together (image pending) and, once this is done, another that allows us to edit and choose which commit message to use.
As we can see the updated gerrit contribution contains the new file and the updated commit message.
To amend a commit properly you just have to run the git commit --amend that will allow you to amend the last commit done on this branch. In this case we create a new file to our test, add it to the index and then run the command. The new file is added to the commit and a message editor is opened to allow us to modify the commit message if need be. After making sure that our branch is still up to date, we push the new modification on gerrit (this time by ssh just to show that you can manipulate both together).
Now that all is up to speed we can push the new modifications.
And the resulting modifications on the Gerrit page.
Here is a list a commands you may find useful:
As a reminder here are some Git related commands, just in case:
Of course, don"t forget the very useful command:
And if you use the VI editor: There are two "modes", one for editing (inserting) and one for navigating through the file, that we will call "I mode" and "Esc mode" respectively. Each of them are entered by pressing the associated key and exited by pressing its counterpart.
More information of how to use git on Contributing via Git
Here is a basic example of how to configure mylyn to receive the bugs associated withe Papyrus: First, after installing the mylyn connector just as you would any other new software (Help>Install New Software), open the mylyn view (Window>Show View). From there select the New Query option and proceed as illustrated below.
As a side note you can file bugs directly from mylyn using the New Task option from the Task Repositories view. Then, proceed to fill the requiered fields corresponding to your use case and submit the newly created bug.
(For further information, see http://www.eclipse.org/legal/EclipseLegalProcessPoster.pdf)
When a non-committer wants to contribute to Papyrus, he must create patchs and attach them to a bug. In the comment of each patch, he must write :
+ Set the field Review to '?'.
Before commiting a patch, you should verify that the contributor has written the following lines in the comment :
If not, he must do that before you commit its patch!
Note : In reality, you should have the autorization of the PMC before doing this commit.
Using the @Deprecated tag, you must do these things in the same time:
Add the end, you must have something like that:
/** * * @deprecated since 3.1 * Use {@link org.eclipse.papyrus.infra.gmfdiag.common.structure.DiagramStructure} API instead. * * This class will be removed in Papyrus 5.0, see Bug 541027. * */ @Deprecated public abstract class DiagramStructure { ... }
Unless there is a good reason as to why, it is the Reviewer that is allowed to merge/push the gerrit patch into the repository. The reviewer must never be the committer of the patch to keep a two way check and minimize errors.
Here are some guidelines (which may be altered and/or improved) that every reviewer and committer should follow:
In addition they must respect the EPL2.0 licensing and, in case of a plugin, include the about.html with the EPL2.0 license summary.
/***************************************************************************** * Copyright (c) 2015, 2018 CEA LIST, Committer Name, and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License 2.0 * which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-2.0/ * * SPDX-License-Identifier: EPL-2.0 * * Contributors: * CEA LIST - Initial API and implementation * Committer Name (CEA LIST) committer.name@cea.fr - Bug 492522, Bug XXXXXX *****************************************************************************/ ############################################################################### # Copyright (c) 2013, 2018 CEA LIST, Committer Name, and others. # # All rights reserved. This program and the accompanying materials # are made available under the terms of the Eclipse Public License 2.0 # which accompanies this distribution, and is available at # https://www.eclipse.org/legal/epl-2.0/ # # SPDX-License-Identifier: EPL-2.0 # # Contributors: # ###############################################################################
/** * Constructs an Editor for multiple Integer values. * The widget is a List, with controls to move values up/down, add values and remove values. * * @param parent * The Composite in which this editor is created * @param directCreation * Indicates if the creation and modification are directed. * @param directCreationWithTreeViewer * Indicates if the creation and modification are directed on the TreeViewer. * @param style * The List's style * * @since 3.1 */ public MultipleIntegerEditor(Composite parent, ...){}
<feature id="org.eclipse.papyrus.XXXXXXX.feature" version="2.0.0.qualifier" label="%featureName" provider-name="%providerName" license-feature="org.eclipse.license" license-feature-version="2.0.0"> <description> %description </description> <copyright> %copyright </copyright> <license url="%licenseURL"> %license </license>
Requirement : requirementID : text Code Instruction: path to the API class
# Requirements defined for the validation of Papyrus profile plug-in # This file must be filled by developer when a task is done in the validation of a profile plug-in
# General Requirements Requirement: Req_Validate_Menu_ProfileValidation_001: The profile validation must be done with a button 'Validate Profile plug-in' on plug-in, in the papyrus developer menu Code instruction: - org.eclipse.papyrus.toolsmiths.validation.profile/src/org/eclipse/papyrus/toolsmiths/validation/profile/handlers/ValidateProfilePluginHandler.java - org.eclipse.papyrus.toolsmiths.validation.profile/src/org/eclipse/papyrus/toolsmiths/validation/profile/testers/ValidateProfilePluginTester.java - org.eclipse.papyrus.toolsmiths.validation.profile/plugin.xml
Requirement: Req_Validation_Dialog_ProfileValidation_002: During the validation, a progress monitor must be opened with correct explanations Code instruction: - org.eclipse.papyrus.toolsmiths.validation.profile/src/org/eclipse/papyrus/toolsmiths/validation/profile/handlers/ValidateProfilePluginHandler.java
# General Technical Requirements Requirement: ReqTechnical_Extensions_Checker_ProfileValidation_001: A checker for the extensions must be implemented Code instruction: - org.eclipse.papyrus.toolsmiths.validation.profile/src/org/eclipse/papyrus/toolsmiths/validation/profile/internal/checkers/ProfileExtensionsChecker.java
Requirement: ReqTechnical_Definition_Profile_Checker_ProfileValidation_002: A checker for the definition profile must be implemented Code instruction: - org.eclipse.papyrus.toolsmiths.validation.profile/src/org/eclipse/papyrus/toolsmiths/validation/profile/internal/checkers/ProfileDefinitionChecker.java
Papyrus Log is using the log from Eclipse (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=292256). Logs are displayed in the "Error Log" view.
First, your plugin should depend on the org.eclipse.papyrus.infra.core.log.LogHelper plugin.
Then, to benefit from the Papyrus log mechanism, you must add onto your bundle :
A public static variable on your bundle activator :
import org.eclipse.papyrus.infra.core.log.LogHelper;
public class Activator extends Plugin { // or AbstractUIPlugin
/** Logging helper */ public static LogHelper log;
/** * {@inheritDoc} */ public void start(BundleContext context) throws Exception { super.start(context); plugin = this; // register the login helper log = new LogHelper(plugin); } ... }
A static import of this variable on your class :
import static org.eclipse.papyrus.[yourPluginName].Activator.log;
public class CreateDiagramAction extends Action {
public void run() { log.info("log"); } }
There are three levels of log in Papyrus : info, debug, error
log.info("..."); //$NON-NLS-1$
A debug log is used for development and/or debug purposes only. It MUST be encapsulated with the condition log.isDebugEnabled().
if (log.isDebugEnabled()) { log.debug("Start - CreateDiagramAction#run"); //$NON-NLS-1$ }
try { ... } catch (IOException io) { log.error(io); ... }
You can write a template for each of those logs to ease your development (Key assist / "Ctrl Space").
First, you have to install on your platform, the bundle "org.eclipse.papyrus.java.template" available on the developer Papyrus repository ( http://dev.eclipse.org/svnroot/modeling/org.eclipse.mdt.papyrus/trunk/plugins/developer)
Then, open the menu "Preferences" > "Java" > "Editor" > "Template"
Finally, create your template. The "name" corresponds to the shortcut you will use in your editor. The "context" is "Java".
${activatorLog}log.info("${cursor}");
${activatorLog}if(log.isDebugEnabled()){ log.debug("${cursor}"); }
${activatorLog}log.error("${cursor}");
In order to display the debug log, you must add the command line argument "-debug" to your platform.
Two others usefull arguments are "-console" and "-consoleLog".
For more information, read this page : http://www.eclipse.org/eclipse/platform-core/documents/3.1/debug.html
Papyrus editor add some new features to GMF, and needs specific generation. Here is a little guide explaining how to deal with the Papyrus generation stuff.
From the Papyrus update site, you need to install the Papyrus Diagram Generation Tools feature.
If you want to work with the generation plug-ins in your workspace, add the following developer plugins to your workspace (first instance).
Now use the "debug/run configurations" dialog to create a new Eclipse Application instance and launch it.
This step is executed in the 2nd Eclipse instance that includes executable versions of the three Papyrus developer plugins that have been added to the workspace of the first instance (see preceding step).
Go to Preferences / Java / Code Style. '''Use the code formatter "papyrus_formatter.xml" (in doc/DevelopperDocuments/templates).
You will need to import from your workspace the following project into your runtime application (do not copy them) :
In your GMFGen, you have to update two properties to take into account the specific Papyrus templates. If you are extending an existing Papyrus diagram, the setup has (of course) already been done and this step can be skipped.
In the node Gen Editor Generator of your gmfgen files, you have to setup the following properties, as shown in the screenshot below for the example for the state-machine diagram: Template Directory to /org.eclipse.papyrus.def/xtend Use Dynamic Templates to true
To run the transformation, right click on your gmfgen file and select the menu Generate Papyrus Diagram.
To fit in with the other UML diagrams provided by Papyrus, you will want to provide Diagram Assistants (the pop-up bar and connection handles) in your diagram. Since the Feb 9 2015 nightly build towards Mars M6, Papyrus has supported modelled diagram assistants. To get started defining your diagram assistants, generate a *.assistants model from the GMFGen:
In the resulting model, you will want to stream-line the assistants so as not to overwhelm users with too many options in the pop-up bar and connection menus:
The assistants model depends on the element types described by the diagram's *.elementtypesconfigurations model, so be sure to generate that, too.
When you are happy with the model (you can hot-deploy it from the workspace for testing as described in the Papyrus User Guide in the on-line help), deploy it on the extension point in your diagram plug-in:
Most shape nodes in the diagram should inherit the PapyrusPopupBarEditPolicy by default from the Papyrus diagram infrastructure. However, most shape compartments (for package contents, activity contents, etc.) will not have this edit policy. To enable the pop-up bar assistant on these compartments, a context-menu action is contributed to the GMFGen editor by the Papyrus Developer Tools plug-ins:
Select any number of GenCompartments in the diagram generator model and invoke this action to generate the required edit policy registration.
To add a new template to the mechanism of generation, you have to :
public TextEmitter get'yourTemplateName'Emitter() { return newXpandEmitter("xpt::yourTemplatePath::yourTemplateName::yourStartingDefine"); //$NON-NLS-1$ }
where yourTemplateName is the name of your template yourTemplatePath is the path to access to your template from the folder xpt. Subfolder has to be separated by :: yourStartingDefine the define that will start the generation
private void generateDiagramPreferencePage() throws InterruptedException, UnexpectedBehaviourException { doGenerateJavaClass(emitters.getyourTemplateNameEmitter(), PackageName, ClassName, Input); }
where getyourTemplateNameEmitter() : is the new TextEmitter defined before PackageName : is the name of the package the class will be contained in. It has to match with the one specified in the template. ClassName : is the name of the class. It has to match with the one defined in the template. Input : is the input element. It has to match with the type defined with FOR in your first xpt define.
You just now have to run your transformation as explained before in this page. Be careful to refresh your projects in your runtime application if you generate in this mode.
Since Papyrus for Eclipse 2021-09, the Papyrus Extension doesn't exist anymore, but its concepts have been included directly in the GMF metamodel. So this documentation is half-deprecated.
Description : This extension allows to define the default visibility for the compartments. The compartments not referenced by this node are visible by default.
Fields for this node:
Warning : Often you have the same preference page for Top Node and Child Node, in this case, you should define your preference for the top node. Currently, we generate in first the Child Node Preference Page, then the Top Node Preference Page erases the Child Node Preference Page.
Description : This extension allows to define the default visibility for the titles of compartments. The titles not referenced by this node are visible by default.
Fields for this node:
Warning : Often you have the same preference page for Top Node and Child Node, in this case, you should define your preference for the top node. Currently, we generate in first the Child Node Preference Page, then the Top Node Preference Page erases the Child Node Preference Page.
Description : This extension is used to define the default visibility for the labels (Connection Labels and External Node Labels). The information provided by this node are used in two ways :
Fields for this node:
The LabelEditPart referenced by the Label Role Node implements the interface ILabelRoleProvider.
Warning with the Preferences Pages : for example, Association can be represented in 3 ways in the Class Diagram :
Currently the value of the field "Display Name" of these nodes in the genModel, is "Association". Now, we need to have 2 preferences pages (one for link and one for node). Concerning AssociationBranch, it should have the same name as AssociationLink, but it should be located before AssociationLink in the genModel.
If you don't use this node :
Examples of usage:
- REQ_001 (id=REQ_001):
The tool must help to model papyrus development
- REQ_0011 (id=REQ_0011):
The tool must help to model requirements.
- REQ_0012 (id=REQ_0012):
The tool must help to make the design
- REQ_0013 (id=REQ_0013):
The tool must help to model test
- REQ_0014 (id=REQ_0014):
The model of development must contain traceability
- REQ_0015 (id=REQ_0015):
The tool must help to model use cases.
- REQ_002 (id=REQ_002):
From the model, it must be able to generate documentation
- REQ_0021 (id=REQ_0021):
From the model, it must be able to generate HTML documentation
- REQ_0022 (id=REQ_0022):
From the model, it must be able to generate WKIMEDIA documentation
UseCases
In order to model your development and generate your documentation. You must install a version of SysML and the plugin org.eclipse.papyrus.uml.developer.mde that can been found in the git org.eclipse.papyrus\plugins\developer
- traces to REQ_0011
The Designer has to create a use case inside the "requirements" model. The requirement may be functional or non functional. Requirements has to be refined or decompose until it can be tested.
In order to create requirements, the Designer can use the module "Papyrus for Requirements" that helps to create requirements
Create a requirement
- traces to REQ_0015, REQ_0014
The "Designer" has to develop Use cases that are refinement of the functional requirements. In each use case, a comment has to be added in order to explain the use case. In each use case, the designer has to add a set of comment stereotyped "userDoc" in order to write the how to. Each Use case must have a link "satisfy" with the refined requirement
In order to create a use case, the designer has to create a use case in the component inside the UseCase model.
Create a Use Case
In each Use case, the designer has to add a nested comment in order to explain the goal of the use case, (it can be also an activity diagram or sequence diagram)
Create a comment
The designer has also to explain how a user can execute this function. This is the "how to" section, the purpose is to explain step by step how the user can do in order to run the functionality. To do that, create a comment stereotyped "UserDoc" write you text inside or associate a screenshot of your execution by adding a hyperlink on this comment.
Add a comment for the user doc
Reference an image by using hyperlinks
- traces to REQ_0012, REQ_0014
The designer must model its development in order to be able to explain its architecture, the behavior, choices of its tool.
To do that, the designer can design the model or make a retro-engineering of the code. To that papyrus provides in papyrus designer a generator and retro tool for the java or C++code.
- traces to REQ_0013, REQ_0014
The Designer must add a least one test case for each use case. A test case is a use case stereotyped "UseCaseTest". The Use case must contain an activity that represents the java class that represents the code of you test.
To do that, go to the "Test" model, create use case and stereotype it "Use case Test". This is the scenario to test a use case. In the use case add a comment and explain the scenario. In the code you must have a JUnit or a java class that corresponds tho this test. Copy qualified name of your test and add it as an activity. Then add a verify link from the test the use case to the requirement. Use papyrus requirement in order to simplify creation of links.
Use Case Test
- traces to REQ_002, REQ_0021, REQ_0022
From the model, it possible to generate the developer Document. This generation is done in two steps: first the tool generate a document model and from the document model it generates a document. The document model contains only package stereotyped "section" and comment stereotyped "content" or "imageRef".
Transformation to the document model: Each package requirements, UseCases, Design and Test become a section. Each requirement becomes a paragraph. Each Use Case becomes a section with its comments a paragraph of the section. The comment stereotyped user doc becomes a sub-section "How to". Each diagram will be serialized and become an image inside the container section. Each image hyperlink associated to a comment becomes an image after the paragraph.
The transformation from the model of document to the document is bijective.
In order to generate the code: Ensure that the following profile are applied.
Applied Profiles
Fill properties of stereotype "Project " for the root model.
Project stereotype properties
Ensure that the model are in directory doc, all images are in the directory doc/imgDOC.
PluginStructure.png
Select the root model in the model explorer and click right to generate html or media wiki.
HTML generation
Open the html document, use a css file, called default css, and you can obtain the following document.
Note that this doc has been obtained by using the tool on itself. You can notice that a new model element with the stereotype Document is also generated. You can remove it. I let it in order to demonstrate that is possible to make all in model.
Generated HTML page
The activator class controls the plug-in life cycle.
Constant included in the MDE process profile.
List of constant contained in the document profile.
Command ClassDiagram
This command transform a model to document model.
Handler ClassDiagram
This class is used to create and html developer doc file.
Abstract handler in order to connect to papyrus.
This class is used to create and wiki developer doc file.
Transcription ClassDiagram
This class is a specialization to generate html files.
This class is used to generated very swiftly a document from the document model.
This class is an engine to traduce a document model into files.
This class is a specialization to generate mediawiki files.
This section contains code examples related to the 'core'
The ServiceRegistry is a central point in Papyrus. It allows to get nearly all objects or services used by papyrus.
There is one and only one ServiceRegistry for each Papyrus Editor.
import org.eclipse.papyrus.infra.core.services.ServicesRegistry;
When you create a Diagram or a Service, Papyrus always provide the ServiceRegistry as an argument. You usually need to store it in a way you could easily retrieve it.
There is several ways to found the ServicesRegistry, depending of the objects you have at your disposal.
If you have the Papyrus main editor part ( IEditorPart):
IEditorPart editorPart = getIEditorPart() // The Papyrus editor, not a nested editorPart ServicesRegistry serviceRegistry = (ServicesRegistry)editor.getAdapter(ServicesRegistry.class);
If you are in a GMF related stuff and you have the IDiagramEditDomain :
IDiagramEditDomain domain = getIDiagramEditingDomain(); // ServicesRegistry serviceRegistry = ServiceUtilsForGMF.getInstance().getServiceRegistry(domain);
If you have an EObject (UML Element, Diagram, ...) attached to one Papyrus model:
EObject eobject = ....; ServicesRegistry registry = ServiceUtilsForResource.getInstance().getServiceRegistry(eobject.eResource());
See also example in Git: http://git.eclipse.org/c/papyrus/org.eclipse.papyrus.git/tree/examples/infra/org.eclipse.papyrus.example.infra.servicesregistry.retrieval
If you are implementing a Command Handler, you can rely on the fact that the currently selected editor is a Papyrus one. In this case, and only in this case, you can get the ServiceRegistry of the currently active Papyrus editor like that:
ServicesRegistry serviceRegistry = ServiceUtilsForActionHandlers.getInstance().getServiceRegistry();
Papyrus has some well known services that can be easily retrieved. To get one of these services, you should use one of the XxxServiceUtils class. You should use the right ServiceUtils class, according to what kind of object you have at disposal. Use one of the following:
org.eclipse.papyrus.core.utils.ServiceUtils
org.eclipse.papyrus.diagram.common.util.ServiceUtilsForGMF
org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForResource
org.eclipse.papyrus.core.utils.ServiceUtilsForActionHandlers
Examples - From the ServiceRegistry:
ServicesRegistry serviceRegistry = getServiceRegistry(); // see How to get the ServiceRegistry TransactionalEditingDomain editingDomain = ServiceUtils.getInstance().getTransactionalEditingDomain(serviceRegistry);
Examples - From an EObject:
EObject eobject = ...; // You should know how to get your EObject :-) ModelSet modelSet = ServiceUtilsForResource.getInstance().getModelSet(eobject.eResource());
Examples - From an Handler (and only from handler, check javadoc):
TransactionalEditingDomain editingDomain = ServiceUtilsForActionHandlers.getInstance().getTransactionalEditingDomain();
The SashWindows system send events when the current active page change (i.e. the nested editor). It is possible to listen on this event.
Your listener should implement the following interface:
org.eclipse.papyrus.sasheditor.editor.IPageChangedListener
Then you need to register your listener to the sashWindowContainer:
ISashWindowsContainer container = getISashWindowsContainer(); // see How to get the ISashWindowsContainer; IPageChangedListener listener = ... // Get your listener container.addPageChangedListener(listener);
The SashWindows system send events during the life cycle of a page (i.e. the nested editor). It is possible to listen on these events.
Your listener should implement the following interface:
org.eclipse.papyrus.sasheditor.editor.IPageLifeCycleEventsListener
Then you need to register your listener to the sashWindowContainer:
ISashWindowsContainer container = getISashWindowsContainer(); // see How to get the ISashWindowsContainer; IPageLifeCycleEventsListener listener = ... // Get your listener container.addPageLifeCycleListener(listener);
The ISashWindowContainer allows to listen on page changed events, or to refresh the windows. There is one ISashWindowsContainer for each Papyrus editor.
It is possible to get it in different ways:
From the ServiceRegistry:
ServicesRegistry serviceRegistry = getServiceRegistry(); // see How to get the ServiceRegistry ISashWindowsContainer container = ServiceUtils.getInstance().getISashWindowsContainer(serviceRegistry);
From an Handler (and only from handler, check javadoc):
ISashWindowsContainer container = ServiceUtilsForActionHandlers.getInstance().getISashWindowsContainer();
From the Papyrus IEditorPart ():
IEditorPart editorPart = getIEditorPart() // The Papyrus editor, not a nested editorPart ISashWindowsContainer container = (ISashWindowsContainer)editorPart.getAdapter(ISashWindowsContainer.class);
You can get the nested editor that is currently active from the ISashWindowContainer.
First, get the ISashWindowsContainer (see ).
Second get the Active nested editor:
ISashWindowsContainer container = getISashWindowsContainer(); // see How to get the ISashWindowsContainer; IEditorPart activeEditor = container.getActiveEditor();
A visible nested editor is one that is visible from the user. There can be several nested editors visible at one time. You can get the list of visible editors:
ISashWindowsContainer container = getISashWindowsContainer(); // see How to get the ISashWindowsContainer; List<IEditorPart> visibleEditors = container .getVisibleIEditorParts();
The IPageMngr class allows to open, close, page in the sash window system. A page is generally a diagram. The IPageMngr also allows to list existing pages, or to check if a page is open. See the javadoc for more.
The IpageMngr can be retrieved from the ServiceRegistry:
ServicesRegistry serviceRegistry = getServiceRegistry(); // see How to get the ServiceRegistry IPageMngr pageMngr = ServiceUtils.getInstance().getIPageMngr(serviceRegistry);
Nested editors can be opened and closed programatically.
For that, you need to have the 'diagram identifier': this is the object that you provide when you open the diagram. The ID. For GMF diagrams, this is usually the notation.Diagram element used as the root of the diagram.
An instance of the class IPageMngr is used to open or close a diagram:
IPageMngr pageMngr = getIPageMngr(); // see How to get the IPageMngr // Open all closed diagrams for( Object id : pageMngr.allPages() { if( ! pageMngr.isOpened(id) pageMngr.open(id); } // Close all opened diagrams for( Object id : pageMngr.allPages() { if( pageMngr.isOpened(id) pageMngr.close(id); }
You can get the current selection inside the active nested editor by using the usual Eclipse way:
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); ISelection selection = page.getActiveEditor().getSite().getSelectionProvider().getSelection();
This will give you a Selection object containing a collection of Graphical Objects (ex: GMF class, Common Navigator class ...). If you want to get the associated "Domain" object (i.e. the UML objects), you should adapt your Graphical Object to a UML one (see How to adapt a Graphical Object to underlying Domain (UML)). See the two next methods for example.
This first method return a list of selected elements:
/** * Lookup selected objects in UI. * @return */ protected List<Object> lookupSelectedElements() { IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); ISelection selection = page.getSelection(); if(selection instanceof IStructuredSelection) { IStructuredSelection structuredSelection = (IStructuredSelection)selection; return structuredSelection.toList(); } else if( selection instanceof TreeSelection) { TreeSelection treeSelection = (TreeSelection)selection; return treeSelection.toList(); } return null; }
When you ask the current selection, you get the selected Graphical Object. Often, you really want the underlying domain object (i.e. the UML object). As there is several graphical technology used in Papyrus (GMF, GEF, Common Navigator ...), you shouldn't test for the type of the selected object, but rather you should "adapt" it to the requested type.
Object obj = ... // The Graphical Object if( obj instanceof IAdaptable ) { NamedElement ele = (NamedElement)((IAdaptable)obj).getAdapter(NamedElement.class); // Adapt object to NamedElement NamedElement ele = null; if( obj instanceof IAdaptable ) { ele = (NamedElement)((IAdaptable)obj).getAdapter(NamedElement.class); } if( ele == null) { ele = (NamedElement)Platform.getAdapterManager().getAdapter(obj, NamedElement.class); } }
The following method get the list of selections, adapt each selected element to get its underlying UML type, and return a list of the found UML types.
/** * Return a list of selected domain (UML) elements. * @return */ protected List<NamedElement> getSelectedUmlObject() { List<Object> selections = lookupSelectedElements(); // see "How to Get the Current Selection from Java code" List<NamedElement> results = new ArrayList<NamedElement>(); // create model with EList<EObject> objects for( Object obj : selections) { // Adapt object to NamedElement NamedElement ele = null; if( obj instanceof IAdaptable ) { ele = (NamedElement)((IAdaptable)obj).getAdapter(NamedElement.class); } if(ele == null) { ele = (NamedElement)Platform.getAdapterManager().getAdapter(obj, NamedElement.class); } if(ele != null) { results.add(ele); } } return results; }
When creating external label you want them to be usable by the framework of MDT Papyrus which handle label visibility. With figure such as WrappingLabel there is a little problem. This consider containing point even if it is invisible. However the correct behaviour for such element is that invisible element should be consider not usable by the diagram. I would advice you from now to use org.eclipse.papyrus.diagram.common.figure.node.PapyrusWrappingLabel instead normal WrappingLabel figure. This figure implement the following method:
@Override public boolean containsPoint(int x, int y) { if (isVisible()){ return super.containsPoint(x, y); } return false; }
If you want to use other figure for externals labels you should make sure the method containsPoint of this method return false if the figure is invisible.
This section contains code example related to diagrams.
The goal is to display a compartment without scroll bar. All elements in this compartment cannot be move outdoor as (the behavior of the scrollbar)
protected void refreshVisuals() { super.refreshVisuals(); ((ResizableCompartmentFigure)getFigure()).getScrollPane().setScrollBarVisibility(org.eclipse.draw2d.ScrollPane.NEVER); refreshBounds(); }
- Overload the method getDragTracker. The purpose of this method is to provide a tracker when you move the editpart. The NoScrollEditPartTracker provides a means to constraint movement in an a compartment without scroll bar
/** * the drag tracker has been specialized in order to constraint mvt inside its container without * scroll bar * {@inheritDoc} */ @Override public DragTracker getDragTracker(Request request) { return new NoScrollDragEditPartsTrackerEx(this); }
-Add an editpolicy for the role PRIMARY_DRAG_ROLE that provides A tracker for the constrained resize “NoScrollResizeTracker” A tracker for the constrained move “NoScrollDragEditPartsTrackerEx”
/** * this code has been overloaded in order to constraint the resize into its container without scroll bars *{@inheritDoc} */ @Override protected ResizeTracker getResizeTracker(int direction) { return new NoScrollResizeTracker((GraphicalEditPart) getHost(), direction); } /** * this code has been overloaded in order to constraint the move into its container without scroll bars *{@inheritDoc} */ @Override protected DragEditPartsTracker getDragTracker() { return new NoScrollDragEditPartsTrackerEx(getHost()); }
It is possible to create graphical elements programmatically. You need to obtain first a reference to an existing graphical view, for instance to obtain a reference to the current diagram in an Eclipse handler.
// event is an ExecutionEvent passed to an Eclipse handler ISashWindowsContainer windowsContainer = ServiceUtilsForHandlers.getInstance().getISashWindowsContainer(event); Object model = windowsContainer.getActiveSashWindowsPage().getRawModel(); if(model instanceof PageRef) { EObject diagramEObj = ((PageRef)model).getEmfPageIdentifier(); if(diagramEObj instanceof Diagram) { Diagram diagram = (Diagram)diagramEObj; ...
The Interfaces Diagram, Edge, View and Node can be found in the package org.eclipse.gmf.runtime.notation.
Once the diagram is recovered, you can use the UMLViewProvider of a specific diagram to create new elements within. In general, you need to create a UML element first and then use the provider to create the associated view. For instance, if you want to create a view for a lifeLine within a sequence diagram, you can use the following code. Note that the lifeline is not placed directly into the passed interaction view. Instead, the interaction view has a child corresponding to its compartment.
/** * Add a lifeline view for a given UML lifeline within an interaction view * @param lifeline the UML lifeline * @param interactionView the view associated with the interaction * @param x layout hint * @param y layout hint * @return the created view */ public View addLifeline(Lifeline lifeline, View interactionView, int x, int y) { // get first compartment of view Object compartment = interactionView.getChildren().get(1); // use the generic view service to create views This is a bit cleaner than using specific operations of the sequence-diagram view // provider (as we do below for the message) final String nodeType = UMLVisualIDRegistry.getType( org.eclipse.papyrus.uml.diagram.sequence.edit.parts.LifelineEditPart.VISUAL_ID); Node lifelineView = ViewService.createNode((View) compartment, lifeline, nodeType, UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT); Bounds location = NotationFactory.eINSTANCE.createBounds(); location.setX(x); location.setY(40); if(lifelineView instanceof Node) { ((Node)lifelineView).setLayoutConstraint(location); } return lifelineView; }
The interaction has a single compartment. Other graphical elements like classes have severals (you can find out via the filters->show/hide compartment dialog). In this case, you need to make sure to obtain the right one.
Edges (lines) are created in a similar way, for instance a message betweeen two lifelines can be added with the following function. It is typically required to set source and target.
/** * Add a message view for a given UML message within a given diagram * @param message UML message * @param diagram Sequence diagram * @param lifelineSrcV view of source lifeline * @param lifelineDstV view of destination lifeline */ public void addMessage(Message message, Diagram diagram, View lifelineSrcV, View lifelineDstV) { View messageView = sequenceDiagViewProvider.createMessage_4004(message, diagram, -1, true, UMLDiagramEditorPlugin.DIAGRAM_PREFERENCES_HINT); if(messageView instanceof Edge) { ((Edge)messageView).setSource(lifelineSrcV); ((Edge)messageView).setTarget(lifelineDstV); } }
The whole plugin, called org.eclipse.papyrus.uml.diagram.example.programmaticcreation, can be found in the Papyrus git. The plugin provides commands that create two lifelines and a message in a sequence diagram and a collaboration use in a composite diagram (when a composite class is selected). If you use the plugin, you have to create the respective diagram first as usual and then call commands from the context menu (sub-menu "Test diagram creation") to call code that programmatically adds elements to UML and the diagram.
Caveat: the example is very simple and does not check whether the user invokes the creation of lifelines in the context of an interaction within a sequence diagram or an interaction within another diagram. The lifeline example only works for interactions within a sequence diagram, the collaboration-use example only for composite classes within a composite structure diagram.
RCPTT was used in some versions of Papyrus but was abandoned for non conclusive tests (differs from developers results). But you can find some explanations:
RCPTT is an Eclipse Project that provides a testing tool for Eclipse RCP application. RCPTT allows to run GUI tests based on ECL. Several functions as the "Record actions" make RCPTT easy to handle and use for beginners. After a bit of experience, it will be easy to understand the different commands and make more complex scripts.
A quick Start guide is available here : Getting Started with RCPTT:
The RCPTT "framework" has been put in place in Papyrus RT. Some tests are already created and could base as example.
RCPTT Eclipse can be found https://www.eclipse.org/rcptt/download/.
You can find an example to create RCTTT test for papyrus here.
Here are some tips to have an homogeneous practice around RCPTT. This is a certain way to work, maybe not the best one. If you have other opinion, please share it here.
A way to organize Rcptt test for Papyrus is to do a RCPTT project by feature to test. For example in org.eclipse.papyrus.tools/rcptt/.
Another way is to only have one project as done in PapyrusRT. In the RCPTT root in org.eclipse.papyrus-rt\releng\rcptt
of the project we should have the following elements:
The structure of projects is different if you choose to have only one RCPTT project or several.
In the case as papyrusRT of one plugin, after importing the rcptt folder into the RCPTT eclipse IDE, the the tests created should respect architecture to make this folder easy to maintain.
Another structure is also possible in case of several RCPTT plugin, with a folder for each type of files:
rcptt.properties is shown as Project Settings file in the Test Explorer and contains Description, default contexts and default Validations.
There are several type of contexts :
There are various types of contexts:
To identify them easily, the names of contexts should be prefixed by a tag according to the type of context file:
Workspace | WS_[context-name].ctx |
Workbench | WB_[context-name].ctx |
Folder | FS_[context-name].ctx |
Parameters | PARAM_[context-name].ctx |
Preferences | PREF_[context-name].ctx |
Group | GROUP_[context-name].ctx |
ECL Script | ECL_[context-name].ctx |
Launch | DEBUG_[context-name].ctx |
Super Context | SUPER_[context-name].ctx |
All tests are executed alphabetically and this should work as each test must be independant ! But in order to have a better overview during execution, it would be a good practice to regroup test by feature. For this reason here is a naming convention used as for now:
[FeatureName]_[XY]_[TestName]
For Example:
CallEvent_15_CreateCallEventTest
Represents a test around CallEvent, 1 = creation , 5 = fifth test of Creation of CallEvent.
When you want to test Papyrus, you need to initialize your application’s workspace. For that you can use Papyrus model files.
First, export or copy model files of the papyrus project that you want use to start your tests and place them in a folder named //models// at the root of your rcptt project.
Then, create a new workspace context, open it and create an empty project. Once the project created, import files from the Papyrus model onto the created project.
Then, if you launch a test linked with your workspace context or if it is add by default in your project settings, the AUT’s workspace will be initialized with model files and creates a project with elements you need to start the test.
Sometimes you have to execute the same tests with variant parameters, with super contexts it’s possible to launch the same script with different values.
For example if you want to use a procedure which create a node on a diagram:
For each possible node, you create a parameter context which contains the node’s label in the palette and the coordinates of the node, for each value, the parameter’s name must be the same in each context.
Link all contexts to a super context of the same type as them and in the test, use the super context by using the parameters’ names in your test script.
RCPTT will launch your test script for each context link to your super context.
The super context is execute with each context successively and give different parameters to your test and give you the possibility to test different elements with the same test.
If one of your tests detects a bug on your AUT and fails, you can add to this test a tag "ignore" and you can configure the job which launch it so that it will skip this test. Then, if your test is linked to a bug, you can add a comment in the bug's report to indicate the presence of the skipped test so that the tag will be removed once the anomaly corrected.
Description : This function open the given model and the given diagram.
Parameters : project : Label of project to open in Project Explorer. (String) model : Label of model to open in Project Explorer. (String) rootName : Label of the RootElement in Model Explorer. (String) diagramName : Diagram’s label in Model Explorer. (String)
Description : This function add a diagram to the current model.
Parameters : type : Type of diagram to create in creation menu. (String) name : Name of the new diagram created. (String) modelExplorerRootName : Name of the Model Explorer view. (String)
Description : This function add a node on the given diagram by using the palette.
Parameters : name : Label of the node to create in the palette. (String) x : Abscissa of the node to create on the editor. (int) y : Ordinate of the node to create on the editor. (int) defaultName : Node’s default name in the model explorer. (String) diagramName : Diagram’s label on the editor. (String) rootName : Name of the RootElement. (String)
Description : This function remove a node on the given diagram.
Parameters : nameNode : Name of the node on the editor. (String) diagramName : Diagram’s label on the editor. (String) rootName : Name of the RootElement. (String)
Description : This function add a child to a parent node on the editor.
Parameters : parentName : Name of the parent node on the editor. (String) childName : Label of the element child to create in the palette. (String) pathChildDefaultName : Path to Child’s default name in model explorer. (String) rootName : Name of the RootElement. (String)
Description : This function removes a node’s child on the editor.
Parameters : parentName : Name of the parent node on the editor. (String) childName : Name of the child to remove on the editor. (String) diagramName : Diagram’s label on the editor. (String) rootName : Name of the RootElement. (String)
Description : This function creates a relation between two given nodes.
Parameters : relation : Label of the relation in the palette. (String) element1 : Name of the first node on the editor. (String) element2 : Name of the second node on the editor. (String) diagramName : Diagram’s label on the editor. (String) rootName : Name of the RootElement. (String)
Description : This function replaces node’s name by a new one.
Parameters : pathOldName : path to node’s name to replace in model explorer. (String) newName : New name of the node. (String) pathNewName : Path to node’s new name in model explorer. (String) diagramName : Diagram’s label on the editor. (String) rootName : Name of the RootElement. (String)
Description : This function modify an element’s property which use a combo-box.
Parameters : propertyTab : Label of tab which contains the combo-box to modify in view properties. (String) propertyLabel : Label of property to modify in view properties. (String) propertyValue : New value of the property to modify. (String) pathNameElement : Path in model explorer of the element’s default name which have a property to modify. (String) rootName : Name of the RootElement. (String)
Description : This function add a comment on the given diagram.
Parameters : x : Abscissa of the comment to create on the editor. (int) y : Ordinate of the comment to create on the editor. (int) textComment : Body of the comment to create. (String) diagramName : Diagram’s label on the editor. (String) editorRootName : Name of the root in editor. (String) explorerRootName : Name of the root in model explorer. (String) pathComment : Path to comment’s name in model explorer. (String)
Description : This function remove a comment of a given diagram.
Parameters : explorerRootName : Name of the root in model explorer. (String) pathComment : Path to comment’s name in model explorer. (String)