DCTM : DFC

See also the page : http://www.javablog.fr/documentum-dfc-standalone-sample-program-all-basic-functionalities-of-documentum.html


——————— CONFIG ————————–


• Display the JVM properties

try {
	System.out.println("########################################################");
	System.out.println("JVM properties");
	System.out.println("########################################################");
	java.util.Properties properties = System.getProperties();
	java.util.Set<Object> set = properties.keySet();
	for (Object object : set) {
		Object object2 = properties.get(object);
		System.out.println(object + "=" + object2);
	}
} catch (Exception e) {
	System.out.println(com.documentum.fc.common.impl.MessageHelper.getStackTraceAsString(e));
}

…outputs:

########################################################
JVM properties
########################################################
java.runtime.name=Java(TM) SE Runtime Environment
sun.boot.library.path=C:\java\jdk1.6.0_27\jre\bin
java.vm.version=20.2-b06
java.vm.vendor=Sun Microsystems Inc.
java.vendor.url=http://java.sun.com/
path.separator=;
java.vm.name=Java HotSpot(TM) Client VM
file.encoding.pkg=sun.io
sun.java.launcher=SUN_STANDARD
user.country=GB
sun.os.patch.level=Service Pack 1
java.vm.specification.name=Java Virtual Machine Specification
user.dir=C:\Workspaces\TestDCTMHUO
java.runtime.version=1.6.0_27-rev-b21
java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
java.endorsed.dirs=C:\java\jdk1.6.0_27\jre\lib\endorsed
os.arch=x86
java.io.tmpdir=C:\Users\HUSEYI~1\AppData\Local\Temp\
line.separator=


java.vm.specification.vendor=Sun Microsystems Inc.
user.variant=
os.name=Windows 7
sun.jnu.encoding=Cp1252
java.library.path=C:\java\jdk1.6.0_27\jre\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32; C:\WINDOWS; C:/APP/Composer/jre/bin/../jre/bin/client;C:/APP/Composer/jre/bin/../jre/bin; C:\Program Files (x86)\EMC IRM\Common\;... ;C:\Users\hozveren\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\.....; C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;.
java.specification.name=Java Platform API Specification
java.class.version=50.0
sun.management.compiler=HotSpot Client Compiler
os.version=6.1
user.home=C:\Users\hozveren
user.timezone=
java.awt.printerjob=sun.awt.windows.WPrinterJob
file.encoding=Cp1252
java.specification.version=1.6
java.class.path=C:\Workspaces\DocumentumCoreProject\bin;C:\Workspaces\TestDCTMHUO\Web Services\bin\classes;C:\Workspaces\TestDCTMHUO\bin;....; C:\Workspaces\DocumentumCoreProject\dfs6.7\emc-dfs-sdk-6.7\lib\java\utils\xws-security.jar
user.name=hozveren
java.vm.specification.version=1.0
sun.java.command=com.huo.test.ecm.test3.ShowClientConfig
java.home=C:\SDK\jdk1.6.0_27\jre
sun.arch.data.model=32
user.language=en
java.vm.info=mixed mode
java.version=1.6.0_27-rev
java.ext.dirs=C:\SDK\jdk1.6.0_27\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
sun.boot.class.path=C:\SDK\jdk1.6.0_27\jre\lib\resources.jar;...; C:\SDK\jdk1.6.0_27\jre\classes
java.vendor=Sun Microsystems Inc.
file.separator=\
java.specification.vendor=Sun Microsystems Inc.
awt.toolkit=sun.awt.windows.WToolkit
...

• Display the JVM environment

try {
	System.out.println("########################################################");
	System.out.println("JVM env");
	System.out.println("########################################################");
	java.util.Map<String, String> map = System.getenv();
	java.util.Set<String> set = map.keySet();
	for (String object : set) {
		String object2 = map.get(object);
		System.out.println(object + "=" + object2);
	}
} catch (Exception e) {
	System.out.println(com.documentum.fc.common.impl.MessageHelper.getStackTraceAsString(e));
}

…outputs:

########################################################
JVM env
########################################################
USERPROFILE=C:\Users\hozveren
ProgramData=C:\ProgramData
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
windows_tracing_logfile=C:\BVTBin\Tests\installpackage\csilogfile.log
ProgramFiles(x86)=C:\Program Files (x86)
windows_tracing_flags=3
TEMP=C:\Users\HOZVER~1\AppData\Local\Temp
SystemDrive=C:
ProgramFiles=C:\Program Files (x86)
Path=C:/TOOLS/Composer/jre/bin/../jre/bin/client;C:/TOOLS/Composer/jre/bin/../jre/bin;...; C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\
PROCESSOR_REVISION=3c03
TNS_ADMIN=C:\SDK\TNS
VSTO_SUPPRESSDISPLAYALERTS=0
USERDOMAIN=LU
SESSIONNAME=Console
TMP=C:\Users\HOZVER~1\AppData\Local\Temp
HOMEPATH=\Users\hozveren
COMPUTERNAME=MYPCHUO
windir=C:\WINDOWS
SystemRoot=C:\WINDOWS
NUMBER_OF_PROCESSORS=8
USERNAME=hozveren
PUBLIC=C:\Users\Public
ComSpec=C:\WINDOWS\system32\cmd.exe
APPDATA=C:\Users\hozveren\AppData\Roaming
...

• Display the DFC properties

try {
	System.out.println("########################################################");
	System.out.println("dfc.properties");
	System.out.println("########################################################");
	com.documentum.fc.client.IDfClient dfClient = com.documentum.fc.client.DfClient.getLocalClientEx();
	com.documentum.fc.client.IDfTypedObject dfTypedObject = dfClient.getClientConfig();
	for (int i = 0; i < dfTypedObject.getAttrCount(); i++) {
		com.documentum.fc.common.IDfAttr dfAttr = dfTypedObject.getAttr(i);
		if (dfAttr.isRepeating()) {
			for (int j = 0; j < dfTypedObject.getValueCount(dfAttr.getName()); j++) {
				StringBuilder sb = new StringBuilder();
				sb.append(dfAttr.getName()).append("[").append(j).append("]=");
				sb.append(dfTypedObject.getRepeatingValue(dfAttr.getName(), j));
				System.out.println(sb.toString());
			}//end-for
		} else {
			StringBuilder sb = new StringBuilder();
			sb.append(dfAttr.getName()).append("=").append(dfTypedObject.getValue(dfAttr.getName()));
			System.out.println(sb.toString());
		}//end-if
	}//end-for
} catch (Exception e) {
	System.out.println(com.documentum.fc.common.impl.MessageHelper.getStackTraceAsString(e));
}

…outputs:

########################################################
dfc.properties
########################################################
dfc.name=dfc
dfc.config.dir=C:\Documentum\DEV\config
dfc.config.file=file:/C:/Documentum/DEV/config/dfc.properties
dfc.data.dir=C:\Documentum\DEV
dfc.data.user_dir=C:\Documentum\DEV
dfc.data.checkout_dir=C:\Documentum\DEV\checkout
dfc.data.export_dir=C:\Documentum\DEV\export
dfc.data.local_diskfull_limit=0
dfc.data.local_diskfull_check_interval=1
dfc.data.local_clean_on_init=T
dfc.data.local_purge_on_diskfull=T
dfc.registry.mode=file
dfc.permit.grant.write.user_default_folder=T
dfc.registry.file=C:\Documentum\DEV\documentum.ini
dfc.config.check_interval=30
dfc.batch_hint_size=50
dfc.search.batch_hint_size=0
dfc.codepage=windows-1252
dfc.date_format=dd/MM/yyyy HH:mm:ss
dfc.locale=en
dfc.time_zone=Europe/Paris
dfc.version=6.7.2000.0038
dfc.verify_registration=T
dfc.acs.avail.refresh_interval=360
dfc.bocs.avail.refresh_interval=120
dfc.acs.check_availability=T
dfc.acs.config.refresh_interval=120
dfc.acs.gr.refresh_interval=120
dfc.acs.request.expiration_interval=360
dfc.admin.ldif_file_charset=UTF-8
dfc.appledouble.resource_file_ext=adp
dfc.bocs.check.keep_number=10
dfc.bocs.check.http_method=GET
dfc.bof.cache.append_name=T
dfc.bof.cache.currency_check_interval=60
dfc.bof.cache.cleanup_interval=7
dfc.bof.cache.enable_preload=T
dfc.bof.classloader.enable_extension_loader_first=T
dfc.cache.dir=C:\Documentum\DEV\cache
dfc.cache.enable_persistence=T
dfc.cache.write_interval=3600
dfc.cache.ddinfo.size=500
dfc.cache.object.size=1000
dfc.cache.query.size=500
dfc.cache.type.size=500
dfc.cache.format.currency_check_interval=300
dfc.cache.store.currency_check_interval=300
dfc.cache.type.currency_check_interval=300
dfc.cache.currency_scoping.enable=T
dfc.cache.currency_scoping.query_result_max_count=5
dfc.compatibility.truncate_long_values=F
dfc.compatibility.return_null_when_no_values=T
dfc.compatibility.preserve_session_info_messages=T
...


——————— CONTENT ————————–


Set current content file exemple for anonymization need:

int countCurrent = 0;
for (String documentId : documentIds) {
	try {
		LOGGER.info(documentId + " : update content (" + countCurrent + ")... ");
		IDfDocument document = (IDfDocument) session.getObject(new DfId(documentId));
		boolean isImmutable = document.isImmutable();
		if (isImmutable) {
			document.setBoolean("r_immutable_flag", false);
			document.save();
		}


		document.setSubject("anonymized");
		document.setContentType("pdf");
		document.setFile(docFolder + File.separator + canal + "-encrypted.pdf");
		document.save();

		if (isImmutable) {
			document.setBoolean("r_immutable_flag", true);
			document.save();
		}
		LOGGER.info(documentId + " : [OK]");
	} catch(Exception e) {
		LOGGER.error(documentId + " : [KO: error to update content]", e);
	}
	countCurrent++;
}

 
Get current content file
SOLUTION 1 : The “standard” way to get content from a document stored via the methods getFile OR getFileEx OR getFileEx2
=> The server will create a temporary file on a filesystem accessible to the user, and return the file name.
=> The server copies the file from the Documentum server to the local drive (current working directory):

doc.getFile(doc.getObjectName()); 

SOLUTION 2 : Copies this object’s content from the Documentum server into a ByteArrayInputStream object via the methods getContent OR getContentEx OR getContentEx2 OR getContentEx3

long contentSize = docPJ.getContentSize();
private String getContentOfDocument(IDfSysObject doc) throws Throwable{
	String originalContent = null;
	ByteArrayInputStream originalContentBais = doc.getContent();
	if (originalContentBais.available() > 0){
		int n = originalContentBais.available();
		byte[] bytes = new byte[n];
		originalContentBais.read(bytes, 0, n);
		originalContent = new String(bytes, "UTF-8");
	}

	return originalContent;
}

 
Get rendition content file

private String getXmlRenditionOfDocument(IDfSysObject doc) throws Throwable{
	String renditionXmlContent = null;

	// RENDITION XML
	//long renditionXmlContentSize = doc.getContentSize(0, "xml", null);
	ByteArrayInputStream renditionXmlContentBais = doc.getContentEx2("xml", 0, null);
	if (renditionXmlContentBais!=null && renditionXmlContentBais.available() > 0){
		int n = renditionXmlContentBais.available();
		byte[] bytes = new byte[n];
		renditionXmlContentBais.read(bytes, 0, n);
		renditionXmlContent = new String(bytes, "UTF-8");
	}

	return renditionXmlContent;
}

 
Extract data from content file with resolution of CHARSET and OS characters encoding problems:

public static final String UN_ENCODED_VALUE = "?";
public static final String DATIME_SEPARATOR_VALUE = "-";

//They are "\n" (Linux and MacOS X), "\r" (MacOS 9 and older) and "\r\n" (Windows)
public static final String WINDOWS_NEW_LINE_SEPARATOR = "\r\n"; // System.getProperty("line.separator");
public static final String LINUX_NEW_LINE_SEPARATOR = "\n";
public static final String MAC_NEW_LINE_SEPARATOR = "\r";
public static final String NOTES_NEW_LINE_SEPARATOR = "
";
public static final char NO_BREAK_SPACE_CHARACTER = '\u00A0';

public enum MetaDataFieldTypes {
	STRING,
	DATE,
	REPEATING,
	INTEGER,
	;
	private MetaDataFieldTypes(){ }
}

/**
 * Do the extraction of data from TEXTUAL content
 */
public Map<String, Object> doExtraction(String content, MetaDataFieldTypes fieldType, String metaDataKey, String startTAG, String stopTAG) throws Throwable{
	Map<String, Object> extractedData = new LinkedHashMap<String, Object>();

	// Replace the newline (line feed) chars and the carriage-return chars by space " "
	content = content.replaceAll(WINDOWS_NEW_LINE_SEPARATOR, "");
	content = content.replaceAll(LINUX_NEW_LINE_SEPARATOR, "");
	content = content.replaceAll(MAC_NEW_LINE_SEPARATOR, "");

	// See http://stackoverflow.com/questions/13992934/how-to-fix-utf-encoding-for-whitespaces
	// Replace all NO-BREAK-SPACE character '\u00A0' by a space character
	content = content.replace(NO_BREAK_SPACE_CHARACTER, ' ');

	if(currContentMetaDataFieldSplitter!=null){
		String metaDataValue = getValueBetweenTAGs(content, startTAG, stopTAG);

		if(fieldType == MetaDataFieldTypes.DATE){
			Date metaDataValueDate = null;
			if(metaDataValue!=null && !"".equals(metaDataValue)){
				metaDataValue = new String(metaDataValue.getBytes(), ENCODING_CHARSET);
				// "Dec?04?2014" -> "Dec-04-2014"
				metaDataValue = metaDataValue.replace(UN_ENCODED_VALUE, DATIME_SEPARATOR_VALUE);
				metaDataValueDate = currContentMetaDataFieldSplitter.getDateFormat().parse(metaDataValue);
			}

			extractedData.put(metaDataKey, metaDataValueDate);

		} else if(fieldType == MetaDataFieldTypes.REPEATING) {
			String[] metaDataValuesArray = null;
			if(metaDataValue!=null && !"".equals(metaDataValue)){
				metaDataValuesArray = metaDataValue.split((String) currContentMetaDataFieldSplitter.getValuesSeparator());
				// Trim white space from all elements in array
				for (int i = 0; i < metaDataValuesArray.length; i++){
					metaDataValuesArray[i] = metaDataValuesArray[i].trim();
				}
			}
			extractedData.put(metaDataKey, metaDataValuesArray);

		} else if(fieldType == MetaDataFieldTypes.INTEGER) {
			if(metaDataValue!=null && !"".equals(metaDataValue)){
				metaDataValue = metaDataValue.trim();
				// "FIELD VALUE   #:           154564 test huo javablog.fr
"
				if(metaDataValue.indexOf(" ")>0){metaDataValue = metaDataValue.substring(0, metaDataValue.indexOf(" "));}
				try{int tmpInt = Integer.parseInt(metaDataValue); metaDataValue=""+tmpInt;}catch(Throwable IgnoreTh){}
				extractedData.put(metaDataKey, metaDataValue);
			}

		} else /**if(fieldType == MetaDataFieldTypes.STRING)*/ {
			extractedData.put(metaDataKey, metaDataValue);
		}
	}
	return extractedData;
}

private String getValueBetweenTAGs(String content, String startTAG, String stopTAG){
	String metaDataValue = null;
	int indexStartTAG = content.indexOf(startTAG);
	if(indexStartTAG>=0){
		int indexStopTAG = content.indexOf(stopTAG, indexStartTAG+startTAG.length());
		if(indexStopTAG>0){
			metaDataValue = content.substring(indexStartTAG+startTAG.length(), indexStopTAG);
			//
			if(metaDataValue!=null){
				metaDataValue = metaDataValue.trim();
				//
				//1. FIRST TEXT XML RENDITION : Replace the NOTES newline (line feed) chars "
" by ""
				metaDataValue = metaDataValue.replaceAll(NOTES_NEW_LINE_SEPARATOR, "");
				//2. SECOND Replace the HTML chars to unicode chars ex:   -> " "
				metaDataValue = org.apache.commons.lang.StringEscapeUtils.unescapeHtml(metaDataValue);
				//
				// See http://stackoverflow.com/questions/13992934/how-to-fix-utf-encoding-for-whitespaces
				// Replace all NO-BREAK-SPACE character '\u00A0' by a space character
				metaDataValue = metaDataValue.replace(NO_BREAK_SPACE_CHARACTER, ' ').trim();
			}
		}
	}

	return metaDataValue;
}


——————— SESSION ————————–


• To get Documentum session object

public IDfSession getDfSession(String user, String passwd, String docbase) throws Exception {
	IDfLoginInfo login = new DfLoginInfo();
	login.setUser(user);
	login.setPassword(passwd);
	IDfClient client = DfClient.getLocalClient(); //new DfClient();
	IDfSessionManager sessMgr = client.newSessionManager();
	sessMgr.setIdentity(docbase, login);
	IDfSession idfSession = sessMgr.getSession(docbase);


	if (idfSession != null)
		System.out.println("Session created successfully");

	return idfSession;
}

• To get user of Documentum session object

// Same value
String technicalUser = getCurrentUser();
technicalUser= dfSession.getLoginInfo().getUser();
technicalUser = dfSession.getLoginUserName();

private String getCurrentUser(){
    	String userName = null;
    	ContextFactory contextFactory = ContextFactory.getInstance();
	IServiceContext serviceContext = contextFactory.getContext();
	for (Iterator<?> iter = serviceContext.getIdentities(); iter.hasNext();) {
		Object identity = iter.next();
		if (identity instanceof BasicIdentity) {
			BasicIdentity basicIdentity = (BasicIdentity) identity;
			userName = basicIdentity.getUserName();
		}//end-if
	}//end-for
	return userName;
}

• To release a Documentum session object with Session Manager

public void releaseSession(IDfSessionManager sessMgr, IDfSession idfSession) throws Exception {
	sessMgr.release(idfSession);
}

• To create a Session with the credentials sent through Web Context (like Web service):

package com.java.lu.service.ecm.utils.context;

import java.text.MessageFormat;
import java.util.Iterator;
import java.util.UUID;

import com.documentum.fc.client.DfAuthenticationException;
import com.documentum.fc.client.IDfSession;
import com.emc.documentum.fs.datamodel.core.context.BasicIdentity;
import com.emc.documentum.fs.rt.context.ContextFactory;
import com.emc.documentum.fs.rt.context.IServiceContext;
import com.emc.documentum.fs.rt.impl.DfsLogger;
import com.emc.documentum.fs.rt.impl.IDfsLogger;

public class SessionUtils {

	private static final IDfsLogger logger = DfsLogger.getLogger(SessionUtils.class);

	private static IDfSession getMySession(String repositoryName, boolean newSession) throws Throwable{
		UUID uuid = UUID.randomUUID();
		if (logger.isTraceEnabled()) {
			logger.trace(MessageFormat.format("{1} - getMySession(repositoryName={0})", repositoryName, uuid));
		}
		IDfSession dfSession = null;
		ContextFactory contextFactory = ContextFactory.getInstance();
		IServiceContext serviceContext = contextFactory.getContext();
		for (Iterator<?> iter = serviceContext.getIdentities(); iter.hasNext() && dfSession == null;) {
			Object identity = iter.next();
			if (identity instanceof BasicIdentity) {
				BasicIdentity basicIdentity = (BasicIdentity) identity;
				String password = basicIdentity.getPassword();
				String userName = basicIdentity.getUserName();
				if (!newSession) {
					if (logger.isDebugEnabled()) {
						logger.debug(MessageFormat.format("{0} - Retrieving session for user {1} and repository {2}", uuid, userName, repositoryName));
					}
					try {
						dfSession = ContextCaching.getSessionManager(repositoryName, userName).getSession(repositoryName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Retrieving session for user {1} and repository {2} - success !", uuid, userName, repositoryName));
						}
					} catch (DfAuthenticationException e) {
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Retrieving session for user {1} and repository {2} - failure : {3}", uuid, userName, repositoryName, e.getMessage()));
						}
						ContextCaching.clearContext(repositoryName, userName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Trying a second time to retrieve session for user {1} and repository {2}", uuid, userName, repositoryName));
						}
						dfSession = ContextCaching.getSessionManager(repositoryName, userName).getSession(repositoryName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Second time retrieving session for user {1} and repository {2} - success !", uuid, userName, repositoryName));
						}
					}
				} else {
					if (logger.isDebugEnabled()) {
						logger.debug(MessageFormat.format("{0} - Creating a new session for user {1} and repository {2}", uuid, userName, repositoryName));
					}
					try {
						dfSession = ContextCaching.getSessionManager(repositoryName, userName).newSession(repositoryName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Creating session for user {1} and repository {2} - success !", uuid, userName, repositoryName));
						}
					} catch (DfAuthenticationException e) {
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Creating session for user {1} and repository {2} - failure : {3}", uuid, userName, repositoryName, e.getMessage()));
						}
						ContextCaching.clearContext(repositoryName, userName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Trying a second time to create a session for user {1} and repository {2}", uuid, userName, repositoryName));
						}
						dfSession = ContextCaching.getSessionManager(repositoryName, userName).newSession(repositoryName);
						if (logger.isDebugEnabled()) {
							logger.debug(MessageFormat.format("{0} - Second time creating session for user {1} and repository {2} - success !", uuid, userName, repositoryName));
						}
					}

				}
			}

		}
		if (logger.isTraceEnabled()) {
			logger.trace(MessageFormat.format("{1} - getMySession(repositoryName={0}) - END", repositoryName, uuid));
		}
		return dfSession;
	}
}


——————— LOG ————————–


• To print the error in Console/Logging file

public void displayError(com.documentum.operations.IDfOperation operation, boolean flag) throws Exception {
	if (!flag) {
		IDfList errlist = operation.getErrors();
		for (int i = 0; i < errlist.getCount(); i++) {
			IDfOperationError errOperation = (IDfOperationError) errlist.get(i);
			System.out.println("Error MSG " + errOperation.getMessage());
		}
	}
}


——————— DOCBASE ————————–


• To get a list of available docbase

public void getAllDocbases() throws Exception {
	IDfClient client = DfClient.getLocalClient();
	IDfDocbaseMap docbaseMap = client.getDocbaseMap();
	for (int i = 0; i < docbaseMap.getDocbaseCount(); i++) {
		System.out.println("Docbase Name : " + docbaseMap.getDocbaseName(i));
		System.out.println("Docbase Desc : " + docbaseMap.getDocbaseDescription(i));
	}
}

…outputs:

Session created successfully
Docbase Name : MY_DOCBASE1_DEV
Docbase Desc : My docbase 1
Docbase Name : MY_DOCBASE2_DEV
Docbase Desc : My docbase 2
Docbase Name : GLOBALR
Docbase Desc : Global Registry Repository
Docbase Name : MY_DOCBASE3_DEV
Docbase Desc : My docbase 3
Docbase Name : MY_DOCBASE4_DEV
Docbase Desc : My docbase 4


——————— CABINET / FOLDER ————————–


• To create a cabinet (dm_cabinet) in docbase

public void createCabinet() throws Exception {
	IDfFolder cabinet = (IDfFolder) idfSession.newObject("dm_cabinet");
	if (cabinet != null) {
		cabinet.setObjectName("Training Cabinet XXX");
		cabinet.save();
	}
}

• To create a folder (dm_folder object) in docbase

public void createFolder() throws Exception {
	IDfFolder folder = (IDfFolder) idfSession.newObject("dm_folder");
	if (folder != null) {
		folder.setObjectName("Folder Level 2");
		folder.link("/Training Cabinet XXX");
		folder.save();
	}
}


——————— DOCUMENT / TYPE ————————–


• To create a document (dm_document object) in docbase

public IDfDocument createDocument() throws Exception {
	IDfDocument document = (IDfDocument) idfSession.newObject("dm_document");
	if (document != null) {
		document.setObjectName("Test-Document");
		document.setContentType("crtext");
		document.setFile("C:\\Documentum\\config\\dfc.properties");
		document.link("/Training Cabinet XXX/Folder Level 1");
		document.save();
	}
	return document;
}

• To import a document into docbase

public void importDocument() throws Exception {
	IDfSysObject sysObject = (IDfFolder) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2");
	System.out.println("Object ID " + sysObject.getObjectId());

	IDfClientX clientx = new DfClientX();
	com.documentum.operations.IDfImportOperation importOper = clientx.getImportOperation();
	importOper.setSession(idfSession);

	if (importOper == null)
		System.out.println("operation object is null");

	importOper.setDestinationFolderId(sysObject.getObjectId());
	importOper.setVersionLabels("imported using operation");

	com.documentum.operations.IDfImportNode node = (com.documentum.operations.IDfImportNode) importOper.add("C:\\Documentum\\config\\log4j.properties");
	node.setFormat("pdf");

	boolean flag = importOper.execute();
	displayError(importOper, flag);
}

• To delete a document from docbase

public void deleteDoc() throws Exception {
	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/Test-Document");
	if (sysObject != null) {
		sysObject.destroyAllVersions(); // delete all versions
		System.out.println("object destroyed…..");
	}
}

• To update document’s in docbase

public void updateAttributes() throws Exception {
	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/New Document");
	sysObject.setString("object_name", "New Document");
	sysObject.setString("authors", "Prasad");
	sysObject.setRepeatingString("authors", 1, "RamKumar");
	sysObject.save();
}

• To retrieve document’s attributes from docbase

public void getAttributes() throws Exception {
	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/New Document");
	if (sysObject != null) {
		System.out.println("objectName " + sysObject.getString("object_name"));
		// System.out.println("authors " + sysObject.getString("authors"));
		String authors = sysObject.getAllRepeatingStrings("authors", ",");

		List list = new java.util.ArrayList();
		java.util.StringTokenizer st = new java.util.StringTokenizer(authors, ",");
		System.out.println("length of st " + st.countTokens());
		while (st.hasMoreTokens()) {
			list.add(st.nextElement());
		}
		System.out.println("length " + list.size());

		for (int i = 0; i < list.size(); i++) {
			System.out.println("Author[" + i + "] " + list.get(i));
		}
	}
}

• To get the attributes of a specific type

public void getTypeAttributes() throws Exception {
	IDfType type = (IDfType) idfSession.newObject("dm_document");
	for (int i = 0; i < type.getAttrCount(); i++) {
		IDfAttr attr = type.getAttr(i);
		System.out.println("Name " + attr.getName());
		System.out.println("Datatype " + attr.getDataType());
		System.out.println("Length " + attr.getLength());
		System.out.println("IS Repeating Attr " + attr.isRepeating());
	}
}

• To retrieve document from document using IDQL

public void collection() throws Exception {
	IDfQuery query = new DfQuery();
	query.setDQL("select * from dm_document where object_name='New Document' and any r_version_label like 'CURRENT%'");
	IDfCollection coll = query.execute(idfSession, 0);

	while (coll.next()) {
		IDfTypedObject typeObject = (IDfTypedObject) coll.getTypedObject();
		System.out.println("Object Name " + typeObject.getString("r_object_id"));
		System.out.println("creation date " + typeObject.getString("r_creation_date"));
	}

	if (coll != null)
		coll.close();
}


——————— CHECKIN / CHECKOUT ————————–


• To check out a document from docbase using com.documentum.operations.IDfOperations

public void checkoutDocument() throws Exception {
	IDfClientX clientx = new DfClientX();
	com.documentum.operations.IDfCheckoutOperation checkoutOper = clientx.getCheckoutOperation();


	System.out.println("Checkout Dir "+ checkoutOper.getDefaultDestinationDirectory());
	checkoutOper.setDestinationDirectory(checkoutOper.getDefaultDestinationDirectory());

	sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2/log4j.properties");

	com.documentum.operations.IDfCheckoutNode node = (com.documentum.operations.IDfCheckoutNode) checkoutOper.add(sysObject);
	boolean flag = checkoutOper.execute();
	displayError(checkoutOper, flag);
}

• To check in a document to docbase using com.documentum.operations.IDfOperations

public void checkinDocument() throws Exception {
	IDfClientX clientx = new DfClientX();
	com.documentum.operations.IDfCheckinOperation checkinOper = clientx.getCheckinOperation();

	com.documentum.operations.IDfCheckinNode node = (com.documentum.operations.IDfCheckinNode) checkinOper.add(sysObject);
	// NEXT_MINOR
	{
		// Set CURRENT version label is implicit
		//node.setCheckinVersion(IDfCheckinOperation.NEXT_MINOR);
	}
	// NEXT_MAJOR
	{
		node.setCheckinVersion(IDfCheckinOperation.NEXT_MAJOR);
		if(StringUtils.isEmpty(checkinOper.getVersionLabels())){
			checkinOper.setVersionLabels("CURRENT");
		}else{
			checkinOper.setVersionLabels(checkinOper.getVersionLabels() + "," + "CURRENT");
		}
	}
	System.out.println("Flag —->" + checkinOper.execute());
}

• To cancel checkout a document into docbase

public void cancelCheckoutDocument() throws Exception {
	IDfClientX clientx = new DfClientX();
	com.documentum.operations.IDfCancelCheckoutOperation cancelcheckoutOper = clientx.getCancelCheckoutOperation();
	sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2/log4j.properties");

	com.documentum.operations.IDfCancelCheckoutNode node = (com.documentum.operations.IDfCancelCheckoutNode) cancelcheckoutOper.add(sysObject);
	boolean flag = cancelcheckoutOper.execute();
	displayError(cancelcheckoutOper, flag);
}
String qualification = "my_document WHERE i_chronicle_id = ID('090xxxxxxxxxxx')";
IDfDocument dfDocument = (IDfDocument) session.getObjectByQualification(qualification);

if (dfDocument == null) {
	throw new DfException("Unable to find object with qualification : " + qualification );
}

if (dfDocument.isCheckedOut()) {
	//Canceling checkout of document
	dfDocument.cancelCheckout();
}

• To check out a document from docbase

public void checkoutDoc() throws Exception {
	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/");
	if (!sysObject.isCheckedOut()) // if it is not checked out
		sysObject.checkout();
	System.out.println("is Check out " + sysObject.isCheckedOut());
}

• To check in a document to docbase

public void checkinDoc() throws Exception {
	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/Test-Document");

	if (sysObject.isCheckedOut()) { // if it is checked out
		sysObject.checkin(false, "CURRENT");
	}
}


——————— API ————————–


• To use of IAPI methods

public void dmclAPI() throws Exception {
	System.out.println("Starting...");
	IDfSysObject sysObj = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='Test-Document'");
	String rObjectId = sysObj.getObjectId().getId();


	String name = (String) idfSession.apiGet("get", rObjectId+ ",object_name");
	System.out.println("Name : " + name);
	// idfSession.apiSet("set",rObjectId+",title","sample-doc");
	idfSession.apiExec("link",rObjectId+",/Training Cabinet XXX/Folder Level 2");
	System.out.println("Linked " + idfSession.apiExec("save", rObjectId));
}


——————— VIRTUAL DOCUMENT ————————–


• To create a virtual document in docbase

public void createVirtualDocument() throws Exception {
	IDfSysObject pSys = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2/log4j.properties");
	IDfSysObject cSys = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 1/trace.log");


	pSys.setIsVirtualDocument(true);
	pSys.save();

	IDfVirtualDocument vDoc = pSys.asVirtualDocument("CURRENT", false);
	IDfVirtualDocumentNode pNode = vDoc.getRootNode();
	pSys.checkout();

	IDfVirtualDocumentNode nodeChild1 = vDoc.addNode(pNode, null, cSys.getChronicleId(), "CURRENT", false, false);
	pSys.checkin(false, "CURRENT");
}

• To export a virtual document from docbase

public void exportVirtualDocument() throws Exception {
	System.out.println("exporting virtual document");

	IDfClientX clientx = new DfClientX();
	com.documentum.operations.IDfExportOperation expOperation = clientx.getExportOperation();

	IDfSysObject sysObject = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2/log4j.properties");
	if (sysObject.isVirtualDocument()) {
		IDfVirtualDocument Vdoc = sysObject.asVirtualDocument("CURRENT", false);
		com.documentum.operations.IDfExportNode expNode = (com.documentum.operations.IDfExportNode) expOperation.add(sysObject);
		expOperation.setDestinationDirectory(expOperation.getDefaultDestinationDirectory());
		boolean flag = expOperation.execute();
		displayError(expOperation, flag);
	}
}

• To view virtual document from docbase

public void viewVirtualDocument() throws Exception {
	IDfSysObject pSys = (IDfSysObject) idfSession.getObjectByPath("/Training Cabinet XXX/Folder Level 2/log4j.properties");
	if (pSys.isVirtualDocument()) {
		System.out.println("virtual document –> true");
		IDfVirtualDocument vDoc = pSys.asVirtualDocument("CURRENT", false);
		IDfVirtualDocumentNode pNode = vDoc.getRootNode();

		System.out.println("Iterating thru the lis to get the child nodes");
		for (int i = 0; i < pNode.getChildCount(); i++) {
			IDfVirtualDocumentNode cNode = pNode.getChild(i);
			System.out.println("Child Name " + cNode.getSelectedObject().getObjectName());
		}
	}
}


——————— LIFECYCLE ————————–


• To attach a lifeCycle to a document in docbase

public void attachLC() throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");


	IDfSysObject procObj = (IDfSysObject) idfSession.getObjectByQualification("dm_policy where object_name='Training_LC' ");
	mDocs.attachPolicy(procObj.getObjectId(), "Author", "");
}

• To promote a lifeCycle state of a document

public void promoteLC(String State) throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");
	mDocs.promote(State, false, false);
}

• To demote a lifeCycle state of a document

public void demoteLC(String State) throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");
	mDocs.demote(State, false);
}

• To expire a lifeCycle state of a document

public void expireLC(String State) throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");
	mDocs.suspend(State, false, false);
}

• To resume a lifeCycle state of a document

public void resumeLC(String State) throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");
	mDocs.resume(State, false, false, false);
}


——————— DOCUMENT PROPERTIES ————————–


• To modify a repeating properties (attributes) list
In some cases your client may need to make a specific change to a list of repeating properties (also called repeating attributes), such as appending values to the end of the list, inserting an item into the list, or removing an item from the list. To accomplish this you can add one or more ValueAction instances to the ArrayProperty. A ValueAction list is synchronized with the ArrayProperty that contains it, such that an item in position p in the ValueAction list corresponds to a value stored at position p of the ArrayProperty. In this example the first item in the ValueAction list (INSERT, 0) corresonds to the first item in the ArrayProperty (snakes). The index value (0) specifies a position in the repeating property of the repository object. Note that if you insert or delete items in a repeated properties list, the positions of items to the right of the alteration will be offset by 1 or -1. This will affect subsequent processing of the ValueAction list, which is processed from beginning to end. You must account for this effect when coding a ValueAction list, such as by ensuring that the repeating properties list is processed from right to left.

public DataPackage updateRepeatProperty(ObjectIdentity objectIdentity)
throws ServiceException
{
	PropertyProfile propertyProfile = new PropertyProfile();
	// Setting the filter to ALL can cause errors if the DataObject
	// passed to the operation contains system properties, so to be safe
	// set the filter to ALL_NON_SYSTEM unless you explicitly want to update
	// a system property
	propertyProfile.setFilterMode(PropertyFilterMode.ALL_NON_SYSTEM);
	serviceContext.setProfile(propertyProfile);
	DataObject dataObject = new DataObject(objectIdentity);


	String[] moreDangers = { "snakes", "sharks" };
	ArrayProperty keywordProperty = new StringArrayProperty("keywords", moreDangers);

	ValueAction insertAction = new ValueAction(ValueActionType.INSERT, 0);
	ValueAction appendAction = new ValueAction(ValueActionType.APPEND, 1);
	keywordProperty.setValueActions(insertAction, appendAction);

	PropertySet properties = new PropertySet();
	properties.set(keywordProperty);
	dataObject.setProperties(properties);

	OperationOptions operationOptions = null;
	return objectService.update(new DataPackage(dataObject), operationOptions);
}


——————— WORKFLOW / TASK ————————–


Some concepts about Workflows:

  • Workflows may be likened to “programs” that treat collections of documents as data. Workflows describe business processes that dictate when (under what circumstances) information (represented by documents) is sent to whom (users and groups), and how documents of interest change state (represented by lifecycles) as they progress through a workflow.
  • Package: A package is a collection of related documents, treated as a unit of information. A package is just a fancy way of talking about the document that is being routed around from person to person. It’s called a package because it can contain multiple documents instead of just a single document.
  • Activity: A step that is performed as part of a workflow. A workflow will typically have multiple activities. Workflows have one or more start activities, one or more step activities and one end activity.
  • Aliases: A named set of names that map onto defined users and groups. An alias is a user-friendly name representing users and groups.
  • Ports: A port is logical point of information exchange in an activity. Ports exchange information via packages. A port may be an Input port (one that accepts packages for processing), an Output port (one that sends packages from this activity to the next), or a Revert port (one that accepts a package that is returned by the next activity).

• To create and start workflow

public void startWorkflow() throws Exception {
	// to get the attachment document
	IDfSysObject sysObj = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='DFCtest'");

	System.out.println(("Starting workflow for document: "+document.getObjectId().getId());

	// to get the Workflow Template
	IDfProcess process = (IDfProcess) idfSession.getObjectByQualification("dm_process where object_name like '%INDIA_TIMES%'");

	System.out.println("Process ID: "+process.getObjectId().getId());

	// to create a Workflo Builder to start a workflow
	IDfWorkflowBuilder builder = idfSession.newWorkflowBuilder(process.getObjectId());
	IDfId wfId = builder.initWorkflow(); // IDfId wfId = builder.runWorkflow();

	System.out.println(("Workflow ID: "+ wfId.getId());

	// get the First Activity
	IDfList startActivityNames = builder.getStartActivityNames();
	IDfList startActivities = builder.getStartActivityIds();
	String activityName = startActivityNames.getString(0);
	IDfId activityID = (IDfId) startActivities.get(0);
	IDfActivity activity = (IDfActivity) idfSession.getObject(activityID);

	// to get the Package Name , Port and Package DocType
	int nPorts = activity.getPortCount();
	String InputPortName = null;
	String PkgType = null;
	String PkgName = null;

	for (int j = 0; j < nPorts; j++) {
		System.out.println("Port Name: " + activity.getPortName(j) + ", " + "Port Type = " + activity.getPortType(j));
		if (activity.getPortType(j).equals("INPUT")) {
			InputPortName = activity.getPortName(j);
			PkgType = activity.getPackageType(j);
			PkgName = activity.getPackageName(j);
		}
	}

	// to Add the attachment document to List
	IDfList dfList = new DfList();
	dfList.append(sysObj.getObjectId());

	IDfId wfId2 = builder.runWorkflow();
	// Add a Package to Workflow Builder
	IDfId packageId = builder.addPackage(activityName, InputPortName, PkgName, PkgType, null, false, dfList);

	System.out.println("Package ID: "+packageId.getId());
}

• Getting a List of All the Installed Workflows.
->Workflow template must be “installed”, which means that all of its associated activities are all valid and installed.

// Get a list of all installed workflows!
System.out.println( "The following workflows are ready to run:-" );
IDfCollection Workflows = session.getRunnableProcesses("");
while ( Workflows.next() )
{
	IDfTypedObject Next = Workflows.getTypedObject();

	// The following chunk of code has to de with
	// obtaining the attributes of the
	// IDfTypedObject we got back!

	java.util.Enumeration e = Next.enumAttrs();

	while ( e.hasMoreElements() )
	{
		IDfAttr NextAttr = (IDfAttr)e.nextElement();

		System.out.print( NextAttr.getName() + " = " );

		int AttrCount = 0;
		if ( NextAttr.isRepeating() )
			AttrCount = Next.getValueCount
			                 ( NextAttr.getName() );
		else
			AttrCount = 1;

		for (int i=0; i<AttrCount; i++)
		{
			// Get the next value!
			IDfValue NextAttrValue = Next.getRepeatingValue
						   ( NextAttr.getName(), i );
			System.out.print( NextAttrValue );
			System.out.print( ", " );
		}
	}
	System.out.println();
}

• To start a new instance of workflow via session object

private void startWorkflow(IDfSession session, IDfDocument document) throws DfException {
	logger.debug("Starting workflow for document: "+document.getObjectId().getId());

	IDfProcess process = (IDfProcess) session.getObjectByQualification("dm_process WHERE object_name = '"+ configGed.getDctmWkfName() +"'");
	logger.debug("Process ID: "+process.getObjectId().getId());
	IDfWorkflowBuilder builder = session.newWorkflowBuilder(process.getObjectId());
	builder.initWorkflow();
	IDfId workflowId = builder.runWorkflow();
	logger.debug("Workflow ID: "+workflowId.getId());

	//...
}

• To create a workflow instance via Workflow Builder object

IDfWorkflowBuilder  workflowBuilder = session.newWorkflowBuilder ( new DfId( "4b0f475b80002164" ) );
// Init the workflow!
IDfId NewWorkflowId = workflowBuilder.initWorkflow();
System.out.println( "Workflow initted! Id: " + NewWorkflowId );

// Start the workflow running!
IDfId NewWorkflowId2 = workflowBuilder.runWorkflow();
System.out.println( "Workflow started! Id: " + NewWorkflowId2 );

// You would add your package here if necessary

// Get the workflow object we created
IDfWorkflow workflow = workflowBuilder.getWorkflow();

/**
Most useful methods of IDfWorkflowBuilder:
- isRunnable() : Returns true if the dm_process is in the installed state
- getStartStatus() : Returns 0 if the user has permission to start the workflow
- initWorkflow() : This method actually does the work of creating a workflow from the business process
- runWorkflow() : This method starts a workflow
- getStartActivityNames() : Returns a list of the names of every start activity in the workflow
- addPackage() : This method adds a package to the start activity of the workflow
- getWorkflow() : Returns the run-time workflow object created by initWorkflow()
-	

Using the IDfWorkflowBuilder object to create and start a workflow is a multi-step process.
- You must first call the initWorkflow() method to create a dm_workflow object.
- You then call the runWorkflow() method to start the workflow. If the workflow is designed with a start activity that has no input ports, the activity will become active and appear in the recipient’s inbox. If the workflow is designed with a start activity that dows have an input port, the start activity will not become active until you attach a package to its input port. To do this, use the addPackage().
If you don’t know the name of the start activity or want to give the user a list of all the valid start activities to choose from, you can use the getStartActivityNames() method.
*/

• To version to a document via a workflow method :
Params
[0] = “METHOD”
[1] = “SAVE_RESULT”
[2] = “ARGUMENTS”

Types
[0] = “S”
[1] = “B”
[2] = “S”

Values
[0] = “VersioningMethod”
[1] = “F”
[2] = ‘-docbase_name MY_DOCBASE -method_trace_level 10 -orig_id ID_ORIG_XXXX -doc_id ID_VERSION_YYYYY’

private void addVersionToOriginal(IDfSession session, IDfDocument original, IDfDocument document) throws DfException {
		IDfCollection collection = null;
		try {
			IDfList params = new DfList();
			params.append("METHOD");
			params.append("SAVE_RESULT");
			params.append("ARGUMENTS");

			IDfList types = new DfList();
			types.append("S");
			types.append("B");
			types.append("S");

			StringBuilder sb = new StringBuilder(0);
			sb.append("'-docbase_name ").append(session.getDocbaseName());
			if (logger.isDebugEnabled()) {
				sb.append(" -method_trace_level 10");
			} else {
				sb.append(" -method_trace_level 0");
			}

			sb.append(" -orig_id ").append(original.getObjectId().getId());
			sb.append(" -doc_id ").append(document.getObjectId().getId());
			sb.append("'");

			System.out.println(sb.toString());

			IDfList values = new DfList();
			values.append("VersioningMethod");
			values.append("F");
			values.append(sb.toString());

			IDfAuditTrailManager mgr = session.getAuditTrailManager();
			mgr.createAudit(original.getObjectId(), "Calling VersioningMethod", null, null);
			collection = session.apply(null, "DO_METHOD", params, types, values);
			while (collection.next()) {
				if (collection.getBoolean("launch_failed")) {
					throw new MyException("L'ajout de la version au document original a échoué!");
				}
			}
		} finally {
			if (collection != null){
				try{collection.close();}catch(Exception ex){logger.error(ex);}
			}
		}
	}

Packages and Activities
A workflow is made up of one or more activities – the tasks that are to be performed. Activities are assigned to certain users or groups and only become active when a package is delivered to one of the activity’s input ports. In a normal workflow, a user completes an activity and starts the next one by taking a package from the current activity’s output port and routing it to the next activity’s input port. This deactivates the current activity and activates the next one. The process of routing packages from one activity to the next is performed by the server.
An activity receives packages through its input port and sends packages through its output port. The input and output ports of different activities are linked together to create the workflow. To send a document from one person to another, you need two activities, A and B. The output port of A should be connected to the input port of B. This indicates who is sending the document and who is receiving it.
Once a package is attached to an activity, it does not need to be manually attached to all the subsequent activities. It will simply flow from one activity to the next without intervention. Any additional packages will have to be manually attached, but again, once they are attached they will flow as designed in the business process.
When you start a workflow, you must take the package being routed and manually attach it to the workflow’s start activity. A start activity is the entry point that allows us to “kick off” a workflow. Even though a workflow is started, its start activity won’t become active until you give it a package. A workflow can have multiple start activities, but often has only one. In the most common case, we will be routing a single document through the entire workflow. In this case, we’ll want to take a document attach it as a package to the workflow’s start activity.
The Workflow Builder’s addPackage() method. This method takes the following arguments:
– startActivityName: Name of the start activity to which you are attaching this package
– inputPortName : Name of the start activity’s input port
– packageName : Name of the package. Specify your own or use the name of the document you are attaching
– packageType : The object type of the components in the package
– noteText : A text message to attach to the package for the recipient
– notePersistent : A boolean indicating whether or not to show the note to all recipients of the package, anywhere in the workflow, or just the first recipient of the package.
– componentIds : A list of all the objects you are including in this package

-> When the attachment is accepted by the activity, the activity will become active and place a work item in the user’s inbox.
 

• To attach a package to a workflow after it is has been started via WorkflowBuilder object
The steps shown are:
– Get the Names and IDs of the workflow’s start activities
– Select the first start activity and determine the name of its first input port (in a real application, you would probably ask the user which start activity to use)
– Attach a package to the activity using a hard-coded object ID (in a real application you would probably ask the user what document to attach)

// Get lists of the start activity Names and IDs
IDfList StartActivityNames = workflowBuilder.getStartActivityNames();
IDfList StartActivities = workflowBuilder.getStartActivityIds();

// Get the first start activity's Name
String ActivityName = StartActivityNames.getString(i);

// Get the first start activity ID
IDfId ActivityId = (IDfId)StartActivities.get(i);
// Construct an IDfActivity from the start activity ID
IDfActivity TheActivity = (IDfActivity)session.getObject( ActivityId );

// Get the number of ports and loop through them until you find an input port
int nPorts = TheActivity.getPortCount();

String InputPortName = null;
for (int j=0; j<nPorts; j++){
	System.out.println( "Port Name: " + TheActivity.getPortName(j) + ", " + "Port Type = " + TheActivity.getPortType(j) );
	if ( TheActivity.getPortType(j).equals( "INPUT" ) )
		InputPortName = TheActivity.getPortName(j);
}

// With AnActivity and InputPort, we can now attach a package
// First create a list of components (even though we only have one component)

DfList List = new DfList();
List.append( new DfId( "090f475b80000140" ) );

IDfId PackageId = w.addPackage(
		AnActivityName,
		InputPort,
		"Package Name",
		"dm_document",
		"This is a message to the first recipient",
		false,
		List );

System.out.println( "The id of the newly created package is: " +PackageId );

// Now that we have "delivered" a package to a start activity
// of the workflow, this activity will be started

• To attach a package to a workflow after it is has been started via session object

logger.debug("Starting workflow for document: "+document.getObjectId().getId());

IDfProcess process = (IDfProcess) session.getObjectByQualification("dm_process WHERE object_name = '"+ configGed.getDctmWkfName() +"'");
logger.debug("Process ID: "+process.getObjectId().getId());
IDfWorkflowBuilder builder = session.newWorkflowBuilder(process.getObjectId());
builder.initWorkflow();
IDfId workflowId = builder.runWorkflow();
logger.debug("Workflow ID: "+workflowId.getId());

String activityName = builder.getStartActivityNames().getString(0);
IDfList list = new DfList();
list.append(document.getObjectId());
IDfId packageId = builder.addPackage(activityName, "Input:0", "Attachment", DCTM_TYPE_DOC, null, false, list);
logger.debug("Package ID: "+packageId.getId());

Inbox Processing
When an activity becomes active, it usually results in a work item being queued up in someone’s inbox. This inbox is a Documentum-specific inbox, not your email inbox. The inbox contains a list of work items that have been forwarded to the user as well as a list of event notifications. Work items are generally workflow-related while event notifications are simply information messages generated by the server.

A user’s inbox is really just a list of the dmi_queue_item objects that are associated with that user. Documentum has created a view that you can query against that makes it easy to see what items are in a particular user’s inbox.

The difference between dmi_queue_item and dm_queue is simple:

  • dmi_queue_item is the object instance associated with a task assigned to a user/person
  • dm_queue is a view in multiple tables associated with task

 
DFC provides some methods that are useful for manipulating your inbox.
– IDfSession.getEvents() : Returns a collection of unread items in the current user’s inbox. This isn’t as useful as it sounds since most users will want to see all the items in their inbox, not just the unread ones. It’s best to call IDfSession.getEvents() to get a list of all the items in a user’s inbox.
– IDfSession.hasEvents() : Returns true if there are any new items in the user’s inbox since the last time you called hasEvents().
– IDfSession.getTasks() : Returns a collection of all the items in a user’s inbox. Use the DF_TASKS filter to get only workflow-related tasks. The getTasks() method only retrieves these attributes: sent_by, date_sent, task_name, due_date, priority, task_state, r_object_id, item_id. The item_id is the r_object_id of dm_sysobject/dm_document. If you want to get other attributes such as the name of the document, you must specify them in the additionalAttributes argument.
– IDfWorkItem.acquire() : Acquires the task/work item. Acquiring a work item indicates that you intend to work on it. If the task was routed to a group, acquiring the task will cause it to disappear from the other group members’ inboxes.
– IDfWorkItem.complete() : Tells the server that you are finished working on the work item. This will cause the task to be forwareded to the next person in the workflow.
– IDfWorkItem.delegateTask() : Delegates the work item to someone else.
In a production application, processing an inbox would probably be a manual process. A user would view the contents of his inbox and select an item to work on. He would acquire the work item to show that he was working on it and would probably need to view or checkout the document attached to the work item. When he finished modifying the document, he would mark the work item as completed and it would be removed from his inbox. If he refreshed his inbox, he would see that the work item was no longer there.
 

• Create a item / task in inbox

public IDfId createQueueItem(IDfSysObject dfSysObject) throws DfException {
	try {
		// dfSysObject.queue(getUserName(), getEventName(), getPriority(), isSendMail(), getDueDate(), getMessage());
		return dfSysObject.queue("myitemname", "myeventname", 0, false, new DfTime(GregorianCalendar.getInstance().getTime()), "my message");
	} catch (DfException e) {
		logger.log(Level.WARNING, MessageFormat.format("Unable to create dmi_queue_item for item {0} : {1}", dfSysObject.getObjectId(), e.getMessage()), e);
	}
	return DfId.DF_NULLID;
}

• To view task in inbox – example 1

public void getInbox() throws Exception {
	IDfCollection tasks = idfSession.getTasks("temp", IDfSession.DF_TASKS, "name, date_sent, message ", "task_name");
	try {
		while (tasks.next()) {
			IDfWorkitem wi = (IDfWorkitem) idfSession.getObject(tasks.getId("item_id"));
			IDfId queueItemId = wi.getQueueItemId();
			IDfQueueItem qi = (IDfQueueItem) idfSession.getObject(queueItemId);
			System.out.println(tasks.getString("sent_by") + "   "
				+ tasks.getString("task_name") + "   "
				+ tasks.getString("date_sent") + "   "
				+ tasks.getString("message") + "   "
				+ qi.getItemName());

			IDfActivity dfActivity = wi.getActivity();
			System.out.println("\tActivity Information : " + dfActivity.getString("object_name"));
			IDfCollection packColl = null;
			try {
				packColl = wi.getPackages("");
				while (packColl.next()) {
					IDfSysObject sysObj = (IDfSysObject) idfSession.getObject(packColl.getId("r_component_id"));
					System.out.println("\t Package Information: " + sysObj.getString("object_name"));
				}
			} finally {
				if (packColl != null)
					packColl.close();
			}
			// to finish a Task or Workitem
			// finishTask(wi);
		}
	} finally {
		if (tasks != null)
			tasks.close();
	}
}

public void finishTask(IDfWorkitem wi) throws Exception {
	if (wi.getRuntimeState() == IDfWorkflow.DF_WF_STATE_DORMANT) {
		wi.acquire();
	}
	wi.complete();
}

• To view task in inbox – example 2
The following example shows how to query the docbase for the contents of the current user’s inbox. It will print the name of the document, the r_object_id of the document (needed if the user is going to view or check out the document), the person who sent the document and that date/time it was sent, the work item’s ID (needed for the user to aquire and complete the work item), the name of the task, the due date requested by the sender, and the message sent by the sender.

// Use getTasks to get all the tasks in the user's inbox
// Use the DF_TASKS filter so that we don't get any event notifications
// Specify these addtionalAttributes: item_name, due_date, message
// Order the results by the date_sent
IDfCollection Tasks = d.getTasks( "/articles/dmin", IDfSession.DF_TASKS,  "item_name, due_date, message", "date_sent" );
	while ( Tasks.next() )
	{
		IDfTypedObject Next = Tasks.getTypedObject();

		java.util.Enumeration e = Next.enumAttrs();

		while ( e.hasMoreElements() )
		{
			IDfAttr NextAttr = (IDfAttr)e.nextElement();

			System.out.print( NextAttr.getName() + " = " );

			int AttrCount = 0;
			if ( NextAttr.isRepeating() )
				AttrCount = Next.getValueCount(
					NextAttr.getName() );
			else
				AttrCount = 1;

			for (int i=0; i<AttrCount; i++)
			{
				// Get the next value!
				IDfValue NextAttrValue = Next.getRepeatingValue( NextAttr.getName(), i );
				System.out.print( NextAttrValue );
				System.out.print( ", " );
			}
		}
		System.out.println();
	}
}

• To get the TASK linked to a document
The following example shows how to query the docbase for the contents of the current user’s inbox. It will print the name of the document, the r_object_id of the document (needed if the user is going to view or check out the document), the person who sent the document and that date/time it was sent, the work item’s ID (needed for the user to aquire and complete the work item), the name of the task, the due date requested by the sender, and the message sent by the sender.

private IDfWorkitem getTask(IDfSession session, String documentId) throws DfException {
	StringBuilder sb = new StringBuilder(0);
	sb.append("dmi_workitem WHERE ")
		.append("r_queue_item_id IN (SELECT r_object_id FROM dmi_queue_item WHERE delete_flag = FALSE) AND ")
		.append("r_workflow_id IN (SELECT DISTINCT r_workflow_id FROM dmi_package WHERE ")
		.append("ANY r_component_chron_id = '").append(documentId).append("')");
	logger.debug("Workitem query: "+sb.toString());
	return (IDfWorkitem) session.getObjectByQualification(sb.toString());
}

• To acquire work items
This example assumes that you know the r_object_id of the work item (which you would have retrieved from the previous example). It shows how to acquire the work item.

IDfPersistentObject pObj = sess.getObjectByQualification("dmi_queue_item where r_object_id='" + TaskId.toString() + "'");

// Make sure the task(s) for this user are associated with the workflow
if (pObj.getId("router_id").toString().equals( wfId.getId() ))
{
	IDfWorkitem wi = (IDfWorkitem)d.getObject(tasks.getId("item_id"));
	wi.acquire();
	// Do some processing on the work item here
	// ...
}

• To accept a task

private void lockTask(IDfWorkitem wi) throws DfException {
	if (wi.getRuntimeState() == IDfWorkitem.DF_WI_STATE_DORMANT) {
		wi.acquire();
		logger.debug("Acquiring task: "+wi.getObjectId().getId());
	}
}

• To complete work items – example 1
This example assumes that you know the r_object_id of the work item (which you would have retrieved from the previous example). It shows how to complete the work item, which will remove it from the users inbox and forward it to the next user in the workflow.

IDfPersistentObject pObj = sess.getObjectByQualification("dmi_queue_item where r_object_id='" + TaskId.toString() + "'");
// Make sure the task(s) for this user are associated with the workflow
if (pObj.getId("router_id").toString().equals( wfId.getId() ))
{
	IDfWorkitem wi = (IDfWorkitem)d.getObject(tasks.getId("item_id"));
	// Acquire the work item here.
	// Done some processing on the work item: ready to complete
	wi.complete();
}

• To complete work items – example 2

private void completeTask(IDfWorkitem wi, String activityName) throws DfException {
	if (wi.getRuntimeState() == IDfWorkitem.DF_WI_STATE_DORMANT)
		lockTask(wi);

	IDfList activities = wi.getForwardActivities();
	int count = activities.getCount();
	if (count > 1) {
		IDfList list = new DfList();
		for (int i = 0; i < count; i++) {
			IDfActivity activity = (IDfActivity) activities.get(i);
			if (activity.getObjectName().equals(activityName)) {
				list.append(activity);
				break;
			}
		}
		wi.setOutputByActivities(list);
	}
	wi.complete();
	logger.debug("Completing task: "+wi.getObjectId().getId());
}

• To reject a task
The following example shows how to query the docbase for the contents of the current user’s inbox. It will print the name of the document, the r_object_id of the document (needed if the user is going to view or check out the document), the person who sent the document and that date/time it was sent, the work item’s ID (needed for the user to aquire and complete the work item), the name of the task, the due date requested by the sender, and the message sent by the sender.

private void rejectTask(IDfWorkitem wi) throws DfException {
	if (wi.getRuntimeState() == IDfWorkitem.DF_WI_STATE_DORMANT)
		lockTask(wi);

	IDfList activities = wi.getRejectActivities();
	IDfList list = new DfList();
	list.append(activities.get(0));
	wi.setOutputByActivities(list);
	wi.complete();
	logger.debug("Rejecting task: "+wi.getObjectId().getId());
}

• To forward the workflow via method server

IDfWorkitem wi = getWorkitem();
IDfDocument document = getDocument();

//...

String activity = (String) wi.getNextActivityNames().get(0);
IDfList performers = new DfList();
String performer = getGroupForService(document.getInt(ATTR_DESTINATION_SERVICE));
performers.append(performer);
IDfWorkflow workflow = (IDfWorkflow) getSession().getObject(wi.getWorkflowId());
workflow.setPerformers(activity, performers);
IDfAuditTrailManager mgr = getSession().getAuditTrailManager();
mgr.createAudit(document.getObjectId(), "Executing WorkflowMethod", null, null);

• To give access without use of ACL (read right to sender and write right to recipient)

IDfDocument document = ...;
String sender = getGroupForService(document.getInt(ATTR_SEND_SERVICE));
printLogDctmServerMethodServer("Sending service: "+sender+" for document: "+document.getObjectId().getId()+" ("+document.getString(ATTR_REFERENCE)+","+document.getString(ATTR_VERSION_LABEL)+") ");
if (sender != null) {
	document.revoke(sender, null);
	document.grant(sender, IDfACL.DF_PERMIT_READ, null);
	printLogDctmServerMethodServer("Revoke permission and add read permission to service: "+sender+" for document: "+document.getObjectId().getId()+" ("+document.getString(ATTR_REFERENCE)+","+document.getString(ATTR_VERSION_LABEL)+") ");
}

String performer = getGroupForService(document.getInt(ATTR_DESTINATION_SERVICE));
printLogDctmServerMethodServer("Grant write permit to Destination service: "+performer+" for document: "+document.getObjectId().getId()+" ("+document.getString(ATTR_REFERENCE)+","+document.getString(ATTR_VERSION_LABEL)+") ");
document.grant(performer, IDfACL.DF_PERMIT_WRITE, null);


——————— LINKING ————————–


• For all others versions of a document in argument, this method :
– Removes all links
– Adds the same links than the document in argument.
If a version has already the same links, no change is applied.

private void linkOtherVersionsToSameLinks(IDfDocument document) throws DfException {
	IDfSession session = document.getSession();


	// Get all links from the document
	Set<String> links = new HashSet<String>();
	int count = document.getFolderIdCount();
	for (int i = 0; i < count; i++) {
		links.add(document.getFolderId(i).getId());
	}

	// Get other versions document
	StringBuilder sb = new StringBuilder();
	String documentId = document.getObjectId().getId();
	String chronicleId = document.getChronicleId().getId();
	sb.append("SELECT r_object_id FROM my_custom_document (all) WHERE i_chronicle_id = '")
		.append(chronicleId).append("' and r_object_id != '").append(documentId).append("'");
	IDfCollection coll = null;
	List<String> otherVersionsIds = new ArrayList<String>();
	try {
		IDfQuery query = new DfQuery(sb.toString());
		coll = query.execute(session, DfQuery.DF_QUERY);
		while (coll.next()) {
			String objectId = coll.getString("r_object_id");
			otherVersionsIds.add(objectId);
		}
	} finally {
		if (null != coll) {
			try {
				coll.close();
			} catch(DfException e) {
				LOGGER.warn("Warning, can't close the DfCollection", e);
			}
		}
	}

	for (String otherVersionId : otherVersionsIds) {
		IDfDocument otherVersionDocument = (IDfDocument) session.getObject(new DfId(otherVersionId));

		// Get all links from the other version
		Set<String> linksOtherVersion = new HashSet<String>();
		int otherVersionCount = otherVersionDocument.getFolderIdCount();
		for (int i = 0; i < otherVersionCount; i++) {
			linksOtherVersion.add(otherVersionDocument.getFolderId(i).getId());
		}

		// Check if the other versions need to be updated with the links
		if (links.size() == linksOtherVersion.size() && links.containsAll(linksOtherVersion)) {
			continue;
		}

		// Unlink other links
		for (String link : linksOtherVersion) {
			otherVersionDocument.unlink(link);
		}

		// Link to new links
		for (String link : links) {
			otherVersionDocument.link(link);
		}

		otherVersionDocument.save();
	}
}


——————— ACL ————————–


• Creation of ACL

package com.huo.test.ecm.test3;


import java.text.MessageFormat;

import com.documentum.fc.client.DfClient;
import com.documentum.fc.client.IDfACL;
import com.documentum.fc.client.IDfClient;
import com.documentum.fc.client.IDfPermit;
import com.documentum.fc.client.IDfPermitType;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.client.IDfSessionManager;
import com.documentum.fc.client.IDfSysObject;
import com.documentum.fc.common.DfLoginInfo;
import com.documentum.fc.common.IDfList;
import com.documentum.fc.common.IDfLoginInfo;

/**
 Documentum DFC - ACL
 */
public class DfcCreationUpdateACLTest {
	IDfSysObject sysObject = null;
	IDfSession idfSession = null;
	IDfSessionManager sessMgr = null;

	public DfcCreationUpdateACLTest(String user, String passwd, String docbase) throws Exception {
		getDfSession(user, passwd, docbase);
	}

	public IDfSession getDfSession(String args1, String args2, String args3) throws Exception {
		IDfLoginInfo login = new DfLoginInfo();
		login.setUser(args1);
		login.setPassword(args2);
		IDfClient client = DfClient.getLocalClient(); // new DfClient();
		sessMgr = client.newSessionManager();
		sessMgr.setIdentity(args3, login);
		idfSession = sessMgr.getSession(args3);

		if (idfSession != null)
			System.out.println("Session created successfully");

		return idfSession;
	}

	public void releaseSession() throws Exception {
		sessMgr.release(idfSession);
	}

	public static void main(String[] args) throws Exception {
		long startTime = 0;
		long stopTime = 0;

		String user = "mysuperuser";
		String passwd = "pwd4superuser";
		String docbase = "MY_DOCBASE_DEV";
		String aclName = "TEST ACL HUO World Write";
		String aclDomain = "MYDOCBASEDEV"; // docbase owner : select owner_name from dm_docbase_config;
		DfcCreationUpdateACLTest object = new DfcCreationUpdateACLTest(user, passwd, docbase);

		boolean isTransactionalSession = false;
		boolean noErrorWithCurrentDocument = false;
		try {
			if (!object.idfSession.isTransactionActive()) {
				object.idfSession.beginTrans();
				isTransactionalSession = true;
			}

			startTime = System.currentTimeMillis();

			IDfACL dfACL = object.idfSession.getACL(aclDomain, aclName);
			if (dfACL == null) {
				dfACL = (IDfACL) object.idfSession.newObject("dm_acl");
				dfACL.setObjectName(aclName);
				dfACL.setDomain(aclDomain);
				dfACL.setACLClass(0); // User ACL
				dfACL.setDescription("ACL test created via DFC");
				dfACL.save();
			}

			String message = MessageFormat.format("acl({0}, {1}) was successfully ", aclDomain, aclName) + ((dfACL.isNew()) ? "created." : "modified.");
			System.out.println(message);

			stopTime = System.currentTimeMillis();

			noErrorWithCurrentDocument = true;

		} finally {
			if(object!=null){
				if (isTransactionalSession) {
					if (noErrorWithCurrentDocument) {
						object.idfSession.commitTrans();
					} else {
						object.idfSession.abortTrans();
					}
				}

				// to release a docbase session
				object.releaseSession();

				long elapsedTime = stopTime - startTime;
				System.out.println(MessageFormat.format("Execute() total execution time : {0} ms ", elapsedTime));
			}
		}
	}
}

/**
... the created ACL will be the following accessors:
r_accessor_name
[0]: dm_world
[1]: dm_owner

r_accessor_permit
[0]: 1 (for None)
[1]: 1 (for None)

r_accessor_xpermit
[0]: 0 (for execute_proc, change_location)
[1]: 0 (for execute_proc, change_location)

r_permit_type
[0]: 0 (for ACCESS_PERMIT)
[1]: 0 (for ACCESS_PERMIT)
*/

• Add new accessors to previous ACL

IDfACL dfACL = object.idfSession.getACL(aclDomain, aclName);
dfACL.grantPermit(new IDfPermit() {
	@Override
	public String getAccessorName() { return "mysuperuser"; }
	@Override
	public int getPermitType() { return IDfPermitType.ACCESS_PERMIT; }
	@Override
	public int getPermitValueInt() { return IDfACL.DF_PERMIT_DELETE; }
	@Override
	public String getPermitValueString() { return IDfACL.DF_PERMIT_DELETE_STR; }
	@Override
	public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
});
dfACL.grantPermit(new IDfPermit() {
	@Override
	public String getAccessorName() { return "myuser001"; }
	@Override
	public int getPermitType() { return IDfPermitType.ACCESS_RESTRICTION; }
	@Override
	public int getPermitValueInt() { return IDfACL.DF_PERMIT_VERSION; }
	@Override
	public String getPermitValueString() { return IDfACL.DF_PERMIT_VERSION_STR; }
	@Override
	public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
	@Override
	public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
});

dfACL.save();

/**
... so, the ACL will be modified like:
r_accessor_name
[0]: dm_world
[1]: dm_owner
[2]: mysuperuser --- inserted ---
[3]: myuser001 	--- inserted ---

r_accessor_permit
[0]: 1 (for None)
[1]: 1 (for None)
[2]: 7 (for Delete) --- inserted ---
[3]: 5 (for Version) --- inserted ---

r_accessor_xpermit
[0]: 0 (for execute_proc, change_location)
[1]: 0 (for execute_proc, change_location)
[2]: 0 (for execute_proc, change_location) --- inserted ---
[3]: 0 (for execute_proc, change_location) --- inserted ---

r_permit_type
[0]: 0 (for ACCESS_PERMIT)
[1]: 0 (for ACCESS_PERMIT)
[2]: 0 (for ACCESS_PERMIT) --- inserted ---
[3]: 3 (for ACCESS_RESTRICTION) --- inserted ---
*/

• Rewoke all current permits/xpermits to previous ACL via DFC
Warning : the “dm_world” and “dm_owner” accessors can not be removed totally => so, these accessors have always entries even if without permissions and extended permissions.

IDfACL dfACL = object.idfSession.getACL(aclDomain, aclName);
IDfList list;
while (0 < (list = dfACL.getPermissions()).getCount()) {
	dfACL.revokePermit((IDfPermit) list.get(0));
}
dfACL.save();

/**
... so, the ACL will be modified like:
r_accessor_name
[0]: dm_world
[1]: dm_owner

r_accessor_permit
[0]: 0 (for NULL) --- modified ---
[1]: 0 (for NULL) --- modified ---

r_accessor_xpermit
[0]: 3 (for None) --- modified ---
[1]: 3 (for None) --- modified ---

r_permit_type
[0]: 0 (for ACCESS_PERMIT)
[1]: 0 (for ACCESS_PERMIT)
*/

• To assign a ACL to a document

public void assignACL() throws Exception {
	IDfSysObject mDocs = (IDfSysObject) idfSession.getObjectByQualification("dm_document where object_name='UniqueDoc' ");
	IDfACL dfACL = (IDfACL) idfSession.getObjectByQualification("dm_acl where object_name='TrainingACL' ");
	mDocs.setACL(dfACL);
	mDocs.save();
}


——————— ALIAS SET / TEMPLATE ACL (PERMISSION SET TEMPLATE) ————————–


• Creation of Alias Set (dm_alias_set)

private boolean setAliasSetValue(IDfAliasSet aliasSet, String aliasName, String aliasValue, int aliasCategory, String aliasDescription) throws DfException {
	int index;
	if ((index = aliasSet.findAliasIndex(aliasName)) >= 0) {
		if (!aliasValue.equals(aliasSet.getAliasValue(index))) {
			System.out.println("Alias set " + aliasSet.getObjectName() + " : modified " + aliasName + " '" + aliasSet.getAliasValue(index) + "' => '" + aliasValue + "'");
			aliasSet.setAliasValue(index, aliasValue);
			System.out.println("Alias set " + aliasSet.getObjectName() + " : modified " + aliasDescription + " '" + aliasSet.getAliasDescription(index) + "' => '" + aliasDescription + "'");
			aliasSet.setAliasDescription(index, aliasDescription);
			return true;
		}
	} else {
		aliasSet.appendAlias(aliasName, aliasValue, aliasCategory, -1, aliasDescription);
		System.out.println("Alias set " + aliasSet.getObjectName() + " : added '" + aliasName + "', '" + aliasValue + "', '" + aliasDescription + "'");
		return true;
	}
	return false;
}


String aliasSetName = "TEST AS HUO Simple";
IDfAliasSet aliasSet = (IDfAliasSet) object.idfSession.getObjectByQualification("dm_alias_set where object_name ='" + aliasSetName + "'");
if (aliasSet == null) {
	aliasSet = (IDfAliasSet) object.idfSession.newObject("dm_alias_set");
	aliasSet.setObjectName(aliasSetName);
	aliasSet.setOwnerName("dm_dbo");
	aliasSet.setObjectDescription("Desc 4 TEST AS HUO Simple");

	//# ALIAS 1 : GROUP
	object.setAliasSetValue(aliasSet, "AS4MyGroup", "huo_grp_all_users", 2, "Entry for a group alias (huo_grp_all_users)");

	//# ALIAS 2 : USER
	object.setAliasSetValue(aliasSet, "AS4SuperUser", "myuser001", 1, "Entry for a user alias (myuser001)");

	aliasSet.save();
}

/**
USER ATTRIBUTES
	owner_name                 : dm_dbo
	object_name                : TEST AS HUO Simple
	object_description         : Desc 4 TEST AS HUO Simple
	alias_name              [0]: AS4MyGroup
				[1]: AS4SuperUser
	alias_value             [0]: huo_grp_all_users
				[1]: myuser001
	alias_category          [0]: 2
				[1]: 1
	alias_usr_category      [0]: -1
				[1]: -1
	alias_description       [0]: Entry for a group alias (huo_grp_all_users)
				[1]: Entry for a user alias (myuser001)
SYSTEM ATTRIBUTES
	r_object_id                : 660xxxxxxx90c
*/

Concerning the the category (alias_category ) for the alias in the specified index position in the alias set. This value is set by the creator of the alias object and used by Documentum client applications. The server does not verify the category value against the alias value to ensure that alias value is in the specified category.
Currently, only the following values are allowed:

  • 0 (Unknown)
  • 1 (User, alias_value is a user)
  • 2 (Group, alias_value is a group)
  • 3 (User or Group, alias_value is either a user or a group)
  • 4 (Cabinet Path, alias_value is a cabinet path)
  • 5 (Folder Path, alias_value is a folder path)
  • 6 (ACL Name, alias_value is an ACL name)

• Creation of Template ACLs or Permission Set Template (acl_class=1)

String aclTemplateName = "TEST PST HUO Simple";
String aclTemplateDomain = "MYDOCBASEDEV"; // docbase owner : select owner_name from dm_docbase_config;
IDfACL dfTemplateACL = object.idfSession.getACL(aclTemplateDomain, aclTemplateName);
if (dfTemplateACL == null) {
	dfTemplateACL = (IDfACL) object.idfSession.newObject("dm_acl");
	dfTemplateACL.setObjectName(aclTemplateName);
	dfTemplateACL.setDomain(aclTemplateDomain);
	dfTemplateACL.setACLClass(1); // PST
		dfTemplateACL.setDescription("Desc 4 TEST PST HUO Simple");

	// grant,c,l,dm_world,AccessPermit,,3
	dfTemplateACL.grantPermit(new IDfPermit() {
		@Override
		public String getAccessorName() { return "dm_world"; }
		@Override
		public int getPermitType() { return IDfPermitType.ACCESS_PERMIT; }
		@Override
		public int getPermitValueInt() { return IDfACL.DF_PERMIT_READ; }
		@Override
		public String getPermitValueString() { return IDfACL.DF_PERMIT_READ_STR; }
		@Override
		public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
	});

	// grant,c,l,dm_owner,AccessPermit,,3
	dfTemplateACL.grantPermit(new IDfPermit() {
		@Override
		public String getAccessorName() { return "dm_owner"; }
		@Override
		public int getPermitType() { return IDfPermitType.ACCESS_PERMIT; }
		@Override
		public int getPermitValueInt() { return IDfACL.DF_PERMIT_READ; }
		@Override
		public String getPermitValueString() { return IDfACL.DF_PERMIT_READ_STR; }
		@Override
		public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
	});

	// grant,c,l,%AS4MyGroup,AccessPermit,,6
	dfTemplateACL.grantPermit(new IDfPermit() {
		@Override
		public String getAccessorName() { return "%AS4MyGroup"; }
		@Override
		public int getPermitType() { return IDfPermitType.ACCESS_PERMIT; }
		@Override
		public int getPermitValueInt() { return IDfACL.DF_PERMIT_WRITE; }
		@Override
		public String getPermitValueString() { return IDfACL.DF_PERMIT_WRITE_STR; }
		@Override
		public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
	});

	// grant,c,l,%AS4SuperUser,AccessPermit,,7
	dfTemplateACL.grantPermit(new IDfPermit() {
		@Override
		public String getAccessorName() { return "%AS4SuperUser"; }
		@Override
		public int getPermitType() { return IDfPermitType.ACCESS_PERMIT; }
		@Override
		public int getPermitValueInt() { return IDfACL.DF_PERMIT_DELETE; }
		@Override
		public String getPermitValueString() { return IDfACL.DF_PERMIT_DELETE_STR; }
		@Override
		public void setAccessorName(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitType(int arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitTypeString(String arg0) { throw new RuntimeException("Not implemented"); }
		@Override
		public void setPermitValue(String arg0) { throw new RuntimeException("Not implemented");}
	});

	dfTemplateACL.save();
}

/**
USER ATTRIBUTES
	object_name                : TEST PST HUO Simple
	description                : Desc 4 TEST PST HUO Simple
	owner_name                 : MYDOCBASEDEV
	globally_managed           : F
	acl_class                  : 1

SYSTEM ATTRIBUTES
	r_object_id                : 450xxxxxx151
	r_is_internal              : F
	r_accessor_name         [0]: dm_world
				[1]: dm_owner
				[2]: %AS4MyGroup
				[3]: %AS4SuperUser
	r_accessor_permit       [0]: 3
				[1]: 3
				[2]: 6
				[3]: 7
	r_accessor_xpermit      [0]: 0
				[1]: 0
				[2]: 0
				[3]: 0
	r_is_group              [0]: F
				[1]: F
				[2]: F
				[3]: F
	r_has_events               : F
	r_permit_type           [0]: 0
	                        [1]: 0
				[2]: 0
				[3]: 0
	r_application_permit    [0]:
				[1]:
				[2]:
				[3]:
	r_template_id              : 0000000000000000
	r_alias_set_id             : 0000000000000000
*/

• Creation of Instance of Template ACL using the PST previous and AS (acl_class=2).
An instance of an ACL template is created when an AliasSet and PST are associated to a document. It is not possible to create directly manually an instance of PST.
The error DM_ACL_E_CANT_CHANGE_INSTANCE occurs if the user tries to modify a instance of PST (acl_class=2). To modify the instances of PST, it is necessary to modify the PST or PST/AliasSet associated to theses instances.

String documentName ="Test DOC HUO WITH AS AND PST";
IDfDocument document = (IDfDocument) object.idfSession.getObjectByQualification("dm_document where object_name ='" + documentName + "'");
if (document == null) {
	document = (IDfDocument) object.idfSession.newObject("dm_document");
	document.setObjectName(documentName);
	document.setContentType("pdf");
	document.setFile("C:/temp/test.pdf");
	document.link("/"+user);
	// ALIAS SET
	document.setString("r_alias_set_id", aliasSet.getObjectId().toString());
	// PST
	document.setACLName(dfTemplateACL.getObjectName());
	document.setACLDomain(dfTemplateACL.getDomain());
	document.save();

	/**
	USER ATTRIBUTES
	  object_name                : Test DOC HUO WITH AS AND PST
	  acl_domain                 : MYDOCBASEDEV
	  acl_name                   : dm_450xxxxxx151_xxxxx90c

	SYSTEM ATTRIBUTES
	  r_object_id                : 09xxxxx87
	  r_object_type              : dm_document
	 */
}//end-if

So, the association between document, AliasSet and Templace ACL generates an instance of Templace ACL (acl_class=2) with name like dm_450xxxxxxx94_xxxxd3e. This instance is created only if its is not already exist.

// Reload document
document = (IDfDocument) object.idfSession.getObjectByQualification("dm_document where object_name ='" + documentName + "'");
IDfACL dfInstanceACL = object.idfSession.getACL(document.getACLDomain(), document.getACLName());
if (dfInstanceACL != null) {
	System.out.println("Document '"+documentName+"' associated with instance of Template ACL '"+document.getACLName()+"' / '"+document.getACLDomain()+"'");
	System.out.println("The instance of Template ACL '"+document.getACLName()+"' / '"+document.getACLDomain()+"' => "+dfInstanceACL.getString("r_object_id"));
	System.out.println("	o Alias Set = '"+dfInstanceACL.getString("r_alias_set_id")+"'");
	System.out.println("	o Template ACL (PST) = '"+dfInstanceACL.getString("r_template_id")+"'");

	/**
	Document 'Test DOC HUO WITH AS AND PST' associated with instance of Template ACL 'dm_450xxxxxx151_xxxxx90c' / 'MYDOCBASEDEV'

	The instance of Template ACL 'dm_450xxxxxx151_xxxxx90c' / 'MYDOCBASEDEV' => 45xxxxxx94e
		o Alias Set = '660xxxxxxx90c'
		o Template ACL (PST) = '450xxxxxx151'

	USER ATTRIBUTES
	  object_name                : dm_450xxxxxx151_xxxxx90c
	  description                : dm_450xxxxxx151_xxxxx90c
	  owner_name                 : MYDOCBASEDEV
	  globally_managed           : F
	  acl_class                  : 2

	SYSTEM ATTRIBUTES
	  r_object_id                : 45xxxxxx94e
	  r_is_internal              : T
	  r_accessor_name         [0]: dm_world
	                          [1]: dm_owner
	                          [2]: AS4MyGroup
	                          [3]: AS4SuperUser
	  r_accessor_permit       [0]: 3
	                          [1]: 3
	                          [2]: 6
	                          [3]: 7
	  r_accessor_xpermit      [0]: 0
	                          [1]: 0
	                          [2]: 0
	                          [3]: 0
	  r_is_group              [0]: F
	                          [1]: F
	                          [2]: T
	                          [3]: F
	  r_has_events               : F
	  r_permit_type           [0]: 0
	                          [1]: 0
	                          [2]: 0
	                          [3]: 0
	  r_application_permit    [0]:
	                          [1]:
	                          [2]:
	                          [3]:
	  r_template_id              : 450xxxxxx151
	  r_alias_set_id             : 660xxxxxxx90c

	APPLICATION ATTRIBUTES

	INTERNAL ATTRIBUTES
	  i_has_required_groups      : F
	  i_has_required_group_set   : F
	  i_has_access_restrictions  : F
	  i_partition                : 0
	  i_is_replica               : F
	  i_vstamp                   : 0
 */
}


——————— DOCUMENT SECURITY ————————–


• To check the user’s permission level on a document. The “getPermit()” method returns an integer number that corresponds to the access permission level that the current user has for the object: DF_PERMIT_NONE = 1 / DF_PERMIT_BROWSE = 2 / DF_PERMIT_READ = 3 / DF_PERMIT_RELATE = 4 / DF_PERMIT_VERSION = 5 / DF_PERMIT_WRITE = 6 / DF_PERMIT_DELETE = 7

String qualification = "my_document WHERE i_chronicle_id = ID(''090xxxxxxxxxxx'')";
IDfDocument dfDocument = (IDfDocument) session.getObjectByQualification(qualification);

if (dfDocument == null) {
	throw new DfException("Unable to find object with qualification : " + qualification );
}

if (dfDocument.getPermit() < IDfACL.DF_PERMIT_DELETE && dfDocument.getXPermitNames(null).indexOf(IDfACL.DF_XPERMIT_DELETE_OBJECT_STR) != -1) {
	throw new DfException(MessageFormat.format("{0} does not have sufficient permissions to delete object {1}", session.getUser(null).getUserName(), dfDocument.getObjectId().getId()));
}
int userPermit = document.getPermit();
if(userPermit < IDfACL.DF_PERMIT_WRITE){
	throw new RuntimeException("Current user has is not authorized to upload a document ");
}


——————— METHOD ————————–


<pre class="wp-block-syntaxhighlighter-code">
IDfApplyDoMethod applyDoMethod = (IDfApplyDoMethod) DfAdminCommand.getCommand(IDfAdminCommand.APPLY_DO_METHOD);
					
StringBuffer arguments = new StringBuffer("");
arguments.append(" -docbase ").append(dfSession.getDocbaseName());
arguments.append(" -userName ").append(dfSession.getUser(null).getUserLoginName());
arguments.append(" -myparam ").append(myvalue);
applyDoMethod.setArguments(StringUtils.trimToEmpty(arguments.toString()));

applyDoMethod.setSaveResults(false);
applyDoMethod.setTimeOut(120); // seconds
applyDoMethod.setLaunchDirect(false);
applyDoMethod.setLaunchAsync(true);
applyDoMethod.setRunAsServer(true);
applyDoMethod.setTraceLaunch(false);

String methodName = "My_MethodToLaunchCmdLauncher";
applyDoMethod.setMethod(methodName);

IDfCollection dfCollection = null;
try {
	dfCollection = applyDoMethod.execute(dfSession);
} finally {
	if (dfCollection != null) {
		dfCollection.close();
	}
}

</pre>