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

Prompted by a couple of queries and Dave Leedy’s blog post, I realised that although I mentioned one big reason I used the OpenNTF Domino API in the Java application, I didn’t elaborate on the differences in coding or side-effects that benefitted from using it.

The starting point for me when using OpenNTF Domino API is in The library, org.openntf.domino.xsp.XspLibrary, needs enabling and I also enable all switches available for XPages. From XPages, the file allows groups of Session fixes to be enabled, and all are described in much detail in the new OpenNTF Domino API Demo Application. Outside of XPages, there is no such file that the API can check and all code will usually go through some single method to create a Domino Session and wrap it into ODA. So the Session fixes (all held in Session.Fixes enum) are enabled individually. This is still a feasible approach from XPages, but using is a simpler way. The ones enabled for this application are:

  • godmode – automatically replaces the session, sessionAsSigner, sessionAsSignerFullAccess and database global variables with OpenNTF Domino API Session and Database objects. This means the Java entry points like ExtLibUtil.getCurrentSession() and ExtLibUtil.getCurrentDatabase() also get OpenNTF Domino API objects so you don’t have to deal with any lotus.domino objects. Without that enabled, you would need to use Factory.getSession(SessionType.CURRENT) to get the current ODA Session, and there are similar SessionTypes for SIGNER and NATIVE, i.e. server.
  • khan – automatically avoids some of the non-intuitive “quirks” of Domino, e.g. that appendItemValue adds another Item with the same name for the separate value, which can cause problems elsewhere in your code, or calling View.setAutoUpdate(false) whenever interacting with a view.
  • marcel – automatically handles converting the Session to handle MIME where appropriate. Again, many developers may not be aware that accessing two different MIME items at once could cause a JRE crash. This ensures it’s not possible.
  • bubbleexceptions – errors within the API, if encountered, are logged within the API’s logging mechanism, including to a log file in IBM_TECHNICAL_SUPPORT. This ensures any such errors are not cleared but thrown up for your application to be aware of and report. So best practice is to enable this as well.

Once that’s done (just a few seconds), I’m ready to start coding. AppUtils is a class that handles many default functions and one I’ve mentioned before is getDataDb(). This was just copied from the many times I’ve used it in the past, which is why it used Factory.getSession() rather than the better practice Factory.getSession(SessionType.CURRENT) and for at least this version we’re maintaining the backwards compatibility, even though the method will show as deprecated.

Another method worth noting is handleException. The API includes all the OpenLog functionality of XPages OpenLog Logger, so it uses XspOpenLogUtil.logError(t). That’s not surprising considering I’m involved in the API.

Another method worth noting is getDocumentByNoteID_Or_UNID(String). This just tries to get the document by either its UNID or NoteID. Experienced developers will be aware that if you try getDocumentByUNID(), you normally have to catch an error with a specific error code – I can’t remember what the error code is, and now I don’t have to. That’s because enabling “khan” means if the UNID doesn’t match a document, the method returns null, as developers without years of Domino experience would expect.

AbstractSmartDocumentModel and AbstractDocumentMapModel also use org.openntf.domino objects instead of lotus.domino objects. The references to Document, DateTime and Item, on the surface, have no material differences. No additional methods are used. However, a significant benefit to the code is that using lotus.domino objects would force the developer to handle or throw a NotesException. This would include on AbstractSmartDocumentModel.getBEDoc(), which just checks whether getUnid()> is empty and, if not, returns the output of AppUtils.getDocumentByNoteID_Or_UNID(String).

The other use of org.openntf.domino is to use org.openntf.domino.Item.Type for item types. This is an enum that corresponds to integer variables in lotus.domino.Item. Again, although it’s not a significant difference, this means fieldTypeMap is a Map where the value is an enum instead of an integer. That means that the Map will not accept an entry "Authors", AUTHOR entered by mistake. Using the integer means that although a careful developer could use Item.AUTHORS, a less careful developer could enter an integer and accidentally use "Authors", 1077, which would still work. (I think switch statements prior to Java 1.5 could not take enums, only integers, which could explain the choice of integers over the more standard modern Java approach of enums, which OpenNTF Domino API uses.)

The final place where org.openntf.domino objects are used is in KeyDateController. Here, in both getContacts() and getCustomers() the code iterates through a ViewNavigator. As well as not needing to catch a NotesException, the code also doesn’t have to recycle. However, the code still needs a while loop to iterate through the entries. If the code were using a ViewEntryCollection or DocumentCollection, the code could use a modern Java for loop, e.g.:

for (Document doc : dc) {
// doSomething();

This is because we have added iterators to ViewEntryCollection and DocumentCollection. For those classes, the concept of next is universal: it can only mean the next ViewEntry or Document. However, for a ViewNavigator, next has different potential outputs and, in this case, instead of getNextEntry() I’m using getNextSibling(). So instead of a for loop, there is still a while loop. But it still has the benefit of avoiding recycling.

Beyond the OpenNTF Domino API functionality used here, there are also things like:

  • DatabaseListeners to process code whenever certain events like document saves occur.
  • Transaction processing, so processing multiple documents only commits the changes if all documents can be updated successfully.
  • SyncHelper to sync fields across multiple document level (e.g. Company name sync’d down to Locations and Contacts in a CRM).
  • Storing Java objects easily into a Notes field.
  • An EmailHelper for creating HTML or other style emails.
  • DocumentScanner to index document fields.
  • DocumentSorter to sort DocumentCollections on the fly based on properties of each document.
  • Graph database structure. This could ensure one instance of a Company or Contact name across the application.
  • Xots for asynchronous or multi-threaded processing.

So there is a wealth of functionality and even implementing it for a small application can avoid a lot of unnecessary lines of code.

In terms of inclusion in the XPages Extension Library, some aspects already have, for example ValuePickers and NamePickers that extended the core functionality. These were XPages components which fitted more properly in the Extension Library. Another one that has been submitted is a modification to DAS to add before / after / error handlers. Again, this is something that makes sense to be in Extension Library, since it’s an extension to XPages-related functionality and pre-existing Extension Library code.

However, the bulk of OpenNTF Domino API, in my opinion, doesn’t fit in Extension Library and I can’t see it ever being contributed (a considerable undertaking) or accepted. It extends core Java code which is not XPages-specific (and, as I understand it, not maintained by the XPages development team). Furthermore, the two examples contributed back were self-contained chunks of code. The ValuePicker and NamePicker extensions were incorporated over a number of Extension Library releases. What remains is more Java classes than individual lines of code that have been incorporated into Extension Library, so the effort required to integrate it would be considerable. And much other functionality is interlinked and calls central utility class methods, so integrating individual enhancements would not be a simple process of copying a few lines of code; it could require adding a large stack of methods. And that is without keeping up-to-date with any enhancements or fixes added.

It is worth bearing in mind that IBM have already spent considerable effort providing developers with standard OSGi extensibility to add central functionality outside an NSF, namely the Update Site. It requires no jars or physical files installing on the server (which does have to be done when releasing any Domino database!), plugins can be loaded just via a secured NSF, security can be restricted to the same IDs the administrator considers valid for LotusScript agents, and the plugins can be turned on or off by clicking a button in an NSF. The only initial setup required is adding a notes.ini variable pointing to an instance of an IBM template that has been provided with the server install since 8.5.3. And the approach – OSGi plugins extensions – is standard beyond just Domino. Furthermore, I’ve yet to encounter any OSGi plugin causing a server to crash, something I did accidentally on more than one occasion before ODA because of incorrect looping code or, in the early days of 8.5.0, not recycling while looping through 20,000 documents. Nor is this just for this kind of advanced Java development, because I remember a tweet last year from Richard Moy where he exceeded the limit of design elements when trying to add a JavaScript framework to an NSF, something that could be managed without hitting such limits and in a more standard manner by using a plugin. This is best practice and, I’m sorry if it causes offence, but I cannot understand or agree with any administrator who allows NSFs to be uploaded but not OSGi plugins like Extension Library from OpenNTF and ODA. Considering all of this, my personal preference would be for IBM to spend their (inevitably limited) development time working on additional functionality rather than integrating large community frameworks (and I don’t just mean ODA, I would also include Jesse Gallagher’s Scaffolding framework in that scope) into the Extension Library.

And on this topic, in the next part I’ll move onto the OSGi web application. Which will require the Domino administrator to add that notes.ini variable mapping to an UpdateSite.nsf and allow an Update Site project that includes not only OpenNTF Domino API but also the custom OSGi application itself to be uploaded to the UpdateSite.nsf.

1 thought on “From XPages to Web App Part Six: Use of OpenNTF Domino API”

  1. Pingback: From XPages to Web App Part Sixteen: OSGi JAX-RS REST Access with ODA Revisited

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.