IDfCollections, Part IV

In this post I will show you how to do a recursive operation using IDfCollection objects.  Perhaps more accurately, I will show you how to do a recursive operation in spite of IDfCollection objects.  As I mentioned in Part I of this series, the number of available IDfCollections is limited and it is very important to close collection objects as soon as you are done processing them.  This leads to two problems when considering a recursive operation:  1) you don’t know ahead of time how many IDfCollection objects will be required; and 2) some of the collection objects may need to remain open for a long time.

The obvious solution to the problem is to replace the IDfCollection object with something that is a little more functional.  In the code below I simply us an ArrayList of IDfTypedObjects to represent the contents of the IDfCollection object.  I know, this solution runs contrary to the warning I made in Part I of this series when I warned never to instantiate the IDfTypedObject from the collection.  Well, in this case it is warranted, and the overhead involved with retrieving and instantiating the object is lost in the recursion itself.

I won’t go through all of this code but simply state that it’s purpose is to traverse a folder structure, and print a directory listing (similar to an old DOS directory listing).  It’s probably not the most practical or useful code,  but it illustrates recursion with IDfCollections pretty well.  The key to the code is line 40 – 50 where the contents of the collection are transferred to the ArrayList of IDfTypedObjects.  The advantage to using IDfTypedObjects, is that later, when the array contents are processed (lines 7 – 17), you have information about each column of the collection (e.g., the attribute type, the attribute name, etc.).  If your application calls for less information, you could get away with a different or custom data structure in the ArrayList.

IDfFolder folder = (IDfFolder) session.getObjectByQualification("dm_cabinet where object_name = 'Temp'");

// do recursion
ArrayList dirList = doRecursiveDir(folder);

// process results
for (IDfTypedObject tObj : dirList) {
	if (tObj.getString("r_object_id").startsWith("0b")) {
		IDfFolder f = (IDfFolder) session.getObject(new DfId(tObj.getString("r_object_id")));

		System.out.println(f.getFolderPath(0));
	} else {
		System.out.println("\t" + tObj.getString("object_name")
				+ "\t\t" + tObj.getString("r_object_id") + "\t"
				+ tObj.getString("r_creation_date") + "\t"
				+ tObj.getString("a_content_type") + "\t"
				+ tObj.getString("r_full_content_size"));
	}
}

private static ArrayList doRecursiveDir(IDfFolder folder) {
	IDfQuery q = new DfQuery();
	IDfCollection col = null;
	ArrayList tempList = new ArrayList();
	ArrayList objList = new ArrayList();

	try {

		// get contents of current folder
		String dql = "select r_object_id, object_name, r_creation_date, a_content_type, r_full_content_size from dm_sysobject "
				+ "where folder(id('" + folder.getObjectId().toString()	+ "'))";
		q.setDQL(dql);
		col = q.execute(session, DfQuery.DF_READ_QUERY);
		while (col.next()) {
			tempList.add(col.getTypedObject());
		}
		col.close();

		// add objects to list or call recursion if necessary
		for (IDfTypedObject tObj : tempList) {
			objList.add(tObj);

			if (tObj.getString("r_object_id").startsWith("0b")) {
				IDfFolder f = (IDfFolder) session.getObject(new DfId(tObj.getString("r_object_id")));
				objList.addAll(doRecursiveDir(f));
			}
		}
	} catch (DfException e) {
		e.printStackTrace();
	}
	return objList;
}

The output of this code looks like this:

/Temp/Jobs
/Temp/Jobs/dm_GwmTask_Alert
11/11/2011 1:59:26 PM dm_GwmTask_Alert 090000018002c503 11/11/2011 1:59:33 PM crtext 0
11/11/2011 3:15:26 PM dm_GwmTask_Alert 090000018002c52b 11/11/2011 3:15:28 PM crtext 0
11/11/2011 4:10:53 PM dm_GwmTask_Alert 090000018002c535 11/11/2011 4:10:53 PM crtext 0
/Temp/Jobs/dm_FTIndexAgentBoot
/Temp/Jobs/dm_ContentWarning
11/11/2011 1:59:50 PM dm_ContentWarning 090000018002c507 11/11/2011 2:00:09 PM crtext 3909
11/14/2011 11:17:21 AM dm_ContentWarning 090000018002c907 11/14/2011 11:17:40 AM crtext 3909
12/3/2011 10:18:40 PM dm_ContentWarning 090000018002d107 12/3/2011 10:19:15 PM crtext 3906

I haven’t had to do recursive operations too often with Documentum — in fact, I think the only times I have had to do recursion is for building GUI widgets that represented a tree or folder structure.  So, you be the judge of how practical this is.

In the next post, I will present a replacement for the IDfCollection object, the dmRecordSet,  that doesn’t suffer from the IDfCollection object’s shortcomings discussed here over the past few weeks.  For example, the dmRecordSet knows if it is empty; it know how many rows it contains; it can be added to; it can be traversed forward, backward, or randomly; it can be reset, etc.  Check back next week.

Advertisements

About Scott
I have been implementing Documentum solutions since 1997. In 2005, I published a book about developing Documentum solutions for the Documentum Desktop Client (ISBN 0595339689). In 2010, I began this blog as a record of interesting and (hopefully) helpful bits of information related to Documentum, and as a creative outlet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: