Skip to main content

Creating custom service method and callback function

D2SV's call service command lets user execute a method from an external service class and perform actions on the UI based on the response sent back through javascript callback function.

There are basically 4 part of the generic action service

  • eService - Existing services or some custom java class from which code needs to be executed.

  • eMethod - Method in eService where it needs to execute a functionality.

  • rType - Type of operation to be performed in the client side post server side execution There are 3 types of post execution

    • JS - a custome javascript method is triggered
    • EVENT - Trigger an event
    • NATIVE - open the result in a new browser tab.
  • rAction - Action to be performed based on the rType

    • For JS, develop specify the path of the JS file with method separated by a colon.
      • Example : d2svomni/actions/clipboard.actions:copyId

        Here it means that it will execute a method called copyId which has input argument that returns response sent from the eMethod. Details can be seen ine sample given in the below section.

    • For EVENT: event name and message parameter separated by '::'.
      • Example: D2_ACTION_SEARCH_DOCUMENT::oam_id==lastSearch Here documentum client will publish an event D2_ACTION_SEARCH_DOCUMENT with the message id as the lastSearch which will route the application to the last search executed by the user.
    • For NATIVE: openUrlInPopup is specified which will open the URL returned as part of the action services executed
      • Example: as part of the eMethod which returns a list of Attributes, add an attribute with name 'RETURNED' or 'URL' which will be opened in the new browser tab

For implementing a menu with generic action, user can either reuse an existing service method and callback function or create a new custom java service class with the method definition and javascript file with the callback function.

The below section illustrate how to create custom service method and callback function and use them in the menu definition delta xml for the D2SVOmni plugin under com.opentext.test group.

Source code structure

D2SVOmni
|
| pom.xml
|
\---src
| \---main
| \---java
| | \---com
| | \---opentext
| | \---test
| | \---webfs
| | \---custom
| | D2SVOmniService.java
| |
| \---resources
| | \---strings
| | | \---menu
| | | \---MenuContext
| | | MenuContext_en.properties
| | |
| | \---xml
| | \---unitymenu
| | MenuContextDelta.xml
| |
| \---smartview
| \---src
| \---bundles
| | d2svomni-bundle.js
| |
| \---actions
| clipboard.actions.js
|
\---target

Files and their purpose

Following are the list of function oriented source files and their purpose. Other source files present within the plugin are part of common infrastructure code and explained in Understanding D2SV plugin project.

  • src/main/resources/strings/menu/MenuContext/MenuContext_en.properties - Add label for the custom menu
menutest=CopyId
  • src/main/resources/xml/unitymenu/MenuContextDelta.xml - Add menu definition for the custom menu
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<delta>
<insert position-after="menuToolsMassUpdate">
<menuitem action="" id="menutest">
<dynamic-action class="com.emc.d2fs.dctm.ui.dynamicactions.actions.U4Generic" eMethod="copySelectedId" eMode="MULTI" eService="D2SVOmniService" rAction="d2svomni/actions/clipboard.actions:copyId" rType="JS"/>
</menuitem>
</insert>
</delta>
  • src/main/java/com/opentext/test/webfs/custom/D2SVOmniService.java - Custom D2SVOmniService class with copySelectedId method.
package com.opentext.test.d2svomni.webfs.custom;

import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.common.DfException;
import com.documentum.fc.common.DfId;
import com.emc.d2fs.dctm.plugin.IPluginAction;
import com.emc.d2fs.dctm.utils.ParameterParser;
import com.emc.d2fs.dctm.web.services.D2fsContext;
import com.emc.d2fs.exceptions.D2fsException;
import com.emc.d2fs.dctm.web.services.ID2fsPlugin;
import com.emc.d2fs.models.attribute.Attribute;
import com.emc.d2fs.utils.AttributeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.opentext.test.d2svomni.D2SVOmniPlugin;

import java.util.List;
import java.util.ArrayList;

public class D2SVOmniService implements IPluginAction {
private static final ID2fsPlugin VERSION = new D2SVOmniPlugin();
private static final Logger LOGGER = LoggerFactory.getLogger(D2SVOmniService.class);

public List<Attribute> copySelectedId(D2fsContext context) throws D2fsException {
LOGGER.debug("copySelectedId()...");
ParameterParser parser = context.getParameterParser();
List<String> ids = parser.getListParameter("id");
String aName = parser.getStringParameter("aName", "");
List<Attribute> result = new ArrayList<>();
if (aName.isBlank() || aName.equals("r_object_id")) {
String idString = String.join("¬", ids);
LOGGER.debug("Selected id(s): {}", idString);
result.add(AttributeUtils.createAttribute("id", idString));
} else {
List<String> attrValues = new ArrayList<>();
StringBuilder sb = new StringBuilder();
try {
for (String id : ids) {
IDfSysObject sObj = (IDfSysObject) context.getSession().getObject(new DfId(id));
if (sObj.hasAttr(aName)) {
attrValues.add(sObj.getString(aName));
}
}
String valString = String.join("¬", attrValues);
result.add(AttributeUtils.createAttribute("id", valString));
} catch (DfException | D2fsException e) {
throw new D2fsException("Unable to copy value to clipboard.");
}
}
return result;
}
}
  • src/main/smartview/src/actions/clipboard.actions.js - The javascript file with the callback function implementation.
define([], function () {
'use strict';
return {
copyId: function (options) {
var oam_id = options.data.id;

console.log('copyId called.');

if (oam_id.indexOf('¬') !== -1) {
oam_id.replace('¬', ',');
}
console.log('oam_id = ' + oam_id);
let ua = navigator.userAgent.toLowerCase();
let isOpera = ua.indexOf('opera') > -1;
let isIE = (!isOpera && ua.indexOf('msie') > -1) || (ua.indexOf('trident') > -1);
let isEdge = ua.indexOf('windows') > -1 && ua.indexOf('edge') > -1;
let isFF = ua.indexOf('firefox') > -1;
let isSafari = (ua.indexOf('webkit') > -1) || (ua.indexOf('khtml') > -1) || (ua.indexOf('safari') > -1);
let isChrome = ua.indexOf('chrome') > -1;
console.log('isOpera', isOpera);
console.log('isIE', isIE);
console.log('isEdge', isEdge);
console.log('isFF', isFF);
console.log('isSafari', isSafari);
console.log('isChrome', isChrome);
if (isIE) {
window.clipboardData.setData('Text', oam_id);
console.log('Text copied to clipboard');
} else if (isEdge) {
console.log('edge clipboard.');
this.pasteInClipboardHTML5(oam_id);
} else {
navigator.clipboard.writeText(oam_id).then(function () {
console.log('Text copied to clipboard');
}).catch(function (err) {

console.error('Could not copy text: ', err);
});
}
console.log('copyId done.');
},

pasteInClipboardHTML5: function (text) {
function selectElementText(element) {
let range;
if (document.selection) {
range = document.body.createTextRange();
range.moveToElementText(element);
range.select();
} else if (window.getSelection) {
range = document.createRange();
range.selectNode(element);
window.getSelection().removeAllRanges();
window.getSelection().addRange(range);
}
}

let element = document.createElement('div');
element.textContent = text;
document.body.appendChild(element);
selectElementText(element);
document.execCommand('copy');
element.remove();
},
};
})
  • src/main/smartview/src/bundles/d2svomni-bundle.js - Add an entry for the callback action's javascript file.
define('bundles/d2svomni-bundle',[
'd2svomni/utils/theme/action.icons',
'd2svomni/utils/startup',
'd2svomni/actions/clipboard.actions'
], {});

After making these changes, build the D2SVOmni plugin and deploy it on the app server. A new menu item CopyId can be seen on the doclist menu toolbar.