In the developerWorks Lotus article, "A custom DXL framework for accessing Notes/Domino data," we examined how three simple agents created a DXL framework for viewing, creating, and updating a Domino database over the Web. In this article, we look at building a JSR 168 portal application as a frontend to a Domino database.
This article assumes that you are an experienced Domino and Web developer, and have read the previous DXL framework article.
JSR 168 portlets
The user interface for the examples discussed in this article is a set of JSR 168 portlets that provide the frontend to access the Domino application. To properly leverage the code base in this article, we will use design best practices to build utility/data access classes. This article will introduce you to the JSR 168 based portlets that will leverage data access classes that will be discussed in a later article. The design of the classes are done in such a way that they have no relationship with, or dependency on, the frontend design or platform. Therefore, the same classes will be used in our Rich Application design in the upcoming article. Also, the same classes can be easily used to access any Domino application.
Figure 1 illustrates the various components and interactions discussed in this article, at the system level.
Figure 1. Components and interactions
The typical user accesses the application via a Web browser. The application is a JSR 168 based portlet, hosted on Tomcat 5.0.30 running the Jetspeed 2 portlet container. The backend Domino server is running release 6.5.1, and is hosting the target Domino application (dxlnab.nsf), a Domino directory with the custom DXL agents. (See the article, "A custom DXL framework for accessing Notes/Domino data," for details on the agents.)
Let's start by looking at the frontend. The following illustrations show the various states of the final working application, accessing a Domino Directory with the three custom agents added. For the purpose of this article, we will only expose key fields (First Name, Last Name, and Full Name) from the backend document. Later we will discuss how to add additional fields.
Figure 2 shows the initial screen for the application interface.
Figure 2. Initial screen
You can click the document listed in the DXL Notes View portlet to view document details (see figure 3).
Figure 3. Document details
When you click the "create" button, figure 4 appears.
Figure 4. Create Document screen
And when you click the "edit" button, you'll see figure 5:
Figure 5. Edit screen
The basic flow of the application operation is as follows.
- You enter the page with the two portlets, the View portlet and the Doc portlet. The View portlet displays 10 rows of view data from the backend Domino Directory. The Previous and Next buttons aid view navigation.
- You can then click the arrow ( -> ) link in each view entry to see additional details of the document. (In our example, we only show a few fields, but there is no limit to what can be shown.)
- You can then choose to edit the current document, or create a new document.
- If you choose to edit the current document, you are presented with edit fields for the given fields (see figure 5). At this point, you can make and save changes, which will be immediately reflected in the View portlet. You also have the option to cancel out of the changes.
- If you choose to create a new document, the Create Document screen (figure 4) appears in the Doc portlet. At this point, you can enter a new first name/last name and full name, and save the new entry. The View portlet will be updated to reflect the change. Again, you have the option to cancel out of the changes.
A word about portlet development
To address the widest possible audience, in this article we are building the portlet application using pure Eclipse, rather than a more sophisticated tool such as Rational Application Developer. We used Xdoclet and Maven as the build and deploy tools. We also deployed and tested the application on Apache Jetspeed Portal 2.
The two JSR 168 based portlets leverage the doView method to display various JSP documents, based on the state and action performed by the user. The actions are captured in the processAction method of the corresponding portlets. Following that, rendering (as part of doView) proceeds to display the JSP document, based on the action set/processed in the processAction. Figure 6 is a JSP/state-based flow diagram of our application.
Figure 6. JSP/state-based flow diagram
The two portlets communicate using PortletSession (see the JSR 168 FAQ page for more information). The View portlet sets the document object as a variable in the PortletSession with an application-level scope (PortletSession.APPLICATION_SCOPE). The Doc portlet looks for this variable upon rendering, and, if present, renders the document. If the variable is not present, the portlet displays a generic message.
The portlets themselves are designed with Facade and Value Object patterns. The portlet class in both portlets acts as a controller that delegates all servicing work to a facade. The facade in turn returns or consumes the appropriate value object, based on the action performed. All views for the portlets are built using JSPs. This design insulates us from future changes in backends, at which point we only will have to rewrite our facade. Figure 7 shows a class diagram that illustrates the various classes and their interactions.
Figure 7. Classes and interactions
The dxlobj and dxldao packages are the generic data access classes that have been designed for this article. We designed these two packages such that you can use them to access a Team Room or custom NSF application. These Data Access Objects (DAO) are designed in a generic fashion, and are backend application agnostic.
The two portlets, View (raj.portlets.DXLView) and Doc (raj.portlets.DXLDoc), rely on the facade (raj.facade.NABFront) to do all the work accessing the backend Domino application. The design of these are application-specific, because the view is integral to the application data it displays. The facade, in turn, returns a people value object (raj.vo.People) for the View portlet or person value object (raj.vo.Person) for the Doc portlet. The facade also accepts a person value object to update or create a person entry in the backend. The two value objects contain attributes that are related to fields in the backend Domino document. For example, the fname attribute in raj.vo.Person corresponds to the FirstName field in the Person form in the backend Domino database. As we stated earlier, for this article, we only expose three fields from the backend application. We will show how to expose Company Name in the document view of the portlet, both in create and edit mode, delving deeper into the class and portlet design.
As you can see, the design of the portlets are highly application-specific. Therefore, if you had a Teamroom database and want the two portlets to access a Domino Teamroom, you could have a Teamroom View and a Teamroom Doc portlet with appropriate value objects that expose fields (data) in the backend Domino database of interest.
Let's take a quick look at the design of the data access utility. The key reason why we decided to have a utility class for data access was to ensure that the same classes could be used to connect to any type of Domino database. The design was database agnostic. The utility also has the ability to support different authentication types. The ones currently implemented are basic and session-based (LTPA). If you need SSL support, you can change the utility classes to add the support, while your view (like in MVC) stays the same.
The custom DXL DAO classes use the HttpClient sub-project from the Apache Jakarta project. All connections to the Domino server to get/post DXL data are done using these classes. For parsing, the XML org.xml.sax (for SAX processing) and javax.xml packages are used. The actual packages can be downloaded from the Downloads section at the end of this article. The Download section also lists the Java Docs of the classes for your reference.
Putting it all together
The set of JSR 168 portlets (raj.portlets.DXLDoc and raj.portlets.DXLView) delegate the loading and updating of data to the raj.facade.NABFront class, which in turn delegates the work to the DAO utility. The portlets themselves use the portlet context to get the runtime parameters for connecting to the Domino database (name, view, authentication type, credentials, Domino server and port, and so on). There is nothing stopping us from having these runtime parameters in the application context, thereby shared by both portlets.
For illustration purposes, we will look at how the View portlet (raj.portlets.DXLView) works.
- The portlet is initialized when the portlet container loads it. Part of initialization is to load the runtime parameters from the portlet context. As part of this method, a DAOConfig object is initialized and populated from the portlet context.
- When a user accesses the page that has the portlet, the portlet container calls the doView method of the portlet, which initializes the worker class NABFront, passing in the DAOConfig object. The doView method of the View portlet calls the getPeople method of the NABFront.
- The NABFront initializes DXLDAOFactory, and gets a handle to get DXLViewObject.
- The DXLDAOFactory initializes ViewXML, and calls the ViewXML process method.
- The process method in ViewXML uses the getData method of HttpConnect to get the XML from the target Domino server. (The DAOConfig object has the details of which server, port, database, view, and so on, to go against.)
- ViewXML processes the XML, using the SAX parser, and creates a DXLViewObject and passes that to DXLDAOFactory.
- DXLDAOFactory passes the DXLViewObject to NABFront.
- NABFront extracts the specific data from the DXLViewObject, and passes a localized People object back to the portlet.
- The doView method of the portlet sets the People object in a request attribute, and sends the request to the view jsp (page/view.jsp).
- The user sees the display of the view within the portlet.
Now we will look at how the DXLDoc portlet displays document details.
- The portlets are initialized when the portlet container loads it. Part of initialization is to load the runtime parameters from the portlet context. As part of this method, a DAOConfig object is initialized and populated from the portlet context.
- When a user views the list of documents in the View portlet and clicks on a document to see details, the processAction method is triggered, which calls the getPerson method of the initialized NABFront, passing in the selected document's UNID.
- NABFront calls getDocObject.
- DXLDAOFactory initializes DocDXL and calls the parseXML method.
- The parseXML method in DocDXL uses the getData method of HttpConnect to get the XML (DXL of the document) from the target Domino server. (The DAOConfig object has the details of which server, port, database, view, and so on, to go against.)
- DocDXL processes the XML using the DOM parser, and creates a DXLViewNoteObject and passes that to DXLDAOFactory.
- DXLDAOFactory passes the DXLViewNoteObject to NABFront.
- NABFront extracts the specific data from the DXLViewNoteObject and passes a localized Person object back to the portlet.
- The processAction method of the View portlet sets the Person object as a dxlperson request parameter. The scope of this attribute is set to APPLICATION_SCOPE.
- The doView method of the Doc portlet sets the People object in a request attribute, and sends the request to the view jsp (page/view.jsp), which displays the people view. The user sees the display of the view within the portlet.
- The doView method gets the Person object from the dxlperson request attribute, and sends the request to the view jsp (page/viewdoc.jsp).
- The user sees the details of the document selected in the Doc portlet.
The edit document process is similar in operation, using a different URL, and using the POST method of HttpConnect to save the data from the Doc portlet. The create document operation is similar to edit, but doesn't need any information from the View portlet. The URL used by this function is different, as well.
If you want to show another field (for example in the Doc portlet) for viewing, here are the steps:
- Update the Person value object in raj.vo.Person, by adding another field and the corresponding getter/setter.
- Modify the facade NABFront to populate the proper value of the field from the backend, by correlating it to the appropriate item name in the DXL.
- Modify the viewdoc.jsp in the portal application to display the appropriate value from the Person object on the JSP page.
In this article, we discussed how to leverage the custom DXL framework described in "A custom DXL framework for accessing Notes/Domino data," to build a JSR 168 portlet application to access a Domino Directory. The core to the access method from a Java-based platform is to use the Data Access Objects (DAO) introduced in this article. In an upcoming article, we will cover the rest of DAO, and outline an Eclipse-based rich client application on Linux to access the same Domino Directory.
|Sample DXL portlets||DXLPortlets.war||235KB|
- The developerWorks Lotus article, "A custom DXL framework for accessing Notes/Domino data," examined how three simple agents created a DXL framework for viewing, creating, and updating a Domino database over the Web.
- The article, "Open Standards, Open Source, and Domino 6: Part 1 - A quick tour of Domino 6 Open Standards," by the same author, presents a quick overview of the Open Standards implemented in Domino 6.
- Get involved in the developerWorks community by participating in developerWorks blogs.