Editor's note: Know a lot about this topic? Want to share your expertise? Participate in the IBM Lotus software wiki program today.
| Lotus Notes wiki | Lotus Sametime wiki | Lotus Expeditor wiki |
|---|
Users in almost any work environment tend to check their e-mail clients for particular incoming e-mails of immediate concern. For example, developers might be interested in reading any incoming e-mails regarding a particular software bug. Similarly, employees in a call center might want to be notified instantly when an e-mail with a specific ticket number comes in.
In this article, you learn how to improve and leverage the announcement service feature that is built into IBM Lotus Sametime to reduce the time users spend checking and monitoring their IBM Lotus Notes clients for particular incoming e-mails.
The advanced e-mail announcer plug-in allows users to record their preferences for a particular topic (a thread) or for particular keywords, When a new e-mail arrives, the plug-in verifies the e-mail and checks its subject (the thread) or any keywords that appear in its content that match the user preferences. If the e-mail and the preferences match, the plug-in sends an immediate announcement of the new e-mail, indicating that the subject or the keywords matched the preferences.
This article also provides another plug-in that is a specific implementation for reading e-mails received by the Lotus Notes client.
This article assumes that you have knowledge of the following topics:
- Eclipse plug-ins
- Java™ development
- IBM Lotus Expeditor toolkit
- IBM Lotus Sametime toolkit
For instructions about how to set up Lotus Expeditor, see the developerWorks® Lotus article, "Getting started with the IBM Lotus Expeditor Toolkit V6.1.1." In the remainder of this article, we assume that the IDE used is the Eclipse IDE. Check the Resources section for links about how to set up your development environment.
Lotus Sametime Connect client services in a nutshell
Lotus Sametime Connect is based on the Eclipse platform, which is both an extensible and a more flexible architecture than traditional applications. If you are familiar with Java and Eclipse plug-in development, you can extend the Lotus Sametime client easily by developing plug-ins. Also, Lotus Sametime provides you with services that you can leverage in your plug-in application. These services are organized into three main categories:
- Community services. These services include awareness, instant messaging, instant meetings, chat, and announcements.
- Online meeting services. These services include a shared whiteboard and the ability to share programs and documents online.
- Customization and integration services. Lotus Sametime offers a wide-ranging API that can integrate real-time collaborative capabilities into other applications.
In this application, you can learn how to use the announcement service functionality, which is one of the community service features, to send announcements to your Lotus Sametime client that inform you of important incoming e-mails.
The Eclipse plug-in architecture is built on an approach that loosely couples different components to deliver a specific functionality. The coupling approach is implemented in Eclipse plug-ins through extensions and extension points. An extension point is a plug-in that exposes a minimal set of interfaces to other plug-ins; an extension is a plug-in that implements those interfaces. Extension points are stored in the extension registry and accessed when needed from client plug-ins.
In this article, the purpose of the extension point in the solution is to separate processing the announcement from collecting e-mails. Because each e-mail provider has its own implementation, it is appropriate to implement each e-mail provider as a separate plug-in.
This solution consists of the Lotus Sametime e-mail announcer plug-in, whose main functionality is to parse received e-mails, check user preferences, and send notification to users. The Lotus Sametime e-mail announcer exposes a simple interface to other plug-ins so that users can plug in different e-mail implementations.
In this article, you also develop the Lotus Notes e-mail reader plug-in, whose main functionality is to connect to the Lotus Notes client, collect new incoming e-mails, and notify the announcer plug-in of those e-mails.
Figure 1 shows how the two plug-ins interact and the role for each plug-in.
Figure 1. Solution overview
Lotus Sametime e-mail announcer plug-in user interface
Let’s look at the Lotus Sametime e-mail announcements plug-in user interface (UI).
Figure 2. E-mail Announcements preferences page
Figure 2 shows the e-mail announcer plug-in preferences page. This plug-in allows you to register an e-mail provider from which you can receive an announcement upon receiving e-mails. For this example, you select only one provider, Lotus Notes, by selecting this option in the E-Mail provider field. users might enhance the graphical user interface (GUI) to include a list of e-mail providers such as Gmail and Hotmail.
The Refresh button queries the Eclipse extension point registry for plug-ins that implement announcer extension points.
The E-Mail Poling interval field lets you set how often the producer (that is, the e-mail provider) checks the e-mail inbox for new e-mails.
In the User Credentials section, you enter your username and password. Because you are connecting only to the Lotus Notes local database file client, you need to enter only the password.
In the Send Announcement based on section, enter the criteria that you are interested in, as either an e-mail topic or e-mail keywords. For example, you might want to be notified about any e-mail with a particular subject such as customer ticket 2212.
Figure 3. E-mail received with the customer ticket 2212
Figure 4. Announcement
Figures 3 and 4 shows the e-mail announcement plug-in in action. Figure 3 shows that an e-mail with "customer ticket 2212" in its subject line was received. Figure 4 shows the e-mail announcement.
Lotus Sametime e-mail announcer plug-in overview
The announcer plug-in parses incoming e-mails from different e-mail providers, checks them against the criteria specified in the preferences page, and sends announcements when needed.
E-mail announcer is a multi-threaded plug-in that follows the producer / consumer model, which uses one or more threads to produce data that is consumed by one or more other threads.
In this example, you have one timed producer, which extends the TimerTask class, that reads e-mail from the Lotus Notes local client database file and one consumer that parses the e-mails received and sends announcements to the user. Adapting the design to support multiple e-mail providers is simple.
Listing 1 is a snippet of code from the Service Controller class that shows how the announcement service initializes and starts when the user enables the service.
Listing 1. E-mailServiceController class
//Email Provider IEmailServiceProvider provider = null; //List of e-mail entries populated by e-mail providers and will be processed by //announcement processor List listOfEntries = new LinkedList(); //Iterate over e-mail provider factories that implemente eail announcer extension //point Iterator iter = (Utils.getEmailServiceFactoryProviders()).iterator(); //loop //Retrieving the service from the factory provider = ((IEmailProviderFactory) iter.next()).getServiceProvider(); // Start consumer thread announcement processor announcementProcessor = new AnnouncementProcessor (listOfEntries); announcementThread = new Thread(announcementProcessor); announcementThread.start(); //An instance of the e-mail service provider processor emailProviderProcessor = new EmailServiceProviderProcessor(listOfEntries, provider); //schedule it with the TimerTask Date timerDate = new Date(); emailThread = new Timer(true); emailThread.schedule(emailProviderProcessor, timerDate, pollInterval); |
The following instructions explain the code in Listing 1:
- Create the queue, which represents a temporary place where the e-mail provider can store retrieved e-mails.
- Retrieve all plug-ins from the Eclipse registry extension, which implements the announcer plug-in factory extension point.
- Get the e-mail service provider from the factory.
- Create the announcement thread (consumer thread).
- Create the e-mail provider timer thread (producer thread).
- Schedule the e-mail provider timer thread to run periodically, according to the user preferences.
Defining the extension point for the announcer plug-in
The announcer plug-in exposes an interface that each e-mail provider can implement. The interface exposed is shown in listing 2; the getServiceProvider function returns an object of type IEmailServiceProvider as shown in listing 3.
Listing 2. The IEmailProviderFactory interface
public interface IEmailProdviderFactory {
public IEmailServiceProvider getServiceProvider();
}
|
Listing 3. The IEmailServiceProvider interface
public interface IEmailServiceProvider {
public void init(Properties prop);
public List getEmailItems(Date day) throws EmailServiceException;
public String getEmailProviderName();
}
|
To expose this interface as an extension point, the announcer plug-in has to create an extension point in its plug-in manifest schema file called EmailPoint.
Listing 4 is a snippet of the schema file emailPoint.xsd.
Listing 4. emailPoint.xsd schema file
<element name="EmailPoint">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation></documentation>
<appInfo>
<meta.attribute kind="java"
basedOn="com.ibm.tivoli.lotus.sametime.IEmailProviderFactory"/>
</appInfo>
</annotation>
</attribute>
</complexType>
</element>
|
To define the extension point, take the following steps:
- Launch the Extension Point wizard by doing these tasks:
- Double-click the plugin.xml file.
- Select the Extension Points tab.
- Click the Add button.
- In the Extension Point Properties window that displays, shown in figure 5, enter the following:
- In the Extension Point ID field, enter EmailPoint.
- In the Extension Point Name field, enter EmailPoint.
- In the Extension Point Schema field, enter schema/emailPoint.exsd.
- Select the option Edit extension point schema when done.
- Click Finish.
A file is created inside the schema folder with the name emailPoint.exsd.
Figure 5. The Extension Point wizard
Double-click the emailPoint xsd file in the schema folder. A schema editor opens the file for you. Rename the default extension point to EmailPoint and create the class attribute as showing in figure 6.
In the Atribute Details section, follow these steps:
- In the Name field, enter class.
- In the Deprecated field, select the option false.
- In the Use field, select required.
- In the Type field, select java.
- In the Implements field, select lotus.sametime.IEmailProviderFactory.
Figure 6. The EmailPoint Extension Point definition window
Querying the extension registry for e-mail providers
You need to read the extension registry for any plug-in that implements the extension point. The code snippet shown in listing 5 illustrates how to read the extension registry. The following items explain code instruction found in listing 5:
- Get the extension registry.
- Get extension points that implement the EmailPoint extension point.
- Construct an instance of the class that implements IEmailProviderFactory.
- Add the constructed instance to the e-mail providers list.
Listing 5. Reading the extension registry
List serviceProvidersList = new ArrayList();
//Get registry
IExtensionRegistry reg = Platform.getExtensionRegistry();
// EXTENSION_POINT = Plug-In id + Extension point
IConfigurationElement[] extensions =
reg.getConfigurationElementsFor(EmailConstants.EXTENSION_POINT);
for (int i = 0; i < extensions.length; i++) {
IConfigurationElement element = extensions[i];
if (element.getAttribute(EmailConstants.LOOKUP_ATTRIB) != null) {
//Create instance of the class that implements
IEmailProviderFactory interface
IEmailProviderFactory factory = (IEmailProviderFactory) element
.createExecutableExtension(EmailConstants.LOOKUP_ATTRIB);
//add to the list
serviceProvidersList.add(factory);
|
Main components of the Lotus Sametime e-mail announcer plug-in
The Lotus Sametime e-mail announcer plug-in consists of these components:
- The e-mail service provider processor
- The announcement processor
- The announcement dispatcher
The e-mail service provider processor
This component plays the role of producer in the multithreaded model, and it is responsible for retrieving incoming e-mails from a particular e-mail provider. The snippet of code shown in listing 6 shows how this component works:
- It get a list of e-mails received since last time you received e-mail or since you started running the service.
- It adds each e-mail to the queue.
Listing 6. EmailServiceProviderProcessor class
// synchronized statements on listOfJobs which provides the intrinsic lock
synchronized (listOfJobs) {
// Get the list of e-mails since last time we received e-mail from this provider
List list = provider.getEmailItems(lastReceived);
// Iterate over the list of e-mails
Iterator iter = list.iterator();
while (iter.hasNext())
Object entry = iter.next();
//Add e-mails received to our list of jobs link list which represents a queue.
((LinkedList) listOfJobs).addFirst(entry);
//notify consumer we are finished
listOfJobs.notifyAll();
|
This component is responsible for processing each e-mail received. The logic of how this component works is illustrated in listing 7. The announcement processor does the following:
- While the service is running, it checks the size of queue. If the queue is empty, it waits and takes no further action.
- If the queue is not empty, then the processor parses each e-mail received in the queue and determines if it meets the announcement criteria.
- The processor sends an announcement if a parsed e-mail meets the user-predefined criteria.
- Finally, the processor removes the e-mail from the queue.
Listing 7. The announcement processor
//initialize the thread to keep running
haltProcessing = false;
//While the service is still running
while (!haltProcessing) {
synchronized (listOfEntries) {
while (listOfEntries.size() == 0 && !haltProcessing) {
//If the Queue is empty then waits and no further action is required
try {
listOfEntries.wait();
} catch (InterruptedException ex)
//Else gets the item from the queue and parses e-mail topic or e-mail body.
EmailEntryBeanImplWrapper record =
process((IEmailEntry) listOfEntries.getLast());
//Send announcement
dispatch(record);
// remove
listOfEntries.removeLast();
|
This component is responsible for sending the actual announcement after the e-mails have been processed and the determination made that at least one e-mail meets the predefined criteria. The code shown in listing 8 shows how this component works:
- In the constructor, the dispatcher retrieves an instance of the Lotus Sametime session to which you are connecting, so that you can use the announcement service. In sendAnnouncement, the dispatcher gets a handle on the Lotus Sametime announcement service.
- The dispatcher retrieves the contact ID from the PeopleUtil class and then creates the STUser object.
- The dispatcher uses the sendAnnouncement function to send the actual announcement. It does not allow a response to the announcement because you previously set the second parameter in sendAnnouncement function to false.
Listing 8. AnnouncementDispatcher class
//Get Lotus Sametime session
public AnnouncementDispatcher(){
Community community = CommunityUtil.getDefaultCommunity();
RtcSession rtc = community.getRtcSession();
session = (STSession) rtc.getProtocolSession();
session.start();
session.loadAllComponents();
me = PeopleUtil.getLocalPerson();
}
public void sendAnnouncement(EmailEntryBeanImplWrapper entry){
//Get announcement service
AnnouncementService announcementService = (AnnouncementService)
session.getCompApi(AnnouncementService.COMP_NAME);
//create STUser
STId stId = new STId(me.getContactId(), "");
STUser user = new STUser(stId, "", "");
//send
announcementService.sendAnnouncement(new STObject[]{user}, false,
}
|
Main component of the Lotus Notes e-mail provider plug-in
This plug-in is the concrete implementation of the e-mail service provider for the Lotus Notes e-mail local client. This plug-in makes connections to the Lotus Notes local database file and queries the database for any new e-mails. As mentioned at the beginning of this article, you can develop other plug-ins to listen to other e-mail providers such as Gmail and Hotmail by following the same technique provided here for Lotus Notes.
The e-mail service provider is the main component in this plug-in, shown in listing 9. The logic of how this component works is illustrated here:
- The e-mail service provider initializes Lotus Notes on the currently running thread by calling the static function sinitThread on that NotesThread class before you use any Lotus Notes classes.
It creates a Lotus Notes session of type LocalClient. This session type uses a local installation of Lotus Notes. With this session type, the Username parameter (IBM Lotus Domino login) is ignored. The Password (Lotus Domino password) must match the password in the ID file used.
- It opens the mail database and iterates over the inbox folder.
- It checks only new e-mails with a delivery date that is later than the date passed as a parameter.
- Finally, it terminate the Lotus Notes thread by calling NotesThread.stermThread in the final block.
Listing 9. E-mail service provider for Lotus Notes
public List getEmailItems(Date since) throws EmailServiceException {
List entries = new ArrayList();
try {
NotesThread.sinitThread();
session = NotesFactory.createSession(NULLSTR, NULLSTR ,this.password);
// Locate the DB Dir
DbDirectory dir = session.getDbDirectory(null);
// Get mail DB
Database db = dir.openMailDatabase();
View view = db.getView("($Inbox)");
Document doc = view.getFirstDocument();
while (doc != null) {
DateTime deliveryDate = (DateTime) doc.getItemValue("DeliveredDate").get(0);
if (deliveryDate.toJavaDate().getTime() > since.getTime()) {
EmailEntryBeanImpl entry = new EmailEntryBeanImpl(
doc.getItemValueString("Body"),
doc.getItemValueString("From"),
((DateTime) doc.getItemValue("DeliveredDate").get(0)).toJavaDate(),
doc.getItemValueString("Subject"));
entries.add(entry);
doc = view.getNextDocument(doc);
} else {
doc = view.getNextDocument(doc);
}
}
} catch (NotesException e) {
throw new EmailServiceException(e);
} finally {
NotesThread.stermThread(); // must terminate every thread
}
|
This article showed you how to leverage and customize the announcement service feature that is built into the Lotus Sametime Connect Client. Also, it discussed the concept of loose coupling in Eclipse and detailed an example of when to use extensions and extension points to achieve this goal in your design.
The solution touched on using a multithreading approach for processing separate tasks such as the consumer / producer model. It also showed you how to use timers in your plug-in to achieve periodical tasks.
| Description | Name | Size | Download method |
|---|---|---|---|
| Announcer plug-in | com.ibm.tivoli.lotus.zip | 55KB | HTTP |
| Lotus Notes Email Provider | com.ibm.tivoli.notes.email.zip | 2.05MB | HTTP |
Information about download methods
Learn
-
Read the developerWorks Lotus article, "Getting started with the IBM Lotus Expeditor Toolkit V6.1.1."
-
Refer to the developerWorks Lotus Expeditor page.
-
Refer to the IBM Lotus Expeditor documentation page.
Get products and technologies
-
Download the IBM Lotus Sametime Standard V8 trial.
-
Download the Eclipse IDE.
-
Download the IBM Lotus Expeditor 6.2 toolkit.
Discuss
Aiman Farhat is a Senior Software Engineer in the IBM software lab in Galway, Ireland. He has a master's degree in Information Technology from University of South Australia, Adelaide, Australia. Aiman has seven years of experience working on projects in a variety of industries including automation, telecommunications, finance, and business management. He currently specializes in developing IBM wireless network management family products. You can reach him at farhatai@ie.ibm.com.




