Update on my Cloudant sample XPages application

I made some additions to my XPages sample app that I am using to understand and demonstrate the usage of IBM Cloudant within XPages.

I am not fully there yet where I want to be, but it is a work in progress. During development I noticed a couple of things:

  • Cloudant’s Lite Pricing Plan has its¬†limitationsūüôā
  • Migrating Notes documents to Cloudant goes fast enough. A set of 10 thousands of simple, small documents takes just a couple of seconds.
  • Loading¬†the same amount of documents into XPages e.g. a Repeat Control and navigate between sets via a Pager control has some delay time. This could be due the limitations of my local application¬†server.

The code is available on Github.


Threads and Jobs on release 9

On OpenNTF you can find a project called Thread and Jobs:

This project contains samples showing how to create threads and Eclipse jobs from XPages to run longer taking operations asynchronously without blocking the XPages user interface or to run scheduled tasks.

It turns out that there have been updates in Release 9 in the ThreadSessionExecutor class and no longer a Status object is returned.

So if you want to have the example application working on your Domino 9 server you should remove the Status/iStatus library import and change the return type from Status to Object as followed:

* © Copyright IBM Corp. 2012
* Licensed under the Apache License, Version 2.0 (the “License”);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an “AS IS” BASIS,
* implied. See the License for the specific language governing
* permissions and limitations under the License.
package org.openntf.samples.thread;

import java.util.Date;
import com.ibm.domino.xsp.module.nsf.ThreadSessionExecutor;
import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.NotesException;
import lotus.domino.Session;

* Thread sample
* @author priand
* @author Niklas Heidloff (simplified sample)
* Updated 2016-10-18 Patrick Kwinten

public class ThreadSample {

private static MyThread myThread;

public static boolean isRunning() {
return myThread != null;

public static void startThread() throws NotesException {
if (myThread != null) {
try {
synchronized(ThreadSample.class) {
if (myThread == null) {
myThread = new MyThread();
System.out.println(“Thread started”);
} catch (Throwable t) {

public static void stopThread() {
if (myThread != null) {
synchronized(ThreadSample.class) {
if (myThread != null) {
myThread.stopRequest = true;
myThread = null;
System.out.println(” >> Thread stopping”);

private static class MyThread extends Thread {
boolean stopRequest;
private ThreadSessionExecutor < Object > executor;
MyThread() throws NotesException {
this.executor = new ThreadSessionExecutor < Object > () {
protected Object run(Session session) throws NotesException {
try {
System.out.println(” >> Thread running”);
Database db = session.getDatabase(null, “ThreadsJobs.nsf”);
if (db != null) {
if (!db.isOpen())
if (db.isOpen()) {
System.out.println(” >> Database opened: ” + db.getTitle());
Document doc = db.createDocument();
try {
doc.replaceItemValue(“Form”, “ThreadTest”);
doc.replaceItemValue(“DateTime”, session.createDateTime(new Date()));
} finally {
} catch (Throwable ex) {
if (!stopRequest) {
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException ex) {
//return Status.OK_STATUS;
return “probably OK”;

public void run() {
while (!stopRequest) {
try {
} catch (Exception ex) {}
System.out.println(“Thread left”);

I have not yet managed¬†how to fix the JobScheduler class…

Using IBM Cloudant with XPages

Last evening I started a little couch development project, in front of the TV. The data I am used to work with is mostly in JSON format already so I read a bit on couchDB. Since my use-case allows storage in the cloud I¬†was curious about Frank van der Linden’s cloudant-connector plugin so I gave it a swing.

Cloudant is the cloud version of CouchDb. Which is invented by Damien Katz, who also was involved by the creation of the NSF.

I found on the internet a very nice easy to use open source project, Java-cloudant, who is doing the heavy lifting in the interaction with Cloudant.

I guess for an XPages developer this is the easiest way to get started with Cloudant. You can also load the libraries yourself as Stephan Wissel describes. At this point I am not sure what option I like best.

It turns out with Frank’s plugin¬†you can develop really fast rapid. If you look at the¬†HR-assistant application he has worked on you find some great examples how to use it. Nevertheless that project was too sophisticated¬†for me to adapt in my 2hr sample app. My goal was to learn more about couchDb and IBM Cloudant and working with documents &¬†views in general and not (yet) building applications around it.

So this is the result I achieved in my restricted time:


Nothing much sophisticated, but a good learning experience which I would like to¬†take with me in my next “couch” projectūüôā The code is available in a Github repo.

In a month Frank is holding a presentation at SUTOL concerning using developing with Cloudant so I am looking forward to hear what he has to say and show thereūüôā

Recently(?) IBM Cloudant on Bluemix has a “Lite” pricing plan which is free with restrictions so it’s developers friendly:



Feeds highlights (video)

I noticed that I had a enormous backlog in my feedreader (feedly) starting from around September (pre IconUK). Allthough the amount of blogposts in the Yellow Bubble is declining (fast) I just did not have the time to keep up with it untill now.

I thought it would be a great idea to consume the feeds in a different matter so the idea came up to take¬†a weekly ‘snapshot’ and mention some of this weeks most interesting posts. The result is a short video which is easy to consume. Probably a demo or two of the highlights would have made things much more clear, but hey I am not Niklas Heidloff nor¬†do I reside in some form of¬†organ of an open source community.

I apologize for the bad quality since I used the internal microphone of my PC and there are constructions taking place in the street I live. At least I am rid off the many unread blog/news itemsūüôā

URL references in XPages

Aaaah URL references, I guess everyone with Domino and XPages have struggled with them. At first you think you have tackled them, but then you open your app from another perspective (e.g. web browser launch – open designated xpage) and you discover the references did no work like you thought they would.

So how do they work? I made an xpage to demonstrate their working:


I made 6 types of references:

/.ibmxspres/domino -> this brings me back to the root of the server (or data directory)

/.ibmxspres/global -> this brings me to the folder domjava/xsp/ on the server. This is where for example server-side themes are installed

/.ibmxspres/dojoroot -> this brings me back to the folder /xsp/.ibmxspres/dojoroot-1.9.7/ on the server. This is the installation folder of dojo.

/ -> this brings me to the root of the nsf (when standing on an xpage ofcourse).

./ -> this brings me also to the root of my nsf.

../ -> a step to much, the filename is cut off, so I am standing in the installation folder of my nsf.

Can you fix the broken ones? Ofcourse:

/.ibmxspres/domino -> compute:¬†return “/.ibmxspres/domino/” + database.getFilePath() + “/” + the resource¬†where you want to point to.

/.ibmxspres/global -> compute:¬†“/.ibmxspres/global/” + “../../” + database.getFilePath() + “/”¬†+ the resource¬†where you want to point to.

/.ibmxspres/dojoroot -> compute:¬†“/.ibmxspres/dojoroot/” + “../../../” + database.getFilePath() + “/”¬†+ the resource¬†where you want to point to.

../ ->¬†“../” + database.getFileName() + “/”¬†+ the resource¬†where you want to point to.

If you have a custom stylesheet called custom.css in your nsf you can refer to it in a Theme design element as followed:


I made the sample available on Github. Hopefully next time I do not make the same mistakes with URL references. Happy development =)

Add 20 years of experience to your workforce

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !



A modern commenting view in XPages


In the old days you a typical commenting feature was something with a form and a view. Typically you could read a list of comments in a historical (flat) order and on the bottom you had the form to enter your comment. Something like in the IBM Domino blog template.


With the rise of social and mobile it became more important to be able to comment-only so the form moved to the top and the list of comments became sorted in the opposite order (Youtube).

Discussions are still displayed in a thread but since threads are less friendly on a mobile device a more what’app like chat display.¬†But these are more instant messaging apps, similar to Slack or IBM’s upcoming Toscana.


My idea: welcome to the bubble

So what can/should we do to modernize the display of the comment feature in our Notes/XPages application?

Well mainly we still have a top level object (TLO) where people comment on. To stimulate people to comment the form should be close to this TLO. We can promote the interaction between a user and others and provide some form of “bubble speech” experience and (ofcourse) the option to “like” a comment.

That would bring us to something more like this:



Notice on the left you see the comments I have made and on the right comments made by others. The latest comment is displayed first and mines are a bit more outstanding using a background-color.

Now how it’s made

To come to this solutions I am using the following technologies:

  • XPages
  • Java
  • SSJS
  • Bootstrap
  • PrettyTime
  • CSS
  • JavaScript / mention JS

Note that in a previous post I described how to add @mention autocomplete like Facebook, Twitter & Google+ to your XPages app. So I will not discuss in this post how to build the form to comment.

Here is a general outline of what we are going to build:


Step 1 – basic structure; a repeater with a panel


First I have a repeat control which is bound to an ArrayList containing JsonObjects. This approach you can find in my Bildr project on OpenNTF (shameless plug).

I also added an infinite scroll function. You can read about how to set that up in this post.

The panel has a computed styleclass. The style defintion “right” does nothing more than a¬† text-align: right. This makes sure the text in the content is … aligned right.

Step 2 – adding a user icon

Humans are visually oriented and idle so nothing wrong making our display attractive with a user icon.


In this example I am just displaying some random icons, but if you have a corporate directory with user profiles containing icons you should embed them here.

The pull-left and pull-right classes are from Bootstrap. My comments are pulled to the left, comments from others to the right.

Step 3 – the media body

Next item that we add is a div with a media-body class. It contains out of 2 sections: the content of the comment (text written) and some meta-data (date, author). I also added a “like” link which is inspired by Thomas Adrian’s Intrapages app also available on OpenNTF.


(Guess I don’t need the attributes here…). Here is the part of the meta-data:


First I display the Author name, only for comments written by others. In order to make the date more human friendly to read I am using PrettyTime. In the past I have blogged about how to use it.

For the remove link I am using the userbean to check if I can delete documents in the database and if the comment is mine: (@UserName() == obj.From) && (userBean.canDeleteDocs == true)

For the event I check and ask if I am sure that I want to remove the entry and then I simply remove it by UNID:


For the “like” button I would like to point to Adrian’s example in his Intrapages project. I made however the exeption to store the likes in a separate document, so not in the comment. By this way I can tighten my security model. Everybody has the role of [liker] and author access. So everybody can update a like document and not the original comment document.

The like function uses the cookie management principles described here. It stores the username:

userCookie = new javax.servlet.http.Cookie(“userid”, @UserName());

I have set the duration of the cookie as long as the session is active:

//Cookie.setMaxAge(-1) will make the cookie expire after the browser is closed

But beware that the cookie still exists when users logout and login with a different username-password combination !!

So I have a counter for the number of likes, and depending on my activity I have a like or unlike link.

Ready! Some CSS whistles

After we have added some more (basic) CSS we are done! As a result we have created something much more modern that the old school comments display as we know from the IBM Domino Blog template.

If you are interested and want to receive the details of this setup I welcome you to send me a message and we can exchange code.

Add 20 years of experience to your workforce

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !





DevTip: using the latest font-awesome CSS toolkit in your XPages application

Tired off or you feel restricted by the Bootstrap Glyphicons? I bet you do. So you fancy to use Font-awesome as addition? Excellent choice. But after you have added them to your web-content folder and place them on an XPage you will notice the desired font does not appear.

Luckily for you other people have bumped into this before and allocated the problem and come with a fix.

So now you started to load the libraries your XPage application is depending on into ODP/NSF by using Bower¬†or another package manager. If you do not specify a specific version but go for “latest” you will notice that in the suggested fix a version is specified for the font, so which each new release (which you are not aware of due to the “latest” option) your fix is out of sync.

CDN to the resque you might think. Since they handle the URL complication you are good to go as a consumer. Try to add a style sheet resource to an XPage without the http/https protocol is not allowed. If you modified it by hand in the source code like:


in the browser something as

link rel=”stylesheet” type=”text/css” href=”/apps/customerx/fontawesomecdn.nsf//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.css”

will be produced which won’t work. You can add the protocol only once and you can not make the protocol conditional here.

Themes to the rescue! In a Theme design element you can check against what scheme the application runs and if so go for the corresponding protocol:

<!– FontAwesome –>
<resource rendered=”#{javascript:context.getUrl().getScheme().equals(‘http’)}”>
<resource rendered=”#{javascript:context.getUrl().getScheme().equals(‘https’)}”>

Here I have choosen to go against maxcdn which provides a “latest” option. If I check in the browser if delivers me

* Font Awesome 4.6.3 by @davegandy – http://fontawesome.io – @fontawesome
* License – http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)

Summary: problem solved.

  • I have the latest version of font-awesome
  • I have not an URL problem
  • I respect the protocol my application runs under

Unfortunately, my library is gone from my package manager file.

If you have a better suggestion then please drop a comment here below.

Update – Use Grunt

After writing this post I thought that their might be customers who block CDN resources. What to do then?

In Brad Ballasaitis example he created an additional CSS to overwrite the default font-family specification, one without the URL ?v= parameter.

In case you use a tool like Bower to download and install 3rd party libraries or plugins the original CSS with the URL ?=v parameter will be installed. You could write a simple Grunt task (I am new to this) that picks up your custom font-family CSS file from a temporary (fixes?) directory and copy it into the font-awesome CSS directory. A simple example would be:

Copy font-awesome fix
Author Patrick Kwinten
All rights reserved
‘use strict’;

module.exports = function (grunt) {

¬† ¬† require(‘load-grunt-tasks’)(grunt);
copy: {
main: {
src: ‘fixes/font-awesome-fontFamily.css’,
dest: ‘WebContent/libs/font-awesome/css/font-awesome-fontFamily.css’,
options: {
process: function (content, srcpath) {
return content;

If you run this task you are back to a state where you can now overwrite the default font-family selector again.

Load the CSS files via a Theme design element e.g.:

Not the following is not working in conjuction with the
XSP Property ‘runtime optimized resources’.

Therefor the following workaround is applied:
– Move the @font-face part into 2 new CSS e.g.

Note the paths to the fonts differ in these files.

– Load 1 of the css via the Theme based upon the context.getProperty(‘xsp.resources.aggregate’) property
<resource rendered=”#{javascript:context.getProperty(‘xsp.resources.aggregate’).equals(‘false’)}”>
<resource rendered=”#{javascript:context.getProperty(‘xsp.resources.aggregate’).equals(‘true’)}”>

Add 20 years of experience to your workforce

You can 20 years of experience within IBM Notes and Web development to your workforce by hiring me.

Interested? Read my curriculum vitae on LinkedIn: http://www.linkedin.com/in/patrickkwinten and get in contact.

I am happy to work WITH you !

End of contract – a retrospect

Introduction – I am out of work !

Hi there. Recently I was informed that the company that invited me urgently to move abroad for a professional and challenging work environment was not intending to continue my contract after my trial period.

Reactions I received were ‘how sad’ and ‘probably we are less easy to work with than we intend to be’.

I guess a healthy and professional work-environment depends on the people and handling expectations, all supported by management. I do may say this has been MY WORST WORKING EXPERIENCE EVER, and this should summarize it.

However, the unsuspected decision (there has never been a discussion, so no outcome) has brought me and my family with infants in a small social nightmare. We have made a considerable investment with a transmigration, short-term high-price accommodation etcetera) based on the promises we received.

In an attempt to make this post not the saddest of all ‘I am a IBM ICS developer and looking for a job ‘ (you may reply however in case you know a job opportunity) I was thinking writing about my activities the last x months and my plans for the near future.

Log of activities

Spring Tool Suite

The last months I have been developing my first Java program in Spring Tool Suite (STS). The program runs as a service and basically it collects data from a financial service and create reports (spreadsheets) from the received data. The bit where IBM Notes plays a role is that for logging activities OpenLog is being used. For displaying the log entries I build an interface with the help of XPages.

Why STS? – Because I was told so.

What is your experience? РAfter programming in XPages with more and more Java (Managed beans, Java classes, External libraries, Expression Language) the learning curve was quiet steep. Luckily I got help with a patient colleague who showed and explained me a lot of ins and outs in developing in STS (Thanks!).  A lot of things that are simply to manage in JSF (e.g beans) I had to setup myself and I have been taking the existance of scope variables for granted. On the other hand the REST templates in STS work like a charm and make it easy to work with REST services.

So this project has been a good learning experience for me, although the working conditions (read: project specifications) were poor.

XPages 2.0 err 1.0

Further I have been working on XPages development by updating an existing XPages application.

When I first looked at the application I saw a load of design elements. Basically each type of document had it own large set of design elements to display information in different views, so with the help of the Dynamic Content control, some Java collections and work more with one JSON configuration file instead of losely coupled keyword documents I managed to reduce the amount of design elements dramatically.

Besides that a search interface had to be added. When I proposed to use the jQuery DataTables plugin for a more dynamic and potential search function instead of a custom form with hard-coding the dropdown boxes I was like talking abracadabra, my blog posts on the datatables plugin prove however this can be implemented fairly quick and easy.

So no chance here to introduce Managed beans, Java classes, JSON as data format for document collections, REST services, use XPages only as render engine, avoid SSJS as much as possible, avoid setting up unnecessary Notes view for delivering (slightly) different sets of data, use expression language above SSJS (when possible). So no chance to prove my skills here. Should I feel sorry for the customer?

Working on a Mac

For some it’s like nature but do you remember the time you came from a Windows environment and started working with a Mac? The last couple of months I have been working with Mac and this was also a great learning experience!

The future

So what will bring the future? From what I understand the Notes market in Sweden has been very low the last couple of years so I might have a problem here. My skills are mainly focussed on XPages development, and the expectations for this platform are very unclear (did I hear a roadmap for IBM Notes / Domino somewhere ?)(please do not post depressing comments about the prospects of this product).

The lack of updates from IBM and the limit amount of companies embracing this technology let consider me to look for alternatives.


I have decided to study some upcoming or rising technologies for web development and one of them I consider React. For a couple of years I have been experimenting with Angular and data residing in IBM Notes. It feels to me that Angular has more rules to follow than React (React is about the view in the MVC concept) so the latter looks more easy to start with.

Knut Herrman gave me a nice introduction on React as front-end for Domino a while ago.

So hopefully I can demonstrate soon my first “React application” to you.

Graph data modelling

The data that we live with becomes more connected so another ‘leg’ I would like to stand on in the near future is on graph data modelling. I have followed several courses for Neo4j now and been exploring the Graph db in the OpenNTF Domino API whichs allows me to build applications in an environment I feel comfortable in.

I have blogged about Graph data-modelling with Notes data in other posts so expect some more posts about this.

One thing I notice the job opportunities in this area seem to be scarce but perhaps I am looking under the wrong categories on the wrong sites.

So hire me!

I am open for all opportunities; a permanent job, a fixed contract, sub contract. Everything working with interesting technology is better than sitting at home. So if you happen to know something of interest do not hesitate to contact me.

For more information on my work experience I direct you initially to my LinkedIn profile.







Building a search function with DataTables plugin (V)


In the last post we moved the input fields out of the table and into a separate form. In this post I will include a nice usability feature for search term highlighting. This feature is particular helpful if you allow search in columns where values do not differ so much from each other like order numbers or article numbers.

Say hello to Mark()

Mark.js is a JavaScript keyword highlighter function. You can use it as pure JavaScript or jQuery plugin.

First let me show the end-result and then we will walk through the changes:



In order to enable Mark I made chances to the following items:

  • webcontent folder
  • theme
  • custom stylesheet
  • xpage
  • javascript library

In the webcontent folder I included the distributed files. I included only the jQuery plugin as a resource in the Theme document:


In the custom stylesheet I added a class definition to distinguish the searched term with some highlight:

span.markSearched {
background: yellow;
color: black;

In our xpage I added the name attribute for each input element e.g. name=firstname. This attribute will be used as reference to apply the Mark feature.

The main changes take place in the JavaScript. I have written a separate function for it so we do not need to call it on loading:

$(function() {
var db = $(“#persons”).DataTable();
// Map inputs with columns (nth-child(X))
var inputMapper = {
“firstname”: 1,
“lastname”: 2,
“company”: 3,
“job”: 4

// Initialize DataTables
var db = $(“#persons”).DataTable({

stateSave : saveState,
fixedHeader: true,
“language” : {
“lengthMenu” : “Entries per page _MENU_”,
// “info” : “Page _PAGE_ of _PAGES_”,
“infoEmpty” : “No entries found”,
“infoFiltered” : “”
scrollY : yScroll,
“ajax” : “api.xsp/Persons” ,
“columns” : [
data : “firstname”,
“defaultContent”: “<i>Not set</i>”
data : “lastname”,
“defaultContent”: “<i>Not set</i>”
data : “company”
data : “job”

// Set elements per page
pageLength: 10,
// Disable entry selection
bLengthChange: false,
// Act on table rendering
drawCallback: function() {
// Iterate over all inputs (by mapper names)
$.each(inputMapper, function(colName, index) {
// Determine the entered keyword

var val = $(“input[name='” + colName + “‘]”).val();
// Determine the column related to the input
var $col = $(“.datatables-table tbody tr > td:nth-child(” + index + “)”);
// Remove marks in related column
“element”: “span”,
“className”: “markSearched”
// Mark in related column
$col.mark(val, {
// Define mark.js options (see https://markjs.io/)
“element”: “span”,
“className”: “markSearched”

// Trigger table redraw on search keyword change
$(“input”).on(“keyup change”, function() {
var db = $(“#persons”).DataTable();
var $this = $(this);
var val = $this.val();
var key = $this.attr(“name”);

// Search inside DataTable column
// subtract -1 because :nth-child starts with 1,
// DataTables with 0
db.columns(inputMapper[key] – 1).search(val).draw();


In the inputMapper variable we define the input fields and their order appearance in the table.

Instead the initComplete callback we will use the drawCallback function instead. The initComplete runs once, the drawCallback runs everytime the table is redrawn, e.g. when we enter search terms. For each input element we take the entered value and match it with values in the corresponding column. When a match is found a span element with the classname markSearched is applied.

Finally we register events for the input elements so if characters are entered or removed the table gets redrawn.

Wrap up

That’s it! I hope you like this feature. I wonder how easily you could do this with a viewPanel control…