Extending spoon's XUL Database Explorer dialog

Spoon's XUL Database Explorer dialog graphical user interface provides a plug in mechanism that allows it to be extended or modified by writing XUL overlays

Extending the XUL Database Explorer dialog can be easily accomplished by following the next five steps.

  1. Create an event handler.
  2. Create a XUL overlay.
  3. Register the event handler in the plug in manager.
  4. Register the XUL overlay in the plug in manager.
  5. Load the event handler and XUL overlay in the XUL Database Explorer dialog.

We'll now show in detail how each one of these steps was implemented by analyzing an extension case for the Actions menu of the XUL Database explorer dialog.

The requirement was to extend the XUL Database explorer dialog by implementing a Model and Quick Visualize menu options.

 

Create an event handler.

An event handler must extend the org.pentaho.ui.xul.impl.AbstractXulEventHandler class, in our case we created the org.pentaho.agilebi.pdi.spoon.AgileBiDatabaseController and overwrote the public String getName() method returning agilebi_database which is the name that will be used to reference this event handler in the the XUL overlay.

Create a XUL overlay.

Next we created the database_dialog_overlay.xul. Note the label attribute of the menuitem elements specify the names desired and how the command attribute uses the agilebi_database to reference methods on the event handler

<?xml version="1.0"?>
<?xml-stylesheet href="file://E:/workspaces/sprint_workspace/pentaho-xul/test/resource/documents/xul.css" type="text/css"?>
<overlay id="label-test" title="Flow Test"
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
    xmlns:HTML="http://www.w3.org/Profiles/XHTML-transitional"
    xmlns:pen="http://www.pentaho.org/2008/xul">

    <menupopup id="action_popup">
      <menuitem id="trans-graph-entry-model" label="Model" command="agilebi_database.openModeler()" />
      <menuitem id="trans-graph-entry-visualize" label="Quick Visualize" command="agilebi_database.quickVisualize()" />
    </menupopup>
</overlay>

Register the event handler in the plug in manager.

Next in the org.pentaho.agilebi.pdi.spoon.AgileBISpoonPlugin at the getEventHandlers() method we created a new instance of our event handler and registered it with a key database_dialog that later will be used to retrieve it and load it.

public Map<String, XulEventHandler> getEventHandlers() {
    HashMap<String, XulEventHandler> hash = new HashMap<String, XulEventHandler>();
    hash.put("spoon", ModelerHelper.getInstance());
    hash.put("database_dialog", new AgileBiDatabaseController());
    return hash;
}

Register the XUL overlay in the plug in manager.

Next also in the org.pentaho.agilebi.pdi.spoon.AgileBISpoonPlugin at the getOverlays() method we registered our database_dialog_overlay.xul with a key database_dialog that later will be used to retrieve it and load it.

public Map<String, XulOverlay> getOverlays(){
  
    HashMap<String, XulOverlay> hash = new HashMap<String, XulOverlay>();
     
    XulOverlay overlay = new DefaultXulOverlay("org/pentaho/agilebi/pdi/spoon/overlays.xul"); //$NON-NLS-1$  //$NON-NLS-2$
    hash.put("spoon", overlay);
   
    overlay = new DefaultXulOverlay("org/pentaho/agilebi/pdi/spoon/database_dialog_overlay.xul"); //$NON-NLS-1$  //$NON-NLS-2$
    hash.put("database_dialog", overlay);
   
    return hash;
}

Load the event handler and XUL overlay in the XUL Database Explorer dialog.

Finally in the org.pentaho.di.ui.core.database.dialog.XulDatabaseExplorerDialog at the open() method we load the event handler and the XUL using the database_dialog key and register them on the container.

XulDomContainer container = theLoader.loadXul(XUL, new XulDatabaseExplorerResourceBundle());

SpoonPluginManager theSpoonPluginManager = SpoonPluginManager.getInstance();
List<XulOverlay> theXulOverlays = theSpoonPluginManager.getOverlaysforContainer("database_dialog");
List<XulEventHandler> theXulEventHandlers = theSpoonPluginManager.getEventHandlersforContainer("database_dialog");

for (XulEventHandler handler : theXulEventHandlers){
                handler.setData(this.controller);
                container.addEventHandler(handler);
}

for (XulOverlay overlay : theXulOverlays){
                container.loadOverlay(overlay.getOverlayUri());
}