We have a release

Hahaha no not a date for Domino-next but last week I received a message from OpenNTF’s IP Manager that my Bildr project is finally released.

Quite interesting to learn about all those licenses and what consequences one might have for your project.

I thank Peter Tanner for his patience and assistance!

Next step perhaps setting up a video how to quickly install the project on your Domino server…

 

I just modernized an application

Introduction

While following the buzz from IBMConnect16 remote I have been working in spare time on my Bildr project available on OpenNTF.

This time I have been focussing on improving the UI by adding more material design principles which should make it easier to distinguish content on a page. Beside that it is just good fun to work with UI sometimes it forces you to improve the back-end logic also.

Capture02

The image above demonstrates the display of related content on a single page where a profile contains lists of related documents.

NoSQL is a party

The following image demonstrates the information (e.g. categories) abstracted from a list of documents and on the right a random selected document from that list and showing some abstracted information from that document.

Capture04

Here you can see well IBM Notes works as a nosql database where documents are loosely coupled and may contain almost anything (well I try to avoid rich text). Especially in a rapid application development paradigm I like the flexibility of nostrict data structure at the time you start developing.

I have not heard much news about NSF from IBMConnect (Solr? Graph features? Performance improvements?) to make it competitive to other nosql options (why do I not see NSF back in this list?).

I hope IBM is aware of NSF’s image problem and admits steps need to be taken to improve it.

Bluemix

I am not sure what the next step for the app will be but I haven’t tried it on Bluemix yet, which could be interesting. The XGallery demo on YouTube shows some great potential.

 

Modernizing a Notes application

Introduction

The quickest way of modernizing your application build on Notes is probably by keeping it on that sublime application platform and provide a new user-interface and updated business logic to it.

As a demonstratable example I would like to bring up my own Bildr project on OpenNTF.

A brief history

The application started initially as a web browser display only and create content via the Notes client application in the early 2000’s. From that the application was updated in a create content via the web browser too features.

Later the oneUI was implemented in a later step also utilizing the Application Layout control. With the Bootstrap4XPages plugin a responsive UI could be delivered a couple of years ago.

Nowadays the Application Layout control is no longer used but the Bootstrap responsive features and components are used further through the application.

The application still relies on XPages and Notes data (allthough used mainly in JSON format). The business logic resides mainly in Java Classes. With the separation of design and data the application could be hosted on Bluemix (not tested, please do).

Modernization

Looking back at this application story I believe the application will change also in the future (or die) perhaps a challenge could be to have the data optional in a different source (e.g. MongoDB) or exchange XPages for Angular and run it on Node.js.

So if you have experience moving data from Notes to MongoDb, applying a similar ACL and Roles security model on your application I would be happy to hear your experiences.

Or if you are still on the Notes client only level and want to bring your application to a (mobile) browser I am happy to exchange ideas with you and learn from your situation.

New release

Why am I saying this? Today I uploaded a new version on OpenNTF and for many Notes developers who a) not have taken the XPages path yet b) unfamiliar with Java and JSON the application could be a great starter example.

Lately there are not that many (new, updated) projects (applications) available at OpenNTF so the chance to find a working demo to see and understand the code and data running are a bit scarce (I am sorry).

I remember in the days of Superhuman Software a quote about Notes and collaboration was “dare to share” so I would challenge more developers to do so. We can learn a lot from examples from others and I thank those people who (still) do and from which I can learn from!

I wish you a wonderful learning experience at IBMConnect 2016!

Capture04

 

Bildr 5 released on OpenNTF

Announcement

Today I released a new version of Bildr on OpenNTF ! There have been spent quiet a few long evenings coding but it was fun (I may drink at home) and interesting!

So just before the holiday season and January’s  IBM Connect buzz I thought it would be a proper moment for a release. So consider it my Xmas present to the community 🙂

Modernization

I label this version 5.0 since I (almost) completely rewrote the application from scratch. Lot of the logic I have placed in Java classes and the data format is mainly JSON.

I also separated the design from the data so in principle you should be able to place the app in the IBM Bluemix environment.

Because of these decisions there is no backward compatibility so a simple replace design will not work for your existing installation.

Below you can find some screenshots of the new interface. I hope you like it.

Screenshots

startpage

uploadprofilepicture

Thank you

I would like to thank all the teachers in our community who post their presentations, code samples and answers on the platforms out there.

I have tried to post the code on Github but this failed with the Github desktop client. If some can get me started with that I will distribute the project there too.

For now:

A Merry Christmas and fortune in 2016 !

Working with JSON in your XPages application

Introduction

In order to develop more inline with leading web standards more and more Domino and XPages developers find themselves attracted to use JSON as the standard to describe and transport their application data.

There are many excellent JSON libraries out there. With XPages we have immediately access to com.ibm.commons.util.io.json.

I intend to write a series of posts and tell how I will rewrite an existing XPages application and introduce Java and JSON as the new working horses in this application.

JSON and XPages

More people have written about JSON in XPages so I do not have to deep dive in that. I especially like Jeff Byrd’s post on using the JSONJavaObject class to create a JSON object from an array.

A simple first example

First let me demonstrate a simple example. We setup a simple construction we will extend in the following steps of our application modernization.

Building blocks

Here is what our construction will contain:

  • a Notes view with a first column for sorting and a second column containing a JSON string
  • a Java class defined as a managed bean in the faces-config file
  • an XPage to display the received ArrayList with JSONObjects

Notes view

Our view looks nothing spectaculair:

notesview

Basically:

  • The first column is used for sorting purpose.
  • The second column constructs the JSON string.

The formula for the second column can be as followed:

REM {This column builds a JSON string};

varUNID := @Text(@DocumentUniqueID);
varCategory:= Photo_Category;
varTitle := Photo_Title;
varAuthor:=Au_Author;
varDesc:=PhotoDescription;
varCreated:=@Created;
varThumb:=Photo_ThumbFilename;

jsonOpener := “{“;
jsonClosure := “}”;
jsonSeparator := “\”,”;
jsonLastItem := “\””;

jsonOpener +
“\”docUNID\”: \”” + varUNID + jsonSeparator +
“\”author\”: \”” + @Name([CN]; varAuthor) + jsonSeparator +
“\”category\”: \”” + varCategory + jsonSeparator +
“\”subject\”: \”” + varTitle + jsonSeparator +
“\”descr\”: \”” + varDesc + jsonSeparator +
“\”created\”: \”” + @Text(@Date(varCreated)) + jsonSeparator +
“\”thumb\”: \”” + varThumb + jsonLastItem +
jsonClosure

Alternatively you can use a normal view (plain column values) and construct the JSON string later, something described here.

JAVA class

Our class has one public method called loadPictures which will call a private method that will return an arraylist of jsonjavaobjects. You notice the com.ibm.commons.util.io.json library will be used.

Don’t worry about the hard-coded server and notes view references now. This will be polished later.

package com.quintessens;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Vector;

import lotus.domino.NotesException;

import lotus.domino.Database;
import lotus.domino.Session;
import lotus.domino.View;
import lotus.domino.ViewEntry;

import lotus.domino.ViewEntryCollection;

import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.JsonJavaFactory;
import com.ibm.commons.util.io.json.JsonJavaObject;
import com.ibm.commons.util.io.json.JsonParser;
import com.ibm.domino.xsp.module.nsf.NotesContext;

public class SimplePictures implements Serializable{
public static final long serialVersionUID = 1L;
public SimplePictures(){
}

public ArrayList<JsonJavaObject> loadPictures() throws NotesException{
ArrayList<JsonJavaObject> PictureCollection = new ArrayList<JsonJavaObject>();

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();

String ServerName = “dev1”;
String DatabaseName = session.getCurrentDatabase().getFilePath();
String ViewName = “$v-pixJSONSingle”;
String Key = “”;
Integer ColIdx = 1; //0 means first column

try {
PictureCollection = loadJSONObjects(ServerName, DatabaseName, ViewName, Key, ColIdx);

} catch (NotesException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return PictureCollection;
}

private ArrayList<JsonJavaObject> loadJSONObjects(String ServerName, String DatabaseName, String ViewName, String Key, Integer ColIdx) throws NotesException {

ArrayList<JsonJavaObject> JSONObjects = new ArrayList<JsonJavaObject>();

NotesContext nct = NotesContext.getCurrent();
Session session = nct.getCurrentSession();
Database DB = session.getDatabase(ServerName, DatabaseName);

if (!(DB==null)) {

View luView = DB.getView(ViewName);

if (!(luView == null)) {

JsonJavaFactory factory = JsonJavaFactory.instanceEx;
ViewEntryCollection vec = luView.getAllEntries();

ViewEntry entry = vec.getFirstEntry();
while (entry != null) {

Vector<?> columnValues = entry.getColumnValues();
String colJson = String.valueOf(columnValues.get(ColIdx));

JsonJavaObject json = null;

try {
json = (JsonJavaObject) JsonParser.fromJson(factory, colJson);
if (json != null) {
JSONObjects.add(json);
}

} catch (JsonException e) {
System.out.println(“ERROR: PP.loadJsonObjects 1: colJson “);
}

ViewEntry tempEntry = entry;
entry = vec.getNextEntry();
tempEntry.recycle();
}
luView.recycle();
}
DB.recycle();
}
return JSONObjects;
}

}

Managed Bean

We register the class as a managed bean so we can call it easily from our XPage:

<managed-bean>
<managed-bean-name>PictureProvider</managed-bean-name>
<managed-bean-class>com.quintessens.SimplePictures</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

XPage

And then last but not least our XPage. Here we will display the list. The XPage contains:

  • A (Bootstrap) table.
  • A Repeat control
  • A Pager control.

By calculation the values for the Repeat control on page load and using a partial refresh for the pager pagination becomes really fast.

The result will be something as followed:

xpage

<?xml version=”1.0″ encoding=”UTF-8″?>
<xp:view xmlns:xp=”http://www.ibm.com/xsp/core”&gt;

<link href=”https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css&#8221; rel=”stylesheet” integrity=”sha256-MfvZlkHCEqatNoGiOXveE8FIwMzZg4W85qfrfIFBfYc= sha512-dTfge/zgoMYpP7QbHy4gWMEGsbsdZeCXz7irItjcC3sPUFtf0kuFbDz/ixG7ArTxmDjLXDmezHubeNikyKGVyQ==” crossorigin=”anonymous” />
https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js

<xp:pager layout=”Previous Group Next” partialRefresh=”true”
id=”pager1″ for=”repeat1″>
</xp:pager>

<table class=”table table-hover”>
<thead>
<tr>
<th>Thumb</th>
<th>Subject</th>
<th>Category</th>
<th>Description</th>
<th>Author</th>
</tr>
</thead>
<xp:repeat id=”repeat1″ rows=”15″
value=”${javascript:PictureProvider.loadPictures();}” var=”pix”>
<tr>
<td>
<xp:text escape=”false”>
<xp:this.value><![CDATA[#{javascript:/*
getAttachmentURL and getBaseURL from:
http://www.wissel.net/blog/d6plinks/SHWL-86QKNM
*/

function getAttachmentURL(docID:java.lang.String, attachmentName:java.lang.String) {
var base = getBaseURL();
var middle = “/xsp/.ibmmodres/domino/OpenAttachment”;
if (base.substr(0,4) == “/xsp”) {
middle += base.substr(4);
} else {
middle += base;
}
var result = base + middle + “/” + docID + “/$File/” + attachmentName + “?Open”;
return result;
}

function getBaseURL() {
var curURL = context.getUrl();
var curAdr = curURL.getAddress();
var rel = curURL.getSiteRelativeAddress(context);
var step1 = curAdr.substr(0,curAdr.indexOf(rel));

// Now cut off the http
var step2 = step1.substr(step1.indexOf(“//”)+2);
var result = step2.substr(step2.indexOf(“/”));
return result;
}
var thumb = pix.thumb;
var id = pix.docUNID;

return “<img src='” + getAttachmentURL(id, thumb) + “‘>”;
}]]></xp:this.value>
</xp:text>
</td>
<td>
<xp:text escape=”true” value=”#{pix.subject}”>
</xp:text>
</td>
<td>
<xp:text escape=”true” value=”#{pix.category}”>
</xp:text>
</td>
<td>
<xp:text escape=”true” value=”#{pix.descr}”>
</xp:text>
</td>
<td>
<xp:text escape=”true” value=”#{pix.author}”>
</xp:text>
</td>
</tr><!– /.row –>
</xp:repeat>

</table>

</xp:view>

Next step

In a next blog I will explain some other (basic) methods that the application will be using to generate collections of documents (by key or restrictbycategory) and based upon these methods we will reconstruct our current XPages app. Untill then.

Bildr on Extension Library (work in progress)

In the last week before vacation I have some time left for some experiment. So I decided after reading the extension library guide to start rewriting the Bildr project on OpenNTF. Untill now I have come pretty far and the first results look promising. Not sure if I can manage to finalize the project before the end of the week, but let’s think positive!

Below some screenshots so far…