IBM Support

Using an ICN Plugin to customize Daeja ViewONE launch.

Technical Blog Post


Abstract

Using an ICN Plugin to customize Daeja ViewONE launch.

Body

Background

 

In ICN 2.0.2 and earlier releases, an upgrade-supported configuration file was provided for Daeja Viewer configuration (navigator.war/applets/filenetViewer_properties.jsp).  This was provided to allow sites the ability to customize viewer startup parameters.  In the past, in P8 Workplace and P8 Workplace XT, customization was done in the actual JSP that launched the viewer, and once those changes were made, the site had to maintain that code through upgrades.

The intent, in ICN, with filenetViewer_properties.jsp was to provide for customization without the need to maintain code through updates.  Upgrade installations to ICN do not overwrite this file.

As it turns out, there are sites that have gone to customizing the viewer startup scripts around filenetViewer_properties.jsp anyway.  Sites have gone this route in order to provide more granular, and context-specific customization to startup parameters.  One of the more common cases for this is to disable annotation support for certain classes of documents, or for certain groups of users.

 

Enter ICN 2.0.3

 

In ICN 2.0.3, all of the configuration of Daeja ViewONE Pro (called FileNet Viewer in earlier releases), the new Daeja ViewONE Virtual, and the related streaming and redaction services have been moved into the ICN admin interface.

Some basic upgrade support is provided in ICN 2.0.3 that reads the filenetViewer_properties.jsp, and initializes default settings in ICN admin, based on the values found there.  The first time these settings are modified and/or saved in the ICN admin database, the filenetViewer_properties.jsp file is never used again.

Moreover, the scripts that launch Daeja ViewONE Pro, and Daeja ViewONE Virtual are heavily modified from prior releases, in order to load ICN admin-stored configuration on viewer startup.

Which leads us to the purpose of this article. 

With ICN 2.0.3, many sites are discovering that their scripted customizations to viewer launch in ICN 2.0.2 and earlier no longer work.  Also, there is no script available that allows for customization of the startup of ViewONE Virtual.

The good news is that with ICN 2.0.3, internal requirements obviated the need to provide a generalized, extensible Daeja ViewONE Pro/Virtual startup customization capability. 

So, as of ICN 2.0.3.3, a new set of services are provided, that allow context-specific customization of both Pro and Virtual launch via ICN plugin.

For sites that had been maintaining custom viewer launch scripts, this is the recommended way forward.  This article describes this new ViewONE Bootstrap service, and provides a basic sample plugin that can be used as a starter for developing a variety of customizations to viewer configuration and behavior.

 

ViewONE Bootstrap Service

 

In ICN 2.0.3.3, a new set of services are introduced “per-platform”:

  • /p8/getViewoneBootstrap.do
  • /cm/getViewoneBootstrap.do
  • /od/getViewoneBootstrap.do
  • /cmis/getViewoneBootstrap.do
  • /box/getViewoneBootstrap.do

Whenever a Daeja Viewer is launched, a request is made to one of these services, depending on the repository where the document is stored.  The document information is passed on the request, so that the service has access to all of those details.

The service sends a JSON response, containing all of the parameters required to launch the viewer for the document to be viewed.

 

ICN Plug-In Support

 

The ICN Plugin interfaces provide the ability to create request and/or response filters for any of the services used in ICN.  A custom plugin can therefore provide an implementation of a request or response filter for the ViewONE Bootstrap service.

These filters receive all of the request parameters that are also used to launch the document, and operate in the context of the current authenticated user.

Therefore, it is possible for a plugin to implement a response filter that adjusts viewer launch parameters on a per-document or per-user basis.

If for certain documents you want to disable annotations, you can do it just for those documents.  This can be by document class, by document property value, the user’s access level, or really anything in context.  If you want to only allow certain users access to certain viewer features, you can enable or disable those features for the user or group in question.

 

Plugin Sample

 

What better way to illustrate how to customize Daeja ViewONE launch in ICN than by providing some sample code?

Another common reason that sites customize viewer launch is to configure custom image stamp annotations.  With the release of ICN 2.0.3.5, image stamp annotation support is introduced with Daeja ViewONE Pro and ViewONE Virtual.

Daeja ViewONE has had image stamp annotation support for a long time.  But in the context of ICN, prior to ICN 2.0.3.5, the parameters used to configure image stamps in ViewONE were restricted such that it was not possible to configure and use with ICN.

Daeja ViewONE 4.1.4 resolves this by introducing a new parameter – imageStampResourceContext, which allows us to configure the service, or resource path that is used to retrieve image stamp content.  This combined with a robust macro substitution capability, also introduced in ViewONE 4.1.4, give us a great deal of flexibility in how the viewer can be set up to use image stamps.

So the sample provided here serves two purposes.  It illustrates how to write a plugin response filter that can be used to customize Daeja ViewONE launch, and it illustrates a basic scheme that can be used as a starting point, to configure image stamp annotations.

 

Basic Approach

 

Note that image stamp support as I am going to describe it here will first appear in ICN 2.0.3.5.  So this example, can only be used “verbatim” on that or newer releases.  The overall technique of implementing a response filter on the getViewoneBootstrap service, and specifying custom viewer launch parameters via the JSON response object is, however, supported back to ICN 2.0.3.3.

This seems like a good point to start with a simple illustration:

 

image

 

In this basic example, the imageStampResourceContext parameter will be set as shown here.  With the single macro - ${originalStampURL.query.path}.  This macro has three parts.  I am not going to get into the details of Daeja’s new macro syntax here, except to say that it offers a great deal of flexibility.  I will provide a link to Daeja’s macro documentation in the comments – once it is available.

In this case, we are going to use a basic path-based approach to the image stamps.  However the macro support is robust enough that we could also store the image stamps in a repository, or serve them via some other service. 

All the macro expression does in this case is pick up the “path” parameter from the query portion of the value in annotationStamp1 (path=resources/images/RedactedStamp.png).

The result, then is that the stamp is addressed as a resource within the web application - /navigator/resources/images/RedactedStamp.png.

 

Plugin Configuration

 

It would be no problem to simply go into the ViewONE Virtual configuration in ICN admin, set these parameters.  There is a new entry in the UI for imageStampResourceContext, and the annotationStampN parameters can be added in the additional parameters.

But with the plugin, we can tailor the configuration to the scheme that has been chosen to set up the image stamps.  Here is a screenshot of the plugin configuration as it is implemented:

 

image

 

The configuration consists of two properties for each stamp that is going to be defined – Label and Path.  The Label is the value that will be displayed in the viewer, to select the image stamp.  And the path is a path relative to the root if IBM Content Navigator, where the image will be stored.

When the user clicks new or edit, a dialog will be displayed to add or edit a new stamp:

 

image

 

The configuration is stored as JSON, which can then be read at runtime by our custom response filter.  Here is the code for the response filter:

 

package com.ibm.ecm.extension.v1BootstrapPlugin;

 

...

 

public class ViewOneBootstrapResponseFilter extends PluginResponseFilter {

 

    private static final String[] filteredServices = new String[] { "/p8/getViewoneBootstrap" };

   

    @Override

    public String[] getFilteredServices() {

        return filteredServices;

    }

 

    @Override

    public void filter(

        String serverType,

        PluginServiceCallbacks callbacks,

        HttpServletRequest request,

        JSONObject jsonResponse) throws Exception

    {

        if ( jsonResponse instanceof JSONViewoneBootstrapResponse  ) {

            PluginLogger logger = callbacks.getLogger();

 

            logParameters(request, callbacks, logger);

           

            // Cast the jsonResponse to it’s native type

            JSONViewoneBootstrapResponse jvbr = (JSONViewoneBootstrapResponse)jsonResponse;

 

            // Load the plugin configuration

            String configString = callbacks.loadConfiguration();

           

            if ( configString != null ) {

                try {

                    // Configuration JSON was found, so parse it and load the values

                    int count = 0;

                    JSONObject jsonConfig = (JSONObject)JSON.parse(configString);  

                   

                    // The JSON is structured as an array of key/value pairs where the key is the

                    // Label, and the value is the resource Path.  Iterate through these, and update

                    // the JSON response with the appropriate values…

 

                    for ( Iterator<String> i = jsonConfig.keySet().iterator(); i.hasNext(); ) {

                        String label = i.next();

                        String path  = (String)jsonConfig.get(label);

                       

                        if ( label != null && path != null ) {

                            ++count; // Increment and use this sequence number to number the parameters.

 

                            // Set annotationStampN to the appropriate value with the path parameter.

                            jvbr.setViewOneParameter(

                               "annotationStamp" + count, "image:" + label + "?path=" + path);

 

                            // Set annotationStampPropertiesN, to define the menu label for the stamp.

                            jvbr.setViewOneParameter(

                               "annotationStampProperties" + count, "<Menu=" + label + ">");

                        }

                    }

                   

                    if ( count > 0 ) {

                        // Since annotation stamps were found, set imageStampResourceContext.

                        jvbr.setViewOneParameter(

                            "imageStampResourceContext", "/navigator/${originalStampURL.query.path}");

                    }

                } catch (Exception exc) {

                    logger.logError(this, "filter", exc);

                }

            }

        }

    }

   

    private void logParameters(

        HttpServletRequest request, PluginServiceCallbacks callbacks, PluginLogger logger)

    {

        // Log all of the parameters sent to the bootstrap service, and the current logged in user ID.

        // This call is just here to show what is available as contextual information.

        ...

    }

   

    private Map<String,String> getDocUrlMap(String docUrl) {

        ...

    }

}

 

And that is the whole response filter.  The configuration JSON corresponding to these two image stamp annotations would look like:

 

[

    { “Redacted”: “resources/images/RedactedStamp.png” },

    { “Pineapple”: “resources/images/PineappleStamp.jpg” }

]

 

The configuration code consists of a pair of widgets that reuse and extend the CustomSettings and CustomSettingsDialog widgets provided in the ICN toolkit.  The code is relatively straightforward, but if there are any questions, please feel free to ask in the comments.

There is one additional function in the filter that I abbreviated above, but would like to also point out.  This is the method logParameters:

 

    private void logParameters(

        HttpServletRequest request, PluginServiceCallbacks callbacks, PluginLogger logger)

    {

        // Log all of the parameters sent to the bootstrap service, and the current logged in user ID.

        // This call is just here to show what is available as contextual information.

       

        String methodName = "logParameters";

        String docUrl = request.getParameter("docUrl");

        String repositoryId = request.getParameter("repositoryId");

        String previewP = request.getParameter("preview");

        String viewer = request.getParameter("viewer");

       

        boolean preview = previewP != null ? Boolean.valueOf(previewP) : false;

        viewer = viewer != null ? viewer : "pro";

        

        Map<String,String> docUrlMap = getDocUrlMap(docUrl);

       

        logger.logDebug(this, methodName, "Repository ID: " + repositoryId);

        logger.logDebug(this, methodName, "Preview Mode: " + preview);

        logger.logDebug(this, methodName, "Viewer Type: " + viewer);

        logger.logDebug(this, methodName, "Document URL: " + docUrl);

 

        for ( String key : docUrlMap.keySet() ) {

            logger.logDebug(this, methodName,

                "Document URL Parameter " + key + ": " + docUrlMap.get(key));

        }

       

        String userId = callbacks.getUserId();

        logger.logDebug(this, methodName, "Desktop user: " + userId);

    }

 

I’ve included this in the sample, to provide an easy roadmap to the parameters and basic contextual information that is available for use in this response filter.  As you can see, you have all of the information about the document that is about to be viewed, access to the current user context, and some details about the type of viewer and mode of launch.

And here is a screenshot that shows the image stamps configured in ViewONE Virtual (and the “Redacted” image stamp placed in the document):

 

image

 

Conclusion

 

So here it is – a sample plugin that will hopefully prove useful for anyone looking to customize Daeja ViewONE Virtual or ViewONE Pro launch.

It illustrates a basic scheme for setting up image stamp annotations in ICN 2.0.3.5, and walks you through the API’s and customization points that are available now for your own ICN plugin.

 

Links

 

A zip containing the plugin source as discussed in this article can be downloaded here:

https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=e8206aad-10e2-4c49-b00c-fee572815374#fullpageWidgetId=Wf2c4e43b120c_4ac7_80ae_2695b8e6d46d&file=69508712-5e24-419c-9196-b546fb3cdd33

A copy of this article in PDF form can be found here:

https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=e8206aad-10e2-4c49-b00c-fee572815374#fullpageWidgetId=Wf2c4e43b120c_4ac7_80ae_2695b8e6d46d&file=e128ca6b-0e65-47a8-9657-ec3e9ca5999b

 

[{"Business Unit":{"code":"BU053","label":"Cloud & Data Platform"},"Product":{"code":"SSCTJ4","label":"IBM Case Manager"},"Component":"","Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"","Edition":"","Line of Business":{"code":"LOB45","label":"Automation"}}]

UID

ibm11281010