You are on page 1of 16

How To Create A Custom Dialog Box In Maximo Allowing User

To Email BIRT Report


Originally posted by Daniel Ng on May 27, 2012. Last revised on June 8, 2012.

Maximo Version:
7.1.1.4

Pre-requisites:

o
o
o
o

Basic understanding of XML.


Some Java development experience.
Know how to compile Java file into a Class file.
Have a Java development environment set up.
Know how to rebuild and deploy Maximo EAR file.
Familiar with and have the rights to the following Maximo applications:
Application Designer
Database Configuration
Security Groups
Logging

File Download:
Right click or option-click the link and choose "Save As..." to download the file.
1. Custom dialog box (2KB)
2. Java source code (9KB)

This is a comprehensive tutorial on how to create a custom dialog box in Maximo allowing user to
email BIRT report as attachment. While this tutorial is about a specific function, the overall aim is to
use this example as a segue to introduce a few useful and common concepts to those who are new to
Maximo/MBO customization, such as:

How to create a custom dialog box in Maximo.


How to associate a custom dialog box to a custom toolbar button.
How to add functionality to the dialog box via custom AppBean class.
How to programmatically assign default value to dialog box controls.
How to programmatically retrieve data from the current MBO record and also from the dialog box.
How to generate a report programmatically.
How to work with logger.
How to display custom message to user via message box.
and etc.
As mentioned, this is a comprehensive tutorial. Meaning it will be lengthy as I walk you through the
entire process from start to finish. Since it is impossible for me to cover every single detail, I expect
you to know some basics. Please check out the Pre-requisites section before reading any further.
The Java source code and the custom dialog box in XML referred to in this tutorial can be
downloaded from the File Download section.

Finished Product

Before we continue, let's take a sneak peek at the finished product (see both figure 1 and 2 below) so
that you are mindful of what we are trying to accomplish here.
Figure 1: What the custom dialog box looks like.

Figure 2: How it works.

Tip: In this tutorial, I am adding the custom dialog box to the Purchase Orders application and attaching the PO
details report to the email. Theoretically, you can add the custom dialog box to one or more Maximo applications
and have each dialog box calling a different report.

So, Let's Get Started!


Just a heads up, we will first create and set up the dialog box and then we will implement the
functionality via custom AppBean class. Here are the detailed steps we are going to take:
1.
2.
3.
4.
5.
6.
7.
8.

Create a custom XML dialog box.


Attach the custom dialog box to the PO application.
Enable security for the custom dialog box.
Associate the custom dialog box to a custom toolbar button.
Create a custom AppBean class.
Create a custom message box.
Turn on debugging mode for the logger.
Deployment and testing.

Depending on your experience, you can either follow the entire tutorial step by step, or you can skip to
the section that requires your attention.

Step 1: Create a custom XML dialog box.

Maximo, at this point of writing, does not provide us a GUI to create a custom dialog box. Since the
dialog box is XML-based, you can create one using any text or XML editor you have. Once you have
added a custom dialog box to a Maximo application, you can actually modify the dialog box via
Application Designer. For those who prefers a GUI, you can always create a skeleton of your dialog
box, import it into Maximo and then leverage Application Designer to design your form that way.
Personally, I am comfortable designing my form with text editor and I always find Application Designer
buggy in Firefox browser.
In figure 1 above, you can see what the dialog box looks like graphically. The following figure shows
the XML code behind, which you may download from the File Download section.
Figure 3: The XML code behind the custom dialog box.

Color Codes Explained:


Blue text = XML element; Red text = XML attribute; Gray text = String;
Yellow highlight = Safe to change as you see fit; Green highlight = Should be changed to reflect your
needs; Purple highlight = Be cautious when changing.

Before I dwell deeper into the XML, let me first mention that each XML element must have a unique
id. If not, you will experience problem importing your XML code into Maximo. Now, let's examine the
XML line-by-line:
Line # Comment
1

The "beanclass" attribute is how you associate a bean class (i.e., the AppBean class which
we will write later) to this dialog box. If you compile your AppBean class under a different
class path, be sure to specify your value here.
The "id" attribute here is the dialog box id. Typically, an element id has no length restriction,
but there is one here so beware! Later on, you will need to create a signature option for this
dialog box and the name of the signature option should match this dialog box id. Maximo only
allows a maximum of 25 characters for the name. Furthermore, when you try to associate a
signature option to a custom toolbar control (which we will also do), Maximo will throw an
error if your signature option is more than 10 characters long. In short, keep your dialog box
id to no more than 10 characters long to save yourself a ton of headache!
The "mboname" attribute is the name of the MBO which we want to associate our dialog box
to. Since our example is about emailing PO details report, the logical MBO to use is "PO". If
you want to add this tool to the Work Order Tracking application and allow user to email WO
details report, you should change the MBO to "WORKORDER".

Line # Comment
2

The "helpgrid" element is entirely optional. It is an excellent way for displaying long static
message on the dialog screen.

This line will require a bit of an explanation, so please bear with me.
Some background information first. Any XML element that is used to store/capture/display
data must be bound to an existing MBO attribute. An MBO attribute can be of persistent or
non-persistent type. If you want to store the data in the database, you have to use an
attribute that is of persistent type. In our example, we have 4 visible textbox controls on the
dialog box to capture email to, email cc, email subject and email message respectively. Since
it doesn't make sense for us to store these data in the database (we only need to store them
temporary somewhere, access them and dispose them thereafter), we need to use attributes
that are of non-persistent type. With that in mind, we now have a choice to make. We need
an MBO with non-persistent attributes which we can bound our controls to. So, we can either
create a custom MBO object or modify an existing one. It turns out that there is a third hidden
option. There is already an MBO object named "REPORTPARAMETER" in the system that
can fulfill all our needs just out-of-the-box. If you look up the object via Database
Configuration application, you can see that it has all the necessary attributes we need for
emailing purposes.
If you refer back to line #1, you can see that we'd already bound an MBO to the dialog box.
To introduce another MBO into the mix, we need to use a datasource element. As a matter of
fact, you can add as many datasource elements as you want or none at all if you only need to
work with one MBO.
Here, I am adding a datasource element with "REPORTPARAMETER" as the MBO. You will
see that all my textbox and defaultvalue controls referenced this datasource element (via the
"datasrc" attribute) and its attributes (via the "dataattribute" attribute). Needless to say, this is
important.

4, 5, 6 As the name implies, defaultvalue element is hidden element and is traditionally used for
setting default value for an MBO attribute. For instance, if you like to provide a default email
message, you can simply add the following line to the XML. Notice the value for
"dataattribute" attribute is the same as the multilinetextbox element's "dataattribute" value
which is "EMAILCOMMENTS".
<defaultvalue id="rptemail_emailmessage"
dataattribute="EMAILCOMMENTS" datasrc="RPTEMAIL_ds1"
defaulttype="insert" value="Type your message here."/>
Here, I am actually using these defaultvalue elements to store system variables. I want to
expose them here (instead of hardcoding them in the Java class) so that they can be easily
changed (by you) and not having to go through the lengthy deployment process. Later I will
show you how we can programmatically access these values from the AppBean class.
About these system variables:
1. Report Name
Use this variable to specify which report to run. You can look up a list of report
names from the Report Administration application. The only caveat is that the report
must be able to accept a simple where clause that matches records by record id. If

Line # Comment
your report expects other report parameter(s) to run, you may need to adjust the
AppBean class yourself.
2. Report Output Directory
Specify a report output directory on the server. The custom AppBean class, which we
will discuss later, will need to write out a temporarily PDF document on the server
and then it will delete the document after sending the email. Occasionally, it may fail
to delete for whatever reason. I am exposing this variable just so that we can control
the ouput and know where to clean up. The custom AppBean class will create the
directory structure if does not exist.
3. Default Email Subject Line
Specify a default email subject line. The is entirely optional of course. This particular
default value also supports substitution variables. If, for instance, you would like to
show the current record id on the subject line, find out what the proper MBO attribute
name is and then surround it with curly brackets, e.g., {ponum}, {wonum}, etc. These
variables will be replaced by actual values on run-time. In the example here, I want to
display the PO number and PO description on the subject line.
7

The section element is mainly a layout element. My example here doesn't really illustrate its
purpose because I am employing a single column layout. If you want to create a multi-column
layout, be sure to read up more on this.

This textbox element is for user to enter email to addresses. Email addresses must be
comma separated. This control is bound to the REPORTPARAMETER.EMAILTO attribute.

This textbox element is for user to enter email cc addresses. Addresses must be comma
separated. The current user's email will be added here by default. If you don't want this, you
need to remove the line from the AppBean class. This control is bound to the
REPORTPARAMETER.EMAILCC attribute.

10

This textbox element is for user to enter email subject line. This control is bound to the
REPORTPARAMETER.EMAILSUBJECT attribute.

11

This multilinetextbox element is for user to enter email message. This control is bound to the
REPORTPARAMETER.EMAILCOMMENTS attribute.

14

When this button is clicked, it will fire the sendEmail() method, as stipulated by the "mxevent"
attribute, in the custom AppBean class. Needless to say, this method name must exist in the
bean class. If you want to change the method name, beware that you must change it in both
places.

15

When this button is clicked, it will cancel out the operation and close the dialog box. The
"dialogcancel" event is actually a common method inherited from the base class. We don't
need to write any custom code to handle this event.

Step 2: Attach the custom dialog box to the PO application.


Tip: Always have a backup of your original Application Definition file. If you happened to corrupt the file you are
working on, you then have the original copy to fall back on.

Tip: When importing an Application Definition file, do not have the application record opened in the Application
Designer application. In fact, make sure the List tab is empty of any record before you do the import.
Tip: If you are developing a general purpose dialog box to be accessed by numerous applications and the dialog
box is bound to fixed MBO(s), you can add your dialog box to the system Library XML file (instead of individual
applications). The upside is less work for you, but the downside is that you may not be able to modify the dialog
box via the Application Designer application.

This tutorial focuses on the PO application. If you want to use other applications, by all means go
ahead. The steps are the same.
i.

Launch the Application Designer application.

ii.

Retrieve the application of your choice, e.g., PO.

iii.

Export the Application Definition (an XML file) of your application and save the file to a local
location.

iv.

Open the exported file with any text or XML editor of your choice.

v.

Scroll all the way down to the bottom of the page.

vi.

Just before the </presentation> end tag, insert your XML code block (from step 1) here.
Make sure your code is within the <presentation> tag and it doesn't break other existing
tags.

vii.

Save your changes.

viii.

Go back to the Application Designer application.

ix.

On the List tab, click on the Import Application Definition toolbar button to import your
modified file.

x.

Done.

Step 3: Enable security for the custom dialog box.


Figure 4: Adding new signature option.

Figure 5: Grant access to signature option in PO application.

Follow these steps to enable security for the dialog box:


i.

Launch the Application Designer application.

ii.

Retrieve the application which you modified on step 2.

iii.

On the Select Action menu, click on Add/Modify Signature Options.

iv.

Click on New Row to add a new row.

v.

At a minimum, you need to provide a name for the option and a description (see figure 4).
Others you can do as you see fit. The only key thing to watch out for is that the option name
must be the same as your dialog box id. This is how the system associates this signature
option to your dialog box.

vi.

Exit out the Application Designer application.

vii.

Launch the Security Groups application and retrieve a security group named "EVERYONE".

viii.

Go to the Applications tab.

ix.

Look up the application of your choice and you should be able to see the new signature
option (see figure 5). Grant access to it and save your changes.

x.

Done.

Note: I am using the "EVERYONE" security group because it is the quickest approach for me to grant wide
access. You should really only give access to group(s) that needs it.

Step 4: Associate the custom dialog box to a custom toolbar button.

Figure 6: Adding new toolbar control.

Follow these steps to create a custom toolbar button to launch your dialog box:
i.

Launch the Application Designer application.

ii.

Retrieve the application which you modified on step 2.

iii.

On the Select Action menu, click on Add/Modify Toolbar Menu.

iv.
o
o
o
o
o
o
o

Click on New Row to add a new row. Use the following values (also shown in figure 6):
Element Type = OPTION
Key Value = <Select your new signature option created in step 3 from the pick list.>
Image = nav_icon_statusSent.gif
Position = <Use any value as you see fit.>
Subposition = <Use any value as you see fit.>
Visible = Yes
Tabs = MAIN

v.

Exit out the Application Designer application.

vi.

Launch the application which you modified on step 2.

vii.

Go to any tab other than the List tab. You should be able to see your new custom toolbar
control. Click on it to open the dialog box. At this point, you can only view your dialog box. It
will not work because no functionality has been implemented yet.

viii.

Done.

Tip: You may use any images found in this


"<maximo>\applications\maximo\maximouiweb\webmodule\webclient\images\" directory on your Maximo server.
To use any image from this directory, simply type in the image file name without the file path like I did here.

Step 5: Create a custom AppBean class.


You can download the entire AppBean source code from the File Download section. This code is
complete and requires no further modification. All you need to do is compile it into a Java class file.
Since the code is lengthy, I will not go over it line-by-line. Rather, I will point out some of the key
features for you. Please refer to the source code as I go over the following:

First, let's take a look at the overall class structure:

The class extends the psdi.webclient.system.beans.AppBean class, which is a requirement.

The package name is custom.webclient.system.beans. If you are to modify this name, you need to
update the XML code for the dialog box accordingly. It is referenced there.

The initialize() is a method from the base class. We are simply overriding it here. This method is
automatically called when the dialog box first load. We will be setting default value for some form
controls here. Do not change the method name.

The sendEmail() is a custom method that will perform the core task, i.e., generate report and email
report. This method name is explicitly referenced in the XML code for the dialog box. You are free to
change the method name, but you must also update the XML code accordingly.

The log() is a custom method for writing out custom message to the log file. This method explicitly
uses the mail logger and it will only output message if the logger is in debug mode. Otherwise,
nothing will be written to the log file. Keep this method handy and use it on your other Java classes.
You might want to consider using other logger as well. The mail logger is appropriate in this tutorial
but may not be so in other situations. Check out the Logging application in Maximo for other types of
loggers.

The msgbox() is a custom method for displaying custom message on screen via a pop up window.
This method explicitly uses a custom message object created in Maximo (see step 6 for details). The
hardcoded strings "messagebox" and "CustomMessage" are used to identify that particular
message object. You may use other if you wish. Keep this method handy and use it on your other
Java classes.
Now, let's examine some specific functions:

i.

How to get the dialog box underlying MBOs?


Recall from step 1 we have bound 2 different MBOs (i.e., PO and REPORTPARAMETER) to our
dialog box. One is assigned on thedialog element and the other through a datasource element. Both
will require different method to access them:

For dialog element, use the getAppBean(), e.g.,

MboRemote mbo = this.app.getAppBean().getMbo();


o

For datasource element, use the getDataBean() and pass in the datasource element id, e.g.,

MboRemote mbo = this.app.getDataBean("RPTEMAIL_ds1").getMbo();

ii.

How to find a dialog box control by id and get its value?


You may use the findControl() and getProperty() respectively, e.g.,

ControlInstance ctr1 =
this.clientSession.findControl("rptemail_emailsubject");
String uservalue = ctr1.getProperty("value");

iii.

How to set default value for dialog box control?


The key is to get the correct MBO (recall we have 2 different MBOs) first and then use the setValue().
The following example will display the current user's email on the Email Cc text field:
MboRemote mbo = this.app.getDataBean("RPTEMAIL_ds1").getMbo();
mbo.setValue("emailcc",
this.clientSession.getMXSession().getUserInfo().getEmail());

iv.

How to generate a dynamic where clause for the current record?


When running a report programmatically, we need to pass in a record filter for the current record.
Otherwise, the report will show all records. The following example will show you how to generate a
dynamic where clause based upon the unique id for the current display record:
MboRemote mbo = this.app.getAppBean().getMbo();
String whereclause = mbo.getUniqueIDName() + " = " +
mbo.getUniqueIDValue();
The value for the whereclause string will look something like this: "POID = 18704"

v.

How to properly concatenate file paths in Java?


Java is finicky about the character slash in file path because back-slash has special meaning in Java.
To avoid headache when concatenating paths, I suggest you use the java.io.File class to combine
paths for you, e.g.,
import java.io.File;
String path1 = "C:/temp";
String path2 = "subfolder\\testfile.txt";
File outputFile = new File(path1, path2);
System.out.println(">>>> Full File Path = '" + outputFile.getAbsolutePath()
+ "'");
System.out.println(">>>> File Name Only = '" + outputFile.getName() + "'");
Output:
>>>> Full File Path = 'C:\temp\subfolder\testfile.txt'
>>>> File Name Only = 'testfile.txt'

vi.

How to generate a report programmatically?


The com.ibm.tivoli.maximo.report.birt.admin.ReportAdminServiceRemote class provides
a runReport() method to generate report into byte array, e.g.,
UserInfo ui = this.clientSession.getMXSession().getUserInfo();
ReportParameterData para = new ReportParameterData();
para.addParameter("where", "POID = 1234");

ReportAdminServiceRemote reportservice =
(ReportAdminServiceRemote)MXServer.getMXServer().lookup("BIRTREPORT");
byte[] reportOutput = reportservice.runReport(ui, "poprint.rptdesign",
"PO", para, "newreport.pdf", "pdf");

vii.

How to close the dialog box?


You need to instantiate a new instance of psdi.webclient.system.controller.WebClientEvent object
and pass in the "dialogclose" type, e.g.,
WebClientEvent newEvent = new WebClientEvent("dialogclose",
this.app.getCurrentPageId(), null, this.clientSession);
this.clientSession.queueEvent(newEvent);

Step 6: Create a custom message box.


To create a generic message box that can be used to display all kind of custom messages, follow
these steps:
i.

Launch the Database Configuration application.

ii.

On the Select Action menu, click on Messages.

iii.

Click on New Row to add a new row. Use the same settings as shown in figure 7 below. Both
the Message Group value and theMessage Key value are referenced in the AppBean class,
so they must match.
Figure 7: Creating a new message object.

Figure 8: What the message box looks like at run-time.

iv.

Done.

Note: The "Display ID?" property doesn't seem to work in my current version of Maximo. Perhaps IBM will fix this
in future version. Supposeably, this property will allow us to hide the message ID on the message box but it
doesn't (as shown in figure 8).
Tip: Once you have a generic message box created, you can keep re-using it in your other Java classes. You
don't really need to create a new one each time.

Step 7: Turn on debugging mode for the logger.


Java development for Maximo can be a daunting task for those who lack patience. Often time, you will
be writing code in blind because you cannot test what you just wrote until you deployed your code
which can take 10 or more minutes. Ability to write out data to a log file can ease the development
and debugging effort. There are many different types of logger in Maximo which you can tap into.
Some are application specific, some are task specific, and so on. The output location of log file should
be <maximo>\logs.
In this tutorial, I used the "mail" logger because it seems to make the most sense. Having said that,
you are welcome to use other as you see fit. In the custom AppBean class, we specifically stated that
only show logging info when the "mail" logger is in debug mode. Simply follow these steps to turn on
the debugging mode for the "mail" logger. This is completely optional by the way.
i.

Launch the Logging application.

ii.

Look up a root logger named "mail".

iii.

Change the Log Level to "DEBUG" as shown below:

Figure 9: Changing logger to debug mode.

iv.

Click on Save and then make sure to click on Select Action > Apply Settings after.

v.

Done.

Once you begin testing the email tool, make sure to check the output log file for logging information,
which should look something like this:
28 May 2012 09:11:37:381 [DEBUG] >>>> Entering
custom.webclient.system.beans.EmailReportAppBean:sendEmail()
28 May 2012 09:11:37:381 [DEBUG] >>>> Report Name = poprint.rptdesign
28 May 2012 09:11:37:381 [DEBUG] >>>> Where POID = 18704
28 May 2012 09:11:37:381 [DEBUG] >>>> Output File Path =
'E:\temp\PO_20120528091137AM.pdf'
28 May 2012 09:11:38:991 [DEBUG] ------------------------------------------28 May 2012 09:11:38:991 [DEBUG] To: johndoe@hotmail.com
28 May 2012 09:11:38:991 [DEBUG] From:
maximo.administrator@company.com
28 May 2012 09:11:38:991 [DEBUG] Subject:
Purchase Order #5992
28 May 2012 09:11:38:991 [DEBUG] Message:
testing
28 May 2012 09:11:38:991 [DEBUG] File
Attachment:E:\temp\PO_20120528091137AM.pdf
28 May 2012 09:11:38:991 [DEBUG] ------------------------------------------28 May 2012 09:12:03:802 [DEBUG] >>>> Exiting
custom.webclient.system.beans.EmailReportAppBean:sendEmail()
Tip: Change the log level back to "ERROR" when not testing or troubleshooting. Otherwise, you will end up with
huge log files taken up precious server disk space. "ERROR" log level means only error will be written to the log
file.

Figure 10: Class file deployment location.

Step 8: Deployment and testing.


Follow these final steps:
i.

Copy your custom AppBean class to the following location on your Maximo server:
<maximo>\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\

ii.

Re-build and deploy Maximo EAR file.

iii.

Done.

At this point, you are ready for testing. Simply launch your application of choice and test out the email
tool.
Tip: Custom bean class must be deployed to a different location on the server than other types of classes (e.g.,
field class, MBO class, etc.). For other types of classes, you have to copy your file to
<maximo>\applications\maximo\businessobjects\classes\. Whereas, for bean class the path is
<maximo>\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\.The system will not inform you if
you have your class file at the wrong location. But you will be left wondering why your code doesn't work.

Final Notes
If you do find this tool useful, you may also want to consider these additional enhancements:

1. On the AppBean class, add a validation check to make sure email addresses entered are
comma delimited. The current code will throw an error if email addresses are delimited by
semi-colon for instance. I have amended the Java source code to replace all semi-colons with
commas.
2. On the AppBean class, add a check to see whether the current user has the necessary rights
to run a particular report before generating one. The psdi.app.report.ReportService object has
a method called "canRunThisReport()" which can do just that.
If you have any questions or comments, feel free to contact me. You can find my contact information
on my home page.
Tip: If you have problem sending email from Maximo (via SMTP) to hotmail, yahoo or google account for
instance, contact your network guys and ask them to configure your SMTP server allowing your Maximo server to
relay email.

You might also like