Monday 30 December 2013

Time to give up coding: way to XCP Designer

Are you tired of doing wdk customizations?

Don't like coding?

WDK,DFC,BOF,Workflow, TBO, SBO, Jobs...hmmm..too much of coding :( Is there any way to get out of this? 

I will say yes... :) Now EMC has come up with the tool where you hardly need to do any customization or coding..until unless you want to do something which xcp designer doesn't support.

I have moved to XCP now :)....Soon I will share my experiences working on XCP Designer :)

Stay Tuned!!!

Tuesday 29 October 2013

Captiva Dispatcher- Document Classification

Dispatcher is a very strong tool used for document classification.        
     
  • Classify/Identify document type  à  to route the document to the correct workflow 
  • Index images  à  to deliver images to the correct repository
  • Extract business data  à  to manage transactional information
  • Validate information  à  to control your process
Capture--->Classify--->Data Extract---> Data validation--->Document Export


Classification technologies: There are 5 technologies which can be used for different types of documents classification. You can use any one or combination of some of them.

Type/ No
Global Image Analysis(Automatic Template Creation)
Local Image Analysis(HPA-High Precision Anchors)
Keyword Analysis
Text Matching Analysis
Handwritten Detection
1
Used when large number of documents present for classification. Document language independent. Categorizes documents based on similarities ,Like document structure. Automatic learning and builds a dynamic knowledge base
Here sample document is provided with anchors marked on places like header, document name etc.  It can be used along with Global Image Analysis to sub group classified documents.
Keyword match is used to classify document. It’s irrespective of any specific area. i.e full text search done on the document.
Useful when documents have different layouts but same text/data.
Used for handwritten documents
2
It works on ‘Fuzzy Logic’ algorithm
High precision anchor concept
Regular expressions used for search text pattern
Full text OCR used to extract information.
Uses Fuzzy Logic for document processing and learining.
3
Structured(Forms) /semi structured documents(Bank Cheques)
Structured /semi structured documents
semi structured /Unstructured documents
Unstructured document classification
Unstructured document classification(Patient Records)


Monday 28 October 2013

Workflow error notifications

Objects involved in workflow
Build Time:
·         dm_process
·         dm_activity
Runtime:
·         dm_workflow- Runtime workflow object created from dm_process workflow template.
·         dmi_workitem- Runtime instances created for each workflow activity.
·         dmi_queue_item- Information about tasks for a aspecific user. If for particular activity, User A is assigned performer or in a group of performer then dmi_queue_item object will be created for the same. All inbox items we see in user’s inbox are dmi_queue_items.
·         dmi_package- This is the object which gives information about the documents attached in the workflow.
Now let’s discuss about the possible errors that can come while running a workflow.
If you have workflow notifications on, you will get a mail notification  if there is any error while processing a aworkitem.
dm_changedactivityinstancestate:-  
In docbase "ABC":

User "superuser" posted event "dm_changedactivityinstancestate" with this message:  "Activity instance, 0, of workflow, 4a012a53802ssscc, failed.".

If any error comes(Timeout error/ code error in auto activity method) workitem is put into paused state. Not while processing workitem if it’s in paused state, such workitem could not be completed and can throw above error.
Possible causes:
ü  Check the timeout value set for respective workflow auto activity.
ü  Check the content server settings. Sometimes it happens because of multiple content servers trying to process same workitem.
dm_wf_resolve_failure:-
In docbase "ABC":

User "xyz" posted event "dm_wf_resolve_failure" with this message:  "An error was encountered in a workflow for which you are the supervisor.  The system was unable to find a performer for 'Group_processor'.  This task has been assigned to you.".
If for an activity particular Group(Group_Processor)has been assigned and if no user is present in  that particular group when workitem is in progress, above error will be thrown. As no user is found the error notification will be sent to workflow supervisor.

Possible causes:
ü  Check the error group if any user is added in it or not.
ü  Check the activity performer configuration. The configuration options are like, select all users from a group/ select any single user from a group of performers.
There are n number of such workflow events. All are not error related. So no need to panic if you receive notification with event name like “dm_startedworkitem”
All such events are listed in dm_event_sender.ebs file. Check the event names associated with routers/ tasks.  The dm_event_sender.ebs file is placed at path ../Documentum/product/6.7/bin
Below is the list of such events for your reference J
dm_startedworkitem
dm_selectedworkitem
dm_completedworkitem
dm_delegatedworkitem
dm_terminateworkflow
dm_changeworkflowsupervisor
Enough spoon feeding done now. Login to your content server and check at the above path for rest of the names J
Happy Learing!!! J


Monday 21 October 2013

Extends Vs Modifies in WDK customizations

While doing wdk customizations many of us get confused with 2 terms “modifies” and “extends”
Similarity: Both the keywords can be used if you want to change the existing component.

Now let me take an example to explain what is the difference between both.

The following example shows the effect of deleting an element from a component configuration that
has been extended.

In my webtop WDK component definition defines a component  “component1” as below

<component id="component1">
<test>
<a>aaa</a>
<b>bbb</b>
</test>
</component>

Now Webtop layer component “component2”  extends this definition as follows:

<component id="component2" extends="component1:wdk/config/component1.xml">
...</component>

In my custom component I don’t want to have configuration element  <test> <a> aaa </a>.. So my custom configuration removes this using modifies keyword,

Note: You have to modify the component where the original definition for  <test> <a> aaa </a>..  configuration added i.e wdk layer and not the webtop layer definition.

<component modifies="component1:wdk/config/component1.xml">
<remove path="test.a"/></component>

This removes the element <a> from your component. If some other application extends the Webtop

component2, it will not be affected by your modification.

Documentum Search Customization

In many of our documentum projects we need to customize the search/ advanced search component. I am not going to explain you how to do this as I have found a very good document which may solve your requirement.
Check out below link and you may be lucky enough to get ready made answer J

Common requirements can be:
Customize advanced search component to
Add types
Change panel visibility
Add the date range to search documents
All above changes can be done using xml changes. Just check for respective attributes in xml file /webcomponent/config/library/search/advsearch_component.xml

Normal search is defined in component /webtop/config/search_component.xml

Main components in search functionality :
Search60.java
AdvSearchEx.java
Search60_component.xml
Search_component.xml
Advsearch_component.xml

Call a method from your WDK component

If you want to handle some business logic asynchronously, the best way can be implement a method. Here is a code snippet which explains how you can call a java method from your wdk code.

In below code we are creating a workflow object.




private void executeMethodCall() {

            try {
                 
                  IDfSession dfSession=getDfSession();
                  StringBuffer strBufQry = new StringBuffer();
                  strBufQry.append("Execute do_method WITH  METHOD='NewMethod',");
                  strBufQry.append(" arguments='-workflowName ");
                  strBufQry.append(m_strWorkflow);
                  strBufQry.append(" -docId ");
                  strBufQry.append(m_strObjectId);
                  strBufQry.append(" -docbase ");
                  strBufQry.append(dfSession.getDocbaseName());
                  strBufQry.append(" -user_name ");
                  strBufQry.append(dfSession.getServerConfig().getString(                       "r_install_owner"));
                  strBufQry.append(" -workItemId ");
                  strBufQry.append(m_strWorkItemId);
                  strBufQry.append("'");
                  IDfQuery dfQuery = new DfQuery();
                  dfQuery.setDQL(strBufQry.toString());
                  dfQuery.execute(getDfSession(), IDfQuery.DF_EXEC_QUERY);

                  MessageService.addMessage(this, "MSG_DOCUMENT_SENT");
            } catch (DfException e) {
                  e.printStackTrace();
            }

      }

Thursday 17 October 2013

Documentum Lifecycle Simplified!!!!!!!

States:     Normal State
            Exception state
Definition for State:
1.      General:  
·         Name-Name of the lifecycle
·         Primary Type- Document type on which the lifecycle is being applied.(Here you can select subtypes of your own choice if needed)
·         Implementation Type- Java/Docbasic
·         Alias sets- You can add alias sets here if they are generic for the state.
2.     Overview:
·         Name- Name of the state
·         General Setting-  Select the checkboxes as per your need(i.e allow demotion to previous state, allow scheduled transitions from the state etc.)
·         Document Demotion Setting- setting if demotion is allowed for the state.
3.     Entry Criteria:
·         State Entry Criteria- Entry criteria based on attribute values
·         Procedure- Procedure if any custom logic is being used for entry criteria.

4.     Actions:       Actions to be taken on the document.
·         Actions- Using this option you can set the new version label for the document or remove old version label, set new location path for the document, set new permission set.
·         Procedure-  Procedure attached with the state to handle business logic.

5.     Post Change:
·         Procedure- Procedure attached with the state to handle business logic.

Lifecycle Related Methods/Operations:
·         doPromote
·         doDemote
·         doSuspend
·         doResume
Object types:
·         dm_policy: Lifecycle object
·         dm_procedure: Type for lifecycle procedures
·         dm_method: type for lifecycle methods

Monday 14 October 2013

Why to use Java Method Server?

There are 3 execution agets available:
1)      Dmbasic method server:- Can be used for dmbasic methods.
2)      Java method server:- Can be used for java methods.
3)      Documentum content server:- Default execution agent
Documentum content server can launch any executable program i.e. dmbasic, java, dmawk or any standalone program written in C,C++.

Then what is the use of having separate method server?
·         Method server is the customized version of Apache Tomcat which can be used for execution of Documentum java methods. So methods are run as servlets under application container.
·         So we can invoke multiple instances of a same method without spawning multiple instances of JVM process.
·         This provides performance benefit as well as saves memory.
·         JMS runs as a separate process independent of content server so it can be start-stopped as and when needed.

Tips: Not to use same JMS tomcat container to deploy wdk applications as it’s a customized one and many features have been eliminated.

How to write a Java method:
        I.            Implement IDmMethod interface.
      II.            Implement method execute(Map params, OutputStream ostream). Here Map contains arguments like repository name, login user name, workitem if you are creation workflow method etc.
    III.            Obtain session using newSessionManager.
    IV.            Handle exceptions.
      V.            Release sessions and collections used.

How to check if Method server is running?

http://<hostname>:9080/DmMethods/servlet/DoMethod

Friday 11 October 2013

Trigger Workflow Programmatically

// Get workflow process Name

IDfId processId = (IDfId) docObj.getSession().getIdByQualification("dm_process where object_name = '" + wfName + "'");

// Create workflowbuilder object and run the workflow

IDfWorkflowBuilder wfBuildObj = docObj.getSession().newWorkflowBuilder(processId);
                wfBuildObj.initWorkflow();
                wfBuildObj.runWorkflow();

// Add package to the workflow.

IDfList attachmentIds = new DfList();
            attachmentIds.appendId(docObj.getObjectId());

            IDfList startActIds = wfBuildObj.getStartActivityIds();
            IDfList startActName = wfBuildObj.getStartActivityNames();

            for (int i = 0; i < startActIds.getCount(); i++) {
                IDfActivity act = (IDfActivity) docObj.getSession().getObject((IDfId) startActIds.getId(i));

                int pkgCount = act.getPackageCount();
                for (int k = 0; k < pkgCount; k++) {
                    if (act.getPortType(k).equals("INPUT")) {
                        String activityName = (String) startActName.get(i);
                        String portName = act.getPortName(k);
                        String packageName = act.getPackageName(k);
                        String packageType = act.getPackageType(k);

                        if (docObj.getTypeName().equals(packageType) || docObj.getType().isSubTypeOf(packageType)) {
                                wfBuildObj.addPackage(activityName, portName, packageName, packageType, "", false,
                                    attachmentIds);
                        } else {
                                wfBuildObj.addPackage(activityName, portName, packageName, packageType, "", false, null);
                        }
                    }
                }

            }

Monday 30 September 2013

DQL to create and run documentum job

create dm_method object set object_name='UtilityMethod', set run_as_server=1, set use_method_server=1, set method_type='java', set method_verb='com.myproj.methods.MethodUtility';


create dm_job object set object_name='UtilityJob', set method_name='UtilityMethod', set method_arguments='-folder_path /ABC/folder1/folder2', set start_date=date(now), set expiration_date=date('27/07/2014','dd/mm/yyyy'), set run_interval=1, set run_mode=2, set pass_standard_Arguments=1

----------------------------------------------------------------
To run a job you can use DA administration/job management/jobs.
or
execue the method directly using DQL query as below.

EXECUTE do_method WITH method = 'UtilityMethod', arguments = '-user_name dmadmin -docbase_name Repository_name -folder_path /ABC/folder1/folder2';

Pass custom arguments in your job

If you want to pass custom arguments along with default one, you should write a code to fetch them manually.

In below piece of code we are passing -folder_path "/Cabinet/Folder1/Folder2" as custom argument.

-------------------------------------------------------------------------------------------
public class TestJobMethod implements IDmMethod{
                public void execute(Map arg0, OutputStream arg1) throws Exception {
      
        IDfSession session = getSession(arg0);
        IDfSysObject oIDfJob = null;
        oIDfJob = (IDfSysObject)session.getObject(new DfId("job id"));
        for (int i = 0; i < oIDfJob.getValueCount("method_arguments"); i++) {  
            String strArgument = oIDfJob.getRepeatingString("method_arguments", i);  
            if (strArgument.indexOf(" ") > 0) {  
                String strKey = strArgument.substring(0, strArgument.indexOf(" ")).trim();  
                String strValue = strArgument.substring(strArgument.indexOf(" ") + 1).trim();  
          
                if (strKey.equalsIgnoreCase("-folder_path")) {  
                                 DfLogger.warn(this, "Key: " + strKey + " value: " + strValue, null, null);
                    // Handle parameter  
                } 
            }  
        }  
      
                }
                private IDfSession getSession(Map map) {
        String userName[] = (String[]) map.get("user_name");
        String docbase[] = (String[]) map.get("docbase_name");
      
        IDfSession session = null;
        IDfClientX clientX = new DfClientX();
        IDfClient client;
        IDfLoginInfo loginInfo = new DfLoginInfo();
        loginInfo.setUser(userName[0]);
        loginInfo.setPassword("");
        IDfSessionManager sMgr = null;
        try {
            client = clientX.getLocalClient();
            sMgr = client.newSessionManager();
            sMgr.setIdentity(docbase[0], loginInfo);
            session = sMgr.getSession(docbase[0]);
        } catch (DfException e) {
            e.printStackTrace();
        }
        return session;
    }

}
----------------------------------------------------------------------------------------------