Transfer a file to your service

Some business logic can require to send a file from the client workstation to the server. Usually to improve performance by doing a server work instead of a client one, sometimes because it’s more convenient for the user or for the developer. I had to transfer a zip to do a zip-add after I noticed that deflating on the client and adding file one by one was to slow for our needs, although it worked fine.

Client side

On the client, we won’t use the function Request.invokePluginService as we usually do when invoking services. Instead, we are going to use Request.postFormToPluginService(pluginName, pluginServiceName, form, pluginParams), which allow posting data to our service. However the syntax differs, here we won’t pass our params in the requestParams attribute of the pluginParams argument, this time they all go in the form, which is a W3C FormData object, along with our W3C File. Here is the example.

var fd = new FormData();
fd.append('file', zipArchive);
fd.append(Constants.PARAM_FOLDER_ID, this.parentFolder.id);
fd.append(Constants.PARAM_REPOSITORY, this.parentFolder.repository.id);
fd.append(Constants.PARAM_SERVER_TYPE, this.parentFolder.repository.type);

var pluginParams = {
    requestCompleteCallback: lang.hitch(this, function (response) {
        this.parentFolder.refresh();
    })
};

Request.postFormToPluginService("GenericActionsPlugin", "AddZipService", fd, pluginParams);

This is all it takes on the client.

Server side

Now let’s see how to fetch this file and use it in our service.

ICN is still using Struts. That means we will use the FormFile interface to get our file (actually the stream). The FormFile is added as attribute of the request by the PluginAction class in charge to call your Plugin class so you can retrieve it with:

FileUploadActionForm uploadForm = (FileUploadActionForm) request.getAttribute(FileUploadActionForm.class.getName());
if (upload != null) {
    FormFile ff = (FormFile) uploadForm.getMultipartRequestHandler().getFileElements().get("file");
}

In order for this to work, you will have to add to your classpath the ICN classes. You can find them by deflating the ear file or going to your application server in the installed app, usually there will be the exploded ear there too. That could be more convenient to zip all WEB-INF/classes in a jar and add that to your classpath.

However, the other parameters are still retrieved with request.getParameter().

Then you can use the stream. If you need a file, even if in the ICN implementation FormFile, the file is actually stored in a WAS temp directory, this is not possible to get it so you’ll have to copy the stream in a temp file and use this file instead.

Here is the server side example corresponding to the client.

String repositoryId = (String) request.getParameter(Constants.PARAM_REPOSITORY);
String parentFolderIcnId = (String) request.getParameter(Constants.PARAM_FOLDER_ID);
String parentFolderId = P8Helper.getP8ID(parentFolderIcnId);

ObjectStore os = callbacks.getP8ObjectStore(repositoryId);

FileUploadActionForm uploadForm = (FileUploadActionForm) request.getAttribute(FileUploadActionForm.class.getName());
if (uploadForm != null) {
    FormFile ff = (FormFile) uploadForm.getMultipartRequestHandler().getFileElements().get("file");

    if (ff != null) {
        InputStream is = ff.getInputStream();
        // Do something with the stream
    }
}

Upgrade to FileNet 5.2.1

Here is a quick summary of how to upgrade to FileNet 5.2.1. As usual, before starting, snapshot/backup your server. Here are the main steps for a single server platform installed with the CPIT installer and where the application server has not been upgraded. If it has been or you platform is different, check the knowledge center but procedure should be mostly the same and you can use this to help you.
Continue reading

Drag and Drop a folder in IBM Content Navigator

Nowadays, everyone seems to think dropping a folder is somehow optional. They all have given up on the File API “Directories and System” (except Google which at least implemented it). I have to admit, I clearly don’t understand because in the ECM world, that just a must-have feature…

Anyway, since this is something our users are expecting, especially since there are used to it with the Workplace XT (via the applet), we had to find a workaround. Actually we found two which are quite complementary. One is using the Chrome Directories and System API, which really allows a true folder drop, but way better than Workplace XT since it’s applet free and therefore mobile supported. The other is supported by all browsers and requires the user to only zip the folder and drop the zip. It’ is only 1 second extra work for the user instead of the hours it would have to spend to create all the folder hierarchy manually and upload files folder by folder. This seems like a good alternative and again, it is supported by every brother.

Let’s present these two workarounds quickly. I won’t explain the whole implementation since it might get quite complex but instead, I will explain how to address the problem.
Continue reading

File Tracker download directory regression

Using Workplace XT, we were able to keep the folder hierarchy of a Document within the Object Store when downloading it with the File Tracker applet. That means, if your document’s path was /Folder/SubFolder/Document.xml, and your FileTracker folder on the client was C:\FileNet\Work, then you would get your document downloaded as C:\FileNet\Work\ObjectStoreName\Folder\SubFolder\Document.xml.

That’s no longer true with ICN. Everything goes into your download folder, C:\FileNet\Work in the previous example, without creating any sub-directories. This is especially an issue if you download a lot of document and want to edit them, this folder becomes a mess, and if a lot of documents are called the same in your Object Store, then you will have conflicts.

Officially, this is because this functionality is now covered by the Sync and Share feature, which uses a client agent on Windows platform, and is embedded in mobile applications. However this does not cover Unix platforms, and does not allow using Entry Templates, which can be a requirement for your platform. That’s why we will see how to make it work in ICN anyway.

How to fix that

Continue reading

Use a Java applet in an ICN plugin

In this post, I will describe how to embed and use a Java applet in your IBM Content Navigator plugin. Applets may be useful to overstep some JavaScript limitations, usually related to security, for instance read/write the client’s file system.

I won’t explain how to write, package and sign your applet since you can find plenty of tutorials on this topic on the web. However I will explain how to embed your applet into your plugin, then how to use it.
Continue reading

Dojo constraints documentation

I couldn’t find any proper documentation on the constraints object we can use in Dojo to validate Text, Number and Date field, especially for ValidationTextBox. So here is what I gather or figured out from Dojo’s code.

ValidationTextBox:

The documentation says “user-defined object needed to pass parameters to the validator functions“, but actually that’s not true. This actually will never be used, except if you set a pattern abeing a function (this.pattern). If you do that then the pattern function you gave will be called on every validation with the constraints object as parameter, which can be anything since you are the only one using it in your function. The pattern function must return a String. Of course this.pattern can also be a simple pattern as a string, then constraints becomes useless and won’t be used. Example:

this._myValidationTextBox.set('pattern', function (constraints) {
    return constraints + '.*'; // For instance my input must start with my constraints
});
// OR
this._myValidationTextBox.set('pattern', constraints + '.*');
// Are exactly the same, but using the combo pattern function and
// dynamic constraints you can have a more dynamic behavior

I guess this could be used for complex scenarios where validation need to be more dynamic and we on;t want to change the pattern every time. Although I’ve never got to use it.

NumberTextBox:

Actually they put some documentation under the NumberTextBox documentation, so I won’t bother rewriting what they already wrote.

DateTextBox:

And the documentation for this one is here.

Workplace XT Entry Template issues when used in ICN

I really had to write one single article about all issues occurring when using Workplace XT Entry Template in ICN, because at the time it wasn’t as clear as now in my mind. There are actually two main different issues (in some ways related) both concerning the Entry Templates in ICN, both because they are Workplace XT Entry Templates.

Therefore I am going to split them in two different issues, in two different threads:

  1. Inheritance of association of Entry Template ob folder made in ICN does not work, all-sub-folders does not inherit the association
  2. Associations of Entry Template on folder made via Workplace XT does not fully work in ICN

 

Workplace XT File Type issue in ICN

This is the second post about the issue occurring when using Workplact XT entry template with ICN. We’ve seen that there is an inheritance problem in this post, we will now see that there is a problem of File Types filters. This issue needs to be addressed if you want to use the second work around of the former issue.

Symptom

You’ve created Entry Templates in Workplace XT, and also created a few File Type Categories gathering several MIME Types. You’ve used these Entry Templates by associating them on a folder to use them when adding document. You restricted them by File Type Category. For example ET 1 is only for Images (File Type Images gathering image/png, image/jpeg, …), ET 2 is only for office documents, and ET3 is for every king of document. That looks a little bit like that in Workplace XT:

wpxt_entrytemplate_associations

Problem is that in ICN, this does not work. You always get the generic entry template (in my case misc doc, or no Entry Template if they all have restrictions on the File Type Categories.
Continue reading

Repository.retrieveItem(itemPath, callback) not working

I just noticed that the following function is not working as the documentation says in the ICN JavaScript model. Actually it can not be used with a document path.

retrieveItem(itemIdOrPath, itemRetrievedCallback, templateID, version, vsId, objectStoreId, action)

Continue reading