The idea is simple: While providing common elements like authentication, configuration and look and feel, the console needs to be assembled out of common and proprietary features. Not everything we build into it, works across BPM runtimes even though it's our foremost goal.
Fortunately GWT already ships with an extension mechanism called "Deferred Binding". It allows you to replace or generate components at build time. Build time in our case means maven, and the easiest way to customize a maven build is by providing different sets of dependencies. Unlike the regular GWT compilation which is restricted to a subset of the JDK, the deferred binding has access to the full API, including classloading. It actually happens before the GWT compiler kicks in.
Great. That means our plugin loader can build upon the availability of plugins in the classloading scope.
Maven already provides the dependency management, then we are set.
Let's look at an example. Trunk contains a plugin-example that should get you going. Take a look at the pom.xml dependencies first. Any plugin has a dependency on the console plugin API:
<dependency>
<groupId>org.jbpm.jbpm3</groupId>
<artifactId>gwt-console-plugin</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
It ships with a few concepts that we need to clarify before we can move on. The console acts as a Workspace. A Workspace contains Editors, which are composed of different Views. Developing a plugin actually means implementing an Editor and providing a workspace configuration (workspace.cfg).
When building the console, the deferred binding generates and links the code that is required to associate all Editors in a workspace configuration with the console framework. Sounds terrible, but a plugin developer only needs to know a few interfaces and create a workspace configuration.
public abstract class Editor extends Panel
{
protected ApplicationContext appContext;
public abstract String getEditorId();
public abstract String getTitle();
public abstract String getIconCSS();
public abstract MenuSection provideMenuSection();
[...]
}
An Editor is your plugin root implementation. It needs to be uniquely identified (editorId) and contribute to the main menu (MenuSection). It can contain one or more views:
public abstract class View extends Panel
{
protected ApplicationContext appContext;
public abstract String getViewId();
public abstract String getIconCSS();
}
The editor and it's views share an ApplicationContext that gives you access to common things like authentication, configuration, logging, etc.
public interface ApplicationContext
{
[...]
void displayMessage(String message, boolean isError);
Authentication getAuthentication();
}
Besides that, you can leverage anything GWT provides for implementing your plugin.
I think you get the idea. Take a look at the plugin example (Google Maps integration), especially the editor implementation.
In order to enable this workspace configuration you need to build with "mvn -Pplugin-example" switch.
Discussion
Please join us in the overlord forum for further discussions.