Mohammed Atef’s Technical blog

Reset ICM Case Information Widget default selected tab


Here, I am going to share with you how to change the default selected tab in Case Information Widget throw the Case Search or Case Details pages.

SelectTab event

First, you have to understand events required to modify selected tab in the Case Information Widget, Which is a Handled events named “Select tab” and requires payload of type SelectTab.

For more information about the payload type you can visit this link

Reset selected tab in Case Search page

I will assume that we are going to set Documents as default selected tab in Case Information Widget, so please follow below steps to do that:

  1. Drag Script Adapter into hidden area
  2. Select Script Adapter, Edit Settings
  3. Add the following line of code before the return command
  4.  payload.selectTabName="Documents";  
  5. Click Ok and Apply to Script Adapter editing settings
  6. Now configure script adapter wires as shown below


Reset selected tab in Case details page

Actually there is now big difference between resetting selected tab in case Information between Case Search and Case Details pages, except the configuration of Script Adapter wires.

So, to achieve this, we will follow all steps shown above except step no 6 and we will configure the Script Adapter wire as shown below



in the above post i tried to tie all information found in different locations in IBM links or forums to give you a complete solution, hope that helped.

June 9, 2013 Posted by | Developement, ECM, FileNet, IBM Case Manager | , , , , , , , , , , | Leave a comment

IBM Case Manager Custom search Widget


In this post I am going to share with you how to build your custom search widget to override and customize you case manager built in search widget.

use case

Here, we will implement custom search for customer management project.
actually, user will have list of checkboxes for customers, then he can select customers and click find customers and he will see the result into CaseList Widget, also he can see customer information and related documents in the Case Information Widget.

Create customer management solution

Actually, I will create new solution named customer management to have a complete tutorial about custom search widget, and since creating project is not our target for this post, so I will quickly write done steps to build this project.

  1. Login to case manager build, then select add solution
  2. Set solution name : customer management and the prefix cust
  3. Add two string properties named as follow (customer name, customer no)
  4. Create new role named admin role
  5. Create new case named relation management
  6. Select case properties from left menu > add properties > Existing > select all > ok all
  7. Go to views and add both customer name and no to all views ( case summery, case search , properties)
  8. Create new take named task1
  9. Design the new task follows


Build custom search project

let’s start building our custom search project, actually this project will have the following files

(web.xml, CustomSearch.js, CustomSearch.xml) , for more information about this files visit this link

Review CustomSearch.xml

Now, We’re going to take a look at CustomSearch.xml file

  • here we will see bulk of xml elements about events as shown below
   1: <iw:eventDescription id="receiveWorkItem" payloadType="WorkItem"    description="Event to receive work item" lang="en" />        
   2:     <iw:event id="receiveEvent" eventDescName="receiveWorkItem" handled="true" onEvent="onreceiveWorkItem" />
   3:     <iw:event id="Send Payload" published="true" eventDescName="SendPayload"/>
   4:     <iw:eventDescription id="SendPayload" payloadType="CaseSearch" description="search for projects" lang="en"/>

  • if you’re familiar with xml, you can understand this, here we have two eventdecription and other two events, you may notice that each event has a reference to the event description. i need just to focus in very important attribute here payload type which used to determine the recipient or sender event type.
  • in our post we are interested with sender event type ‘CaseSearch’, this payload is responsible to descript the case search object that will sent to CaseList widget and in same xml will and immediately after above code snippet, you will find casesearch payload definition as shown below
   1: <iw:payloadDef name="CaseSearch">
   2:     <iw:payloadDef name="CaseType" type="string" defaultValue="" description=""/>
   3:     <iw:payloadDef name="ObjectStore" type="string" defaultValue="" description=""/>
   4:     <iw:payloadDef name="SortingProperties" type="any" defaultValue=""  description=""/>
   5:     <iw:payloadDef name="SystemProperties" type="any" defaultValue="" description=""/>
   6:     <iw:payloadDef name="SummaryProperties" type="any" defaultValue="" description=""/>
   7:     <iw:payloadDef name="SearchProperties" type="any" defaultValue=""  description=""/>
   8:     <iw:payloadDef name="QuerySQL" type="string" defaultValue=""   description=""/>
   9: </iw:payloadDef>

  • the above payload definition has different sections to decrepit name and type of each object in our casesearch payload, it shows details about (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql)
  • finally we will see below mentioned code this line
    • <iw:resource src="CustomSearch.js"/> , which is used to reference to our JavaScript file resource that will deal with above events.
Review CustomSearch.js

here i am not going deeply because most of you are familiar with JavaScript, i will focus only in JavaScript functions and the JavaScript code that sends cases

arch payload to the event.

let’s see now the list of functions in this file

  1. RenderCustomersLst : it is used to render customer list found in json data object as checkboxes.
  2. SelectedProjLST : it is used to find out selected customers to send it to caselist for search
  3. Servletcall : actually it is not used but i build it, for future use if you have servlet that retrieve list of customers in the mention json format.
  4. onreceiveWorkItem : this is event implementation when our custom widget receive event of type workitem.

finally, lets see this line of code

   1: this.iContext.iEvents.fireEvent("Send Payload", "CaseSearch", payload);
  • it is using icontext to get our custom widget context and then fire event of type casesearch
  • above this line of code you will see a JavaScript object named data, which used to build the casesearch payload, here i have static json object that descript (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql) objects in the payload, later we will see how to get this static information.
  • but there is another dynamic value that i use it to modify the search query based on selected customers from the widget.

Now our project is ready, so you can go a head and export it as war then deploy and register it to Case Client, for more information about this topic visit this link .

Duplicate Cases Page

since we finished all development effort let’s move now to Case Client and do some customization.

first we have to create new page to use our new custom search widget there,so please follow below steps to do this.

  1. Manage Spaces > Customers Management > Actions (for cases) > Duplicate
  2. Actions (for cop of cases) > setting
  3. Rename it to be > Custom Search

Modify Custom search page

now we are going to modify our new page to use the new custom search widget, and this task has two phases, first to find our the casesearch payload to extract basic information about (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql) as mentioned above and then modify same page to finalize the custom search.

Prepare the search case payload

we can get the casesearch payload by following the below steps:

  1. Click Edit Page link
  2. Add script adapter to the page
  3. Wire script adapter as follows

    a. Add incoming wire to Search Widget > select search cases event name

    b. Add outgoing wire to case list > select search cases event name

  4. Use the built in search widget and apply search shown belowimage 
  5. Once result shown in case list, open the script adapter and take copy of its payload.
  6. Below list of json script should be found in payload object
  7.    1: {"CaseType":"","ObjectStore":"DTargetOS",
       2: "SortingProperties":[{"symbolicName":"cmis:lastModificationDate","type":"datetime","displayName":"Date Modified"},{"symbolicName":"cmis:lastModifiedBy","type":"string","displayName":"Modified By"}]
       3: ,"SystemProperties":[{"symbolicName":"p8ext:ClassDisplayName","type":"string","displayName":"Case Type"},{"symbolicName":"cmis:lastModifiedBy","type":"string","displayName":"Modified By"},{"symbolicName":"CmAcmCaseState","type":"string","displayName":"Case State"},{"symbolicName":"cmis:lastModificationDate","type":"datetime","displayName":"Date Modified"}]
       4: ,"SearchProperties":[{"symbolicName":"CUST_customername","displayName":"customer name","type":"string","orderable":true}],"SummaryProperties":[{"symbolicName":"CmAcmCaseIdentifier","displayName":"Case Identifier","type":"string","orderable":true},{"symbolicName":"CUST_customername","displayName":"customer name","type":"string","orderable":true},{"symbolicName":"CUST_customerno","displayName":"customer no","type":"string","orderable":true}],
       5: "QuerySQL":"SELECT cmis:objectId, cmis:objectTypeId, cmis:lastModifiedBy, CmAcmCaseState, cmis:lastModificationDate, CmAcmCaseIdentifier, CUST_customername, CUST_customerno FROM CmAcmCaseFolder WHERE CmAcmParentSolution = 'ido_40C02E31-7631-4C2E-9EB6-1E0D4676507F:idt_616EA2CB-2F81-4AE7-8E9E-A787A0B224AF:idx_A992C31D-31D8-41EE-8E65-4DC64608357D' AND CmAcmCaseState > 1 
       6: AND (CUST_customername LIKE 'cust%') "}

    Add customer list widget
    • Now we are going to delete the script adapter widget and before that make sure you have cleared all wire linked to it.
    • Then we will add our new custom widget by following below steps

                a. Click edit page link

                b. Select customer list widget as shown below


    • Drag it above case list widget as shown below


    • Drag the in basket widget to the hidden area beside the command widget as shown below


    • Configure in basket wires as shown below


    • Configure customer list widget as shown below


    Testing the widget

    • eventually we finished all tasks related to development, deployment, customization, wiring and our custom search widget is ready now for testing
    • i will assume that you have entered two customers using Case client with the following details

      1- customer name : customer 1    , customer number : 111

      2- customer name : customer 2    , customer number : 2

    • Click the refresh button into customer list widget
    • Then check customer 1 and customer 2
    • Click find customers , select customer 1
    • Now you should have result as shown below
    • image


    since we have ended this post let’s recap activities we went throw, we learned in this post customizing built in widget, configurations, and building new solutions and customizing pages and finally wiring widget with each others.

    Download source code

    you can find out the project war file and all other resources related to this post here , hope that helped.

    May 31, 2013 Posted by | Developement, ECM, FileNet, IBM Case Manager, XML,XSL,XSLT,DHTML,HML,CSS | , , , , , , , , , , , , , , | Leave a comment

    Build and register a IBM Case Manager custom Widget


    As a user interface developer for IBM Case Manager, you need to customize Case Manager Client by creating your custom Widgets. Here I am going to share with you basics for developing, deploying and registering Custom Widgets.
    Our use case for this post is creating custom widget to print hello world message.

    Application structure

    we know that each application should have known structure, Below table shows the application files structure.

    File or folder name Description
    HelloWorld Web project name and folder
    HelloWorld.xml Widget definition file
    Web.xml Configuration file

    Create a web project

    First, we have to create new project using Eclipse, so please follow this procedures to create a new web project

    1- Open Eclipse, Click File > New > Dynamic web project

    2- Follow the wizard to create project, but do not forget to set project name HelloWorld and to tick Generate web.xml deployment descriptor check box.

    3- Open Project Explorer pane, expand the HelloWorld node and expand the WebContent > WEB-INF folder, then Open the web.

    4- Add the following entry to include the BasicWidget.xml to the welcome file:
    <welcome-file> HelloWorld.xml</welcome-file>       , then save the file.
    5- Add new file with the following names HelloWorld.xml

    Modify Widget Definition file

    • Open the HellowWrold.xml file and add the following lines of codes, then save the file.
       1: <?xml version="1.0" encoding="UTF-8" ?>
       2: <iw:iwidget id="HelloWorld" xmlns:xsi=""
       3: xmlns:iw=""
       4: supportedModes="view edit" iScope=" HelloWorldScope">
       5: <iw:content mode="view">
       6: <![CDATA[ <h1>Hello World</h1> ]]>
       7: </iw:content>
       8: </iw:iwidget>

    • Above code is very clear but we need to highlight some attributes here
      • supportedModes: this attribute used to determine if users can view or edit the widget.
      • iScope: The iScope is a Dojo wrapper class for the Custom widget
      • iw:content: it is content area for the edit or view mode in your Widget.

    Create Catalog file

    • Create new xml file name it catalog_HelloWorld.xml and add the following list of code to it then save.
       1: <?xml version="1.0" encoding="UTF-8"?>
       2: <catalog id="Demo"> <resource-type>Catalog</resource-type>
       3: <category name="Demo">
       4:     <title> <nls-string lang="en">HelloWorld</nls-string></title>
       5:     <description> <nls-string lang="en">HelloWorld</nls-string>    </description>    
       6:     <entry id="iWidget.widgets.HelloWorld" unique-name="iWidget.widgets.HelloWorld">                <title> <nls-string lang="en">HelloWorld</nls-string> </title>
       7:         <description> <nls-string lang="en">HelloWorld</nls-string> </description>                <definition>endpoint://</definition>
       8: <preview>
       9: endpoint://
      10: </preview>
      11: <icon>endpoint://</icon>
      12: <previewThumbnail>endpoint://</previewThumbnail>            <help>endpoint://{}bspaceWidgetHelpRootId/topic/</help>
      13: <shortDescription> <nls-string lang="en">HelloWorld</nls-string></shortDescription>        <metadata name=""></metadata>            <metadata name="">International Business Machines Corp.</metadata>
      14: </entry></category></catalog>

    • now let’s talk a look at this file
      • entry ID: is the widget id for the business space and it should be unique
      • category name: used to add this widget to an exist category or and new category for the new widget if not exist.
      • Other attributes used for determine widget title, description, icons, images.

    Create End point file

    • It is the last file, we need to build end point file, actually it is very please create new xml file and name it HelloWorldEndPoint.xml and add the following lines of code there.
       1: <?xml version="1.0" encoding="UTF-8"?>
       2: <tns:BusinessSpaceRegistry xmlns:tns="" xmlns:xsi="" xsi:schemaLocation=" BusinessSpaceRegistry.xsd ">    <tns:Endpoint>    <tns:id></tns:id>    <tns:type></tns:type>
       3:     <tns:version></tns:version>
       4:     <tns:url>/HelloWorld/</tns:url>
       5:     <tns:description>Location of Hello World</tns:description>
       6:   </tns:Endpoint>    </tns:BusinessSpaceRegistry>

    Deploy and register the Widget

    We have finished all development effort and we are going forward to deploy and register the new widget to case manager client.

    However, we have can follow two options to do this, I will share with both of them now

    • First option: export project as war and register the catalog and endpoint xml files
    • Second option: export project as ear and zip it with the catalog and endpoint xml files
    Export project as war and register the catalog and endpoint files

    Here we are going to export the HelloWorld project as war file, let’s see procedures to do this

    1. Click File > export > war file
    2. select war file path for exporting and then finish
    3. Go to websphere and deploy the war file and keep the web application name HelloWorld
    4. Register the catalog file by following the below steps
      1. Open windows command and go to the web sphere bin folder
      2. Run the below commands
        1. wsadmin -user user1 -password pwd1 -lang jython
        2. AdminTask.updateBusinessSpaceWidgets(‘[-nodeName node1 -serverName server1

          -catalogs C:\HellowWolrd\catalog_ HellowWolrd.xml]’)
    5. Register the End point file by following the below steps
      1. Open windows command and go to the web sphere bin folder
      2. Run the below commands
        1. wsadmin -user user1 -password pwd1 -lang jython
        2. AdminTask.updateBusinessSpaceWidgets(‘[-nodeName node1 -serverName server1 –endpoints C:\HellowWolrd\HellowWolrdEndPoint.xml]’)
    Export project as ear and zip it with catalog and endpoint files

    Here we are going to export our project as ear file and without deploying it to Websphere, we will create one package and with couple of command lines we will deploy and register our widget.

    Let’s see how it goes here:

    1. 1- Open Eclipse and create new Enterprise application project
    2. 2- Select HelloWorld from Java EE module dependencies, then click finish
    3. 3- Click File > Export EAR , set the ear file name helloworld
    4. 4- Create folder named HelloWorld and copy the following files to it (HelloWorld.ear, catalog_HelloWorld.xml, HelloWorldEndpoints.xml)
    5. Zip the HelloWorld folder
    6. Open windows command and go to the web sphere bin folder
    7. Run the following commands
      1. wsadmin -user user1 -password pwd1 -lang jython
      2. AdminTask installBusinessSpaceWidgets {-serverName server1 -nodeName node1 -widgets C:\HellowWolrd\}

    Testing Widget

    Eventually, we have finished developing, deploying and registering the Hello World widget now you can open any page in your case client and click Edit page link then drag the hello world widget there.


    In this post I tried to share with you how to build and deploy IBM case manager widget and also to register it in two different ways, hope that helped.

    Now you can download all resources related to this post from here .

    May 31, 2013 Posted by | Developement, ECM, FileNet, IBM Case Manager, XML,XSL,XSLT,DHTML,HML,CSS | , , , , , , , , , , , , , | 8 Comments

    ICM Repeated DB Execute for any task steps


    In our real world we always found new needs that cannot done easily throw out-of-the-box tools. Currently I am using IBM Case Manager for delivering Automation solution, but I realized that our solution needs a custom database, during discussing with my technical colleagues, we came up with the following solution and now I am sharing this with you.

    Use case

    You are working in a new IBM Case Manager solution, and you have to log some case properties details in custom SQL Database for each and every step, you can do this regularly by calling stub step after each and every step, but this solution with complex your tasks design.
    I am going to share with you another solution to do same requirements with better and simple solution.


    Our solution is simply built on creating an automatic task (dbexec) that run with precondition based on case property value, this task actually used to run the DB Execute system step. Other task steps will set specific case property to trigger the dbexec task.


    Let go throw this solution in more details.

    Procedure 1: Create the solution, case and tasks

    1- Open Case Manager Builder from the browser, and login with valid user name and password.

    2- Create solution name loans, then create the following properties (Loan Name, tmpstepid) and create role named loan manager

    3- Create case named Loan DB Exec and modify the tmpstepid property to be hidden from properties, then add both properties to the case properties.

    4- Create new automatic tasks named Main Task , and another automatic tasks named dbexec but with condition and repeated as shown in the following pictures


    Procedure 2: Design tasks

    1- Open the main task designer and drag Role Lane then add three steps names (step1, step2, complete) to it.

    2- Assign the two case properties for each step, then draw the connectors between launch Step and other three steps as shown below


    3- Open dbexec designer and drag Role Lane then add step to it, after that add another stub step to the system Lane and draw connectors as follows


    Procedure 3: Prepare SQL table and procedure

    1- Here we are going to create the SQL table and stored procedure that needs to execute for each and every step in the Main Task2.

    2- Below SQL scripts shows how to create both of them:

       1: CREATE TABLE [dbo].[loans](
       2:     [stepid] [nchar](10) NULL,
       3:     [loanname] [nvarchar](50) NULL
       4: ) ON [PRIMARY]
       6: create PROCEDURE [dbo].[sp_addloan]
       7:         @loanname varchar(100) output
       8:     ,@stepid varchar(100) output    
       9: AS
      10: BEGIN
      11: insert into loans values(@loanname,@stepid)    
      12:     END
      13: GO

    Procedure 4: Modify the main task from Process Designer

    1- In Workplace XT, click Tools > Advanced tools > Process Designer.

    2- Click File > Solution > Edit > case_manager_design_object_store_name > IBM Case Manager > Solutions > Loans > Solution Definition

    3- Open the Main Task and Assign the tmpstepid property after or before execution for each step as follows


    3- task care you have to assign different value for each step to launch the DBexec task

    Procedure 5: Modify the DBexec from Process Designer

    1- Open the dbexec task in designer as shown in procedure 4, steps 1 & 2

    2- Configure the DBexecute step

    3- Select the Route between the Stub and Dummy step and modify it to be a conditional  Route the in the expression space enter the following line 1=2, as shown below:


    4- Yes you are right this condition will never happen and the task will ends after the Db execution.

    Procedure 6: Deploy and test the solution

    1- From Process Designer Check in the solution

    2- Open Case Manager Builder and deploy the solution

    3- Open Case Manager Client and create new case from Loan Db Exec

    4- Go throw step1, step2 and complete steps.

    5- Open the database and you will find three records in you custom table.


    In this post we have seen how to run repeated DB execute task for each step in other tasks. This solution may be used in other ways for different requirements for example you can use it to send email instead of executing DB. i hope that help.


    before ending this post i would like to thank Mr. ahmed Elwakeel my dear colleague who worked with me to implement this solution.

    March 1, 2013 Posted by | Uncategorized | , , , , , , , | 9 Comments

    Tips and tricks for IBM Case Manager V5.1.1


    After passing the initiation phase of developing and designing my first IBM case Manager project, i decided to share with you my experiences about this tools and give you some tips and trick about developing solutions using ICM.

    Tips & Tricks

    • Of course first tips comes to my mind here is to take care of using the Case Manager Builder “Reset Test Environment” button , because once you click it, it will remove deployed solutions and other data from the development target environment.
    • Using Case Manager Builder, Make sure you have determined all step responses before starting design the tasks because you can not delete these responses if you have used for connecting to other steps, you will face some errors saying this response is used.
    • If you need to edit or delete any response exists in tasks, after you have finished designing the task, you have to do this from Process designer.
    • Make sure you have clicked ok button after each and every action for creating step or connectors.
    • Also, make sure you Clicked the validate and save buttons every action in designing tasks steps.
    • If you used DB execute in any system step for Stub Step using SQL Stored Procedure, make sure that all parameters are output.
    • If you needs to set conditions in responses for your steps, you have to do that from Process Designer.
    • Make sure you did not register two Widgets with same ID on the Business Space, because this will raise an error in the Case Manager Client and clear all custom and built in Widgets from edit pages.
    • If you have widget wired to another one and you needs delete this widget , you have to delete the wires then the Widget.
    • If you need to assign properties created by Case Manager Builder you have to assign the variables with the following expression F_CaseFolder.[Propertyname], for example if you have property called loanname you have to set it as follows F_CaseFolder.LoanName=”loan1”
    • If you have Custom Validation of Task Step Data visit, you visit this link
    • If you need to Add IBM forms or FileNet EForm, please visit the following link
    • When you have custom page and you need to assign it for specific task step, you have to register this page to the solution from IBM Case Client then you can assign this page latter from Builder.
    • Use this JS line of code, DEFAULT_XHR_PREVENT_CACHE: true , to Disable Widget cashing.
    • To Customizing the IBM Case Manager Client to hide or show existing banner content visit this link .
    • To Change Manage role to search by username instead of Display name follow these step(open FileNet Enterprise Manager Administration Tool, right click then select properties, select directory configuration tab, then modify the AD, go to Users tab and finally update user display name attribute to samAccountName) .


    Actually this post not ended as i am still working in this project and i will update it as soon as i found something interesting to you, but can you share with me this activity and enrich this post with your comments about any new tips you noticed in working with ICM.

    February 16, 2013 Posted by | ECM, FileNet, IBM Case Manager | , , , , , | Leave a comment

    Create new FileNet document instance using image content of exist document instance Using FileNet Web Service


    I have wrote this post to tell you how to Create new FileNet document instance using image content of exist document instance Using FileNet Web Service. Really I have spent some hours to implement this solution and I want to share it with you to save your time.


    I will assume the following points so please, do not forget to follow these points for future use:

    1- The Web Service proxy named FNWSP8351.

    2- The main namespace named FileNetWS

    3- I will download the image from source document at the following path c:\Temp\Images\

    4- I have built new class to contain all FileNet configuration that named FNWSConfiguration and the below list of codes contain implementation of that class .

       1: Public Class FNWSConfiguration
       2:         Private Shared mWSUrl As String = CSCSettingReader.FNWSURL
       3:         Private Shared mUserName As String = CSCSettingReader.FNWSUserName
       4:         Private Shared mPassword As String = CSCSettingReader.FNWSPassword
       5:         Private Shared mObjectStore As String = CSCSettingReader.FNWSObjectStoreName
       6:         Public Shared ReadOnly Property WSUrl() As String
       7:             Get
       8:                 Return mWSUrl
       9:             End Get
      10:         End Property
      11:         Public Shared ReadOnly Property UserName() As String
      12:             Get
      13:                 Return mUserName
      14:             End Get
      15:         End Property
      16:         Public Shared ReadOnly Property Password() As String
      17:             Get
      18:                 Return mPassword
      19:             End Get
      20:         End Property
      21:         Public Shared ReadOnly Property ObjectStore() As String
      22:             Get
      23:                 Return mObjectStore
      24:             End Get
      25:         End Property
      26:     End Class


    The below list of code has complete implementation for Create new FileNet document instance using image content of exist document instance, I will explain the code after this code snippet.

       1: Imports System.Configuration.ConfigurationManager
       2: Imports System.IO
       3:     Public Class FNWSHelper
       4:         Public Property WSobjBinding() As FNWSP8351.FNCEWS35ServiceWse
       5:             Get
       6:                 Return mWSobjBinding
       7:             End Get
       8:             Set(ByVal value As FNWSP8351.FNCEWS35ServiceWse)
       9:                 mWSobjBinding = value
      10:             End Set
      11:         End Property
      12:         Sub New()
      13:             mWSobjBinding = LoginFNWS()
      14:         End Sub
      16:         Private Function LoginFNWS() As FNWSP8351.FNCEWS35ServiceWse
      17:             Try
      18:                 ' Get the WS binding object and extract the WSE SoapContext for it
      19:                 '    (this will be used to add an attachment, and to set WS-Security parameters)
      20:                 Dim objBinding As FNWSP8351.FNCEWS35ServiceWse = New FNWSP8351.FNCEWS35ServiceWse
      21:                 Dim objCtx As Microsoft.Web.Services2.SoapContext
      22:                 objCtx = objBinding.RequestSoapContext ' Create a ChangeRequest and populate it
      25:                 ' Fill in the security headers...
      26:                 Dim strUser As String = FNWSConfiguration.UserName
      27:                 Dim tok As Microsoft.Web.Services2.Security.Tokens.UsernameToken
      29:                 tok = New Microsoft.Web.Services2.Security.Tokens.UsernameToken(strUser, FNWSConfiguration.Password, _
      30:                                 Microsoft.Web.Services2.Security.Tokens.PasswordOption.SendPlainText)
      31:                 objCtx.Security.Tokens.Add(tok)
      32:                 objBinding.Url = FNWSConfiguration.WSUrl
      33:                 Return objBinding
      34:             Catch ex As Exception
      35:             End Try
      37:         End Function
      38:         Public Function AddDocument(ByVal ID As String) As Boolean
      39:             Try
      40:                 Dim docpropcount As Integer = 2
      41:                 ' Create a ChangeRequest and populate it
      42:                 Dim objChangeRequest As FNWSP8351.ChangeRequestType = New FNWSP8351.ChangeRequestType
      43:                 objChangeRequest.Action = New FNWSP8351.ActionType(2) {}
      45:                 PrepareDocumentObj(objChangeRequest, dr("DocClassName"))
      47:                 ' Build a list of properties to set in the new document 
      48:                 objChangeRequest.ActionProperties = PrepareDocumentProperties(docpropcount, dr)
      49:                 'attach doc
      50:                 If Not IsImageExist(ID + ".tif") Then
      51:                     GetDocumentContentByID(ID)
      52:                 End If
      53:                 AttachDocumentContent(objChangeRequest.ActionProperties, objChangeRequest, ID + ".tif")
      55:                 PrepareExcludedProperties(objChangeRequest)
      58:                 Dim objResponseArray() As FNWSP8351.ChangeResponseType
      59:                 objResponseArray = New FNWSP8351.ChangeResponseType() {}
      61:                 objResponseArray = WSobjBinding.ExecuteChanges(FinalizeRequest(objChangeRequest))
      62:                 Return True
      63:             Catch ex As Exception
      65:                 Return False
      66:             End Try
      68:         End Function
      70:         Private Sub PrepareDocumentObj(ByVal objChangeRequest As FNWSP8351.ChangeRequestType, ByVal docclassname As String)
      71:             Try
      72:                 Dim CreateVerb As FNWSP8351.CreateAction = New FNWSP8351.CreateAction
      73:                 CreateVerb.classId = docclassname
      75:                 Dim chkin As New FNWSP8351.CheckinAction
      76:                 chkin.checkinMinorVersion = False
      77:                 chkin.checkinMinorVersionSpecified = False
      78:                 objChangeRequest.Action(0) = CreateVerb
      79:                 objChangeRequest.Action(1) = CType(chkin, FNWSP8351.ActionType)
      80:                 CType(chkin, FNWSP8351.CheckinAction).checkinMinorVersion = False
      81:                 CType(chkin, FNWSP8351.CheckinAction).checkinMinorVersionSpecified = False
      82:                 objChangeRequest.TargetSpecification = New FNWSP8351.ObjectReference
      83:                 objChangeRequest.TargetSpecification.classId = "ObjectStore"
      84:                 objChangeRequest.TargetSpecification.objectId = FNWSConfiguration.ObjectStore
      85:        = "1"
      86:             Catch ex As Exception
      88:             End Try
      90:         End Sub
      92:         Private Function PrepareDocumentProperties(ByVal docpropcount As Integer, ByVal dr As DataRow) As FNWSP8351.ModifiablePropertyType()
      93:             Try
      94:                 Dim objInputProps As FNWSP8351.ModifiablePropertyType()
      95:                 objInputProps = New FNWSP8351.ModifiablePropertyType(docpropcount) {}
      97:                 objInputProps(0) = GetDocPropertyObject(subjectcodesymbolicname, "Subject")
      98:                 Return objInputProps
      99:             Catch ex As Exception
     101:             End Try
     103:         End Function
     106:         Private Function GetDocPropertyObject(ByVal symbolicname As String, ByVal propval As Object)
     107:             Dim Propobj
     108:             Select Case symbolicname
     109:                 Case "Subject"
     110:                     Propobj = New FNWSP8351.SingletonString
     111:             End Select
     112:             Propobj.Value = propval
     113:             Propobj.propertyId = symbolicname
     114:             Return Propobj
     115:         End Function
     117:         Private Function GetDocumentContentByID(ByVal docid As String)
     118:             'prepare document object
     119:             Dim objSpec As FNWSP8351.ObjectSpecification = New FNWSP8351.ObjectSpecification
     120:             objSpec.objectId = docid
     121:             Dim objRequest As FNWSP8351.ObjectRequestType = New FNWSP8351.ObjectRequestType
     122:             objSpec.classId = "Document"
     123:             objSpec.objectStore = FNWSConfiguration.ObjectStore
     124:             objRequest.SourceSpecification = objSpec
     125:    = "1"
     127:             'prepare request properties
     128:             Dim incProps() As FNWSP8351.FilterElementType
     129:             objRequest.PropertyFilter = New FNWSP8351.PropertyFilterType
     132:             ' Ask for the content properties...
     133:             Dim maxSize As UInt64 = Convert.ToUInt64(1000000)
     135:             incProps = New FNWSP8351.FilterElementType(4) {}
     136:             incProps(0) = New FNWSP8351.FilterElementType
     137:             incProps(0).Value = "ContentElements"
     138:             incProps(1) = New FNWSP8351.FilterElementType
     139:             incProps(1).Value = "ContentData"
     140:             incProps(1).maxSize = maxSize
     141:             incProps(1).maxSizeSpecified = True
     142:             incProps(2) = New FNWSP8351.FilterElementType
     143:             incProps(2).Value = "Content"
     144:             incProps(3) = New FNWSP8351.FilterElementType
     145:             incProps(3).Value = "DocumentTitle"
     146:             incProps(4) = New FNWSP8351.FilterElementType
     147:             incProps(4).Value = "ContentType"
     149:             objRequest.PropertyFilter.IncludeProperties = incProps
     150:             objRequest.PropertyFilter.maxRecursion = 1
     151:             objRequest.PropertyFilter.maxRecursionSpecified = True
     153:             ' Create the request array
     154:             Dim objRequestArray() As FNWSP8351.ObjectRequestType = New FNWSP8351.ObjectRequestType(1) {}
     155:             objRequestArray(0) = objRequest
     157:             ' Fill in the security headers...
     158:             Dim objDimeBinding As FNWSP8351.FNCEWS35ServiceWse = New FNWSP8351.FNCEWS35ServiceWse
     159:             Dim objCtx As Microsoft.Web.Services2.SoapContext = objDimeBinding.RequestSoapContext
     160:             Dim strUser As String = FNWSConfiguration.UserName
     161:             Dim tok As Microsoft.Web.Services2.Security.Tokens.UsernameToken
     162:             tok = New Microsoft.Web.Services2.Security.Tokens.UsernameToken(strUser, _
     163:                         FNWSConfiguration.Password, _
     164:                         Microsoft.Web.Services2.Security.Tokens.PasswordOption.SendPlainText)
     165:             objCtx.Security.Tokens.Add(tok)
     166:             objDimeBinding.Url = FNWSConfiguration.WSUrl
     168:             ' Send off the request
     169:             Dim objResponseArray() As FNWSP8351.ObjectResponseType
     170:             objResponseArray = New FNWSP8351.ObjectResponseType() {}
     171:             Try
     172:                 objResponseArray = objDimeBinding.GetObjects(objRequestArray)
     173:             Catch Ex As Exception
     174:                 Exit Function
     175:             End Try
     178:             If objResponseArray(0).GetType().FullName.Contains("ErrorStackResponse") Then
     179:                 Dim objErrResp As FNWSP8351.ErrorStackResponse = objResponseArray(0)
     180:                 Dim objStack As FNWSP8351.ErrorStackType = objErrResp.ErrorStack
     181:                 Dim objErr As FNWSP8351.ErrorRecordType = objStack.ErrorRecord(0)
     183:                 Exit Function
     184:             End If
     186:             ' Extract the document object from the response
     187:             Dim objDoc As FNWSP8351.ObjectValue
     188:             If objResponseArray(0).GetType().FullName.Contains("SingleObjectResponse") Then
     189:                 Dim objSingleObjResponse As FNWSP8351.SingleObjectResponse = objResponseArray(0)
     190:                 objDoc = objSingleObjResponse.Object
     191:             ElseIf objResponseArray(0).GetType().FullName.Contains("ObjectSetResponse") Then
     192:                 Dim objSetResponse As FNWSP8351.ObjectSetResponse = objResponseArray(0)
     193:                 Dim objSet As FNWSP8351.ObjectSetType = objSetResponse.ObjectSet
     194:                 objDoc = objSet.Object(0)
     195:             Else
     196:                 Exit Function
     197:             End If
     199:             Dim objResponseContext As Microsoft.Web.Services2.SoapContext = objDimeBinding.ResponseSoapContext
     200:             If (Not (objResponseContext Is Nothing)) And (Not (objResponseContext.Attachments Is Nothing)) Then
     201:                 Dim att As Microsoft.Web.Services2.Attachments.Attachment
     202:                 Dim len As Integer
     203:                 Dim nItem As Integer = 0
     204:                 Dim byteContent() As Byte
     205:                 For Each att In objResponseContext.Attachments
     206:                     Dim objStream As System.IO.Stream = att.Stream
     207:                     byteContent = New Byte(objStream.Length) {}
     208:                     len = objStream.Read(byteContent, 0, objStream.Length)
     210:                     ' Write it out to a file
     211:                     Dim now As System.DateTime = System.DateTime.Now
     212:                     Dim strFileName As String = "C:\Temp\Images\" + docid + ".tif"
     213:                     saveContentToFile(strFileName, byteContent)
     214:                     nItem = nItem + 1
     215:                 Next
     216:             End If
     218:         End Function
     220:         Private Sub saveContentToFile(ByVal strFileName As String, ByVal binaryData() As Byte)
     221:             Try
     222:                 Dim outFile As System.IO.FileStream = New System.IO.FileStream(strFileName, _
     223:                         System.IO.FileMode.CreateNew, _
     224:                         System.IO.FileAccess.Write)
     225:                 outFile.Write(binaryData, 0, binaryData.Length)
     226:                 outFile.Close()
     227:             Catch Exp As Exception
     228:                 MessageBox.Show("Saving content failed: [" + Exp.Message + "]")
     229:             End Try
     230:         End Sub
     233:         Private Function GetFileName(ByVal filepath As String)
     234:             Dim indx As Integer = filepath.LastIndexOf("\")
     235:             Return filepath.Substring(indx + 1)
     236:         End Function
     237:         Private Sub AttachDocumentContent(ByVal objInputProps As FNWSP8351.ModifiablePropertyType(), ByRef objChangeRequest As FNWSP8351.ChangeRequestType, ByVal imgpath As String)
     238:             Try
     239:                 Dim ulContentSize As Integer
     240:                 Dim inFile As System.IO.FileStream
     241:                 Dim strContentLocation As String = "c:\Temp\Images\" + imgpath
     242:                 ' Create the content element list and set it into the document's properties
     243:                 Dim contentObjects() As FNWSP8351.DependentObjectType
     244:                 contentObjects = New FNWSP8351.DependentObjectType(1) {}
     245:                 Dim objContentList As FNWSP8351.ListOfObject = New FNWSP8351.ListOfObject
     246:                 objContentList.propertyId = "ContentElements"
     247:                 objContentList.Value = contentObjects
     248:                 objInputProps(5) = objContentList
     250:                 Dim ctProps() As FNWSP8351.PropertyType
     251:                 ctProps = New FNWSP8351.PropertyType(3) {}
     253:                 ' Set the ContentType property
     254:                 Dim typeProp As FNWSP8351.SingletonString = New FNWSP8351.SingletonString
     255:                 typeProp.propertyId = "ContentType"
     256:                 typeProp.Value = GetAttachmentFileType(strContentLocation)
     257:                 ctProps(0) = typeProp
     259:                 ' Create the dependent object type object
     260:                 Dim ct As FNWSP8351.DependentObjectType = New FNWSP8351.DependentObjectType
     261:                 ct.dependentAction = FNWSP8351.DependentObjectTypeDependentAction.Insert
     262:                 ct.dependentActionSpecified = True
     265:                 Dim nameProp As FNWSP8351.SingletonString = New FNWSP8351.SingletonString
     266:                 nameProp.propertyId = "RetrievalName"
     267:                 nameProp.Value = imgpath
     268:                 ctProps(1) = nameProp
     269:                 ' create content type object
     270:                 Dim contType As FNWSP8351.DIMEContent = New FNWSP8351.DIMEContent
     271:                 contType.size.Parse(ulContentSize.ToString())
     273:                 ' Add an attachment (uses the DIME binding)
     274:                 Try
     275:                     Dim att As Microsoft.Web.Services2.Dime.DimeAttachment
     276:                     inFile = New System.IO.FileStream(strContentLocation, _
     277:                         System.IO.FileMode.Open, _
     278:                         System.IO.FileAccess.Read)
     280:                     att = New Microsoft.Web.Services2.Dime.DimeAttachment(GetAttachmentFileType(strContentLocation), _
     281:                                     Microsoft.Web.Services2.Dime.TypeFormat.MediaType, _
     282:                                     inFile)
     283:                     att.Id = "attachment1"
     284:                     contType.Attachment = New FNWSP8351.DIMEAttachmentReference
     285:                     contType.Attachment.location = "attachment1"
     286:                     Dim objCtx As Microsoft.Web.Services2.SoapContext
     287:                     objCtx = WSobjBinding.RequestSoapContext
     288:                     objCtx.Attachments.Add(att)
     289:                 Catch Ex As Exception
     290:                     Throw New System.Exception(Ex.Message, Ex)
     291:                 End Try
     294:                 ' create content data object
     295:                 Dim contData As FNWSP8351.ContentData = New FNWSP8351.ContentData
     296:                 contData.propertyId = "Content"
     297:                 contData.Value = contType
     298:                 ctProps(2) = contData
     300:                 ' Dependent object is of type ContentTransfer
     301:                 ct.classId = "ContentTransfer"
     302:                 ct.Property = ctProps
     303:                 contentObjects(0) = ct
     305:                 objChangeRequest.ActionProperties = objInputProps
     307:             Catch ex As Exception
     309:             End Try
     312:         End Sub
     314:         Private Function GetAttachmentFileType(ByVal filepath As String)
     315:             If filepath.ToLower.Contains(".jpeg") Or filepath.ToLower.Contains(".jpeg") Then
     316:                 Return "image/jpeg"
     317:             ElseIf filepath.ToLower.Contains(".tif") Or filepath.ToLower.Contains(".tiff") Then
     318:                 Return "image/tiff"
     319:             ElseIf filepath.ToLower.Contains(".txt") Then
     320:                 Return "text/txt"
     321:             End If
     322:             Return "image/jpeg"
     323:         End Function
     326:         Private Sub PrepareExcludedProperties(ByRef objChangeRequest As FNWSP8351.ChangeRequestType)
     327:             ' Build a list of properties to exclude on the refreshed doc object that is returned
     328:             Dim strExclude() As String = New String(2) {}
     329:             strExclude(0) = "DateCreated"
     330:             strExclude(1) = "DateLastModified"
     331:             objChangeRequest.RefreshFilter = New FNWSP8351.PropertyFilterType
     332:             objChangeRequest.RefreshFilter.ExcludeProperties = strExclude
     333:         End Sub
     334:         Private Function IsImageExist(ByVal docimage As String) As Boolean
     335:             Dim dir As New DirectoryInfo("C:\Temp\Images")
     336:             If dir.GetFiles.Length > 0 Then
     337:                 For Each mfile As FileInfo In dir.GetFiles
     338:                     If mfile.Name = docimage Then
     339:                         Return True
     340:                     End If
     341:                 Next
     342:             End If
     343:             Return False
     345:         End Function
     346:         Private Function FinalizeRequest(ByVal objChangeRequest As FNWSP8351.ChangeRequestType) As FNWSP8351.ExecuteChangesRequest
     347:             Dim objRequest As FNWSP8351.ExecuteChangesRequest = New FNWSP8351.ExecuteChangesRequest
     348:             objRequest.ChangeRequest = New FNWSP8351.ChangeRequestType(1) {}
     349:             objRequest.ChangeRequest(0) = objChangeRequest
     350:             objRequest.refresh = True
     351:             objRequest.refreshSpecified = True
     352:             Return objRequest
     354:         End Function
     355:     End Class

    Now let’s go deeply in the FNWShelper class, note I will give you high level of understanding and I am not going to explain this class line by line.

    • Lines 4 to 11 we create property of the web service extension for reusing it in other places.
    • Lines 12 to 14 we create the class constructor and calling the LoginFNWS function .
    • Lines 16 to 37 we create the web service extension UserNameToken for preparing login to the FileNet web service.
    • Lines 38 to 68 we commit the new document to filenet with image found in the document that has ID passed to that method, now let’s see this AddDocument function in more details.
    • Lines 40 to 43 is used for creating a ChangeRequest instance and set the Action Property with new list of two ActionType items.
    • Line 45 is calling preparedocumentobj which implemented between lines  70 an 90 at this method we create two ActionType instance one of CreateAction and another one of CheckInAction for check in the committed document at FileNet, while lines 78 to 85 are preparing the ChangeRequestType instance.
    • Go back to the adddocument method and see line 48 that used for building the list of properties to be saved in the new document, this line of code calls method named preparedocumentpreopties that implemented between lines 92 and 103 and it just creates instance of ModifiablePreopertyType list of specific length and assign only one property called subject.
    • Again back to adddocument method and see line 50,51 and 52 that check if the images folder has image named “dociid.tif” where document ID is the value of document ID passed to this method, If the image found the If statement will be escaped else it will call getdocumentcontentbyid method that will be explained in more details now.
    • Lines 117 to 218 we implement method getdocumentbyid that used for saving document image content that has ID passed throw this method to images folder that defined in assumption section.
    • Again back to adddocument method and see line no 53 that used to call method named AttachDocumentContent that take the ChangeRequestType instance and the new image path as parameter to attach the passed image to the new document this method is implemented at lines 273 to 312.
    • After calling the attachdocumentcontent method in the adddocument method build the excluded list properties for the new document with the same way we define the ModifiablePropertyType list.
    • Finally  adddocument method submit the request to FileNet at lines 58 to 61 by using filenet web service method called ExecuteChanges.

    I understand that implementation is very big and all lines of code note explained in details but I was trying to save your time for searching and implementing this solution and also I was trying to give you quick help and summary about this implementation.

    For testing and using this code write the following two line of code

       1: dim mFNWSHelper as new FNWSHelper
       2: mFNWSHelper.AddDocument("docid")'where docid is the id of the document that you want to copy it image content to the new created document

    I hope that was helpful………………….

    September 18, 2010 Posted by | FileNet | , , | 2 Comments