TBOs – Part 2

In the last post we looked at types of functionality that could be (should be) implemented in a TBO.  In this post I will provide some skeleton code for creating a TBO.  Chapter 7 in the EMC Documentum Foundation Classes 6.5 Developer’s Guide provides an example of TBO code.  Unfortunately, I have never found this example very helpful or complete.  Instead I offer this code:


/*
* Case Document TBO
* (C) 2010 M. Scott Roth / dm_misc
*
*/

package com.dm_misc.tbo;
import com.documentum.fc.client.*;
import com.documentum.fc.common.*;

// #1

public class CaseDocumentTBO extends DfDocument implements IDfDynamicInheritance, IDfDocument {
private static final String COPYRIGHT ="(C) 2010 M. Scott Roth / dm_misc";
private static final String VERSION = "1.0";
private static final String FEATURES = "";

// #2

public String getVersion() {
return VERSION;
}
public String getVendorString()    {
return COPYRIGHT;
}
public boolean isCompatible( String s )    {
return s.equals(VERSION);
}
public boolean supportsFeature( String s ) {
if( FEATURES.indexOf(s) == -1) {
return false;
} else {
return true;
}
}

// #3

public void doSave(boolean saveLock, String versionLabel, Object[] extendedArgs) throws DfException {

// #4

DfLogger.debug(this, "ENTER: doSave method for obj id {0}, obj name {1}",
new String [] {this.getObjectName(),this.getObjectId().toString()},
null);

// #5

/*
*
* your custom code here
*
*/

// #6

// call super
super.doSave(saveLock, versionLabel, extendedArgs);

//# 7

DfLogger.debug(this, "EXIT: doSave method for obj id {0}, obj name {1}",
new String [] {this.getObjectName(), this.getObjectId().toString()},
null);
}
}

Code Notes:

  1. Make sure you extend the correct base type: DfDocument for documents, DfFolder for folders.  Also make sure you implement the IDfDynamicInheritance interface.  This interface does a lot of powerful stuff that you can read about in Chapter 7 of the EMC Documentum Foundation Classes 6.5 Developer’s Guide. Most notably, without this interface your TBOs will not inherit functionality in the same way repository objects do.
  2. These four methods are required by the TBO and can implemented as-is.  The static FEATURES variable should be a comma delimited string containing a list of special features implemented by this TBO.  I personally have never had use for these methods, but I can see where they would be valuable in a very dynamic system.
  3. This is the method declaration for the doSave() method.  This implementation of doSave() overrides the implementation in DfDocument (or DfFolder depending upon your extended base type).  A complete list of override-able method signatures can be found at the end of Chapter 7 in the EMC Documentum Foundation Classes 6.5 Developer’s Guide.
  4. Use the DfLogger facility to output plenty of debug statements.  I find it best to mark the beginning and the end of method execution in a TBO.
  5. Your custom code goes here.  In the next post I will fill this in with an example.
  6. Be sure to call the supertype method for the method you overrode here.  Depending upon what your TBO does, you might want to call the supertype method before your custom code.  The point is, somewhere call the overridden method, otherwise nothing will happen.
  7. Just like the entry to the method was logged, so is the exit.

Here are a few other notes and things to remember about this code and TBOs in general:

  • Never create TBOs for ‘dm_’ types.  There are numerous notes and warning about doing this and I can tell you from personal experience that doing so can wreck your Docbase.
  • If you are overriding a standard method (one of the ‘doMethods’), make sure to call the supertype’s functionality (but only if necessary – you’ll see an example of this in a later post).  If you don’t, your TBO might not work exactly as you expect it to.
  • You should only call ‘onMethod()’ methods of the supertype, otherwise you risk an infinite loop.
  • Creating an interface for the TBO is optional.  If you only intend to override methods inherited from the parent class, and do not intend to extend the the parent class, an interface class is not necessary.  If you add custom methods that you would like to expose to SBOs or POJOs, an interface is necessary.
  • To detach a TBO from an object type, delete or rename the TBO folder in /System/Modules/TBO/<type name>.
  • Be sure to read Chapter 7, Using the Business Object Framework, in the EMC Documentum Foundation Classes 6.5 Developer’s Guide to familiarize yourself with all of the nuance of DFC and BOF programming.

In the next post I will flesh-out the skeleton code presented here to enable metadata inheritance.

Note:  all of the code discussed in this series can be downloaded here.

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.

4 Responses to TBOs – Part 2

  1. Pingback: Deleting/Disabling TBOs « dm_misc: Miscellaneous Documentum Tidbits and Information

  2. Pingback: Deleting/Disabling TBOs « dm_misc: Miscellaneous Documentum Tidbits and Information

  3. Pingback: TBOs – Part 1 « dm_misc: Miscellaneous Documentum Tidbits and Information

  4. Pingback: Links to All of My Source Code | dm_misc: Miscellaneous Documentum Information

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: