Saturday, February 18, 2012

How to start a Documentum Workflow from DFC

Launching and running a Documentum Workdlow from DFC code is not such a trivial task.
Below is a DFC code sample of starting a Workflow and attaching a package to it:

public void startWorkflow(IDfSession session, String processName, String wfName, String supervisorName) throws DfException {
if (processName == null || processName.equals("")) {
DfLogger.error(this, "the process is empty", null, null);
throw new IllegalArgumentException("The process name not specified");
}

IDfProcess process = (IDfProcess) session.getObjectByQualification("dm_process where object_name = '" + processName + "'");
if (process == null) {
DfLogger.error(this, "process not found!", null, null);
throw new DfException("startWorkflow - No such process: " + processName);
}

IDfWorkflowBuilder workflowBuilder = session.newWorkflowBuilder(process.getObjectId());
workflowBuilder.getWorkflow().setObjectName(wfName);
workflowBuilder.getWorkflow().setSupervisorName(supervisorName);
if ((workflowBuilder.getStartStatus() != 0) || (!(workflowBuilder.isRunnable()))) {
DfLogger.warn(this, "startWorkflow - workflow '" + wfName + "' is not runnable or StartStauts=0!", null, null);
throw new DfException("cannot start Workflow!");
}
workflowBuilder.runWorkflow();

// Adding attachments:
IDfList attachIds = new DfList();
attachIds.appendId(new DfId("09024a8580235bc4"));

IDfList startActivities = workflowBuilder.getStartActivityIds();
int packageIndex = 0;
for (int i = 0; i < startActivities.getCount(); i++) {
IDfActivity activity = (IDfActivity) session.getObject(startActivities.getId(i));
workflowBuilder.addPackage(activity.getObjectName(), activity.getPortName(packageIndex),
activity.getPackageName(packageIndex), activity.getPackageType(packageIndex), null, false, attachIds);
}
}

How to save a SysObject with new version in DFC

If you want to save an (udpated) object with a new version, you won't find a method for that in the IDfSysObject implementation.
You will have to do 2 operations: checkout, then a checkin specifying a new version.
Well, there are 2 approaches to do that: using the IDfCheckoutOperation and IDfCheckinOperation operations or methods of the IDfSysObject class: checkout() and checkin(boolean keepLock, String versionLabels).
The second approach is quite simple as requires just 2 lines of code, while the first one is more complex, so let's see the code sample.
Beware: if you don't set the 'CURRENT' version on your new version, it will be the last, but not the current one. So it will be 'hidden'.
Find below code samples for the operations.

public IDfId saveAsNewVersion(IDfSysObject object) throws DfException {
try {
checkOut(object);
// update object here if necessary
IDfClientX clientX = new DfClientX();
IDfCheckinOperation ciop = clientX.getCheckinOperation();
ciop.setCheckinVersion(IDfCheckinOperation.NEXT_MAJOR);

IDfCheckinNode ciNode = (IDfCheckinNode) ciop.add(object);
// if you don't specify the CURRENT version this document won't be the current version
ciNode.setVersionLabels("CURRENT");
if (! ciop.execute()) {
DfLogger.error(this,"saveAsNewVersion: Save signed document with new version failed!", null, null);
}
IDfId id = ciNode.getNewObjectId();
DfLogger.debug(this, "Signed document saved with new version, ID: " + id.getId(),null,null);
return id;
} catch (DfException e) {
DfLogger.error(this, "",null,e);
throw e;
}
}

public void checkOut(IDfSysObject object) throws DfException {
IDfClientX clientX = new DfClientX();
IDfCheckoutOperation coop = clientX.getCheckoutOperation();
IDfCheckoutNode coNode = (IDfCheckoutNode) coop.add(object);
if (coNode == null || ! coop.execute()) {
throw new DfException("Could not checkout document: " + object.getObjectId());
}
}