Enable DEBUG logging on the ICN server

Sources for the server part of ICN are not available. However it contains code for all public API services you are using in the ICN JavaScript model, like retrieve an item, a folder content, check in or check out an item and so on. And sometimes it is nice to know what is going on in these services, which can’t be debugged. A way to do that is to set the log level on DEBUG for the ICN server. Of course never do that on production…

This is actually really easy, you don’t even have to do it using Websphere, just go to the administration of ICN, Settings, Logging tab and set the Application-level logging to DEBUG. You can even define what classes/packages you want to log. Then restart WebSphere (maybe restarting the navigator application should be enough I haven’t tried) and you should have all debugs log in the SystemOut.log file of WebSphere (/opt/IBM/WebSphere/AppServer/profiles/AppSrv01/logs/server1). That’s might be a lot so don’t forget to filter on some classes/packages.
Continue reading

Using an external JavaScript (not Dojo module) in your ICN plugin

Sometimes you need to use an external JavaScript libraries in your plugin, because you don’t want to reinvent the wheel. Problem is that often those libraries are not Dojo modules. So how to use them in your dojo class?

Well that’s simple, dojo provides an generic script injection mechanism. Everything declared in the external script will be available in your class. Code is the following:

require(["http://host.com/stuff.js"], function(){
    // Everything declared in stuff.js is available here
});

You can link to an http location, or relative location into your project, for instance /application/stuff.js.

Now how to use that in your plugin? You can place your JavaScript file in another application or a CDN to refer it with an http protocole, example:

require(["http://host.com/application/stuff.js"], function(){
    // Everything declared in stuff.js is available here
});

Or you can leave the file in your plugin so everything is embedded when you deploy:

require(["plugin/MyPluginID/getResource/jszip/zip.js"], function () {
  // Here I can use the variable zip
});

Continue reading

How to count results from a query

When programming with P8, one recurrent task is counting how many results a query has.

There are a few options to do this, none of them being count(*) and I’ll explain why. The purpose of this post is to expose them and compare their execution time and limitations with benchmarks. We will also see how to optimize each of them separately. Hopefully, after reading this post, you will be able to choose which one best fits your needs. Before introducing all options IBM made available to us, a little introduction important to understand this post and its benchmarks.

When counting, it may be strange, but it is a lot better to expect something. Or if you can’t, at least have a limit over which the result doesn’t really matter, you are happy enough knowing it is more than this limit. Actually in most case that’s enough. For UI you would say over something, to forbid an operation you usually have a limit over which you will forbid it anyway, and so on. Of course, if you want the exact number of item, it can be done but it will be a lot slower.

Benchmarks will be counting the number of documents in a 5/4/10 folder hierarchy, meaning 5 level of sub-folders, each level with 4 sub-folders and 10 documents. This is about 55,000 documents in 5,500 folders. And we don’t always want to count exactly, in the benchmarks we will ask if there is more than 5, 10, 15,50 … until 40,000 documents. Because sometimes knowing than there is more than 50 documents is enough to forbid an operation.

Now let’s introduce the few options we have to count.
Continue reading

My first android application

Finally, it’s been almost 2 years I’ve started this and I actually managed to get it done! I’m talking about my first Android application. I started back in China when I thought it would be nice to have something more convenient to learn my Chinese than hundred of paper sheets everywhere, small one to pick them randomly, big one to write everything and so on…

That’s how I came up with the idea of an application asking me to write, or read Hanzis, and allowing me to build list of Hanzis to work on a specific lesson. Of course I wasn’t willing to add manually all my Hanzis so I least it needed to come with the 5000 Hanzis of the HSK.

During those two years I lost everything in the process, we backpacked for $10 a day (not the best work condition 🙂 ) for a few months, and I started a new job, hence the long time to go through. But it’s done. Posted on the play store today and I even made a video of it.

The good thing about that is since I had to test extensively this app, my Chinese is coming back (at least HSK 1, 2 and almost 3 for now 🙂 )

I know that people reading this blog are usually not interested in Mandarin but if you are enjoy. I chose to make it free, I hope it will help you as much as it helped me to progress.

Here is the app on the Play Store (Yes I have my own account now ! 🙂 )

And here is the video to introduce the app.

Working with Entry Templates

The two states of the Entry Templates

Be careful with the Entry Template, they can have two states, retrieved or not retrieved. They contain a lot less information when they are not retrieved.

Here is how to check if it’s retrieved or not, and retrieve it if you need to:

if (!entryTemplate.isRetrieved) {
    // Retrieve it
    entryTemplate.retrieveEntryTemplate(lang.hitch(this, function (retrievedEntryTemplate) {
        // Do something with retrievedEntryTemplate
    }), false, true);
}

Here is the JSDoc of the ecm.model.EntryTemplate class, and the one of the retrieveEntryTemplate function. Actually the entry template object itself is updated so most of the time you won’t have to do anything in the callback except wait for it to happen. Example (function converting to classic callback to promise):
Continue reading

Working with documents

Retrieving the ecm.model.ContentItem from the ecm.model.item

repository.retrieveItem(documentOrFolderId, function (contentItem) {
    // Do something with the ContentItem
});
repository.retrieveItem(folderPath, function (contentItem) {
    // Do something with the ContentItem
});

Note: Unlike the documentation says, that does not work with an document path (see this), only with a folder path. However that works with both Document and Folder ID.

Example:

repository.retrieveItem(item.id, function (contentItem) {
    // Do something with the ContentItem
});
repository.retrieveItem('/Folder/MySubFolder', function (contentItem) {
    // Do something with the ContentItem
});

JSDoc.
Continue reading

Test a method calling System.exit()

Today I was writing test for one of our command line tools, and I had this problem where the method dumping everything, which I really needed to be called since that’s the outcome I was checking, also called System.exit(). I had to find a way to test this anyway. I thought about using PowerMock and mocking system but that would have been complicated because I would have to find the exact class calling the System.exit(). So here is another solution to avoid the System.exit to exit (yes that’s possible I didn’t know about that either).

The secrets lays in the SecurityManager mechanism of Java, this class not only allows you to check permissions, but also to check exit event. Therefore you can throw an exception if you want to stop the exit. Here is the code:
Continue reading

Changing an ICN file type filter name

Have you ever changed a File Type filter name in ICN? Well don’t, that’s not pretty. All the associations of Entry Templates you’ve done on folders will just stop working, or at least stop offering the user the right Entry Template for the document’s MIME Type. In the configuration it looks like this:

icn_filetype_filter_broken

Explanation is simple. In ICN, apparently there is no ID for File Type filter, or more specifically the name is the ID, which means where you are doing an Entry Template association in ICN, an JSON object is stored as a folder preferences annotation, persisting the File Type filter name directly. Of course if you change the File Type filter name, they won’t look for all folder preferences annotations and change the File Type filter name in it, which means they will all be broken.

Continue reading