Table of Contents
Part One – The Application
Part Two – XPages Advanced 1
Part Three: XPages Advanced Database Separation
Part Four: XPages Advanced Document Wrapper
Part Five: XPages Advanced MVC Controller
Part Six: Use of OpenNTF Domino API
Part Seven: OSGi Application Development Introduction
Part Eight: OSGi JAX-RS REST Access with ODA
Part Nine: OsgiWorlds
Part Ten: Vaadin
Part Eleven: OsgiWorlds Document Wrapper
Part Twelve: Key Date Page
Part Thirteen: Application Structure
Part Fourteen: Calendar View
Once XPages developers understand managed beans and have started the road from SSJS to Java, the next natural progression is controller classes and MVC. I’m not going to re-hash the excellent work others have done on what MVC is and how it might be applied to XPages. John Dalsgaard and Ulrich Krause have presented at various user groups on the concept. The aim is simply to have the XPage itself just handle UI and have separate, standalone Java classes that interact with the database (model) layer – so document wrappers managed outside the XPage itself, as we showed last time, and a separate Java class for any lookups and other actions (controller).
It’s worth pointing out that the approach I’m taking here is not intended as best practice and is not a standard MVC approach. But, like managed beans, it’s intended to highlight that MVC, managed beans, dataObjects, dominoDocument datasources, components like Edit Box, even XPages and Custom Controls, all of these are just instances of a Java class.
If you want best practice, I would recommend Jesse Gallagher’s XPages Scaffolding project on OpenNTF. That uses a ViewHandler, which is what the XPages runtime uses before loading any XPage. It then loads the relevant Java class for the current XPage or XPage associated with the current document, giving a consistent mapping from XPage to controller class, and using the name pageController. Jesse’s approach also uses base Java classes that provide core functionality which can be extended for individual XPages, again one of the benefits of using Java. It also provides a wealth of additional functionality like flashScopes for passing messages across XPages, model classes similar to what I covered in the last part, MIME Bean classes (which Jesse also contributed to OpenNTF Domino API) and much more. But that would be overly complex for this demonstration application and it is also much more tightly coupled to Domino, making it harder to extricate when moving to a web application, the focus of this series.
So I’m using a sort of poor-man’s controller class. But although I’m just using it for the editing of the Key Date document, the aim is still the same, to allow us to use a consistent name on every XPage, controller. So the managed bean approach would not work. Because every page would then map to the Java class for the first reference it came across for “controller”, not one specific to the current XPage. We need to define something on the XPage itself. We could create an instance of a Java class in the
beforePageLoad event and store that in viewScope – as I’ve blogged before, viewScope variables can be referenced just by the variable name, without prefixing with
viewScope.. But I’m going to use a component added by the Extension Library but probably not used by many people,
xe:dataObject. The Data Object datasource can be added anywhere a dominoDocument datasource can – XPage, Custom Control, Panel – and has two key properties,
saveObject. The first maps to a SSJS/Java method that creates a Java object, the second maps to a SSJS/Java method that is triggered by a Save Data Source or Save All Data Sources simple action. The code on the KeyDate XPage is:
createObject property imports the
uk.co.intec.controllers Java package and creates a new instance of
KeyDateController. In addition, I set
true. That’s not essential, because I don’t use a simple action that might save it, but it’s a quick and easy addition to ensure best practice.
Looking at that KeyDateController Java class, it has one property that gets the data bean, the wrapper for the Key Date document being created / edited. That again demonstrates a reason for using Java: the dataBean property is not initially loaded into the controller, but only when it is needed. From then on its available for any other code that might wish to use it. That lazy loading is not the kind of approach SSJS developers will be familiar with (typically I had used
initUser methods to load everything when the application is first accessed), but it’s actually best for performance.
There are then two more methods, one for loading all unique customers in the application and the second for loading all contacts for the selected customer. It is the latter which draws upon the dataBean property, to find the selected customer. After all, best advice is to go to the data source whenever possible, and it is possible here.
So what we’ve managed to do is remove all interaction with the back-end database from the XPage. This will become very helpful in the next step, where we replace the front end with an open source Java-based UI, but still need those same interactions with the back-end.