Mindoo Blog - Cutting edge technologies - About Java, Lotus Notes and iPhone

  • Big update for Domino JNA project on Github

    Karsten Lehmann  July 11 2016 23:33:05
    Last weekend, I committed a big update for the




    Here is what's new:

    Note (Document) APIs
    The last weeks since creating the project, I added basic APIs to work with database notes (documents). The main focus was to be able to read the classic note item value types, e.g. String, Number and Date/Time with single or multiple values per item, handle a few rarely known edge cases (e.g. multiline text values that Domino stores with delimiter \0 between the lines instead of platform dependent \n or \r\n), do proper LMBCS/Unicode conversion routines for special characters like Umlauts and provide access to item metadata like the sequence number or the last modified date of an item.

    While reading the note flag documentation, I discovered NOTE_FLAG_READONLY, which Domino automatically adds to the note info area. This note flag can be used to quickly check whether the current Domino user has edit access to a document without all the work of traversing all author items and manually compare the values to @UserNamesList. So that's what is being queried now when you call NotesNote.isReadOnly().

    Attachment streaming
    Another thing I added was support for note attachment streaming. You probably know that IBM's (poor) implementation of EmbeddedObject.getInputStream() internally first extracts the file to a temp directory and then returns an InputStream to this temporary file. Depending on the file size, that may ruin application performance and fill disk space. So the Domino JNA way of reading attachment is to manually decode the $File items and read the file content in small chunks of 16K, the buffer size of the C function to read attachment data.

    The Domino C API provides some easy methods to set item values for selected data types (e.g. single values for text, number and Date/Time). I added them to the Domino JNA as well, but there is still work to do to write multiple values.

    A few other things that are new:

    User spoofing - reader items on steroids
    A NAMES_LIST data structure is what Domino returns when you call NSFBuildNamesList with a Domino username. This NAMES_LIST contains all name variants/wildcards and groups/nested groups on the server for the specified username.
    It is passed as a parameter when you open a database or a view so that Domino can compute document visibility (reader items) and write access rights.

    Ever since writing the code to decode this simple memory data structure, I was asking myself whether it can be built programatically, because it's just the number of names and the null terminated LMBCS encoded list of names.

    And since I need that functionality for an upcoming customer project (Google+ like application with very flexible read access rights for postings), I tried it and it worked like a charm. :-)

    So now you can build your own Domino users at runtime that do not have to be in a Domino directory. Just pass a Java List with name variants in the NotesDatabase constructor and all operations are executed on behalf of that user.

    Unification of view column value reading
    Domino has two ways to read view column data: READ_MASK_SUMMARY which returns programmatic column names and their values in the summary buffer and READ_MASK_SUMMARYVALUES that just returns the column values.

    The latter leaves more space in the summary buffer for data, as the column names never change between view entries. Unfortunately, one new optimized lookup call that IBM added in R9 to atomically look up a key and start reading values, currently only works with READ_MASK_SUMMARY.

    I don't think that developers should care about this difference, so I now handle all that internally in the NotesViewEntryData object and you simply call NotesViewEntryData.get("Firstname") to read a column value.

    Here is a test case to see some sample code for view data reading (the API has changed compared to the initial release).

    Performance optimizations
    I did some profiler sessions and optimized the API for performance. The main optimization was to add an LMBCS string decoder cache that reduces the string conversion operations and to lazily convert strings when they are first needed (e.g. when reading only a few view column values).


    The code on Github was tested on Mac 64 bit and Windows 32 bit clients so far. The next days, I will do further tests with Windows 64 bit servers since we are using the API in multiple customer projects.

    The repository contains various test cases to get started.