JWT Extensions

From Eclipsepedia

Jump to: navigation, search

This page provides information on how to extend the JWT Workflow Editor (JWT-WE) through plugins.

Contents

Overview

The JWT Workflow Editor defines several extension points and mechanisms that allow users to customize and extend the abilities and properties of JWT-WE without changing the editor itself. However, there may be cases in which it becomes necessary to alter the Workflow Editor code itself, notably when the new features need to be implemented by committers of the JWT project. This page is intended to describe how third party suppliers can extend JWT-WE (e.g. with custom views on the model elements) through external plugins using the defined extension points (if you're instead looking for tutorials on how to modify the Workflow Editor or how to directly implement new features, please take a look at JWT_Modifications).

Extending JWT-WE through Plugins

The JWT-WE Platform

The Workflow Editor can be extended using standard Eclipse extension points and it also defines several new extension points.

The plugin interfaces of the JWT Workflow Editor

Adding Actions to Menu/Toolbar

New actions can be added to the Workflow Editor using the org.eclipse.jwt.we.menu extension point. It is then added to the WE toolbar as a selectable option in the External Functions dropdown menu. If the editor is run in RCP mode, an additional entry in the main menu bar is created. The action itself has access to several resources of the editor and the loaded model.

Some sample actions which are displayed in the toolbar of the Workflow Editor
Menu entries for the external actions (only in RCP mode)


An action which is hooked into the Workflow Editor must extend the abstract class org.eclipse.jwt.we.editors.actions.external.WEExternalAction:

  • Overwriting the method getImage() allows to provide an ImageDescriptor, which contributes an icon for the action (or null)
  • The run() method is called, when the user selects the action in the toolbar or main menu

Help methods available in WEExternalAction are:

  • getActiveWEEditor(): returns the active WEEditor, which allows to access many parts of JWT-WE
  • getActiveActivitySheet(): returns the active graphical editor (WEEditorSheet)
  • getActiveResource(): returns the XMIResource, that contains the currently loaded model file
  • getActiveShell(): returns the active shell

Additional interesting points for plugin developers:

  • org.eclipse.jwt.we.editors.preferences.PreferenceReader: allows easy access to the preference store
  • org.eclipse.jwt.we.figures.FigureFactory: creates the Draw2D figures used by GEF to display the diagram
  • org.eclipse.jwt.we.misc.logging.Logger: the logger
  • org.eclipse.jwt.we.misc.util.*: several help classes
  • org.eclipse.jwt.we.misc.views.Views: access the views subsystem
  • org.eclipse.jwt.we.model.*: The EMF meta model and edit code
  • org.eclipse.jwt.we.PluginProperties: access the localized strings used in the editor
  • org.eclipse.jwt.we.Plugin: the main plugin

The required steps to register one ore more actions with JWT-WE are:

  • Create a new plugin project
  • Add jwt-we to your project dependencies
  • Add an extension for the point org.eclipse.jwt.we.menu
  • Create a new action child element for this extension point
    • class must be set to the Java class which contains the action (must subclass org.eclipse.jwt.we.editors.actions.external.WEExternalAction)
    • name and description refer to the displayed name and tooltip description. They can be set directly or read from plugin.properties using the %-prefix
    • showInToolbar and showInMenu define whether the action is shown in the Toolbar and/or the Menu bar (menu is only available in RCP mode)
    • forceText forces the name of the action to be shown in the toolbar, even if an icon is provided in the action.
    • If requiresOpenEditor is set to true, the action is hidden/disabled if no Workflow Editor is active in Eclipse (this only affects RCP mode)

If you want to listen to selection changes, WEExternalActions are already ISelectionListener but you have to make it listen to them by adding this code to your own WEExternalAction :

Plugin.getInstance().getWorkbench().getActiveWorkbenchWindow().getSelectionService().addSelectionListener(this);

To register the external actions shown above, you will need to add the following code to your plugin.xml:

   <extension
         id="org.eclipse.jwt.we.menu"
         name="org.eclipse.jwt.we.menu"
         point="org.eclipse.jwt.we.menu">
      <action
            class="org.eclipse.jwt.we.ExternSample.actions.SampleAction1"
            description="Sample1 Description"
            forceText="false"
            name="Sample1"
            requiresOpenEditor="true"
            showInMenu="true"
            showInToolbar="true"/>
      <action
            class="org.eclipse.jwt.we.ExternSample.actions.SampleAction2"
            description="Sample2Description"
            forceText="true"
            name="Sample2"
            requiresOpenEditor="true"
            showInMenu="true"
            showInToolbar="false"/>
      <action
            class="org.eclipse.jwt.we.ExternSample.actions.SampleAction3"
            description="Sample3 Description"
            forceText="true"
            name="Sample3"
            requiresOpenEditor="true"
            showInMenu="false"
            showInToolbar="true"/>
      <action
            class="org.eclipse.jwt.we.ExternSample.actions.SampleAction4"
            description="Sample4 Description"
            forceText="true"
            name="Sample4"
            requiresOpenEditor="false"
            showInMenu="true"
            showInToolbar="true"/>
   </extension>

Example plugin for defining external actions (org.eclipse.jwt.we.ExternSample):

Zip File: Media:jwt-we-external-action-sample.zip
CVS: [1]

Adding Views

The Workflow Editor can be extended with views that allow to customize how the model is displayed. JWT comes with a technical, business, Event-driven Process Chains and an UML Activity view.

Views must be registered through the org.eclipse.jwt.we.view extension point.

The two standard views that come with JWT-WE

How to create external views:

  • Set an internal ID and a display name for the view.
  • Using the JWT WE View Editor, create a *.view file. This file specifies which model elements will be visible in this view.
  • Optional: Set a display icon for the view
  • Optional: Set a FactoryRegistry for the view

A FactoryRegistry allows to provide a custom Palette, FigureFactory, EditPartFactory and ImageFactory thereby enabling to completely change the layout of the displayed mode.

Additional views provided by the example plugin (toolbar)
Additional views provided by the example plugin (RCP menubar)

Adding Editor sheets

The Workflow Editor is of the type MultiEditorPart and thus may contain multiple editors which are represented as independet sheets. JWT-WE already contains two built-in editor sheets:

  • The Overview Sheet, which is a SWT Control. It is automatically opened for each loaded workflow and cannot be closed.
  • The Activity Editor, a graphical GEF EditorPart. Multiple activity editors can be opened for activities contained in one workflow. The ActivityEditor sheet is closable.

Through the extension point for external editor sheets, it is possible to integrate your own editors into JWT-WE. They can be opened automatically when loading a workflow model or manually using the context menu of the Workflow Editor.

The two types of editor sheets that come with JWT-WE

The sheet must be provided to the Workflow Editor through an IWEExternalSheetProvider, i.e. a class must be created that implements org.eclipse.jwt.we.editors.pages.externalSheet.IWEExternalSheetProvider. This interface contains two methods:

  • init(WEEditor editor) is called before the new editor sheet should be displayed. This method offers the possiblity to initialize the custom editor and to save a reference to the parent MultiEditorPart of the type WEEditor.
  • getExternalSheet() is called to obtain the editor sheet. The editor sheet may be provided as an IEditorPart or a SWT Control. In case of adding a Composite, the parent container is the tabfolder of the MultiPartEditor: editor.getTabFolder().

The required steps to register one ore more sheets with JWT-WE are:

  • Create a new plugin project
  • Add jwt-we to your project dependencies
  • Add an extension for the point org.eclipse.jwt.we.sheet
  • Create a new sheet child element for this extension point
    • title is the name of the editor sheet displayed in its tab in the MultiPartEditor
    • class must be set to the Java class which provides an IEditorPart or SWT Control as editor sheet (must implement org.eclipse.jwt.we.editors.pages.externalSheet.IWEExternalSheetProvider)
    • If closable is set to true, the editor sheet can be closed
    • If autoshow is set to true, an instance of the editor sheet is automatically created when a workflow is loaded
    • If multiple is set to true, multiple instances of the editor sheet can be created
A custom editor sheet that can be opened multiple times

If you want your editor sheet to be notified about changes in the model, you'll need to implement org.eclipse.emf.common.notify.Adapter and add your sheet as listener to the main model element of the editor ((EObject)editor.getModel()).eAdapters().add(this) and remove the listener in the dispose() method.

To register the external sheets as shown above, you will need to add the following code to your plugin.xml:

   <extension
         id="org.eclipse.jwt.we.sheet"
         name="Example"
         point="org.eclipse.jwt.we.sheet">
      <sheet
            autoshow="true"
            class="org.eclipse.jwt.we.plugins.sheetexample.sheets.ExampleSheet1SheetProvider"
            closable="false"
            multiple="false"
            title="%sheet_Example1_title">
      </sheet>
      <sheet
            autoshow="true"
            class="org.eclipse.jwt.we.plugins.sheetexample.sheets.ExampleSheet2SheetProvider"
            closable="true"
            multiple="true"
            title="%sheet_Example2_title">
      </sheet>
   </extension>

The example plugin for defining external editor sheets (org.eclipse.jwt.we.plugins.sheetexample):

Zip File: Media:jwt-we-external-sheet-sample.zip
CVS: [2]



Adding Property Sheet Pages

The workflow editor contains support for a multi-tab property sheet (TabbedPropertiesView) which is only activated if additional tabs are provided by plugins. If this is not the case, the classical property sheet is used which does not display any tabs. If the multi-tab sheet is used, a single tab Standard is always shown, which contains the model element properties as would be normally shown in the classical property sheet.

The classical property sheet without tabs that shows the model element properties
The multi-tab sheet with the Standard tab that shows the model element properties

To add a new property sheet page to the editor, it is necessary to define a new property tab in the plugin.xml and fill it with one or more property sections. The implementation of property sections is described in this Eclipse article. Once the property section have been implemented, they can be registered with the property tab.

The required steps to create one ore more new property tab(s) are:

  • Create a new plugin project
  • Add jwt-we to your project dependencies
  • Add an extension for the point org.eclipse.ui.views.properties.tabbed.propertyTabs
  • Create a new propertyTabs child element for this extension point and set its contributorID to org.eclipse.jwt.we.editors.WEEditor
  • Create a new propertyTab child element for each property tab that you wish to add to the property sheet. The label corresponds to the displayed name of the tab (use % as prefix to load a language specific caption from plugin.properties). The category should be set to WEStandardCategory. The id should be a unique identifier (use org.eclipse.jwt.we.propertytabs. as prefix) and setting afterTab to org.eclipse.jwt.we.PropertyTabStandard will ensure that the standard tab remains the topmost tab entry.

The required steps to register property sections with the newly defined tab(s) are:

  • Add an extension for the point org.eclipse.ui.views.properties.tabbed.propertySections
  • Create a new propertySections child element for this extension point and set its contributorID to org.eclipse.jwt.we.editors.WEEditor
  • Create a new propertySection child element for each property section that you wish to add to one of your property tabs. The tab must be set to the id of the property tab which should contain this section. The id should be a unique identifier (use org.eclipse.jwt.we.propertysections. as prefix). The class attribute connects this entry to the actual implementation of the section, which should be a subclass of org.eclipse.ui.views.properties.tabbed.AbstractPropertySection. Setting enablesFor to 1 ensures, that the section is only available if a single element is selected. afterSection can be used to specify the arrangement of multiple sections in one tab.
  • Create an input child for each section and assign its type a Java class type like org.eclipse.emf.ecore.EObject. The property section/tab is only shown if an element of this type (or a subtype) is selected.

The following excerpt from plugin.xml shows the definition of a new property tab (Advanced) that contains only one section (implemented in org.eclipse.jwt.we.propertiesexample.sections.AdvancedPropertySection). The new property tab is only activated if a model element of the type org.eclipse.jwt.we.model.processes.ActivityNode is selected.

   <extension
         point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
      <propertyTabs
            contributorId="org.eclipse.jwt.we.editors.WEEditor">
         <propertyTab
               afterTab="org.eclipse.jwt.we.propertytabs.Standard"
               category="WEStandardCategory"
               id="org.eclipse.jwt.we.propertytabs.Advanced"
               label="%properties_Advanced_label">
         </propertyTab>
      </propertyTabs>
   </extension>
   <extension
         point="org.eclipse.ui.views.properties.tabbed.propertySections">
      <propertySections
            contributorId="org.eclipse.jwt.we.editors.WEEditor">
         <propertySection
               class="org.eclipse.jwt.we.propertiesexample.sections.AdvancedPropertySection"
               enablesFor="1"
               id="org.eclipse.jwt.we.propertysections.Advanced"
               tab="org.eclipse.jwt.we.propertytabs.Advanced">
            <input
                  type="org.eclipse.jwt.we.model.processes.ActivityNode">
            </input>
         </propertySection>
      </propertySections>
   </extension>
An additional tab named Advanced was added to the multi-tab property sheet



Adding an import or export transformation

See JWT Transformations


Adding support for synchronization to a domain-specific Document Management System

See JWT ECM Sync


Adding a new Double click handler

Description

The extension point org.eclipse.jwt.we.doubleclick allows you to add an handler for double clicks event on model elements,

Behavior

  • Beware that for application, roles and data, double-clicked model element is not the item directly, but a Reference model element. This often introduce the need to check for Reference.getReference().
  • When implementing the DoubleClickHandler.processDoubleClick method, ensure to wrap all code that modifies the model into a Command, and add it to the editionDomain commandStack, so that undo redo and save will work

Code

TODO when committed



Adding a new DropTargetAdapter

Description

The extension point org.eclipse.jwt.we.dnd allows you to add TransferDropTargetListener to the activity diagram editor and to the Outine tree.

You simply have to plus to this extension point a factory that creates the TransferDropTargetListener for the workflow editor.

Behavior

  • event.data is only aivalable in the drop method. In other methods, it is null.
  • When implementing the isEnabled method, then you must respect these principles, otherwise the wrong TransferDropTargetListener will be called
    • isEnable must return false only when you are sure that this drop behavior cannot be applied (for example if event.data contains a specific value)
    • in case you don't have enough information to ensure the drop behavior in the good one (for example when event.item or event.data is null), then you should return true
  • When implementing the drop method, you must use a command, that you add to the editingDomain command stack and that contains the operations you want to apply on model. That way, you'll be able to use save undo and redo icons.

Code

TODO when committed


Adding Custom PropertyDescriptor (and editors) in property sheets

Description

The aim of this extension is to provide the ability to use a different Property Editor than the default one provided by EMF. This can be used for example to facilitate the input of data by proposing choices instead of letting user type something (reduce error risks).

The extension point is named org.eclipse.jwt.we.propertyDescriptor, it is made of:

  • The description of the EMF feature whom editor we want to change in property sheet
    • The EMF packageName (eg org.eclipse.jwt/application
    • The EMF className (eg WebServiceApplication)
    • The EMF featureNane (eg method)
  • The PropertyDescriptorFactory (defined in JWT-WE) that is responsible of creating an instance of PropertyDescriptor for the specified feature

For each property descriptor that should be different than the original, you need to extend the predefined extension point as follows:

  <extension
        point="org.eclipse.jwt.we.propertyDescriptor">
     <customPropertyEditor
           PropertyDescriptorFactoryImpl="de.uniAugsburg.project.ProjectSpecificPropertyDescriptorFactory"
           className="NameOfTheClassInEMF"
           featureName="NameOfTheFeatureThatIsSpecifiedInTheMetamodelOrConfModel"
           packageName="de.uniAugsburg.project>
     </customPropertyEditor>
  </extension>

In my example "NameOfTheClassInEMF" is a subclass of AspectInstance and provides the feature "NameOfTheFeatureThatIsSpecifiedInTheMetamodelOrConfModel".

The factory is pretty simple. It looks as follows:

 public class ProjectSpecificPropertyDescriptorFactory implements
 		PropertyDescriptorFactory {
 
 	public IPropertyDescriptor getPropertyDescriptor(Object object,	IItemPropertyDescriptor itemPropertyDescriptor) {
 		return new ProjectSpecificPropertyDescriptor(object, itemPropertyDescriptor);
 	}
 }

The ProjectSpecificPropertyDescriptor extends the EMF PropertyDescriptor and overrides the createPropertyEditor method. In this case it creates an own ProjectSpecificDialogCellEditor:

 public class ProjectSpecificPropertyDescriptor extends PropertyDescriptor {
 	
 	
 	public ProjectSpecificPropertyDescriptor(Object object, IItemPropertyDescriptor itemPropertyDescriptor)
 	{
 	  super(object, itemPropertyDescriptor);
 	}
 
 	@Override
 	public CellEditor createPropertyEditor(Composite parent) {
 		ProjectSpecificDialogCellEditor cellEdit =
 			(ProjectSpecificDialogCellEditor) new ProjectSpecificDialogCellEditor(parent, getLabelProvider(), "");
 			return cellEdit;
 	}	
 }

In this case the ProjectSpecificDialogCellEditor extends the ExtendedDialogCellEditor and simply opens a dialog box.

Behavior

  • If there are several propertyDescriptors on this extension point for the same feature, then we can't guess which one will be used.
  • Override when Subclass: If there is a propertyDescriptor PropInClazzPropertyDescriptor for property Prop of EMF class Clazz, and a propertyDescriptor PropInSubClazzPropertyDescriptor for property Prop of EMF class SubClazz, then it will use PropInSubClazzPropertyDescriptor for SubClazz and children, and PropInClazzPropertyDescriptor for Clazz and chhildren, except for SubClazz and children.

Utils

  • Since several propertyDescriptor may share common and useful classes, generic PropertyDescriptors can be found in the "library" plug-in org.eclipse.jwt.we.editors.properties.widgets

Example / Code

  • jwt-we-helpers-files is a simple plugin that sets browser property descriptor and editor through this extension point.

HowTo / Wink

TODO

Use cases

  • Use a file browser for "icon" property (plugin: org.eclipse.jwt.we.editors.properties.extension.icon)
  • Use a file browser for "jarArchive" property (plugin: org.eclipse.jwt.we.editors.properties.extension.jarFile)
  • Use a combo box for property "method" of class Application when succeeding to introspect specified class (plugin: org.eclipse.jwt.we.editors.properties.extension.applicationmethod).

Adding NotificationChangeListener when a value is changed in EMF Model

Description

The aim of this extension is to provide the ability to listen to changes of EMF values of EMF Model and then to run a piece of code according to the notification. For example, automatically generate an alert when a value does not fit a constraint, or automatically set a property value according to the one that just changed (eg set parameters of an application according to the choosen method signature)

The extension point org.eclipse.jwt.we.changeListener is defined by:

  • The EMF feature that we want to listen changes
    • EMF packageName
    • EMF className
    • EMF featureName
  • An implementation for INotifyChangedListener

Behavior

A notification listener on a feature is applied to feature of specified class and subclasses. When several extensions associates a change listener to the same feature, then all listeners will run their notifyChanged method when notified in an order that can not be previwed.

Code / Example

TODO when commited

Demo / Howto / Wink

TODO

Use cases

  • Set application parameters when method is set on an application (plugin: org.eclipse.jwt.we.changeListener.applicationMethod)

Adding Meta Model Extensions

See JWT_Metamodel_Extension :

See also