ShowTable of Contents
In this tutorial we are going to extend the Notes View Container that is part of the Lotus Notes 8.5.1 platform with our own custom action. We will write an action that will output the median number from a set of selected numbers. There are already a set of numeric actions that come pre-packaged with the Notes View Container such as Total, Average and Sum. This tutorial will show how simply we can add a Median action to the pre-existing library that can be used when assembling an application.
Prerequisites
You will need Lotus Notes 8.5.1 and the Lotus Expeditor 6.2.1 toolkit installed into your Eclipse 3.4 IDE. You will be able to create the sample if you do not have the toolkit as long as you define your Target Platform to be your Notes 8.5.1 installation.
It will be best if you have done the Creating custom actions in Java tutorial prior to performing this one. The creating custom actions tutorial will help you better understand the concept of custom actions and it will also detail some steps such as packaging and installing a feature into Lotus Notes 8.5.1.
Step One Creating the plugin
The first thing we will do is create an Eclipse plug-in. We will use this plug-in to define our new action.
a) From the Eclipse menu bar select File -> New -> Other..
b) In the Select Wizard that displays choose Plug-in project and press Next.
b) In the second panel name your plug-in
com.ibm.ca.wiki.viewcontainer.action
c) Click Next
d) Click Finish.
Step Two Extending the actionConfiguration extension point
The new plug-in now exists in your workspace and can be seen in the Package Explorer view. The first thing that we will do with our plug-in is extend the com.ibm.rcp.composite.container.core.actionConfiguration extension point.
a) In the Package Explorer navigate to META-INF/MANIFEST.MF and select this file so it will open in the editor area.
b) Select the Extensions tab at the bottom of the Manifest editor area .
c) While in the Extensions editor press the Add... button and type com.ibm.rcp.composite.container.core.actionConfiguration into the text field in the Extension Point Selection window. This will add an actionConfiguration extension to your plugin.xml
d) Select the plugin.xml tab at the bottom of the manifest editor to open the source for the plugin.xml. This is what our extension looks like.
<plugin>
<extension
point="com.ibm.rcp.composite.container.core.actionConfiguration">
<actions>
<action
class="com.ibm.ca.wiki.viewcontainer.action.Median"
id="com.ibm.ca.wiki.viewcontainer.action.median"
name="Median Action"
type="com.ibm.notes.view.container.views.BaseNotesViewContainer">
</action>
</actions>
</extension>
</plugin>
For the action you will define the handler class, the id for the action, the name of our action and the type of container it can be used with.
Step Three Creating the action class
We have defined our action in the plugin.xml file and now we need to create the class we have declared as our action class.
a) Create the Action class by right clicking on your plug-in in Eclipse and selecting New -> Class
b) In the New Java Class dialog enter Median for the class name and browse to com.ibm.rcp.composite.container.core.actions.Action
for the superclass. Press Finish
The Median class can now be seen under src in the Package Explorer. We will now write our execute method. The execute method is what will be called by the container framework. Before we write the code for our class
we need to declare some packages to import in our manifest.
c) Add the Imported-Packages, seen below on the Dependencies tab, to your Manifest
d) Export the com.ibm.ca.wiki.viewcontainer.action package using the Export-Package manifest header. The Manifest should now look like this:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Action Plug-in
Bundle-SymbolicName: com.ibm.ca.wiki.viewcontainer.action;singleton:=true
Bundle-Version: 1.0.0
Bundle-Activator: com.ibm.ca.wiki.viewcontainer.action.Activator
Bundle-Vendor: IBM
Require-Bundle: org.eclipse.core.runtime,
com.ibm.rcp.composite.container.core,
com.ibm.notes.java.api
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Import-Package: com.ibm.notes.view.container.views,
com.ibm.rcp.composite.container.core,
com.ibm.rcp.composite.container.core.actions,
com.ibm.rcp.composite.container.core.events
Export-Package: com.ibm.ca.wiki.viewcontainer.action
e) Open our Median class for editing by selecting it in the Package Explorer view if it is not already open.
f) Enter the source code for our Median class.
package com.ibm.ca.wiki.viewcontainer.action;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.Session;
import com.ibm.notes.view.container.views.BaseNotesViewContainer;
import com.ibm.rcp.composite.container.core.AppContainer;
import com.ibm.rcp.composite.container.core.actions.Action;
import com.ibm.rcp.composite.container.core.events.LandmarkEvent;
public class Median extends Action {
public void execute(AppContainer container, LandmarkEvent event, Object context) {
String total = String.valueOf(getMedian(container, event));
((BaseNotesViewContainer )container).publishProperty(property, total);
}
private double getMedian(AppContainer container, LandmarkEvent event) {
BaseNotesViewContainer bnvc = (BaseNotesViewContainer )container;
// Get the notes session from the event
Session session = bnvc.getSession();
// Get the document list
List documents = (List )event.getData("docList");
String value = null;
double median = 0.0f;
if (documents == null){
return median;
}
ArrayList doubleList = new ArrayList();
Iterator iter = documents.iterator();
while(iter.hasNext()){
Document d = (Document)iter.next();
try {
Vector v = session.evaluate(field, d);
if (v == null || v.size() == 0)
continue;
value = v.firstElement().toString();
if (value.trim().length() == 0)
continue;
//add values to list
Double fv = Double.valueOf(v.firstElement().toString()).doubleValue();
doubleList.add(fv);
}
catch (NotesException e) {
//log error here and continue
}
}
//convert list to array
Double[] doubleArray = (Double[])doubleList.toArray(new Double[doubleList.size()]);
//sort the array
Arrays.sort(doubleArray);
//calculate the middle, division of odd number is rounded down
int middle = doubleArray.length / 2;
if (doubleArray.length % 2 == 1) {
//length of array is odd
median = doubleArray[middle];
} else {
//length of array is even, must return average of middle elements
median = (doubleArray[middle - 1] + doubleArray[middle]) / 2.0;
}
return median;
}
}
g) Save the Median class.
We now have a custom container action.
Step Four Installing our plugin
To install your plug-in into Lotus Notes you will need to create a feature to contain the new plug-in and also create an update site that will be used to install the plug-in. As part of this you will also need to update the Notes plugin_customization.ini file to enable application installation.
There are a large number of steps to perform for this and here I will refer you to the
Creating a custom action in Java
tutorial for all the details on performing these steps. The 24 steps detailed in Step 4 of that tutorial will all need to be done the same. The only difference is that you will want you use
the naming structure we have established in this tutorial for our plug-in in your new feature and site names.
Step Five Assembling an application that will use our action
We are now going to assemble a new composite application and use our new custom action. For our sample we will use a Notes database that has a column with some number values and a browser so we can show the results of our selections. Once we define our median action and wire it to the
setHTMLText action of the browser we will be able to select a document or multiple documents in the database component. Our action will then get called, we will find the median of the numbers from the selected documents and then publish the results.
a) In Notes select File -> Application -> New... In the New Application dialog enter a name for your application, MedianTest, and select the -Blank Composite Application- template. Press OK.
A new, blank composite application will open in Notes. We will edit this using the Composite Application Editor (CAE)
b) With our new composite application as the active perspective select Actions -> Edit from the Notes menu bar.
We are going to add 2 components to our application. The Notes View Container, under the Containers category, and the Managed Browser.
c) From the CAE palette on the right select the Notes View Container component and drag it onto your application in the center of the screen.
d) From the CAE palette on the right select the Managed Browser component
and drag it onto your application in the center of the screen. While dropping the browser component size it so it only takes up half of the page.
We have edited the component properties of the Notes View Container to show an internal database as opposed to the default view. This is done by right clicking on the component from the left side of CAE and selecting Edit Component Properties. From the displayed dialog you can change the view that the Notes View Container displays.
e) From the Notes View Container tool bar we are now going to create our landmark for the median action. We will name our action, selection 'Median action' from the drop down of available actions and then select the database column to get the values from. The 'Median action' shows up in this drop down now because we have created and defined it so the container framework now knows about this and will call our execute method.
d) Once we have defined median from our toolbar we can wire this to our Managed Browser component. Right click on the Notes View Container component in the left navigation of CAE and select wiring
Now that the application has been assembled and wired we can try it out. While still in edit mode in CAE I can select some documents from my database. The Median action gets called with the items from the column we selected, here it was severity. Median processes these numbers and publishes the median.
In the screen shot below I selected 3 documents. These have the values of 1, 1 and 3 in the severity column. Median publishes 1 - the number in the middle of the set - As we expect.
Conclusion
This tutorial demonstrated how simple it is to create a custom action for the Notes container that you can use in your application. It also showed that there are already a good number of pre-defined actions that are part of the platform. The options are essentially endless as to what you could have your action do. Create your component, extension the actionConfiguration extension-point and implement the execute method in your class that extends Action and you are on your way!