Tag Archives: IBM Content Navigator

Create your custom attribute editor (part 2)

Create the editor

In part 1, we learned how to inject our new editor in the list of existing editors in order to use it in the Entry Template Designer tool. That’s sweet, but we still don’t have a custom editor. We could, of course use the existing ones (take a look at the pvr/widget/editors folder) if they fit our needs, but if not, this is how to create a new editor from scratch.

Basics

The basic idea is quite simple, an editor is a dojo widget, extending :

  • the widget used for editing (TextBox, CheckBox, Select, Custom Widget, …): Allows you to edit the value of the property
  • The pvr/widget/editors/mixin/_EditorMixin class: Takes care of all communication between the property object and your editor widget

So let’s start with creating our editor file customEditorPluginDojo/editors/MyCustomEditor.js. The skeleton of our editor will be:
Continue reading

Create your custom attribute editor (part 1)

In this series of posts, we will learn how to develop and use a new attribute/property editor in your Entry Template layout.

ICN_editor_settings

This is not as easy as it first sounds, so I will split this tutorial in 6 parts.

Here is the summary of all parts, they should be taken in order.

  1. Part 1: Principle and configuration injection
  2. Part 2: Create the editor
  3. Part 3: Create the widget
  4. Part 4: Deploy and test
  5. Part 5: Add custom settings
  6. Part 6: Create a fancier widget and extra editor configuration

First part, how is it all connected

It’s good to start with some basic comprehension of how the editor mechanism works in ICN. The most important class is the ecm/model/configuration/ControlRegistry class

Everything starts with this class, this is the main registry storing the configuration of the editors. This consists of:

  • The editors configuration: Label, class, options
  • The mappings: types/cardinality to editor and free/choices/coumpound to editor

This is how looks this class:
Continue reading

Upgrade from ICN 2.0.3 to 2.0.3 FP5

Note: This post is superseded by its new version.

Here is a way to silently upgrade from IBM Content Navigator 2.0.3 to 2.0.3 FP5. You can use this right after using the CPIT installer to be up-to-date with your ICN version. You need at least ICN 2.0.3.0 to upgrade to ICN 2.0.3 FP5.

In the same folder you copied 2.0.3-ICN-FP005-LINUX.tar, execute these commands:

# The profile used when installing ICN 2.0.3, if you use the CPIT installer it should already be correct
export profilePath=/opt/IBM/cpit/install-scripts/profiles/NexusConfig
# The path of the IBM Content Navigator Configuration and Deployment Tool, if you used the default location to install ICN, that should be correct
export configmgr_cl=/opt/IBM/ECMClient/configure/configmgr_cl
# WebSphere profile path
export was=/opt/IBM/WebSphere/AppServer/profiles/AppSrv01
# WebSphere node
export wasNode=P8Node01
# WebSphere server
export wasServer=server1

mkdir icnfp
tar -xvf 2.0.3-ICN-FP005-LINUX.tar --directory=icnfp
cd icnfp
sed -i "s/LICENSE_ACCEPTED=false/LICENSE_ACCEPTED=true/g" ecmclient_silent_install.txt
./IBM_CONTENT_NAVIGATOR-2.0.3.5-FP005-LINUX.bin -f ecmclient_silent_install.txt


$configmgr_cl execute -task configureicntask -profile $profilePath
$configmgr_cl execute -task rebuildear -profile $profilePath
$configmgr_cl execute -task deployapplication -profile $profilePath

# Delete cache and restart WAS
$was/bin/stopServer.sh $wasServer
rm -rf $was/temp/$wasNode/$wasServer/navigator
rm -rf $was/wstemp/*
$was/bin/startServer.sh $wasServer

It will ask you for your WebSphere administrator username and password when restarting WAS, you can also add the -username and -password options to fully automatize the upgrade

Make a MessageDialog larger

I’ve been really busy for the past three months but I’ll be writing again soon. Meanwhile, here is a quick tip that may be handy sometimes to make any MessageDialog larger, because default size is 350x275px, which is really not much if you have large information to display.

Use the following code just before calling the show function on your MessageDialog.

domClass.add(dialog.domNode, "largeMessageDialog");
dialog.show();

You will have to import dojo/dom-class as domClass of course.

And add the following code in your css file of your plugin:

.ecmBaseDialog.ecmMessageDialog.largeMessageDialog {
    height: 90%;
    width: 90%;
}

If you’re using this a lot, I would recommend creating a new dialog extending MessageDialog and putting this in the postCreate but that will do the trick for one dialog.

And last quick thing, if you want to pre-positioned/scrolled down the content at the bottom of the div because the bottom is more important (like success/failure…), you can just do this:

dialog.description.scrollTop = dialog.description.scrollHeight;

It has to be after the call to the show function:

dialog.show();
dialog.description.scrollTop = dialog.description.scrollHeight;

Upgrade from ICN 2.0.3 to 2.0.3 FP3

Note: This post is superseded by its new version.

Here is a way to silently upgrade from IBM Content Navigator 2.0.3 to 2.0.3 FP3. You can use this right after using the CPIT installer to be up-to-date with your ICN version.

In the same folder you copied 2.0.3-ICN-FP003-LINUX.tar, execute these commands:

# The profile used when installing ICN 2.0.3, if you use the CPIT installer it should already be correct
export profilePath=/opt/IBM/cpit/install-scripts/profiles/NexusConfig
# The path of the IBM Content Navigator Configuration and Deployment Tool, if you used the default location to install ICN, that should be correct
export configmgr_cl=/opt/IBM/ECMClient/configure/configmgr_cl

mkdir icnfp
tar -xvf 2.0.3-ICN-FP003-LINUX.tar --directory=icnfp
cd icnfp
sed -i "s/LICENSE_ACCEPTED=false/LICENSE_ACCEPTED=true/g" ecmclient_silent_install.txt
./IBM_CONTENT_NAVIGATOR-2.0.3.3-FP003-LINUX.bin -f ecmclient_silent_install.txt

$configmgr_cl execute -task configureicntask -profile $profilePath
$configmgr_cl execute -task rebuildear -profile $profilePath
$configmgr_cl execute -task deployapplication -profile $profilePath

Customize the progress message of your service

By default, in IBM Content Navigator, the progress message when you are invoking a plug-in’s service is always Working… However, you may want something more meaningful. Give a progressMessage attribute to the plugin parameters doesn’t work because the Request class overwrite it anyway. You have to define one of the following attribute in the messages list.

  • progress_message_repositoryType_serviceName
  • progress_message_serviceName

Here is an example:

var serviceParams = {};
serviceParams[Constants.PARAM_REPOSITORY] = repository.id;
serviceParams[Constants.PARAM_SERVER_TYPE] = repository.type;
serviceParams[Constants.PARAM_FOLDER_ID] = items[0].id;
ecm.messages.progress_message_PrimeReleaseService = "Priming " + items[0].name + "...";

Request.invokePluginService("GenericActionsPlugin", "PrimeReleaseService", {
    requestCompleteCallback: lang.hitch(this, function (response) {
        this.displayResults(response);
    }),
    requestParams : serviceParams
});

Callback not working in the FileTracker functions

Status: fixed in 2.0.3.3

You might have noticed that when using the ecm/model/FileTracker class in IBM Content Navigator, the callback is never called.

For instance if you are using the following code:

FileTracker.downloadAndTrackFiles(documentInfoObj, function (response) {
    console.log("Never invoked");
});

the callback is never called. This is because there is a defect in the FileTracker processMessage function, it does not look correctly for the callback because of a = missing in the condition:

var callbackResponse;
if (response.responses && response.responses.length > 0) {
	var callbackResponse;
	for ( var i = 0; i < response.responses.length; i++) {
		if (response.responses[i].errorCode = this.SERVER_RESPONSE_CALLBACK) {
			callbackResponse = response.responses[i];
			break;
		}
	}
} else if (response.errorCode == this.SERVER_RESPONSE_CALLBACK) {
	callbackResponse = response;
}

This is fixed in Fix Pack 3 though (2.0.3.3), so you can either upgrade or use a plugin to do an aspect around and replace the function by the correct one, which is:

processMessage: function(json, showSuccessMessage) {
	var methodName = "processMessage";
	this.logEntry(methodName);

	var response = dojojson.fromJson(json);
	if (response.hasError) {
		var errorPrefix = "", inserts = [];
		var showError = true;
		if (response.errorCode == 7) {//ERROR_OPEN_FAILED
			errorPrefix = "runtime_file_tracking_file_not_found_error";
		} else if (response.errorCode == 3) {
			errorPrefix = "runtime_file_tracking_ioexception_error";
		} else if (response.errorCode == this.ERROR_NOT_TRACKED) {
			showError = false;
		} else if (response.errorCode == this.ERROR_OPEN_FAILED) {
			showError = true;
			errorPrefix = "runtime_file_tracking_open_error";

		} else if (response.errorCode == this.ERROR_SAVE_FILE_FAILED) {
			showError = true;
			errorPrefix = "runtime_file_tracking_save_file_error";

		} else if (response.errorCode == this.ERROR_SAVE_FILE_FAILED_AND_OPEN_FIALED) {
			showError = true;
			errorPrefix = "runtime_file_tracking_save_file_after_checkout_error";

		} else if (response.errorCode == this.ERROR_ENVIRONMENT_VARIABLE_PATH_NOT_FOUND) {
			showError = true;
			errorPrefix = "runtime_file_tracking_ev_file_path_not_found_error";

		} else if (response.errorCode == this.ERROR_OPEN_CONNECTION) {
			showError = true;
			errorPrefix = "runtime_file_tracking_ioexception_error";

		} else if (response.errorCode == this.ERROR_FOLDER_NOT_FOUND) {
			showError = true;
			errorPrefix = "runtime_file_tracking_exact_file_path_not_found_error";

		} else if (response.errorCode == this.ERROR_EXACT_PATH_NOT_FOUND) {
			showError = true;
			errorPrefix = "runtime_file_tracking_exact_file_path_not_found_error";

		} else if (response.errorCode == this.ERROR_CANNOT_CREATE_TRACKING) {
			showError = false;
			errorPrefix = "runtime_file_tracking_exact_file_path_not_found_error";

		} else if (response.errorCode == this.ERROR_DELETE_FILE_FAILED) {
			showError = true;
			errorPrefix = "runtime_file_tracking_cannot_delete_file_error";

		} else {
			showError = true;
			errorPrefix = "runtime_file_tracking_generic_error";
		}

		if (showError) {
			if (response.responses && response.responses[0].value) {
				inserts.push(response.responses[0].value);
			} else if (response.value) {
				inserts.push(response.value);
			}
			Desktop.addMessage(Message.createErrorMessage(errorPrefix, inserts, false));
		}

	} else {
		var successMessage = "";
		if (response.responses) {

			if (response.responses.length == 1 && ((response.responses[0].errorCode == this.ERROR_DELETE_FILE_FAILED || response.responses[0].errorCode == this.FOUND_TRACKED_RECORD_BY_FILE_PATH) || (response.responses[0].errorCode == this.FOUND_TRACKED_RECORD_BY_SCANNING) || (response.responses[0].errorCode == this.SUCCESSFULLY_TRACKED_FILE_USING_ADS))) {

				successMessage = string.substitute(ecm.messages.file_tracking_successfully_downloaded_document, [
					response.responses[0].originalDocumentName,
					response.responses[0].value
				]);
			} else if (response.responses.length > 1 && ((response.responses[0].errorCode == this.FOUND_TRACKED_RECORD_BY_FILE_PATH) || (response.responses[0].errorCode == this.FOUND_TRACKED_RECORD_BY_SCANNING) || (response.responses[0].errorCode == this.SUCCESSFULLY_TRACKED_FILE_USING_UD) || (response.responses[0].errorCode == this.SUCCESSFULLY_TRACKED_FILE_USING_ADS))) {

				var count = response.responses.length;
				var documentsDownloaded = [];
				for ( var i = 0; i < count; i++) {
					documentsDownloaded.push(response.responses[i].originalDocumentName);
				}
				successMessage = string.substitute(ecm.messages.file_tracking_successfully_downloaded_document, [
					documentsDownloaded.join(",")
				]);

			}
		}

		if (successMessage && successMessage.length > 0) {
			Desktop.addMessage(new Message({
				number: 0,
				level: 0,
				text: successMessage
			}));
		}

		var callbackResponse;
		if (response.responses && response.responses.length > 0) {
			var callbackResponse;
			for ( var i = 0; i < response.responses.length; i++) {
				if (response.responses[i].errorCode == this.SERVER_RESPONSE_CALLBACK) {
					callbackResponse = response.responses[i];
					break;
				}
			}
		} else if (response.errorCode == this.SERVER_RESPONSE_CALLBACK) {
			callbackResponse = response;
		}
		if (callbackResponse && callbackResponse.value) {
			var lookupId = callbackResponse.value.callbackId;
			if (lookupId && this.callbackMap[lookupId]) {
				var callbackFunc = this.callbackMap[lookupId];
				if (callbackFunc) {
					callbackFunc(callbackResponse.value.response);
				}
			}
		}

	}

	this.logExit(methodName);
	return response;
	//MessageFactory.createErrorMessage = function(messagePrefix, inserts, backgroundRequest);

},