Jump to: navigation, search

Difference between revisions of "JWT Modifications"

m (Writing (Example) Plugins for JWT-WE)
(Capabilities/Activities)
 
(16 intermediate revisions by 4 users not shown)
Line 1: Line 1:
This page provides information on how to add modify and add new features to the JWT Workflow Editor (JWT-WE).
+
This page provides information to JWT contributors on how to add modify and add new features to the JWT Workflow Editor (JWT-WE).
  
 
== Overview ==
 
== Overview ==
Line 8: Line 8:
 
== Writing (Example) Plugins for JWT-WE ==
 
== Writing (Example) Plugins for JWT-WE ==
  
== General Standards for Plugins ==
+
=== General Standards for Plugins ===
* Required Execution Environment: Java 1.5
+
* '''Provider''': Eclipse.org
* Provider: Eclipse
+
* '''Name''': Must end with ''(Incubation)'' while JWT is incubating
* '''CVS:''' In the we/jwt-we-plugins/ folder with the project dir as directory name
+
* '''Required Execution Environment:''' Java 1.5
* '''Versioning:''' x.y.z, same as corresponding Workflow Editor release
+
* '''CVS:''' In the we/jwt-we-plugins/''PLUGINDIR''
 +
* '''Versioning:''' ''x.y.z''.qualifier, same as corresponding Workflow Editor release (see [[Version Numbering]])
 +
* '''Legal:''' Must contain CQ, about.html, and license.txt (containing [http://www.eclipse.org/legal/epl/notice.php SUA])
  
 
=== Standards for Example Plugins ===
 
=== Standards for Example Plugins ===
  
* '''Project Directory:''' jwt-we-XY-example
+
* '''Project Directory:''' jwt-we-''PLUGINTYPE''-example (e.g. view, sheet, ...)
* '''Project Name:''' JWT WE XY Example Plugin
+
* '''Project Name:''' JWT WE ''PLUGINTYPE'' Example Plugin
* '''Package Structure:''' org.eclipse.jwt.we.plugins.XYexample
+
* '''Package Structure:''' org.eclipse.jwt.we.plugins.''PLUGINTYPE''example
  
 
=== Standards for Productive Plugins ===
 
=== Standards for Productive Plugins ===
  
* '''Project Directory:''' jwt-we-PLUGINTYPE-PLUGINNAME
+
* '''Project Directory:''' jwt-we-''PLUGINTYPE''-''PLUGINNAME'' (e.g. viewuml, doc, ...)
* '''Project Name:''' JWT WE PLUGINNAME Plugin
+
* '''Project Name:''' JWT WE ''PLUGINNAME'' Plugin
* '''Package Structure:''' org.eclipse.jwt.we.plugins.PLUGINNAME
+
* '''Package Structure:''' org.eclipse.jwt.we.plugins.''PLUGINNAME''
 +
 
 +
=== Documentation of your Source Code ===
 +
 
 +
* For all files you _modified_, you have to add yourself to the list of contributors in the legal header of the file
 +
* For all files you _created_, you have to add the same header as other source files include. Update the date, the creator and the copyright (that belongs to Bull)
 +
* Please remove all "development" comments
 +
* The target runtime environment of plugins must be set to J2SE-1.5
 +
 
 +
=== Hide internal package and leverage API analysis ===
 +
 
 +
=== Enable API analysis ===
 +
* [http://www.ibm.com/developerworks/opensource/library/os-eclipse-api-tools/ Article about API Tools by Chris Aniszczyk]
 +
* [[Api_Tooling]]
 +
* [[ApiTools Architecture]]
 +
 
 +
Every plugin that is already part of or the is intended to be part of Java Workflow Tooling distribution must *Enable API Analysis*. When developing for JWT, make sure that:
 +
* you have the latest *release* available somewhere
 +
* Have created a baseline that contains JWT
 +
* Activate API analysis using the JWT release as Baseline
 +
 
 +
Then API versioning should almost automatically deal with versions of plugins and API.
 +
 
 +
==== Restrict API when developing a new plugin ====
 +
 
 +
* When creating a new plugin, there is a checkbox "Enable API Analysis". Ensure it is checked and API analysis is enabled (requirement for Eclipse release train)
 +
* Separate your packages between API and internal
 +
** If a class that is intended to be used by clients (''API'') of your plugin is in package (''org.example.pack''),
 +
** Then all internal classes that you use (impl and co) must be in package (''org.example.pack.internal'')
 +
* Export only the required package (no *internal* should appear in those packages), if you are tempted to export a internal package, then you should consider moving the class you want to export into a non-internal package.
 +
* On all exported classes (= classes of exported packages), add to the JavaDoc of the class the tag '''@since [plugin version where the class was introduced]'''
 +
* On all exported interfaces and classes that are not intended to be implemented by clients (such as singletons), you can add a '''@noimplement''' tag
 +
* Once this is done, the API tooling should automatically deal with this '''@since''' tag when adding or modifying API,
 +
 
 +
==== Restrict API of an existing plugin ====
 +
 
 +
The most efficient "methodology" I've used to find what is API and what is not:
 +
* Get the "target" plugin you want to change it your workspace
 +
* Get all direct client plugins in your workspace
 +
* Remove all export package from the "target" plugin MANIFEST.MF.
 +
* All client plug-ins will crash... Then reexport all packages that are necessary to get them building, but...
 +
* Each time you reexport a package
 +
** If there are some classes that are in this package but that are clearly not API, you have 2 choices
 +
*** 1. Create an "internal" subpackage (that won't be exported), and put them into it
 +
*** OR 2. Create an "api" package that will contain the classes and interfaces you'd like to export, and export this package
 +
** And, obviously, add JavaDoc and '''@since [version]''' tag on classes that are still in exported package, because they are classes that have external clients.
 +
 
 +
=== Externalize your Strings ===
 +
* If your string is a UI message (ie title, content of a dialog...), then it '''must''' be externalized and referenced from a NLS Message Bundle
 +
* If your string is an EMF-generated class (seek for @generated annotation on class comments), then simply put a '''@SuppressWarnings("nls")''' on that class
 +
* If your string is a "logic" string (for examples if it the name of a plugin extension point attribute, or "true"/"false" strings) and if it is used several times, then create a constant for that string and use it.
 +
* It your string is '''never''' intended to be displayed (for example log messages or bundle names...) then, add a //$NON-NLS-''n''$ comment.
 +
 
 +
==== Look out for strings ====
 +
 
 +
Here is a set of ways to look out for non-externalized or NON-NLS string easily in Eclipse:
 +
# Activate warnings for NLS
 +
[[Image:NLS_Warnings.png|150px]]
 +
# Get the exhaustive list of strings to externalize or mark as non-nls
 +
[[Image:NLS_list_1.png|150px]]
 +
[[Image:NLS_list_2.png|150px]]
 +
Then your "Problems" list will only contain NLS related warnings, time for hunting!
 +
 
 +
=== Control the UI ===
 +
 
 +
==== Separate UI and non-UI ====
 +
 
 +
It is important for JWT clients that they can be able to ignore UI parts of JWT, if they only want to depend on the core fonctionality. A good way to do so is to put core functionality into a plugin ''org.my.plugin.core'' and ''org.my.plugin.ui''.
 +
 
 +
For example, org.eclipse.jwt.transformations.transformationBase should be refactored into:
 +
* ''org.eclipse.jwt.transformations.core'' that contains API for transfos and the extension point where transfo can be plugged
 +
* ''org.eclipse.jwt.transformations.ui'' that contains UI: integration into the Import/Export wizards and extension of JWT-WE actions
 +
 
 +
==== Capabilities/Activities ====
 +
 
 +
See [http://help.eclipse.org/help33/index.jsp?topic=/org.eclipse.platform.doc.isv/reference/extension-points/org_eclipse_ui_activities.html activities extension point doc].
 +
 
 +
JWT defines a category and an activity in its global "capabilities" ''org.eclipse.jwt.ui.capabilities'' plugin, that can be found on CVS at ''org.eclipse.jwt/releng/jwt-ui-capabilities''. This must be the only one to bind extensions with Activity bindings.
 +
 
 +
It defines dedicated Category, Activity, their bindings and default enablement (see [http://dev.eclipse.org/viewcvs/viewvc.cgi/trunk/releng/jwt-ui-capabilities/plugin.xml?view=markup&root=SOA_JWT its plugin.xml]). For now there is a single Activity the following expression binding :
 +
<source lang="xml">
 +
      <activityPatternBinding
 +
            activityId="org.eclipse.jwt.Activity"
 +
            pattern="org\.eclipse\.jwt\..*/.*">
 +
      </activityPatternBinding>
 +
</source>
 +
 
 +
We don't have to change this definition, except if we wanted to separate JWT into several UI activities (such as modeling, model extensions, transformations...).
  
 
== Integrating new Features into JWT-WE ==
 
== Integrating new Features into JWT-WE ==

Latest revision as of 13:26, 24 April 2012

This page provides information to JWT contributors on how to add modify and add new features to the JWT Workflow Editor (JWT-WE).

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 JWT committers can deal with recurring tasks when adding features to the Workflow Editor like adding new options to the Eclipse preferences dialog (if you're instead looking for information on how to extend JWT-WE through providing external plugins, please take a look at JWT_Extensions).

Writing (Example) Plugins for JWT-WE

General Standards for Plugins

  • Provider: Eclipse.org
  • Name: Must end with (Incubation) while JWT is incubating
  • Required Execution Environment: Java 1.5
  • CVS: In the we/jwt-we-plugins/PLUGINDIR
  • Versioning: x.y.z.qualifier, same as corresponding Workflow Editor release (see Version Numbering)
  • Legal: Must contain CQ, about.html, and license.txt (containing SUA)

Standards for Example Plugins

  • Project Directory: jwt-we-PLUGINTYPE-example (e.g. view, sheet, ...)
  • Project Name: JWT WE PLUGINTYPE Example Plugin
  • Package Structure: org.eclipse.jwt.we.plugins.PLUGINTYPEexample

Standards for Productive Plugins

  • Project Directory: jwt-we-PLUGINTYPE-PLUGINNAME (e.g. viewuml, doc, ...)
  • Project Name: JWT WE PLUGINNAME Plugin
  • Package Structure: org.eclipse.jwt.we.plugins.PLUGINNAME

Documentation of your Source Code

  • For all files you _modified_, you have to add yourself to the list of contributors in the legal header of the file
  • For all files you _created_, you have to add the same header as other source files include. Update the date, the creator and the copyright (that belongs to Bull)
  • Please remove all "development" comments
  • The target runtime environment of plugins must be set to J2SE-1.5

Hide internal package and leverage API analysis

Enable API analysis

Every plugin that is already part of or the is intended to be part of Java Workflow Tooling distribution must *Enable API Analysis*. When developing for JWT, make sure that:

  • you have the latest *release* available somewhere
  • Have created a baseline that contains JWT
  • Activate API analysis using the JWT release as Baseline

Then API versioning should almost automatically deal with versions of plugins and API.

Restrict API when developing a new plugin

  • When creating a new plugin, there is a checkbox "Enable API Analysis". Ensure it is checked and API analysis is enabled (requirement for Eclipse release train)
  • Separate your packages between API and internal
    • If a class that is intended to be used by clients (API) of your plugin is in package (org.example.pack),
    • Then all internal classes that you use (impl and co) must be in package (org.example.pack.internal)
  • Export only the required package (no *internal* should appear in those packages), if you are tempted to export a internal package, then you should consider moving the class you want to export into a non-internal package.
  • On all exported classes (= classes of exported packages), add to the JavaDoc of the class the tag @since [plugin version where the class was introduced]
  • On all exported interfaces and classes that are not intended to be implemented by clients (such as singletons), you can add a @noimplement tag
  • Once this is done, the API tooling should automatically deal with this @since tag when adding or modifying API,

Restrict API of an existing plugin

The most efficient "methodology" I've used to find what is API and what is not:

  • Get the "target" plugin you want to change it your workspace
  • Get all direct client plugins in your workspace
  • Remove all export package from the "target" plugin MANIFEST.MF.
  • All client plug-ins will crash... Then reexport all packages that are necessary to get them building, but...
  • Each time you reexport a package
    • If there are some classes that are in this package but that are clearly not API, you have 2 choices
      • 1. Create an "internal" subpackage (that won't be exported), and put them into it
      • OR 2. Create an "api" package that will contain the classes and interfaces you'd like to export, and export this package
    • And, obviously, add JavaDoc and @since [version] tag on classes that are still in exported package, because they are classes that have external clients.

Externalize your Strings

  • If your string is a UI message (ie title, content of a dialog...), then it must be externalized and referenced from a NLS Message Bundle
  • If your string is an EMF-generated class (seek for @generated annotation on class comments), then simply put a @SuppressWarnings("nls") on that class
  • If your string is a "logic" string (for examples if it the name of a plugin extension point attribute, or "true"/"false" strings) and if it is used several times, then create a constant for that string and use it.
  • It your string is never intended to be displayed (for example log messages or bundle names...) then, add a //$NON-NLS-n$ comment.

Look out for strings

Here is a set of ways to look out for non-externalized or NON-NLS string easily in Eclipse:

  1. Activate warnings for NLS

NLS Warnings.png

  1. Get the exhaustive list of strings to externalize or mark as non-nls

NLS list 1.png NLS list 2.png Then your "Problems" list will only contain NLS related warnings, time for hunting!

Control the UI

Separate UI and non-UI

It is important for JWT clients that they can be able to ignore UI parts of JWT, if they only want to depend on the core fonctionality. A good way to do so is to put core functionality into a plugin org.my.plugin.core and org.my.plugin.ui.

For example, org.eclipse.jwt.transformations.transformationBase should be refactored into:

  • org.eclipse.jwt.transformations.core that contains API for transfos and the extension point where transfo can be plugged
  • org.eclipse.jwt.transformations.ui that contains UI: integration into the Import/Export wizards and extension of JWT-WE actions

Capabilities/Activities

See activities extension point doc.

JWT defines a category and an activity in its global "capabilities" org.eclipse.jwt.ui.capabilities plugin, that can be found on CVS at org.eclipse.jwt/releng/jwt-ui-capabilities. This must be the only one to bind extensions with Activity bindings.

It defines dedicated Category, Activity, their bindings and default enablement (see its plugin.xml). For now there is a single Activity the following expression binding :

      <activityPatternBinding
            activityId="org.eclipse.jwt.Activity"
            pattern="org\.eclipse\.jwt\..*/.*">
      </activityPatternBinding>

We don't have to change this definition, except if we wanted to separate JWT into several UI activities (such as modeling, model extensions, transformations...).

Integrating new Features into JWT-WE

Adding Preferences

notes:

  • konstanten in preferenceconstants
  • standardwerte in preferenceinitializer
  • zugriffselemente in preferencereader
  • beschriftung in plugin*.properties
  • feldelemente in preferencepages
  • preferences über preferencereader auslesen
  • aktualisierung durch preferencechangelistener

neue seite:

  • category in preferenceconstants
  • category in preferencechangelistener
  • page in pages erstellen
  • seite in plugin.xml hinzufügen
  • category in plugin.properties eintragen

Adding Menu/Toolbar Entry

See also