HowTo extend Fujaba4Eclipse

From FujabaWiki

This article describes how to develop an Eclipse plug-in that extends Fujaba4Eclipse by a new type of diagram/model and provides a graphical editor for it. The article explicitly considers already existing Fujaba plug-ins.

Table of contents

Getting started

  • Install Eclipse (http://www.eclipse.org/) 3.3 and GEF (http://www.eclipse.org/gef/) 3.2 or higher.
  • You may want to checkout an example plug-in from module MyPlugin4Eclipse. The MyPlugin4Eclipse plug-in contains example implementations for most of the things described in the following.

Create a new plug-in

New Plug-in Project wizard
Enlarge
New Plug-in Project wizard

Create a new Eclipse plug-in project via the new Plug-in Project wizard (menu File->New->Project->Plug-in Project), cf. figure New Plug-in Project wizard.

  • Generate a plug-in Java class which will make contributions to the UI
  • Do not use any template
  • Add a dependency to the Fujaba4Eclipse plug-in in the plug-in manifest generated for the new plug-in

Reuse/Port an existing Fujaba plug-in

In order to port an existing Fujaba plug-in to the Eclipse platform we suggest to create a new Eclipse plug-in (as described in the previous section) which will contain all the Eclipse specific stuff and work as a sort of adapter.

This new 4Eclipse plug-in will of course depend on classes defined by the existing Fujaba plug-in. One way to provide the required classes would be to package the Fujaba plug-in in a jar file and make it available to the new plug-in as a library. However, changes to the Fujaba plug-in would require an update of this jar file.

Therefore we suggest to turn your existing Fujaba plug-in into an Eclipse "library" plug-in which makes classes available to other Eclipse plug-ins but does not contribute anything else to Eclipse.

In order to turn your Fujaba plug-in into an Eclipse library plug-in you have to:

1. Rename the existing plugin.xml file to fujabaPlugin.xml

2. Create an Eclipse plugin.xml file. The simplest way will be to copy the example shown below and change it appropriately.

<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin
   id="de.upb.patternspecification"
   name="PatternSpecification Plug-in"
   version="2.1.1">

   <runtime>
      <library name="patternspecification.jar">
         <export name="*"/>
      </library>
   </runtime>

   <requires>
      <import plugin="de.uni_paderborn.fujaba" version="4.3.2" match="greaterOrEqual"/>
   </requires>   
</plugin>

You have to provide an id, a name and version information. The runtime-tag specifies that the plug-in contents be exported as a jar file named patternspecification.jar, e.g. for deployment in the runtime workspace. How this jar file is to be built is specified in a separate file called build.properties (see below). The requires-tag specifies the Eclipse plug-ins this plug-in depends on, in this case the Fujaba Eclipse library plug-in (not the FujabaForEclipse plug-in!).

3. Create an Eclipse build.properties file. The easiest way will be to copy the example shown below and change it appropriately.

source.patternspecification.jar = src/
output.patternspecification.jar = bin/
bin.includes = plugin.xml,\
               patternspecification.jar

Create/Reuse Meta-Model

MyPlugin4Eclipse meta-model
Enlarge
MyPlugin4Eclipse meta-model

When porting an existing Fujaba plug-in to Eclipse you already have a meta-model and its implementation. Otherwise create your meta-model with Fujaba and generate its implementation. Use classes from Fujaba's Abstract Syntax Graph (ASG) - package de.uni_paderborn.fujaba.asg, in particular ASGElement - as super classes. The figure MyPlugin4Eclipse meta-model shows a class diagram of the MyPlugin4Eclipse meta-model as an example. Its implementation can be found in de.uni_paderborn.myPlugin4Eclipse.metamodel.

Fujaba4Eclipse uses the Graphical Editing Framework (GEF) (http://www.eclipse.org/gef/) to create visual editors for models. GEF (http://www.eclipse.org/gef/) assumes that instances of your meta-model elements fire PropertyChangeEvents when they are changed. Consequently, if you plan to provide a visual editor in Fujaba4Eclipse, you have to adapt your meta-model in such a way that all required events are fired. Since your meta-model classes are derived from ASGElement the necessary property change support is already available.

Displaying and editing models

GEF (http://www.eclipse.org/gef/) Overview
Enlarge
GEF (http://www.eclipse.org/gef/) Overview

Fujaba4Eclipse uses the Graphical Editing Framework (GEF) (http://www.eclipse.org/gef/) to create visual editors for models. GEF (http://www.eclipse.org/gef/) follows the model-view-controller (MVC) paradigm, cf. figure GEF (http://www.eclipse.org/gef/) Overview.

ModelElement objects of course are instances of your meta-model classes. EditPart objects are the controllers and Figures are used to display model elements and thus play the view part. For each model element to be displayed by an Editor, the editor creates an edit part. The edit part listens to PropertyChangeEvents fired by the model element and creates/updates figures displaying the model element. Thus, the edit parts correspond to unparse modules and updaters used in Fujaba.

The editor sends Request objects to the edit parts, e.g. when model elements are to be moved or resized. The edit parts forward the requests to a set of EditPolicy objects which respond to the requests by creating Commands. The commands are executed and put on a stack by the editor.

Please have a look at the GEF (http://www.eclipse.org/gef/) documentation for more details. The following sections explain the steps necessary to provide the required implementations of e.g. edit parts, or edit policies and which abstractions Fujaba4Eclipse provides for displaying and editing meta-models based on Fujaba's Abstract Syntax Graph (ASG).

Create EditParts & Figures

  • Create EditPart class for each model class to be displayed
  • Subclass AbstractASGEditPart, AbstractBoundedASGEditPart, AbstractASGNodeEditPart, or AbstractASGConnectionEditPart which already implement
    • de-/registering as property change listener
    • creation of ASGUnparseInformation
    • computing dimensions and location
  • Implement creation and update of figures
  • Implement reaction to property change events
  • Provide model children or connection model elements
  • Create and set EditPolicy instances (see also)
  • Reuse figures from e.g. de.uni_paderborn.commons4eclipse.gef.figures.*, de.uni_paderborn.fujaba4eclipse.uml.figures.*, de.uni_paderborn.fujaba4eclipse.uml.behavior.figures.*, or de.uni_paderborn.fujaba4eclipse.uml.structure.figures.*.

Cf. MyPluginForEclipse, package de.uni_paderborn.myPlugin4Eclipse.edit.editparts for examples.

Create Editor

  • AbstractASGDiagramEditor
    • Plugs into multi-page Fujaba4Eclipse editor
    • Provides basic actions (undo, redo, delete, save, print)
    • Has a DefaultPaletteRoot instance with tool for selecting diagram objects
    • Needs an EditPartFactory to create edit parts

  • Subclass AbstractASGDiagramEditor
  • Reuse DefaultEditPartFactory (by subclassing or instantiation)
  • Add your PaletteDrawer instance to it
  • Or provide your own PaletteRoot implementation by subclassing AbstractPaletteRoot
  • Create additional actions, context menu, … have a look at Fujaba4Eclipse for examples

Cf. MyPlugin4Eclipse, package de.uni_paderborn.myPlugin4Eclipse.editors for examples.

Create Commands

  • AbstractUndoableCommand is base class of all Fujaba4Eclipse commands (uses Coobra for undo/redo)
  • Fujaba4Eclipse provides commands for
    • changing position and size of elements
    • creating, deleting, moving bends in connections
    • deleting ASG elements
  • New commands are needed for all other actions except property changes, e.g. creation of MyDiagrams, MyNodes, MyEdges
  • Subclass AbstractCreateASGDiagramCommand, AbstractCreateWithDefaultNameCommand, or AbstractCreateConnectionCommand

Have a look at the commands for editing the diagrams in Fujaba4Eclipse packages de.uni_paderborn.fujaba4eclipse.uml.behavior.commands, de.uni_paderborn.fujaba4eclipse.uml.structure.commands or in MyPlugin4Eclipse package de.uni_paderborn.myPlugin4Eclipse.commands.

Create EditPolicies

  • ComponentEditPolicy
    • for handling anything, asked for arbitrary and deletion commands
    • can be used by any edit part
  • XYLayoutPolicy
    • moving and resizing elements
    • creation of elements
    • used by node edit parts for adding child elements, e.g. UMLAttr‘s to a UMLClass
  • GraphicalNodeEditPolicy
    • creation of connections between model elements
    • typically used by node edit parts

You may find some base classes in package de.uni_paderborn.fujaba4eclipse.edit.editpolicies. Create subclasses as needed. Cf. MyPlugin4Eclipse, package de.uni_paderborn.myPlugin4Eclipse.edit.editpolicies for examples.

Create PropertySourceAdapters

In order to use the property sheet page for editing model elements a property source adapter that implements the IPropertySource interface is required for each type of model element. Since most adapter implementations would be almost identical the Commons4Eclipse plug-in provides with PropertySourceAdapter a generic property source adapter implementation which can be used through the extension point de.uni_paderborn.commons4eclipse.propertyDescriptors. The following listing shows an excerpt from the MyPlugin4Eclipse plugin.xml file in which property source adapters are configured for the MyDiagram and MyNode model elements.

<extension point="de.uni_paderborn.commons4eclipse.propertyDescriptors">
    <modelelement category="MyDiagram"
                  class="de.uni_paderborn.myPlugin4Eclipse.metamodel.MyDiagram">

       <property label="name" name="name"/>

    </modelelement>

    <modelelement category="MyNode"
                  class="de.uni_paderborn.myPlugin4Eclipse.metamodel.MyNode">

       <property label="name" name="name"/>

       <property label="active" name="active">
          <range label="yes" modelvalue="true"/>
          <range label="no"  modelvalue="false"/>
       </property>

    </modelelement>
</extension>

For each model element (identified by its fully qualified class name given in the class attribute of the modelelement tag), the editable properties are configured. For each property a label used for display and a name is given. The PropertySourceAdpater implementation assumes, that the model element class has access methods for each property which are named get/is and set followed by the given name with first uppercase letter, e.g. getName and setName or isActive and setActive in case of the MyNode model element. You may configure a range for the values of a property as in case of the active property of MyNode. The property sheet view will display a combo box for such a property containing the given range elements. The label given for a range element will be used for display and the modelvalue will actually be set on the model element.

In order to make the configured adapters available you have to register them at the Eclipse platform. This is done by placing the following calls in the constructor or the start-method of your plug-in class:

Commons4EclipsePlugin.getDefault()
                     .getPropertyFactory()
                     .registerAdapters ("de.uni_paderborn.myPlugin4Eclipse");

The registerAdapters method requires the id of the plug-in for which the configured adapters are to be registered as argument.

If you need more sophisticated property source adapter behavior e.g. properties with dynamic range as in case of the type of a UMLAttr, you have to provide your own adapter implementation by subclassing PropertySourceAdapter. Your own adapter implementation must be included in the modelelement-tag using the attribute adapter. Cf. Fujaba4Eclipse, packages de.uni_paderborn.fujaba4eclipse.uml.behavior.adapters.propertysource or de.uni_paderborn.fujaba4eclipse.uml.structure.adapters.propertysource for examples.

Create TreeViewAdapters

You may customize the appearance of a model element in the Fujaba Navigator view by providing a tree view adapter implementation for it. A tree view adapter has to implement the interface de.uni_paderborn.fujaba4eclipse.adapters.treeview.ITreeViewAdapter. The class de.uni_paderborn.fujaba4eclipse.adapters.treeview.DefaultTreeViewAdapter provides a default implementation which you can reuse. You may find example implementations in Fujaba4Eclipse and MyPlugin4Eclipse in packages de.uni_paderborn.fujaba4eclipse.uml.structure.adapters.treeview, de.uni_paderborn.fujaba4eclipse.uml.behavior.adapters.treeview, or de.uni_paderborn.myPlugin4Eclipse.adapters.treeview.

Fujaba4Eclipse provides the extension point de.uni_paderborn.fujaba4eclipse.treeViewAdapters at which you have to register your tree view adapters. The extension point requires you to supply the fully qualified class name of the model element for which you want to provide an adapter and the fully qualified class name of the adapter class. The following listing shows an excerpt from the MyPlugin4Eclipse plugin.xml file in which tree view adapters are configured for the MyDiagram and MyNode model elements.

<extension point="de.uni_paderborn.fujaba4eclipse.treeViewAdapters">
    <modelelement
          adapterClass="de.uni_paderborn.myPlugin4Eclipse.adapters.treeview.MyDiagramTreeViewAdapter"
          class="de.uni_paderborn.myPlugin4Eclipse.metamodel.MyDiagram"/>
    <modelelement
          adapterClass="de.uni_paderborn.myPlugin4Eclipse.adapters.treeview.MyNodeTreeViewAdapter"
          class="de.uni_paderborn.myPlugin4Eclipse.metamodel.MyNode"/>
</extension>

In order to make the configured adapters available you have to register them at the Eclipse platform. This is done by placing the following calls in the constructor or the start-method of your plug-in class:

Fujaba4EclipsePlugin.getDefault()
                     .getTreeViewAdapterFactory()
                     .registerAdapters ("de.uni_paderborn.myPlugin4Eclipse");

The registerAdapters method requires the id of the plug-in for which the configured adapters are to be registered as argument.

Plug into Fujaba4Eclipse: ExtensionPoints Diagram, DiagramElement, PersistencySupport, TreeViewAdapters

  • ExtensionPoint Diagram (de.uni_paderborn.fujaba4eclipse.diagrams)
    • Adds a new diagram type to Fujaba4Eclipse
    • New diagrams appear in navigator and may be opened
    • Implement interface IDiagramExtension

  • ExtensionPoint DiagramElement (de.uni_paderborn.fujaba4eclipse.diagramElements)
    • Adds a new diagram element to Fujaba4Eclipse
    • New element may appear on configured diagram
    • Implement interface IDiagramElementExtension

  • ExtensionPoint PersistencySupport (de.uni_paderborn.fujaba4eclipse.persistencySupport)
    • Enables loading and saving of model elements provided by your plug-in
    • 4Eclipse plug-ins mimic existing Fujaba plug-ins by providing version information, class loader, plug-in key
    • Implement interface IPersistencySupportProvider

  • ExtensionPoint TreeViewAdapters (de.uni_paderborn.fujaba4eclipse.treeViewAdapters)
    • Allows to register tree view adapters for your model elements which are used by the Fujaba Navigator view.
    • Your tree view adapters have to implement the interface ITreeViewAdapter (see also)

Cf. MyPlugin4Eclipse, package de.uni_paderborn.myPlugin4Eclipse.extensions for examples.

The extensions have to be configured in your plug-in's plugin.xml. The following listing shows an excerpt from the MyPlugin4Eclipse plugin.xml in which a diagram and a persistency support extension are registered.

<extension point="de.uni_paderborn.fujaba4eclipse.diagrams">
   <diagram class="de.uni_paderborn.myPlugin4Eclipse.extensions.MyDiagramExtension"
            name="MyDiagram"
            id="MyDiagram"/>
</extension>
   
<extension point="de.uni_paderborn.fujaba4eclipse.persistencySupport">
   <provider class="de.uni_paderborn.myPlugin4Eclipse.extensions.MyPersistencySupportProvider"
             name="myPlugin4Eclipse.persistencyProvider"
             id="de.upb.myplugin.MyPlugin"/>
</extension>

New Diagram Wizard

In order to contribute a wizard for creating your diagram you have to provide an implementation of a wizard and a wizard page. Subclass AbstractNewASGDiagramWizardPage and AbstractNewASGDiagramWizard (cf. MyPlugin4Eclipse, package de.uni_paderborn.myPlugin4Eclipse.wizards) and add an extension definition to your plugin.xml (the following listing shows an excerpt from the MyPlugin4Eclipse plugin.xml:

<extension point="org.eclipse.ui.newWizards">    
   <wizard name="My Diagram" icon="icons/sample.gif"
           category="de.uni_paderborn.fujaba4eclipse.categoryWizard/de.uni_paderborn.fujaba4eclipse.categoryWizard.diagrams"
	   class="de.uni_paderborn.myPlugin4Eclipse.wizards.NewMyDiagramWizard"
	   id="de.uni_paderborn.myPlugin4Eclipse.wizards.NewMyDiagramWizard">
	
      <description>Create a new My Diagram</description>
   </wizard>
</extension>

If you want your wizard to appear directly in Eclipse's New menu, you have to configure a shortcut extension to the Fujaba4Eclipse perspective (or any other perspective in which you want to have your wizard appear directly). The following example is taken from the MyPlugin4Eclipse plugin.xml again:

<extension point="org.eclipse.ui.perspectiveExtensions">
    <perspectiveExtension targetID="de.uni_paderborn.fujaba4eclipse.perspective">
       <newWizardShortcut id="de.uni_paderborn.myPlugin4Eclipse.wizards.NewMyDiagramWizard"/>
    </perspectiveExtension>
</extension>

Your Contribution

If you find a bug or miss a feature in Fujaba4Eclipse or Commons4Eclipse please file a report in the bug or feature request trackers (http://dsd-serv.uni-paderborn.de/tracker/?group_id=22) of the GForge project (http://dsd-serv.uni-paderborn.de/projects/fujaba4eclipse/).