ShowTable of Contents
The XPages2Eclipse feature "Startup JavaScript Jobs" allows for the execution of JavaScript background jobs during the startup phase of the Lotus Notes Client.
Those jobs are running standalone, not in the context of an XPages application.
Please note:
It is recommended that you read the article about the
NSF classloader first before you go on reading this
article.
The sample application in this article demonstrates how three features/APIs of XPages2Eclipse can be combined: Startup JavaScript Jobs, the Extension Registry API and the XPages API.
The application contains buttons to register/unregister a startup job:
This startup job adds a toolbar icon to the Notes UI which lets you add
Firebug lite support to any XPages application in the Client.
The startup job registration is pretty easy. All you need to do is define one Notes.ini variable per Job, starting with $mndStartupJSJob1, then $mndStartupJSJob2 and so on.
The Notes.ini values need to be formula language constructs that define a list of variable values. On Client startup, the formulas (and some automatically generated extra code like "FIELD server:=server") are evaluated on a temporary Notes document to retrieve the Job properties, like the location of the job code, the job name and up to 5 additional parameter values that are free to use.
Here is the code of the JavaScript library "StartupJobRegistration" which is used to check if a startup job is defined, to register and to unregister the job:
//The method checks if a startup job is currently registered.
//
//XPages2Eclipse can launch more than one job at Client startup.
//The Notes.ini variables mndStartupJSJob1, mndStartupJSJob2 etc.
//are used to store the job information (location of the code, display
//progress dialog yes/no, optional parameters).
//XPages2Eclipse will iterate through the Notes.ini variables, until
//a variable returns an empty string. A value of "-" is skipped
//without stopping the iteration and may be used to give fixed numbers
//to specific startup jobs
function isStartupJobRegistered() {
var jobCode=session.getEnvironmentString("mndStartupJSJob1");
if (jobCode)
return true;
else
return false;
}
//The method adds the startup job code to the Notes.ini variable mndStartupJSJob1
function registerStartupJob() {
//We are using formula language to define the startup job parameters.
//That way, the values can be computed dynamically for each user.
//
//Here is a list of available variables for the startup job formula:
//Mandatory parameters
//--------------------
//Database location: server and filepath or dbid (or both)
//Method code location and calling code: libraryname,jsmethodname
//
//Optional parameters
//-------------------
//Name of startup job: jobname
//Startup job visibility: isuser,issystem
//Additional parameters passed as global JavaScript variables: jsparam1,jsparam2,jsparam3,jsparam4,jsparam5
var startupFormula='server:="'+database.getServer()+'";'+
'filepath:="'+database.getFilePath()+'";'+
'dbid:="'+database.getReplicaID()+'";'+
'libraryname:="StartupCode";'+
'jsmethodname:="onStartup();";'+
'jobname:="Adding Firebug lite toolbar icon";'+
'isuser:="false";'+
'jsparam1:="Add Firebug lite to this XPage"';
session.setEnvironmentVar("mndStartupJSJob1", startupFormula);
}
//the method removes the startup job value from the Notes.ini variable mndStartupJSJob1
function unregisterStartupJob() {
session.setEnvironmentVar("mndStartupJSJob1", "");
}
As you can see in the code comments, there are a few mandatory parameter values that need to be defined so that XPages2Eclipse can find the job code:
- Database location: server and filepath or dbid (or both)
- Method code location and calling code: libraryname, jsmethodname
When you define the replica id (dbid) for a database, Xpages2Eclipse will try to find the database locally by dbid first before an attempt is made to load it via server/filepath and as the last option via server/dbid.
The following optional variable names can be used to configure the job appearance (e.g. isuser=true to display a progress dialog) and pass up to 5 values to the job, leading to global JavaScript variables jsparam1-jsparam5 in the executed code:
- Name of startup job: jobname
- Startup job visibility: isuser, issystem
- Additional parameters passed as global JavaScript variables: jsparam1, jsparam2, jsparam3, jsparam4, jsparam5
The startup code contains some pretty advanced content that a developer will most probably only understand with some Eclipse experience. We are using the Extension Registry API of XPages2Eclipse to add an extension programmatically to Eclipse, in our case an extension for a toolbar icon.
Extension registration is normally done statically in XML format inside the plugin.xml file of a plugin, In Eclipse version 3.4.2 on which the Lotus Notes Client 8.5.2 or higher is based, there is no official well-designed API for dynamic extension registration. The only way to add an extension at runtime is to manually add the XML code at the
IExtensionRegistry of Eclipse. The Extension Registry API of XPages2Eclipse is just a wrapper around this Eclipse registry.
So here is the code for the startup job (script library "StartupCode"). Most of it is documented. Please note how we pass the variable jsparam1 right from the startup job definition in the Notes.ini file to the action set definition. This variable contains the label/tooltip for the toolbar action.
The
documentation for the extension point org.eclipse.ui.actionSets contains information about the Eclipse extension syntax itself:
//This code is executed during the Notes Client startup phase. It
//generates a snippet of XML code and injects it into the Extension
//registry of Eclipse to dynamically register an action set with
//a toolbar icon.
function onStartup() {
var pUI=com.x2e.PlatformUIAPI.getUI(eclipseconnection);
//use a small Java class to read the icon for the toolbar action
//from the database design and extract it temporarily on disk.
//We need the URI of a locally stored icon for the action
//registration code.
var tmpIconFile=com.mindoo.xpages2eclipse.sample.firebug.tools.TempFileSupport.createFile(nsfclassloader, "/com/mindoo/xpages2eclipse/sample/firebug/icons/firebug-icon.png");
var extRegTools=com.x2e.ExtensionRegistryAPI.getTools(eclipseconnection);
//build the extension code; if we specify the dbid, XPages2Eclipse will
//first try to find the database locally (even if we're on the server)
//for better performance; if not successful, we try to load the
//database with server/filepath and as the last choice, we try server/dbid
var server=database.getServer();
var filepath=database.getFilePath();
var dbid=database.getReplicaID();
//location of toolbar action JavaScript code: method showFirebugLite() in library Actions
var libraryname="Actions";
var jsmethodname="showFirebugLite();";
//isuser=false to not display a progress dialog
var isuser="false";
var issystem="false";
var jobname="Adding firebug to XPages application";
//the parameter jsparam1 got passed into this method invocation
//as a global variable (from the content of the Notes.ini variable mndStartupJSJob1);
var xml='<?xml version="1.0" encoding="UTF-8"?>\n'+
'<?eclipse version="3.4"?>\n'+
'<plugin>\n'+
'<extension id="com.mindoo.xpages2eclipse.samples.startupjob.firebuglite.action" point="org.eclipse.ui.actionSets">\n'+
' <actionSet id="com.mindoo.xpages2eclipse.samples.startupjob.actionset"\n'+
' label="'+jsparam1+'"\n'+
' visible="true">\n'+
' <action id="com.mindoo.xpages2eclipse.samples.startupjob.firebuglite"\n'+
' label="'+jsparam1+'"\n'+
' toolbarPath="com.mindoo.xpages2eclipse.startupjob.firebuglite.global/global"\n'+
' icon="'+tmpIconFile.toURI().toString()+'"\n'+
' tooltip="'+jsparam1+'">\n'+
' <class class="com.mindoo.xpages2eclipse.ui.actions.GenericCommandActionDelegate">\n'+
' <parameter name="commandId" value="com.mindoo.remote.api.notesclient.commands.RunJavaScriptInLibHandler"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.server" value="'+server+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.filepath" value="'+filepath+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.dbid" value="'+dbid+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.libraryname" value="'+libraryname+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.jsmethodname" value="'+jsmethodname+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.isuser" value="'+isuser+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.issystem" value="'+issystem+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.jobname" value="'+jobname+'"/>\n'+
' <parameter name="com.mindoo.remote.api.commands.runjavascriptjob.jsparam1" value="'+jsparam1+'"/>\n'+
' </class>\n'+
' </action>\n'+
' </actionSet>\n'+
'</extension>\n'+
'</plugin>';
//register extension:
extRegTools.addExtension(xml);
//now display the action set that we just created
var wb=pUI.getWorkbench();
var activeWindow=wb.getActiveWorkbenchWindow();
var activePage=activeWindow.getActivePage();
activePage.showActionSet("com.mindoo.xpages2eclipse.samples.startupjob.actionset");
pUI.logToStatusBar("Firebug toolbar icon added");
}
A click on the toolbar action will execute the class
com.mindoo.xpages2eclipse.ui.actions.GenericCommandActionDelegate
, which is part of the XPages2Eclipse API and simply forwards the call to the command
com.mindoo.remote.api.notesclient.commands.RunJavaScriptInLibHandler
, a piece of code that handles the JavaScript code loading and execution.
Our final code snippet contains the code in the Script library "Actions" - the actual code that adds Firebug lite support to the currently active XPages application:
//The method is executed in a Javascript job when the user clicks on
//the toolbar icon. It checks if the active workbench part belongs
//to an XPages application and executes a piece of JavaScript code
//on the XPages browser context to add the Firebug lite tool
function showFirebugLite() {
var pUI=com.x2e.PlatformUIAPI.getUI(eclipseconnection);
var mbTools=pUI.getMessageBoxTools();
var wb=pUI.getWorkbench();
var activeWindow=wb.getActiveWorkbenchWindow();
var partService=activeWindow.getPartService();
var part=partService.getActivePart();
if (!part) {
//no active part found
mbTools.showMessageBox(1+32 /* ERROR+OK */, "No part", "Could not get a handle on the active workbench part");
return;
}
var xspAPI=com.x2e.XPagesAPI.getTools(eclipseconnection);
if (!xspAPI.isXspViewPart(part)) {
//no XPages application visible
mbTools.showMessageBox(1+32 /* ERROR+OK */, "No XPages application", "This action only works when an XPages application is focused");
return;
}
//now build the JavaScript code to add the Firebug lite library to the page
var firebugLiteUrl="http://getfirebug.com/firebug-lite.js";
var jsCode='try {\n'+
'var fbNode=document.getElementById("firebugLite");\n'+
'if (!fbNode) {\n'+
' var headNodes=document.getElementsByTagName("head");\n'+
' if (headNodes && headNodes.length>0) {\n'+
' var headNode=headNodes.item(0);\n'+
' fbNode=document.createElement("script");\n'+
' fbNode.setAttribute("id", "firebugLite");\n'+
' fbNode.setAttribute("type", "text/javascript");\n'+
' fbNode.setAttribute("src", "'+firebugLiteUrl+'");\n'+
' headNode.appendChild(fbNode);\n'+
' }\n'+
'}\n'+
'} catch (e) {alert("error");}';
xspAPI.execute(part, jsCode);
pUI.logToStatusBar("Firebug lite added to XPage");
}
The sample application can be downloaded
here.