My thoughts about the org.opentf.domino api milestone 2.5

A few months ago there was a little fuzz going on in the openntf / domino community. There where some guys who wanted to go where IBM didn’t want to go. Updating the JAVA api that was available to us notes developers.

Since that moment there have been a few releases of the org.openntf.domino api and I decided to take a look and work with it on a little home project. One of my biggest hobbies is playing Wheelchair floorball. Every year it is a little challenge to keep track of the results, the current standings and so on because everything is kept in excel sheets that are downloadable from the official website. I want to have it on a website which gives me a direct overview of where my team is standing in the competition and for other people to see if their team is winning.  So why not create a xpage application from it. From the start I made the decision to use the new org.openntf.domino api to see how it works.

My first impression is.. wow. 

Of course there is the obvious ‘where did my .recycle’ go. The API takes care for that of us. Somehow ( have to check the source for it ) it keeps track of every object you create and recycle’s it when needed.

Secondly there is the iterator support on collections. If you have a NotesDocumentCollection or a ViewEntryCollection you are able to iterate over it using the usual iterator’s as many java developers are accustomed to.

Because I’m still playing around with the new JAVA api I will keep it at these two points. When my project has advanced a bit more I will write another blog about it.

oh btw.. there is a small thing I would like to be added to the API.

ViewEntry.getColumnValue(String name);

In a view you can add the programmatic name. The xsp wrapper of a viewentry is able to retrieve the data from a column by name. For some reason this Api won’t allow it. I think that it would be really nice asset because it makes the code a bit more readable (and that’s what it is all about.. ) see for yourself:

This could be possible because inside the viewentry object you can call its parent. Retrieve all the column names and chekc if the given column was found in the namesvector. If so retrieve its index and do a simple getColumnValues().get(index);

ViewPanel vs. Dijit.Tree part 3… or not

I planned to write the 3th parth in these series in the next couple of days but something unfortunate has happened. By windows 7 install decided to crash. And ofcourse I didn’t backup my domino 9 beta data directory.. So the work I had done was lost. I appologize for this :(.

The upcoming weeks I will use to prepare a new box with domino 9 and to prepare for the 3th part of this series.

Software installation and %temp%

I justed reïnstalled my windows 7 notebook. One of the many drivers I need to install are the drivers for my nvidia graphics card.

When started it askes the user where to extract the setup files. So I set the directory to %temp%/nvidia .  The etraction process began and after it completed the installer returned with an error stating it could’nt find the installation files.

I was wondering two things

1) Why does the installer have to ask me where to put the extracted files if we the OS offers a TEMP directory

2) And secondly if you change the default path, why did the installation program got lost?

I see this much to often. Software that isn’t using the %temp% directory when it should be. If more software would utilize this shortcut it would be much much easier to keep your pc neat and clean..

>> EOF

CSS layouts

A quick post from me about layouts. If you are as lazy as I am and don’t want to use the application layout all the time but also dont want to burn up precious hours only finetuning CSS you could take a look at this page: http://layouts.ironmyers.com. It features a enormous amount of ready to use CSS layouts.

Easy to retrieve, easy to change. Have fun!

Enable autogrow feature of CKEditor

In a xPage project the customer asked us if the following would be possible: ” When the content of the richtext editor exceeds the height of the richtext editor we want to have it expanded” . And this is ofcourse possible!

The richtexteditor is based on the CKEDITOR plugin ( since 8.5.2 ). There is a plugin which does exactly that what the customer wanted. The Autogrow plugin. To enable it in your xpage you simple have to define it as an extraplugin using a dojo attribute. See the following line of code:

This way you can add extra plugins you want to load in the ckeditor. If you want to have multiple plugins being loaded you only need to separate the plugin names with a comma. I haven’t found out yet how to add plugin settings using this attribute. 🙁

update: I tested it today on 8.5.3 fp1 and 9 and both seem to work perfectly.

ViewPanel vs. Dijit.Tree part 2

In this article I will describe how I converted. We will concentrate on how to use a restService control and how to get the data needed to load the first categories in the tree.

This in This
viewpanel grid

In the previous part of the series I explained a bit about how to create a simple dijit.tree and how it works. Now in this part I will explain how I used the restservice component from the extLib to generate a JSON structure which is compatible with the dijit.tree.

note: for these series you will need a copy of the fakenames.nsf file.

For those who are not familiar with the RestService control from Extlib. This control gives you the ability to create fairly easy an restfull service. I contains lots of default service types but for this tutorial we are going to write the Get method ourselves.We start by placing the following control on our xpage.

Configure the rest control

When we open up the properties pane we will see that the control offers a great deal of properties. The first one we will look at is the pathInfo property.

pathinfo

This property will tell the service when it should be rendering. A rest service typicaly is accessed by an http get, post, put or delete call. Therefore it needs an url identifier. Lets say we named the xpage api.xsp. And we define /names/  as the pathInfo. This way we can access the restService with the following url

http://yourdomain/database.nsf/api.xsp/names/

Now lets try it. You will notice that the service returns an empty string page ( among some header information). This is ofcourse because we told the service when to render but we didn’t tell it what to render. For this series it is enough to add the code that should be used in the Get call.

In the properties list expand the following path basic / service.  There are lots of properties but for now the following are the most important.

Property Description
doGet SSJS code that is being executed when the user does a get on the rest service
contentDisposition content disposition header
contentType Defines how the response ( which you will receive from the service)  is being formatted. Aka: which headers are being send out

Lets fill the doGet method. Open up the SSJS editor of this property and add the following code:

Now add a SSJS library to your application and add the following lines of code:

As you can see this code is fairly easy. It first checks if the request made is a category only request (currently it defaults to true ). Next on it will retrieve all categories from the view on the first level. ( See fakenames.nsf for details of the view ). Last but not least add this library to your xPage.

When we visit http://yourdomain/database.nsf/api.xsp/names/ you will get a result which looks like like:

Creating the dijit.tree

With this response we can start to customize the dijit control we saw in party 1. Open up the xPage where you pasted the dijit.tree code from part 1 on. Or create a new xPage with the code from part 1. We have to make the following adjustments to the code.

As you can see we replaced the store with an instance of JSONRestStore. Since we retrieve our data from a RestService we need to have a correct way to interact with it. A JSONRestStore retrieves its data a restfull way. This means it will read /api.xsp/names/ and when we click a node it will read /api.xsp/names/A till Z ( depends on the node ofcourse ).

Next we create a new TreeModel. In this model we define the rootId ( undefined since there is none..) and we set the default name of the root. The last attribute tells the tree at which attribute name in the JSON it should check for children.

This concludes the second part of this series. We have a nice little dijit tree which only shows the first categories as nodes. I showed you how to create a simple RestService using the RestService control and some lines of SSJS and how we can use this data to populate a dijit.tree.

In the next part I will explain how we can change the SSJS so it will retrieve leaves ( aka content of a category ) when the tree needs it and I will show you how to add lazy loading.

update: Changed code for the getCategories call . It should be isCategory = false 

xPages and Beer 12-06-2013

Yesterday I attended a new edition of the xPages and Beer sessions. xPages and Beer is an initiative started by some very great xPages developers to share their knowledge for anyone who wants to attend.

The very first edition started with around ~10 people and yesterday a stunning crowd of 20! people where attending. It realy shows that gatherings like these are wanted by the community. During the session we saw three presentations done by different people

Peter Pennings – Ilionx : Mobile xPages.

During his presentation Peter talked about an application he  created for the newest blackberry. The idea behind the application was that it retrieved it’s data from ‘a’ source and saved it locally on the phone to update it the next the time the user wanted or came online ( if I understood correctly ). Althrough the application itself was not made with the mobile xPage controls (which I actually hoped to get some more information about ) the data is being retrieved using an call to a xAgent. This realy shows the power of xPages.

Thimo Jansen – Defrog: xe:ObjectData ( link )

The second, and for me personally the most interesting session, was about the use of the xe:Object data. xe:ObjectData were introduced in the extension library quit some time ago. xe:ObjectData is a new type of datasource. Instead of using a document or a view you can now use a Pojo as the model of your xpage. I’ve used them in the past but didn’t quit understand the need for them because sooner or later the data is saved to a notesdocument anyway. Now with the presentation from Thimo I’m eager to use them again in future projects!

Mark Leusing: Debugging / Debug toolbar (link)

During the last presentation Mark talked about his debug toolbar (which every xpage developer should be using.. !) and about java  / ssjs debugging in general. Now with the remote debugging capabilities  in Notes 9 and the debugtoolbar at hand there really shouldn’t be a reason for a developer to use print! ( so called poor man’s debugger ) statement anymore.

Many thanks to every one for organising this event and see you next time!

update: Added links to a presentation about debug toolbar and xe:objectdata

xPages and Java : Usage of 3th party packages and jsonsimple.

A small post from my side about 3th party packages. Be sure whenever you make us of an 3th party jar file:

  1. Check the license file
  2. Make use of libraries which are open source when possible.
  3. Make sure the libraries don’t have lots and lots of dependencies ( other 3th party libraries )

One example to think about is the creation of JSON. When generating JSON in xPages you can make use of the IBM package:  com.ibm.commons.util.io.json.JsonJavaFactory. In the context of xPages this seems a logical step. But what happens if you want to reuse created classes in xPages in other projects for instance a native desktop app?

You could face the problem that the package is not available or not compatible with the jvm you are using but your custom classes are. In the worst case scenario you need to rewrite your code because you are adding another library. Therefore you will end up with 2 versions of the same code and as we all know.. that could be a pain in the .. to maintain.

In this case you could make use of the org.json.simple package. This package is opensource and makes use of the apache licens. So go fetch a copy of this great json library and start working with it!

ViewPanel vs. Dijit.Tree part 1

In this article I will describe how I converted this:

This

This in This
viewpanel grid

note: for these series you will need a copy of the fakenames.nsf file.

As we all know the default ViewPanel control is good for generic cases in where you want to translate the default notes charactaristics into a web application. One of the ‘features’ notes views offer are categories. And there is also the problem with ViewPanels. The HTML that is being produced by a viewPanel…  It ain’t highly customizable and sometimes just a pain in the ##!@ to style. And ofcourse there is also the great feature that categories that are displayed in the last row of the page don’t show their children on the same page as the category when expanded!

Luckily for us (some people think otherwise) xPages is shipped with Dojo. This javascript framework offers lots and lots of default UI widgets ready to use. One problem tho. You need to know how to adapt them in xPages and the notes structure. One of them is the dijit.tree. A dijit.tree as the same already suggests renderes a Tree of categories and childnodes. Just like the ViewPanel but then highly customizable and and fairly easy to generate. I tried to implement a dijit.tree using notesview data from the Fakenames.nsf which contains 40.000 person documents and succeeded in less then 5 hours of code crunching. These series will be about this proces. So lets start.

First of all we need to know how we can create a dijit.tree by example. To do this you need to copy the following code in a xPage.

Next step is to add the following file countries.json to your file resources in the nsf as countries.json. If you fire up your newly created xPage you will see that a dijit.tree has been created

grid

As you can see with only a few lines of code we have created a great looking dijit tree. But how do we hook it up to an existing notesview? First of lets find out what the code does we just pasted. We will skip the dojo module loading ( dojo.require)

line 13 ~ 15:

A tree needs data to generate its tree from. On these lines we create a new variable in which we hold the filestore. This store is pointing to our countries.json file. But ofcourse this could also be an url / or a rest service! (hint)

19 ~ 27:

A dijit.Tree uses a treemodel to represents the actual data in the store. By adding / remove properties from the model we can influence how the data is being loaded and displayed. First we tell the model where to look for some data. In our case the local variabel store.

next we have to define the query which will be performed on the data. A query is nothing more then a statement that tells the model where to start expanding. Next are the rootId and rootLabel. These tell the model where to start and how to display the very first node in the data.

Last but not least the childrenattrs tells the model where to look for child nodes in the store.

30 ~ 33:

Here we really create the dijit.tree. In this object we specify on which dom node we want to  treemodel to be generated.

Easy. Isn’t it. Now lets have a look at the data that is stored in the countries.json and compare it with json that is generated by a notesview by default.

As you can see JSON contains an array called ‘items’. Which contains a node with id, name, type etc as its properties. Every node contains a Children array if there are any children. Very straightforward and easy to read.

Now lets take a look at the JSON notes gives us when we open a random view

Well, I dont know about you but I think the first example is much easier to read then the notes way of doing things. So now we need to find a way to get the view to render the JSON just as we want it to be rendered.

Because I wanted to know more about the Rest service and the use of beans in this extlib component I decided I wanted to populate the dijit.tree using this technique. If you want to know more on how I achieved this. Stay tuned for part 2.

Serving media files to iPad/iPhone on Domino part 2

Finally, after almost 2 months I finally have time to blog a bit again. This blog will be the second part in a 2 part series about how to serve files for iPad / iPhone devices on a domino server.

Back in part 1 I talked about an xpage application I was developing where the customer wanted to serve video streams to mobile devices. After a couple of days development I got a nice little application running where video’s could be uploaded and watched on all major browsers. The site used the video tag from HTML5 to serve the video files to the browser which accepted this tag. As said in Part 1 mobile safari uses the byte range header to retrieve the first few bytes of a stream to see which type of file is being streamed. By default, as far as I know, the domino server does not understand this header so we have to build this ourselves.

The first step in building this functionality is to create a simple custom control. The custom control contains the following lines of code:

As you can see nothing to fancy, an xp:text box which generates the correct html for the video tag. In the afterPageLoad I generate the correct url for for the video to be played. As you already notice I’m using an xPage as the url for the video tag src attribute. Lets see what happens on the this videoTest page?

The VideoRangeUtil.renderResponse method is called with the current facescontext, the id of the document and the filename we want to retrieve. The renderReponse method looks like this. I have added comments on important places. This code was not completely written by me but was inspired by code from balusC.

Just be aware that this code is not perfect and can be optimized here and there.