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
Last time I introduced the XPages advanced application and briefly outlined the differences. One of the key differences was pointing everything to a separate data database. That means this database has no Forms, only the default View (the NSF can’t have no views) and no documents. The database path is defined in xsp.properties file, as below:
Interaction with this is handled from a static Java method. For those getting started with Java, adding the
static keyword to the method means it is accessible via
MyClass.myMethod() rather than creating an instance of the
MyClass class and then calling
myMethod() on that. So there is a
getDataDbPath() method which, if the
dataDbPath variable is empty, calls
setDataDbPath(). That method uses another static method to access xsp.properties – it’s something I’ve used for XPages OpenLog Logger and has also been extended for OpenNTF Domino API to map down to the notes.ini, if the xsp.property variable is not set. Here are the two methods:
For those coming from SSJS, having three methods like this may seem excessive. But having a getter that calls a setter only if the value is empty means the value can be lazy loaded and just retrieved subsequently. It improves loading time (you don’t load values into scopes in case you might use them later, but only when they’re first needed) while still avoiding duplicate unnecessary calls. And the
getXspProperty() method can be re-used without the code needing duplication. Eclipse makes this easier by allowing the developer to highlight Java code, right-click and choose Refactor > Extract Method…, which allows you to suck out the code into a separate method and replace it with a call to that method. Refactor > Rename or Ctrl + Shift + R makes it easy to rename variables or methods across all Java classes too. Code templates make it easy to have a standard try/catch block that points to your standard error handling method. And from an initial variable declaration, you can right click and generate default getters and setters. So although the code may be more verbose, all this means better performing, easier to refactor code that ensure fewer runtime errors because more is picked up at compile time.
Interacting with the static methods from SSJS is slightly more fiddly though, as shown in the definition of the
databaseName for the
importPackage call needs is made before calling the static method on the
AppUtils class. Alternatively the fully qualified name could have been used,
uk.co.intec.utils.AppUtils.getDataDbPath(). This needs to be done everywere the database name was set. Also worth bearing in mind is that this “SSJS code” is just text strings, so changing the name of the method in Java can’t update SSJS references.
Applying it in Java code is easier. The editor handles the import automatically. And applying this kind of database abstraction retrospectively in Java is very easy, thanks to the Eclipse search. I’ve done this before, and it took only a short time to apply to the whole application.
Next time I’ll move onto the document wrappers.