Merging WorkItems which are having some common Property values

There was a customer requirement to merge WorkItems which are having same Suppliercode and Location. (Suppliercode and Location are properties). To achieve that task we used component operation step with Filenet API. This is the code,

import java.util.ArrayList;
import com.filenet.api.core.Factory;
import com.filenet.wcm.api.impl.Logger;
import com.filenet.api.util.UserContext;
import filenet.vw.api.*;

public class CFBulkSubmit {

public static Logger log = Logger.getLogger(CFBulkSubmit.class);

public static VWSession getPESession() {
 String strAppURI1 = "CONNECTION_URL";  //[example :-]
 System.out.println("[ENTER PEManager getPESession()]");

 String connectionPoint = "CONNECTION_POINT";
 String password = "PASSWORD";
 String username = "USERNAME";

System.setProperty("", "C:\\IBM\\FileNet\\ContentEngine\\config\\samples\\jaas.conf.WSI");
 com.filenet.api.core.Connection conn = Factory.Connection.getConnection(""); subject = UserContext.createSubject(conn, username, password, "FileNetP8WSI");
 log.debug("Subject Created");
 UserContext uc = UserContext.get();

VWSession vwSession = new VWSession();

try {
 vwSession.logon(username, password, connectionPoint);
 String sn = vwSession.getPEServerName();
 System.out.println("++++++++++++++++" + sn);

System.out.println("PE session established:" + vwSession);
 } catch (VWException e) {
 System.out.println("Exception occured while establishing PE session.");

 return vwSession;

public static void closePESession(VWSession peSession) {
 log.debug("[Enter closePESession]");
 try {
 if (peSession != null)
 System.out.println("[Exit : closePESession]");
 } catch (VWException e) {
 log.error(e.getMessage(), e);

log.debug("[Exit : closePESession]");

public static void getVWWorkObject(String wobNum, String SupplierCode, String Location, String tempAttA, String refernaceNo, String total) {
 if(wobNum!="" && wobNum!=null){
 try {
 VWSession session=getPESession();
 VWQueue queue1 = session.getQueue("BulkSubmit");
 VWQueueQuery query1 = queue1.createQuery(null, null,null, VWQueue.QUERY_READ_LOCKED, null, null,VWFetchType.FETCH_TYPE_WORKOBJECT);
 System.out.println("All item count in Bulk Step : " + query1.fetchCount());
 VWRoster roster = session.getRoster("GLPayments");
 int queryFlags=VWRoster.QUERY_NO_OPTIONS;
 int queryType = VWFetchType.FETCH_TYPE_WORKOBJECT;
 String queryFilter = "F_WobNum = '"+wobNum+"'";
 VWRosterQuery query = roster.createQuery(null, null, null, queryFlags, queryFilter, null, queryType);
 while(query1.hasNext()) {
 VWWorkObject workObject1 = (VWWorkObject);
 System.out.println("Unique Supplier Code: "+ workObject1.getDataField("SupplierCode").toString());
 String UniqueSupplierCode = workObject1.getDataField("SupplierCode").toString();
 String UniqueLocation = workObject1.getDataField("Location").toString();
 String UniqueTotal = workObject1.getDataField("total").toString();
 if(UniqueSupplierCode.equals(SupplierCode) && UniqueLocation.equals(Location)){
 System.out.println("Inside of if Condition");
 VWStepElement stepElement1 = workObject1.fetchStepElement();
 VWParameter[] parameters1 = stepElement1.getParameters(VWFieldType.ALL_FIELD_TYPES, VWStepElement.FIELD_USER_AND_SYSTEM_DEFINED);
 //get the existing attachment value

VWAttachment[] tempAttA1=(VWAttachment[])stepElement1.getParameterValue("DocBulk");
 ArrayList<String> law=new ArrayList<String>();
 ArrayList<String> bulkReferenceNumbers=new ArrayList<String>();

 System.out.println("+++++++++++++++Currently DocBulk is Empty+++++++++++++++");
 String tempAttA11 = stepElement1.getParameterValue("GLMainDoc").toString();
 tempAttA=tempAttA11.substring(0, 65)+(tempAttA.substring(65));
 System.out.println("new tempAttA : "+tempAttA);
 String[] x=(String[]) workObject1.getDataField("BulkReferenceNumbers").getValue();
 for(int i=0;i<tempAttA1.length;i++){
 tempAttA=tempAttA1[0].toString().substring(0, 65)+(tempAttA.substring(65));
 System.out.println("new tempAttA : "+tempAttA);
 workObject1.setFieldValue("DocBulk", law.toArray(), true);
 workObject1.setFieldValue("BulkReferenceNumbers", bulkReferenceNumbers.toArray(), true);
 int updated_total=Integer.parseInt(total)+Integer.parseInt(UniqueTotal);
 workObject1.setFieldValue("total", Integer.toString(updated_total), true);
 while (query.hasNext())
 VWWorkObject xc = (VWWorkObject);
  xc.doDelete(true, true); 
 System.out.println("Failed to find similar supplier code");


} catch (VWException vwe) {
 log.error("Exception found at PEManager.getVWWorkObject():" + vwe,
 System.out.println("WobNum is null or empty"); 

public static void main(String args[]) {

In here First we have to establish a connection to process engine.

Merged WorkItems are going to “BulkSubmit” queue. When new WorkItem comes to this component operation step it check the BulkSubmit Queue. Is there any Workitem with same SupplierCode and same Location, it updates some property values in BulkSubmit queue WorkItem. Updating properties are total, DocBulk, BulkReferenceNumbers. In here we put initially attached documents (“GLMainDoc”) of both cases to “DocBulk” array type Attachment field. Because we can’t have multiple initial documents for one case. And also reference numbers of merged Workitems are going to new array type property called BulkReferenceNumbers.

Then finally terminates the new comer.

If it can’t find any matching Workitem in BulkSubmit, new WorkItem goes to the next step without any change.

In here we use small trick to add attachment to WorkItem in BulkSubmit queue. (We add new comer’s attachment to BulkSubmit workItem) GLMainDoc is the initial attachment field.

System.out.println("+++++++++++++++Currently DocBulk is Empty+++++++++++++++");
 String tempAttA11 = stepElement1.getParameterValue("GLMainDoc").toString();
 tempAttA=tempAttA11.substring(0, 65)+(tempAttA.substring(65));
 System.out.println("new tempAttA : "+tempAttA);

We get the property value “GLMainDoc” of new comer and subString from 65. Then get the property value “GLMainDoc” from BulkSubmit’s WorkItem and subString 0 to 65. Then merge these vales and pass it to DocBulk array type Attachment field. In here I found that first 65 characters are unique for particular case and other characters starting from 65th are floating. So in here I’m modifying this floating values with new comers floating values which are placed after 65th character.

So by modifying attachment property value like this you can transfer attachments between 2 cases.





File name set to GUID in ACCE and FEM

We have use a entry template to add files to Content engine and found a serious administrative issue in  some of the Document classes. In it the GUID will be set to the document title irrespective of  given document name .However document title can be properly seen at the Workplace XT and Navigator.
Acce error


CRBook Folder

Frist,I thought this is a error due to security permission  .And try  to simulate the error with different security permission However ,With the support of PMR team  ,We able to identify the reason  for error with property templates .

Please Fallow the following Steps

  1.  Right click on your document class (e.g., “Loan”) in FEM,
  2. select the Property Definitions tab and check the “Inherited Properties” and “System Properties” checkboxes to show these properties.
  3. Click on the “Document Title” property and select Edit.
  4. Then click on the More tab.
  5. select the “Name Property” checkbox, click OK.


Customize Styles in IBM Content Navigator

Its a major issue we face desktop wide styles within content navigator. We need to change the labels and Font Color of the Read only fields based on customer requirement and  I was looking at the better way to achieve without changing step processor files. Our consultant  Anand Ayer guide us  to achieve it .Appreciate him a lot.

The Style Sheet plugin enable to add customization specific to Theme. Following is the way to achieve it .


In here we have to Create a new Plugin with  stylesheet.css file.

In the Style Class  you can define  Required custom style using the theme ID as a prefix for the default css apply.

For an example the default style for text areas will be as fallows.

.dijitSelect input, .dijitTextBox input {
padding: 1px 1px 2px;

In order to change default style , we need to add the prefix of the theme  to default plugin and add to the custom style sheet like below .

.CustomTheme .dijitSelect input, .dijitTextBox input {
padding: 1px 1px 2px;

Integrate Search Templates within Workflow

only initial attachment already know there can be many  documents we uploaded to Content Engine but we can attachment while workflow intonation  to display within the workflow.



However We can attach any other document to workflow ,by using search template and display it in the  workflow using component.


First We need to Create the Search Object from WorkPlaceXT. Advanced Tools >> Search Designer Search Template Design

You can see the search from all search in Object Store as well as the Folder it saved.

test Serch working

Locate the saved Object from FEM and go to properties.


Go to Content Elements >> and Select UIContent.xml >> View and identify the item ID’s of Search Parameters . This is identified by the XMl with Were clause which indicated like below.Here Item ID’s is 7.

content Eliments

<eq><whereprop editproperty=”editable” itemid=”7″ name=”CaseID” objecttype=”document” symname=”CaseID”><propdesc datatype=”typestring” haschoices=”false” hasmarkings=”false” symname=”CaseID”/></whereprop><literal/></eq></where>



Go to the Workflow you have Created.In Workflow porpoises sections, Go to attachments and  define the the crated object.


Create a CE Operation object and select “SearchForMany” operation and  provide following parameters.


object type : “document”

itemIDs : “7”  << value taken from where in UI.xml

Values : “<Workflow Propriety Name>”  this will give the dynamic value for the property

return_value :  the attachments returned will be taken to here. This can be used within the Workflow as a separate attachment to display returned attachments.

Transfer Data Within the Step Processor UI’s

I found it difficult to Set a CaseID in Step Processor to the Document Add UI.  Because Client  required to set that value when adding a document .I had to put enormous effort  like searching  clinetContext Javascript array.However using Property editor I able to achieve it .Here are the technical steps followed .


I have created property editor in the to get the CaseID value  which trigger @ workitem properties  response filter

—————————————————————-java file

String value = criteriaObject.get(“value”).toString();
System.out.println(“CaseID value :: ” + value);
criteriaObject.put(“propertyEditor”, “filterPluginDojo/eduPropertyEditorSetCaseID”);

————————————————————– js file

postCreate: function() {
// Remove the base class from the domNode
domClass.remove(this.domNode, this.baseClass);
domClass.add(this.domNode, “eduPropertyEditorSetCaseID”);

this.logInfo(“Post Create edupropeditor”,this.value);
this.logInfo(“Post Create edupropeditor Case ID”,this.values[0]);
window.caseid=this.values[0]; // get the case Id to the window property



The other property editor will be fired @ the document openclass event  response filter .At the button click event the widow object value will be assessed and set the value to CaseiD property.

—————————————————————-java file

String templateName = request.getParameter(“template_name”);
System.out.println(“templateName” + templateName);

JSONArray properties = (JSONArray)jsonResponse.get(“criterias”);
for (int i = 0; i < properties.size(); i++)
JSONObject jsonPropDef = (JSONObject)properties.get(i);
String name = (String)jsonPropDef.get(“name”);
System.out.println(“templateName CaseID prpoerty” + name);
if ((name != null) && (name.equals(“CaseID”)))
jsonPropDef.put(“propertyEditor”, “filterPluginDojo/eduPropertyEditorCaseID”);

————————————————————– js file

_buttonClick: function(evt) {
this.logInfo(“Event log 2”,window.caseid);
this.set(“value”, window.caseid);

Navigator Assign Item for Particular User

Content Navigator Allows for easy Popup window to user Pickup and Assign particular case to a User Personal In Basket.Within the Workflow you have to define .

The Work Queue (CFVG ) will make available to visible @ particulate step by making it to Selected Parameters .The subsequent Step make Personal Queue with CFVG.



Within Navigator  Work Queue (CFVG ) will be displayed as follows and after submitting in that step,it will go to personal in basket .

Add User To Queue

Content Navigator ECM user Object Email

According to the reference SelectUserGroupDialog Widget Use the ecm.model.User Which has the email Attribute @ class level.However When it come to Content Foundation ,The Email will not able to retrieve to Navigator UI level ,Although it is correctly configured with Active Directory.



We have Discuss the issue in DeveloperWorks and there is solution to develop the customization using response filter.

Response Filter Utilise following  Services :   /p8/getDirectories,/p8/findUsers,/p8/findGroups

The special program has written to communicate with AD using LDAP connection and retrieve the email by passing the username.Retrieved Email  will be in added to json response .

String emailAdd = getUserEmail(displayName,ldapContext);
jsonPropDef.put(“emailAddress”, emailAdd);

Just adding to response will not display the email in the UI tool tip .After a significant effort we able to display it as above using fallowing steps.

SelectUserGroupDialog , _createRendering method has overided with a custom code . The tooltip section having the custom code indicated .


_createRendering: function(repository) {


this._selector = new UserGroupSelector({

queryMode: “all”,
selectionMode: “extended”,
_showTooltip: function(event, grid) {
var item = grid.getItem(event.rowIndex);
if (item) {
var toolTip = [];

” + idxHtml.escapeHTML(this._messages.display_name) + “ “);
toolTip.push(has(“dojo-bidi”) ? this.enforceTextDirWithUcc(null, idxHtml.escapeHTML(item.displayName)) : idxHtml.escapeHTML(item.displayName));


” + idxHtml.escapeHTML( + “ “);
toolTip.push(has(“dojo-bidi”) ? this.enforceTextDirWithUcc(null, idxHtml.escapeHTML( : idxHtml.escapeHTML(;


” + idxHtml.escapeHTML(this._messages.shortName) + “ “);
toolTip.push(has(“dojo-bidi”) ? this.enforceTextDirWithUcc(null, idxHtml.escapeHTML(item.shortName)) : idxHtml.escapeHTML(item.shortName));


“+idxHtml.escapeHTML(“emailAddress : “)+”“);

toolTip.push(has(“dojo-bidi”) ? this.enforceTextDirWithUcc(null, idxHtml.escapeHTML(item.emailAddress)) : idxHtml.escapeHTML(item.emailAddress));

“);“”), event.cellNode, [
], !this.isLeftToRight(), this.textDir);//38360 toolTip.push(has(“dojo-bidi”) ? this.enforceTextDirWithUcc(null, idxHtml.escapeHTML(item.displayName)) : idxHtml.escapeHTML(item.displayName));









Change Document Property to Text Area

It is common that the user requirement where changing some of the document fields to text areas,, I understand such still some time i could find successful way ,, With the help of friend and Sample plugin We achieve it easily as follows.

Thanks  goes to  :



You can retrieve  the sample plugin referring to following codes. Upload it  following the same procedure you followed to other plugin

Go the FEM or ACCE and locate the  property template you need to make it as Test area .Change the value of Maximum String Length to 500.After cache clearing  the text area will get appeared .

Iterate through Filenet Array Object 

When I started to work with multiple value document  properties , I had to assign them to array objects within workflow .To Retrieve value from them array need to be iterate,where I could not find a direct object in filenet to achieve this . I had to use the basic concept of Programming and implement items need to iterate as follows .




In here, I have performed  values of the NewSubCategoryAlignment  will be assigned to SubCategoryAlignment array. I have used  two integer type variables  NewSubCatAligmentloop (0) and NewSubCatAlignemtCount (NewSubCategoryAlignment   array element count ) which get there inital value @ Lunch Step.




Iteration Happen using two activity steps , where Increment activon will increase the value of the NewSubCatAligmentloop if the condition to exhit from the loop not satisfied.

NewSubCatAligmentloop = NewSubCatAligmentloop+1


Within the action activity step following actions will be triggered ,

SubCategoryAlignment[NewSubCatAlignemtCount+NewSubCatAligmentloop]  =NewSubCategoryAlignment[NewSubCatAligmentloop]

Route [1] condition will be to exist from the loop – NewSubCatAligmentloop > NewSubCatAlignemtCount

Route[2] condition to iterate trough the loop –  NewSubCatAligmentloop <= NewSubCatAlignemtCount