JavaForLotusScriptDevsFinal.pdf

Writing Java to build applications using IBM Lotus
Domino Designer
Oscar I. Hernandez
IBM Software Group
Staff Software Engineer, Lotus Notes/Domino
Austin, TX
August 2009
© Copyright International Business Machines Corporation 2009. All rights reserved.
Summary: The objective of the article is to help the traditional LotusScript® developer, who
typically has no hard-core development background, move to JavaTM. With little or no existing
Java knowledge, this article will help you get started on developing Java applications in IBM®
Lotus® Domino®.
Table of Contents
1 Introduction.................................................................................................................. 2
2 Java language.............................................................................................................. 2
2.2 Line by line explanation ........................................................................................ 3
2.3 Java language basics........................................................................................... 4
2.4 Differences between LotusScript and the Java language .................................. 10
3 Examples................................................................................................................... 10
3.1 Example 1: Sending an email ............................................................................. 10
3.2 Example 2: Cycling through a Notes view........................................................... 16
3.3 Example 3: Generate a report with mail database information ........................... 21
4 Other essentials......................................................................................................... 30
5 Conclusion................................................................................................................. 31
6 Resources.................................................................................................................. 31
7 About the author ........................................................................................................ 31
1
1 Introduction
For IBM Lotus Notes application developers, LotusScript and the LotusScript classes are
invaluable when designing Notes applications. The LotusScript API allows you to interact
programmatically with databases, documents, and even with design elements. As Javahas
continued to emerge as a mainstream programming language, more and more Notes
application developers are making the move to Java.
This article is intended for LotusScript developers who want to start programming with Java in
IBM Lotus Domino. It is assumed that the reader is an experienced LotusScript programmer.
This document consists of three main sections: Java Language, Examples, and Other
essentials. Java programmers may feel comfortable enough to jump into the Examples
section, while beginners should review the Java Language section first.
2 Java language
Released in 1995, Java is an object-oriented programming language that was created to
address the need for platform independence. This was accomplished by compiling the Java
source code into bytecodes, which could then be interpreted by any Java Virtual Machine
(JVM) on any platform.
Hence, as long there was a JVM implemented for the desired platform, it could run any Java
application. For more information, visit The History of Java Technology.
Java's syntax is similar to C, and its object-oriented implementation is similar to C++, making it
an easy-to-learn language for C/C++ programmers. LotusScript developers, however, will find
the Java syntax quite different from LotusScript.
Since this article focuses on using Java in Lotus Domino, the examples presented will be in the
context of Lotus Domino.
Let’s begin with the classic "Hello World" example. When you create a new Java agent in
Domino Designer, you received the template code on the left-hand side of table 1. The code
on the right-hand side has been modified to accommodate the "Hello World" example.
2
Table 1. Hello World example
Template Java Agent Code
Hello World Java Agent Code
import lotus.domino.*;
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public class JavaAgent extends AgentBase {
public void NotesMain() {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
try {
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
// (Your code goes here)
}
}
// (Your code goes here)
System.out.println("Hello World!");
} catch(Exception e) {
e.printStackTrace();
}
}
}
} catch(Exception e) {
e.printStackTrace();
}
2.2 Line by line explanation
Let's examine the code, line by line:
import lotus.domino.*;
Java uses the import statement to include other Java classes. In this case, all the lotus.domino
classes are available to the agent code. Java classes are usually contained within JAR files.
There are several methods for making JAR files available to an agent. Refer to the “Using
external JAR files with Java agents”paragraph in Section 4 of this paper for information on JAR
files.
public class JavaAgent extends AgentBase {
Java is an object-oriented programming language. This line demonstrates that, when you
create a Java agent, it creates a JavaAgent class, which will be the main class where you will
write your Java code.
You may also notice that the JavaAgent class extends the AgentBase class. Since Java is
object-oriented, extending the AgentBase class gives us an entry point into the agent, which
brings us to the next line.
public void NotesMain() {
The NotesMain method is the entry point to the agent. Here we override the AgentBase
method definition with our own.
try {
In Java, error handling is handled through try and catch blocks. Methods that throw exceptions
in Java must be surrounded by a try block, and every try block must have a corresponding
3
catch block. The try and catch blocks are required in the "Hello World" example because the
getAgentContext method throws a NotesException. To see which Domino methods throw an
exception, refer to their method signature in the Domino Designer Help file.
Session session = getSession();
The getSession method from the AgentBase class allows us to create a session object. The
Java Session class is similar to the LotusScript NotesSession class.
AgentContext agentContext = session.getAgentContext();
The AgentContext class lets you get a handle to the current database (using its
getCurrentDatabase method). In LotusScript, this additional class is not required to get a
handle to the current database.
// (Your code goes here)
The thing to note with this line is that a single line comment begins with "//". For multiple line
comments we use "/*" at the beginning and end with "*/" (similar to C++).
System.out.println("Hello World!");
This is the Java method used to print to the console. To open the Java console in Notes, select
Tools > Show Java Debug Console, from the menu. The System.out.println method is similar
to the LotusScript Print method.
} catch(Exception e) {
This is the corresponding catch statement for the try above.
e.printStackTrace();
In the catch block, you can opt to handle the exception as you wish; in this case, we are simply
printing out the stack trace.
2.3 Java language basics
Java provides eight primitive types: byte, short, int, long, char, float, double, and Boolean.
Table 2 describes each type and indicates the LotusScript equivalent (if any).
Table 2. Primitive types and LotusScript equivalents
Java Primitive Type
Java Description
LotusScript Equivalent
byte
8-bit signed two's complement
integer (-128 to 127)
Byte
Similar: 8-bit
Difference: unsigned (0 to 255)
short
16-bit signed two's complement
integer (-32,768 to 32,767)
Integer
Similar: 16-bit, signed (-32,768 to
32,767)
int
32-bit signed two's complement
integer (-2,147,483,648 to
2,147,483,647)
Long
Similar: 32-bit, signed
(-2,147,483,648 to
2,147,483,647)
long
64-bit signed two's complement
N/A
4
integer
(-9,223,372,036,854,775,808 to
9,223,372,036,854,775,807)
char
single 16-bit Unicode character
N/A
However, LotusScript does
provide a String type which can
contain multiple characters.
float
single-precision 32-bit IEEE 754
floating point
Single
Similar: single-precision 32-bit
floating point
double
double-precision 64-bit IEEE 754 Double
floating point
Similar: double-precision 64-bit
floating point
Boolean
true or false value
Boolean
Similar: true or false value
Operators
Java has a rich set of operators. Table 3 shows merely a subset of its operators along with the
description and LotusScript equivalent. For a complete listing, visit the Java Tutorials
Operators page.
Table 3. Java operators
Java Arithmetic Operator
Description
LotusScript Equivalent
=
Assignment
=
+
Addition
+
++
Increment
N/A
+=
Addition assignment
N/A
-
Subtraction (also unary minus)
-
--
Decrement
N/A
-=
Subtraction assignment
N/A
*
Multiplication
*
*=
Multiplication assignment
N/A
/
Division
/
/=
Division assignment
N/A
%
Modulus
Mod
%=
Modulus assignment
N/A
Java Relational Operator
==
Description
Equal
LotusScript Equivalent
=
5
!=
Not equal
<>, ><
>
Greater than
>
>=
Greater than or equal to
>=, =>
<
Less than
<
<=
Less than or equal to
<=, =<
Java Logical (bitwise)
Operator
Description
LotusScript Equivalent
&
Bitwise And
And
|
Bitwise Or
Or
^
Bitwise exclusive Or
Xor
~
Bitwise complement
Not
>>
Shift bits right with sign
extension
N/A
<<
Shift bits left
N/A
Java Logical (Boolean)
Operator
Description
LotusScript Equivalent
&&
Boolean And
And
||
Boolean Or
Or
==
Boolean equals
Eqv
!
Boolean Not
Not
Declaring a variable
The syntax for declaring a variable in Java is the type, followed by the variable name:
type variable_name;
In Java, variable names can consist of letters, digits, and the underscore. Variable names are
case sensitive and cannot begin with a digit:
Java
LotusScript
int i;
Dim i as Integer
String s;
Dim s as String
6
Creating a function
There are two key differences regarding the function syntax between LotusScript and Java.
First, the return type is placed in front of the function name (as opposed to LotusScript, in
which it is placed at the end). Secondly, Java uses the return keyword to return the value from
the function (see listing 1).
Listing 1. Creating a function example
return_type function_name(parameter_type1 parameter_name1, parameter_type2
parameter_name2)
{
//function code...
return return_type_object;
}
Java
LotusScript
public int product(int x, int y)
{
return x*y;
}
Function product(x As Integer, y As Integer) As
Integer
product = x * y
End Function
Calling the function:
int i = product(2,4);
System.out.println(i);
Calling the function:
Dim i As Integer
i = product(2, 4)
Print i
Creating a class
The syntax for creating classes in Java is similar to that of LotusScript. Both use the class
keyword with the private/public option, and both allow class members as well as class
methods. Note, however, that the LotusScript class constructor uses the New keyword, while
Java uses the name of the class with zero arguments (see listing 2 and table 4).
Listing 2. Example of creating a class
class class_name
{
type class_member1;
type class_member2;
....
class_name()
//constructor
{
//constructor code
}
return_type class_method1(parameter list)
{
//method code
7
}
return_type class_method2(parameter list)
{
//method code
}
....
}
Table 4. Creating a class
Java
LotusScript
public class Person
{
private String Name;
private int Age;
Public Class Person
Private PName As String
Private PAge As Integer
Sub New
PAge = 0
PName = ""
End Sub
public Person()
{
this.Name="";
this.Age=0;
}
Public Property Set Person_Name As String
PName = Person_Name
End Property
public void SetName(String name)
{
this.Name = name;
}
Public Property Get Person_Name As String
Person_Name = PName
End Property
public String GetName()
{
return this.Name;
}
Public Property Set Age As Integer
PAge = Age
End Property
public void SetAge(int age)
{
this.Age = age;
}
Public Property Get Age As Integer
Age = PAge
End Property
Sub AddYears (i As Integer)
PAge = PAge + i
End Sub
public int GetAge()
{
return this.Age;
}
}
End Class
public void AddYears(int i)
{
this.Age = this.Age + i;
}
8
Creating an Instance of the Class:
Creating an Instance of the Class:
Person p = new Person();
p.SetName("John Doe");
p.SetAge(20);
Dim p As New Person
p.Person_Name = "John Doe"
p.Age = 20
System.out.println(p.GetName() + " " +
p.GetAge());
Messagebox p.Person_Name & " " & Cstr
(p.Age)
p.AddYears(5);
p.AddYears(5)
System.out.println(p.GetName() + " " +
p.GetAge());
Messagebox p.Person_Name & " " & Cstr
(p.Age)
Flow control statements
To control the flow of your script, Java provides all the standard flow control statements you
would expect from any programming language. Table 5 lists Java's most common flow control
statements and their LotusScript equivalent. For further information on Java's flow control
statements, visit the Java Tutorials Control Flow Statements page.
Table 5. Java flow control statements
Java Flow Control Statements
LotusScript Equivalent
if (condition) {
//perform these statements
}
If condition Then
'perform these statements
End If
if (condition) {
//perform these statements
}
else {
//perform these statements
}
If condition Then
'perform these statements
Else
'perform these statements
End If
switch (expr) {
case c1:
//perform these statements if expr == c1
break;
case c2:
//perform these statements if expr == c2
break;
...
default:
//perform these statements if expr != any
of cases
}
Select Case expr
Case c1
'perform these statements if expr = c1
Case c2
'perform these statements if expr = c2
...
Case Else
'perform these statements if expr <> any
of the cases
End Select
while (condition) {
//perform these statements
}
While condition
'perform these statements
Wend
do {
Do While condition
'perform these statements
Loop
//perform these statements
} while (condition);
9
for (initialization; termination; increment) {
//perform these statements
}
For countVar = first To last
'perform these statements
Next
2.4 Differences between LotusScript and the Java language
LotusScript and Java are similar in that they are both are object-oriented programming
languages. Besides the syntax, one of the main differences between the languages is that
Java is strongly typed, while LotusScript is not.
In Java, you must declare all variables (name and type) before they are used. This is not a
requirement in LotusScript, although there is some type enforcement.
Another major difference is that Java is case sensitive, while LotusScript is not. You should
keep this in mind when writing Java code because p and P are two different variables, and
setName and SetName are two different methods.
Domino-specific differences
Although the names may differ, most of the Domino classes provided for LotusScript are
available in Java. In LotusScript, Domino classes begin with “Notes”; for example, the class for
dealing with databases is “NotesDatabase”, and for documents it's “NotesDocument”.
In Java, on the other hand, the names of the classes do not begin with “Notes”. Hence, the
class for dealing with databases is just “Database”, and for documents it's “Document”.
A major difference between the LotusScript and Java Domino classes is the UI classes.
LotusScript provides the following classes for UI interaction:
NotesUIWorkspace, NotesUIDatabase, NotesUIDocument, and NotesUIView
These classes let you interact with the current database, document, or view open in Notes. In
Java, however, there are no equivalent UI classes. For a complete listing of the Java Domino
classes, refer to the Domino Designer Help file.
3 Examples
Let's look at some common tasks that are performed using LotusScript and see how we can
do the equivalent in Java. Our first example is sending an email message.
3.1 Example 1: Sending an email
Take a minute to examine the LotusScript code in listing 3 below:
Listing 3. Example LotusScript send email code
1
2
3
4
Dim session As New NotesSession
Dim database As NotesDatabase
Dim email As NotesDocument
Dim sendto As String
10
5
6
Dim subject As String
Dim body As String
7
8
9
10
11
Set database = session.CurrentDatabase
Set email = database.CreateDocument
sendto = "Enter_Email_Address_Here"
subject = "Email sent by LotusScript code"
body = "Text in body of email sent by LotusScript code"
12
13
14
15
16
Call email.ReplaceItemValue("Form", "Memo")
Call email.ReplaceItemValue("SendTo", sendto)
Call email.ReplaceItemValue("Subject", subject)
Call email.ReplaceItemValue("Body", body)
Call email.Send(False)
Now let's code the above example in Java, starting off with the Java template code that is
provided for us (see listing 4).
Listing 4. Java template code
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
} catch(Exception e) {
e.printStackTrace();
}
}
}
In lines 1--6 of the LotusScript example in listing 3 above, we declare the session, database,
email, sendto, subject, and body variables. Since the template code already provides us with a
session object, let's declare the remaining variables (see listing 5).
Listing 5. Declaring the remaining variables
import lotus.domino.*;
11
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
Document email;
String sendto;
String subject;
String body;
} catch(Exception e) {
e.printStackTrace();
}
}
}
In lines 7--11 from listing 3, we initialize our database, email, sendto, subject, and body
variables (see listing 6). As mentioned earlier, we must use the agentContext object instead of
the session object to get a handle to the current database. Also, we do not need the Set
keyword in Java to set the variables.
Listing 6. Initializing the variables
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
Document email;
String sendto;
String subject;
12
String body;
database = agentContext.getCurrentDatabase();
email = database.createDocument();
sendto = "Enter_Email_Address_Here";
subject = "Email sent by Java code";
body = "Text in body of email sent by Java code";
} catch(Exception e) {
e.printStackTrace();
}
}
}
In lines 12--15 of listing 3, we replace the value of fields Form, SendTo, Subject, and Body,
and finally, in line 16, we send the email. Notice Java does not require the Call keyword (see
listing 7) when calling methods.
Also, even though the replaceItemValue and send methods have the same spelling between
LotusScript and Java, you must remember to use the correct case in Java (since Java is case
sensitive).
Listing 7. Setting the appropriate fields and sending the email
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
Document email;
String sendto;
String subject;
String body;
database = agentContext.getCurrentDatabase();
email = database.createDocument();
sendto = "Enter_Email_Address_Here";
subject = "Email sent by Java code";
body = "Text in body of email sent by Java code";
13
email.replaceItemValue("Form", "Memo");
email.replaceItemValue("SendTo", sendto);
email.replaceItemValue("Subject", subject);
email.replaceItemValue("Body", body);
email.send(false);
} catch(Exception e) {
e.printStackTrace();
}
}
}
There are no more LotusScript lines left, but we still have some additional work to perform in
our Java agent. Specifically, in Java, we must call recycle on all Domino objects (see listing 8).
Calling recycle ensures that all the memory allocated for those objects is released. For more
information on the recycle method, see the “The recycle() method” paragraph in Section 4.
Listing 8. Calling recycle on Domino objects
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
Document email;
String sendto;
String subject;
String body;
database = agentContext.getCurrentDatabase();
email = database.createDocument();
sendto = "Enter_Email_Address_Here";
subject = "Email sent by Java code";
body = "Text in body of email sent by Java code";
email.replaceItemValue("Form", "Memo");
14
email.replaceItemValue("SendTo", sendto);
email.replaceItemValue("Subject", subject);
email.replaceItemValue("Body", body);
email.send(false);
//recycle Java Domino objects
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (database !=null)
database.recycle();
if (email !=null)
email.recycle();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Table 6 sums up this example comparison.
Table 6. Side-by-side comparison of Example 1
LotusScript
Java
Example 1: Sending an Email
Example 1: Sending an Email
Dim session As New NotesSession
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
Dim database As NotesDatabase
Dim email As NotesDocument
Dim sendto As String
Dim subject As String
Dim body As String
Database database;
Document email;
String sendto;
String subject;
String body;
Set database = session.CurrentDatabase
Set email = database.CreateDocument
sendto = "Enter_Email_Address_Here"
subject = "Email sent by LotusScript code"
body = "Text in body of email sent by
LotusScript code"
Call email.ReplaceItemValue("Form", "Memo")
Call email.ReplaceItemValue("SendTo", sendto)
Call email.ReplaceItemValue("Subject", subject)
Call email.ReplaceItemValue("Body", body)
database = agentContext.getCurrentDatabase();
email = database.createDocument();
sendto = "Enter_Email_Address_Here";
subject = "Email sent by Java code";
body = "Text in body of email sent by Java
code";
Call email.Send(False)
15
email.replaceItemValue("Form", "Memo");
email.replaceItemValue("SendTo", sendto);
email.replaceItemValue("Subject", subject);
email.replaceItemValue("Body", body);
email.send(false);
//recycle Java Domino objects
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (database !=null)
database.recycle();
if (email !=null)
email.recycl
3.2 Example 2: Cycling through a Notes view
For our second example, we cycle through a Notes view (see listing 9). Though fairly simple,
this example is very important when coding in Java since it demonstrates using the recycle
method properly so as to prevent memory exceptions.
Listing 9. LotusScript code for cycling through a view
1
2
3
4
Dim session As New NotesSession
Dim database As NotesDatabase
Dim view As NotesView
Dim document As NotesDocument
5
6
7
Set database = session.CurrentDatabase
Set view = database.GetView("Enter_View_Name_Here")
Set document = view.GetFirstDocument
8
While (Not document Is Nothing)
'Process the document
Print document.Created
Set document = view.GetNextDocument(document)
Wend
9
10
11
Starting out with the Java template, let's declare the database, view, and document variables
(LotusScript lines 1--4 in listing 9). In addition to these three variables, we need a temporary
Document. The temp Document variable is required in our while loop, to recycle the current
document (see listing 10).
Listing 10. Declaring database, view, and document variables
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
16
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
View view;
Document document;
Document temp;
} catch(Exception e) {
e.printStackTrace();
}
}
}
Moving on to lines 5--7 (see listing 9), let's initialize our database, view, and document
variables, as shown in listing 11.
Listing 11. Initializing database, view, and document variables
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
View view;
Document document;
Document temp;
database = agentContext.getCurrentDatabase();
view = database.getView("Enter_View_Name_Here");
document = view.getFirstDocument();
} catch(Exception e) {
e.printStackTrace();
}
17
}
}
In lines 8--11 in listing 9, we cycle through each document in the view. Java has the same
while keyword for the loop; however, we must use != instead of Not, and null instead of
Nothing (see listing 12).
Also, if we're to assign the same Domino variable multiple times in Java, we need to call
recycle on it before the new assignment, to prevent memory leaks (hence the need for the
temp variable).
Listing 12. Cycling through each document in view
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
View view;
Document document;
Document temp;
database = agentContext.getCurrentDatabase();
view = database.getView("Enter_View_Name_Here");
document = view.getFirstDocument();
while (document != null)
{
//Process the document
System.out.println(document.getCreated());
temp = view.getNextDocument(document); // get the next
document
document.recycle(); // recycle the document we're done with
document = temp;
}
} catch(Exception e) {
e.printStackTrace();
}
}
18
}
We wrap up this example by calling recycle on all the other Domino objects we created, as
shown in listing 13.
Listing 13. Calling recycle on all other Domino objects
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database database;
View view;
Document document;
Document temp;
database = agentContext.getCurrentDatabase();
view = database.getView("Enter_View_Name_Here");
document = view.getFirstDocument();
while (document != null)
{
//Process the document
System.out.println(document.getCreated());
temp = view.getNextDocument(document); // get the next
document
document.recycle(); // recycle the document we're done with
document = temp;
}
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (database !=null)
database.recycle();
if (view != null)
view.recycle();
19
} catch(Exception e) {
e.printStackTrace();
}
}
}
Table 7 sums up this comparison.
Table 7. Side-by-side comparison of Example 2
LotusScript
Example 2: Cycling through a Notes View
Dim session As New NotesSession
Dim database As NotesDatabase
Dim view As NotesView
Dim document As NotesDocument
Set database = session.CurrentDatabase
Set view = database.GetView
("Enter_View_Name_Here")
Set document = view.GetFirstDocument
While (Not document Is Nothing)
'Process the document
Print document.Created
Set document = view.GetNextDocument
(document)
Wend
Java
Example 2: Cycling through a Notes View
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
Database database;
View view;
Document document;
Document temp;
();
database = agentContext.getCurrentDatabase
view = database.getView
("Enter_View_Name_Here");
document = view.getFirstDocument();
while (document != null)
{
//Process the document
System.out.println(document.getCreated());
temp = view.getNextDocument
(document); // get the next document
document.recycle(); // recycle the document
we're done with
document = temp;
}
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (database !=null)
database.recycle();
if (view != null)
view.recycle();
20
3.3 Example 3: Generate a report with mail database information
Our last example is fairly extensive. Here we cycle through mail databases on a Domino server
and create an email report with various items from from each mail file. First, take a moment to
review the LotusScript example in listing 14.
21
Listing 14. LotusScript code example
1
2
3
4
5
6
7
Dim session As New Notessession
Dim nab As New Notesdatabase("Enter_Server_Name_Here", "names.nsf")
Dim reportDatabase As Notesdatabase
Dim personDocument As NotesDocument
Dim report As NotesDocument
Dim view As NotesView
Dim temp As String
8
9
Set reportDatabase = session.CurrentDatabase
Set report = reportDatabase.CreateDocument
10
11
Call report.ReplaceItemValue("Form" , "Memo")
Call report.ReplaceItemValue("Subject" , "Mail Applications Report")
12
Dim richTextItem As New NotesRichTextItem(report, "Body")
13
Set view = nab.GetView("People")
14
Set personDocument = view.GetFirstDocument
15
While Not personDocument Is Nothing
16
On Error Resume Next
17
Dim mailDatabase As New NotesDatabase(personDocument.mailserver(0),
personDocument.mailfile(0))
18
If mailDatabase.IsOpen Then
19
temp = "Mail Owner: " & personDocument.fullname(0) & " Size: " &
Cstr(mailDatabase.size) & " _ bytes Template: " + mailDatabase.DesignTemplateName
20
Else
21
temp = "Could not open mail file for: " & personDocument.fullname(0) &
" Server: " & personDocument.mailserver(0) & " , " & personDocument.mailfile(0)
22
End If
23
24
25
26
27
richTextItem.AppendText(temp)
richTextItem.AddNewline(1)
temp = ""
Set personDocument = view.GetNextDocument(personDocument)
Wend
28
Call report.Send(False, "Enter_Email_Address_Here")
We start out with lines 1--7 (in listing 14), declaring the needed variables, and we initialize the
nab Database variable. In Java, notice that we must use the session object to set nab (see
listing 15).
22
Listing 15. Declaring the variables
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database nab;
nab = session.getDatabase("Enter_Server_Name_Here","names.nsf");
Database reportDatabase;
Document personDocument;
Document report;
Document tempDocument;
View view;
String temp;
} catch(Exception e) {
e.printStackTrace();
}
}
}
The main difference between the LotusScript lines 8--14 (in listing 14) and the Java equivalent
is the RichTextItem class; in Java, you need to use the createRichTextItem method of the
Document class to create the rich text field (see listing 16).
Listing 16. Initializing the variables and creating the report email
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
23
Database nab;
nab = session.getDatabase("Enter_Server_Name_Here","names.nsf");
Database reportDatabase;
Document personDocument;
Document report;
Document tempDocument;
View view;
String temp;
reportDatabase = agentContext.getCurrentDatabase();
report = reportDatabase.createDocument();
report.replaceItemValue("Form" , "Memo");
report.replaceItemValue("Subject" , "Mail Applications Report");
RichTextItem richTextItem;
richTextItem = report.createRichTextItem("Body");
view = nab.getView("People");
personDocument = view.getFirstDocument();
} catch(Exception e) {
e.printStackTrace();
}
}
}
In lines 15--27 of listing 14, we do most of the work in the while loop. In Java, we use try/catch
blocks for error handling instead of the On Error statement in LotusScript. Since the
getDatabase method can throw an exception, we take advantage of the catch block to set the
temp string variable (see listing 17).
Another thing we must remember in Java is to use the recycle method within loops when
reusing Domino variables. In this particular while loop, we must remember to recycle the
mailDatabase and personDocument before each new assignment.
Listing 17. Gathering the mail database information
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
24
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database nab;
nab = session.getDatabase("Enter_Server_Name_Here","names.nsf");
Database reportDatabase;
Document personDocument;
Document report;
Document tempDocument;
View view;
String temp;
reportDatabase = agentContext.getCurrentDatabase();
report = reportDatabase.createDocument();
report.replaceItemValue("Form" , "Memo");
report.replaceItemValue("Subject" , "Mail Applications Report");
RichTextItem richTextItem;
richTextItem = report.createRichTextItem("Body");
view = nab.getView("People");
personDocument = view.getFirstDocument();
while (personDocument != null)
{
Database mailDatabase;
try {
mailDatabase = session.getDatabase
(personDocument.getItemValueString("MailServer"), personDocument.getItemValueString
("MailFile"));
temp = "Mail Owner: " +
personDocument.getItemValueString("FullName") + " Size: " + mailDatabase.getSize()
+ " _ bytes Template: " +
mailDatabase.getDesignTemplateName();
mailDatabase.recycle();
} catch (Exception e) {
temp = "Could not open mail file for: " +
personDocument.getItemValueString("FullName") + " Server: " +
personDocument.getItemValueString
("MailServer") + " , " + personDocument.getItemValueString("MailFile");
}
richTextItem.appendText(temp);
richTextItem.addNewLine(1);
25
temp = "";
tempDocument = view.getNextDocument(personDocument);
personDocument.recycle();
personDocument = tempDocument;
}
} catch(Exception e) {
e.printStackTrace();
}
}
}
We wrap up this example by sending the email (line 28 of listing 14) and then recycling the rest
of the Domino objects we created (see listing 18).
Listing 18. Sending email and calling recycle on Domino objects
import lotus.domino.*;
public class JavaAgent extends AgentBase {
public void NotesMain() {
try {
Session session = getSession();
AgentContext agentContext = session.getAgentContext();
// (Your code goes here)
Database nab;
nab = session.getDatabase("Enter_Server_Name_Here","names.nsf");
Database reportDatabase;
Document personDocument;
Document report;
Document tempDocument;
View view;
String temp;
reportDatabase = agentContext.getCurrentDatabase();
report = reportDatabase.createDocument();
report.replaceItemValue("Form" , "Memo");
report.replaceItemValue("Subject" , "Mail Applications Report");
RichTextItem richTextItem;
richTextItem = report.createRichTextItem("Body");
26
view = nab.getView("People");
personDocument = view.getFirstDocument();
while (personDocument != null)
{
Database mailDatabase;
try {
mailDatabase = session.getDatabase
(personDocument.getItemValueString("MailServer"), personDocument.getItemValueString
("MailFile"));
temp = "Mail Owner: " +
personDocument.getItemValueString("FullName") + " Size: " + mailDatabase.getSize()
+ " _ bytes Template: " +
mailDatabase.getDesignTemplateName();
mailDatabase.recycle();
} catch (Exception e) {
temp = "Could not open mail file for: " +
personDocument.getItemValueString("FullName") + " Server: " +
personDocument.getItemValueString
("MailServer") + " , " + personDocument.getItemValueString("MailFile");
}
richTextItem.appendText(temp);
richTextItem.addNewLine(1);
temp = "";
tempDocument = view.getNextDocument(personDocument);
personDocument.recycle();
personDocument = tempDocument;
}
report.send(false, "Enter_Email_Address_Here");
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (nab != null)
nab.recycle();
if (reportDatabase !=null)
reportDatabase.recycle();
if (personDocument !=null)
personDocument.recycle();
if (report !=null)
report.recycle();
if (view !=null)
27
view.recycle();
if (richTextItem !=null)
richTextItem.recycle();
} catch(Exception e) {
e.printStackTrace();
}
}
}
Table 8 sums up the comparison.
Table 8. Side-by-side comparison of Example 3
LotusScript
Java
Example 3: Generate a Report with Mail Database
Information
Example 3: Generate a Report with Mail Database
Information
Dim session As New Notessession
Session session = getSession();
AgentContext agentContext =
session.getAgentContext();
Dim nab As New Notesdatabase
("Enter_Server_Name_Here", "names.nsf")
Database nab;
nab = session.getDatabase
("Enter_Server_Name_Here","names.nsf");
Database reportDatabase;
Dim reportDatabase As Notesdatabase
Dim personDocument As NotesDocument
Dim report As NotesDocument
Document personDocument;
Document report;
Document tempDocument;
View view;
String temp;
Dim view As NotesView
Dim temp As String
Set reportDatabase = session.CurrentDatabase
Set report = reportDatabase.CreateDocument
Call report.ReplaceItemValue("Form" , "Memo")
Call report.ReplaceItemValue("Subject" , "Mail
Applications Report")
Dim richTextItem As New NotesRichTextItem
(report, "Body")
Set view = nab.GetView("People")
Set personDocument = view.GetFirstDocument
While Not personDocument Is Nothing
On Error Resume Next
Dim mailDatabase As New NotesDatabase(
personDocument.mailserver(0),
personDocument.mailfile(0))
If mailDatabase.IsOpen Then
reportDatabase =
agentContext.getCurrentDatabase();
report = reportDatabase.createDocument();
report.replaceItemValue("Form" , "Memo");
report.replaceItemValue("Subject" , "Mail
Applications Report");
RichTextItem richTextItem;
richTextItem = report.createRichTextItem
("Body");
view = nab.getView("People");
personDocument = view.getFirstDocument();
while (personDocument != null)
{
Database mailDatabase;
try {
mailDatabase = session.getDatabase(
28
temp = "Mail Owner: " &
personDocument.fullname(0) & "
Size: " & Cstr(mailDatabase.size) &
" _ bytes
Template: " +
mailDatabase.DesignTemplateName
personDocument.getItemValueString
("MailServer"),
personDocument.getItemValueString
("MailFile"));
temp = "Mail Owner: " +
personDocument.getItemValueString
("FullName") + "
Size: " + mailDatabase.getSize() + " _
Else
bytes
temp = "Could not open mail file for: " &
Template: " +
personDocument.fullname(0) & "
mailDatabase.getDesignTemplateName();
Server: " & personDocument.mailserver(0)
mailDatabase.recycle();
&" ,"
} catch (Exception e) {
& personDocument.mailfile(0)
temp = "Could not open mail file for: " +
End If
personDocument.getItemValueString
("FullName") + "
Server: " +
personDocument.getItemValueString
richTextItem.AppendText(temp)
("MailServer") + " , "
richTextItem.AddNewline(1)
+ personDocument.getItemValueString
temp = ""
("MailFile");
Set personDocument =
view.GetNextDocument(personDocument)
}
Wend
Call report.Send(False,
"Enter_Email_Address_Here")
richTextItem.appendText(temp);
richTextItem.addNewLine(1);
temp = "";
tempDocument = view.getNextDocument
(personDocument);
personDocument.recycle();
personDocument = tempDocument;
}
report.send(false,
"Enter_Email_Address_Here");
if (session !=null)
session.recycle();
if (agentContext !=null)
agentContext.recycle();
if (nab != null)
nab.recycle();
if (reportDatabase !=null)
reportDatabase.recycle();
if (personDocument !=null)
personDocument.recycle();
if (report !=null)
report.recycle();
if (view !=null)
view.recycle();
if (richTextItem !=null)
richTextItem.recycle();
29
4 Other essentials
Let's go over some other essential points relevant to our discussion of Java code and
LotusScript.
JVM versions. Unlike LotusScript, Java code is run on a Java Virtual Machine (JVM). Table 9
shows the JVM version that is shipped with the various Notes/Domino releases.
Table 9. JVM and Notes/Domino versions
Notes/Domino Version
JVM Version
6.5.x
1.3.1
7.0.x
1.4.2
8.0.x
1.5.0
8.5
1.6.0
The JVM is installed during the normal client/server install and is independent from a JVM that
can be installed on the operating system. The version is important when using classes
provided by the JVM since there are differences between versions.
The recycle() method. If you browse through the Domino classes in the Designer Help file,
you will notice that each Java class has an additional method called the recycle method (there
is no corresponding LotusScript method). The description of this method (from the Help file)
states “The recycle method unconditionally destroys an object and returns its memory to the
system.”
We won't go into the importance of why you should call the recycle method because this topic
is covered in detail in Lotus Support Technote #1097861, “Why it is important to use Recycle()
method on every Java object.” Just remember that, to prevent memory leaks, you should
ALWAYS call the recycle method on all Domino Java objects you create.
Security exceptions. Since Java code is run on the JVM, there is an additional security layer
for Java code that is not present when using LotusScript. Depending on the Java classes /
methods being used, you may run into security exceptions such as the
java.security.AccessControlException exception when running your Java code in Lotus
Domino.
If you do encounter security exceptions, you must explicitly grant access in the java.policy file
of the JVM. For more information, see the Lotus Support Technote #1279509, “Security
exceptions are encountered when developing Java agents.”
Using external JAR files with Java agents. Similar to LotusScript .lss files, Java agents can
use existing Java classes. If you have a JAR file with the Java classes you want to use, you
can make these classes available to an agent by using one of the following three methods:
30
•
Attach the JAR file to the agent itself:
1. Open the Java agent in Domino Designer and click “Edit Project”.
2. Select the directory in which the JAR file is located in the Base directory field.
3. Select and add the JAR file.
•
Copy the JAR file to the {Lotus Notes\Domino program directory}\jvm\lib\ext.
•
Use the JavaUserClasses Notes.ini variable; in your Notes or Domino Notes.ini file, add the
variable and point to one or more JAR files, for example:
JavaUserClasses=C:\jar_files\file1.jar;C:\jar_files\file2.jar
NOTE: After making the JAR files available, you must use the import statement in the agent to
refer to the specific class you want to use.
5 Conclusion
Hopefully this paper has helped provide a bridge for the traditional Domino developer to begin
developing Java agents in Domino Designer. The examples presented above can serve as
template code in developing more extensive Java agents. Remember that the Domino
Designer 8.5 Help file provides an extensive collection of Java examples for each Domino
class.
6 Resources
•
The Java Tutorials
•
Lotus Domino Designer 8.5 Information Center, Java/CORBA Classes section
•
developerWorks Lotus Notes and Domino product page
•
IBM Lotus Notes/Domino 8.5 Forum
•
Lotus Notes and Domino wiki
7 About the author
Oscar I Hernandez is a Staff Software Engineer with the IBM Lotus Technical Support
organization. He is a member of the Application Development team for Lotus Notes/Domino
and is an IBM Certified Advanced Application Developer. You can reach Oscar at
[email protected].
31
Trademarks
• Domino, IBM, Lotus, LotusScript, and Notes are trademarks or registered trademarks of IBM
Corporation in the United States, other countries, or both.
•
Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun
Microsystems, Inc. in the United States, other countries, or both.
•
Other company, product, and service names may be trademarks or service marks of others.
32