Vous êtes sur la page 1sur 98
Documentum Business Objects Framework Developer's Guide DFC Version 5.1 August 30, 2002 Documentum Confidential and

Documentum Business Objects Framework

Developer's Guide

DFC Version 5.1 August 30, 2002

Copyright © 1999-2002

by Documentum, Inc.

6801 Koll Center Parkway

Pleasanton, CA 94566

All Rights Reserved. Documentum™, Documentum 4i™, Documentum e-Content Server™, Documentum Desktop Client™, Documentum Intranet Client™, Documentum WebPublisher™, Documentum RightSite®, Documentum Administrator™, Documentum Developer Studio™, Documentum WebCache™, Documentum ContentCaster™, AutoRender Pro™, Documentum Content Personalization Services™, Documentum Site Delivery Services™, Documentum Content Authentication Services™, Documentum DocControl Manager™, Documentum Corrective Action Manager™, DocInput™, Documentum DocViewer™, Documentum DocPage Server®, Documentum WorkSpace®, Documentum SmartSpace®, Documentum ViewSpace®, and Documentum SiteSpace™ are trademarks of Documentum, Inc. in the United States and other countries. All other company and product names are used for identification purposes only and may be trademarks of their respective owners.

Table of Contents

DOCUMENTUM BUSINESS OBJECTS FRAMEWORK

1

TABLE OF CONTENTS

3

CHAPTER 1 INTRODUCTION

1-1

Overview

1-1

Business Objects in Perspective

1-2

CHAPTER 2 ARCHITECTURAL OVERVIEW

2-1

DBOF Runtime Architecture

2-1

Summary

2-8

CHAPTER 3 DEVELOPING YOUR FIRST BUSINESS OBJECTS

3-1

Getting Started with DBOF

3-1

Problem Scenario: Business-Wide Auto-numbering

3-2

Solution: Documentum Business Objects

3-2

A Simple Type-based Object Example

3-4

A Simple Service-based Object Example

3-21

CHAPTER 4 DOCUMENTUM BUSINESS OBJECT REGISTRY (DBOR)

4-1

Overview

4-1

Architecture of the DBOR

4-1

DBOR Usage - Runtime Object Lookup

4-4

DBOR Management

4-4

Error Handling

4-7

CHAPTER 5 DBOF SESSION MANAGER

5-1

Introduction

5-1

Session Manager Features and Details

5-2

Managed Sessions

5-5

Authentication

5-12

CHAPTER 6 SERVICE BASED BUSINESS OBJECTS

6-1

Introduction

6-1

Architecture

6-1

Rules and Guidelines (with examples)

6-2

CHAPTER 7 TYPE BASED BUSINESS OBJECTS

7-1

Introduction

7-1

Architecture

7-1

Implementation Rules, Guidelines, and Examples

7-3

Calling Rules, Guidelines, and Examples

7-7

Error Handling

7-8

Best Practices

7-8

CHAPTER 8 USING BUSINESS OBJECTS

8-1

Overview

8-1

How to use a Business Object from WDK

8-1

How to use a Business Object from Visual Basic using IDispatch

8-5

Guidelines and Best Practices

8-6

CHAPTER 9 DEPLOYING BUSINESS OBJECTS

9-1

Overview

9-1

Packaging

9-1

Business Object Registration

9-2

Documentation

9-4

Custom Installer / Uninstaller

9-4

AutoName Components

9-4

Introduction

Documentum Business Objects Framework (DBOF)

Chapter 1 Introduction

Documentum Business Objects Framework is a new framework for developing and executing reusable business logic components. This framework is built in to the Documentum DFC and accessible from applications written using DFC.

New to DFC Version 5.1, the Documentum Business Objects Framework (DBOF) provides a framework and a methodology to develop reusable middleware server components for business logic called Business Objects. This chapter introduces Documentum Business Objects and the benefits this technology provides. It contains the following major sections:

"Overview " on page 1-1

"Business Objects in Perspective" on page 1-2

Overview

The Documentum Business Objects Framework (DBOF) provides an object oriented framework for building, testing, discovering, and deploying server business logic as Business Objects. In addition, it provides a way for developers to hook their own logic into normal DFC procedures by extending DFC classes.

DBOF lives wherever DFC lives, either on the Content Server or application servers, or on any of the other clients.

DBOF is part of the DFC library and consists of several Java classes and interfaces for constructing and running Documentum Business Objects (DBO) (see Figure 1-1). There are two types of Documentum Business Objects, type-based business objects, and service-based business objects. A type-based business object can extend a Documentum Server persistent object type (e.g. "com_accelera_catalog" or "com_accelera_autonumber" might extend "dm_document") and extend its capabilities by providing new methods for those types (actually, new user defined Java classes) and allowing overriding of existing methods, like save(), checkinEx() and checkoutEx(). A service-based business object provides methods that perform more generalized procedures that are not usually bound to a specific object type or even Docbase.

The specific business logic within the business objects is implemented using the standard DFC framework allowing developers to implement a new DBO without a steep learning curve. Since DBOF objects are based on the Documentum Foundation Classes (DFC), the developer can maintain a high degree of compatibility with existing DFC applications.

This framework was designed to provide the ability to develop pluggable components, each component implementing one or more middle-tier business rules. Figure 1-2 shows a diagram of DFC and which parts of it are related to DBOF. Notice that the DBO framework is implemented mostly in the DFC core layer. Custom business objects can hook in and extend parts of DFC. In the future, DFC might implement some of its own

Introduction

Documentum Business Objects Framework (DBOF)

business objects. Service-based business objects can call into DFC, but are not considered part of DFC.

Figure 1-1 DFC Provides DBO Framework Service-based Business Objects Service-based Business Objects Other Bus. Obj.
Figure 1-1 DFC Provides DBO Framework
Service-based Business Objects
Service-based Business Objects
Other Bus. Obj.
Other Bus. Obj.
Your Bus. Obj.
Your Bus. Obj.
Other Bus. Obj.
Other Bus. Obj.
Your Bus. Obj.
Your Bus. Obj.
DCTM Sample
DCTM Sample
DCTM Sample
DCTM Sample
ISubscription
ISubscription
Workflow
Workflow
ISubscription
Workflow
Workflow
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Services
Documentum Foundation Class Library (DFC)
Documentum Foundation Class Library (DFC)
Intrinsic
Intrinsic
Business
Business
DFC
DFC
Future Intrinsic Objects
Future Intrinsic Objects
Future Intrinsic Objects
Business Objects
Business Objects
Objects
Objects
Extensions
Extensions
Type-based
Type-based
Operations
Operations
High-Level
High-Level
Business
Business
Objects
Objects
Services
Services
Query Builder
Query Builder
Workflow
Workflow
Validation
Validation
Virtual Document
Virtual Document
Layer
Layer
Other Business
Other Business
Other Business
Objects
Objects
Objects
Core DFC Layer – Object oriented access to Server API Layer
Core DFC Layer – Object oriented access to Server API Layer
Your Business
Your Business
Your Business
Objects
Objects
DBO Framework
DBO Framework
fc.client
fc.client
Objects
DBO Framework
Low-Level
Low-Level
Documentum
Documentum
Documentum
Sample Objs
Sample Objs
Sample Objs
DFC to Server Access Layer
DFC to Server Access Layer
Server Access
Server Access
(Object-based access to Server API)
(Object-based access to Server API)

Business Objects in Perspective

A typical content rich Documentum application will be logically partitioned into layers

also referred to as "tiers". Each tier has a different responsibility in the overall deployment, and within each tier, there can be one or more parts. The three main layers

in an n-tier model are the Presentation Layer, the Business Logic Layer, and the Data

Layer.

Introduction

Documentum Business Objects Framework (DBOF)

Figure 1-2 Documentum Business Objects N-Tier Model

Presentation Layer

Presentation Layer

• •

• •

• •

Generic Components

Generic Components

Custom Components

Custom Components

Industry / Company specific behavior

Industry / Company specific behavior

Business Logic Layer

Business Logic Layer

• •

• •

• •

Application Specific Abstraction

Application Specific Abstraction

Business Rules and Policies

Business Rules and Policies

Common Object Model

Common Object Model

Data Layer

Data Layer

Content and Data Sche ma

Content and Data Sche ma

• •

• •

• •

Co ntent Object Hier ar ch y

Co ntent Object Hier ar ch y

Aggregat ed Business Dat a

Aggregat ed Business Dat a

Common Schema

Common Schema

Core Content Management Services

Core Content Management Services

• •

• •

• •

Library Services

Library Services

Process Automat ion

Process Automat ion

Content Authentication

Content Authentication

Presentation Layer

The presentation layer contains components dealing with user interfaces and user interaction. It is used to display content and structured information in a web browser or stand alone application. For example, the presentation layer of a stand alone application could be written in Visual Basic or Java Swing. In a web environment, Documentum WDK would be the choice to present the layout and to manage the flow and sequence of user interactions. The presentation layer consists of commercial or custom UI components that display information in different ways depending on such factors as the user role or their privileges. For most implementations, this layer is highly customized and must be very configurable. The presentation layer relies on the components (business objects) of the business logic layer to implement and enforce the rules and policies of the company.

Business Logic Layer

The business logic layer is completely independent of visualization and of the toolkit used to display information. It provides application specific generalization as a layer of abstraction and implements the customer specific business rules and policies. It is based on a component object model with components shared between different application areas. In most cases, the policies and procedures of a given company are not very likely to change greatly so the business object components implement those policies and procedures. Alternatively, if a policy or procedure does change, the implementer can just modify the corresponding business logic component and all the dependent applications and components will automatically conform to the new

Introduction

Documentum Business Objects Framework (DBOF)

policy. The business logic layer is the focus of the Documentum Business Objects Framework described in this document.

One of the major improvements of Documentum 5.1 is the ability to support both statefull and stateless Docbase sessions. This allows the business object to focus on the business rules and to leave the session management and transaction handling to the framework.

Data Layer

The data layer is used by the business logic layer to permanently store the state of the objects, content, and other information. Central to the data layer is one or more data servers that house the stored state. The Documentum implementation of the data layer is comprised of one or more eContent Servers with their associated RDBMS servers. The data layer is logically separated into two useful parts, the Content and Schema Layer and the Core Content Management Services Layer.

Content and Data Schema Layer

The data schema layer defines the content object hierarchy as well as the physical schema used to store the aggregated business data. Creation and management of the schema can be achieved using the Documentum Administrator utility or directly by using DFC calls. The business objects in the business object layer provide a logical abstraction of the details of the DFC interfaces to the content and data schema. Therefore, the business objects can manipulate content and its metadata on behalf of the presentation layer applications without relying on those applications being aware of how the data and content is physically organized. Separation of the schema from the business logic layer and the database layer promotes the ability to scale to a different database and continue to use the business objects and applications unmodified.

Core Content Management Services Layer

The core content management services layer provides the library services, process automation, and content authentication to the business objects. This layer is implemented by the Documentum eContent Server. It provides the basic building blocks to construct higher-level business logic components.

Documentum Business Objects (DBO) Defined

Documentum Business Objects are designed to provide modular business logic to the presentation layer by hiding the underlying Docbase schema and by using the core services of the Documentum eContent Server. DBOs are either type-based or service based:

Type Based Objects (TBO)

Type based objects are implemented as classes that extend basic persistent DFC types

such as DfDocument, DfSysObject, DfPersistentObject, DfFolder, etc. They

allow you to encapsulate business logic that is specific to a particular Docbase object type.

Introduction

Documentum Business Objects Framework (DBOF)

There are two main reasons for creating a TBO:

1. To provide a new behavior for new or existing custom object types. For instance, a developer may decide to add getter and setter methods for object specific attributes or add new methods like adding a Product to a Catalog TBO.

2. Customizing low-level operations to enforce data validations, referential integrity and object specific business rules. For instance, a developer may decide to override the save() and checkinEx() methods to be able to validate data before saving them in the persistent storage.

Service Based Objects (SBO)

Service based objects are not tied to a specific Documentum object type. They are generalized objects that provide a specific service that may operate on different Documentum object types or other business objects. An example of a service-based object is the Documentum IInbox service that retrieves items from a user's inbox and may also perform a number of other operations such as remove item, forward item, etc. Such an object would not be tied to a specific object type. Your SBOs are built using public DBOF interfaces and implementation classes supplied by DFC. Service and session manager factory methods are also provided by DFC.

Benefits of using DBO

Faster development - DBO allows developers to reuse the business logic implemented in existing components, shrink analysis time by using a predefined collection of business logic components implemented in the business objects, and use the application expertise captured in object sets. When applications are built by calling upon several business objects services, the development time should decrease, as more of these components are reused.

Protection of investment - DBO provides better portability and interoperability of applications and Docbase model integrity, leverages work already done by Application Servers, Web Services, etc., and facilitates application specific best practices and standards.

Therefore, you should consider using Documentum Business Objects to implement business logic that must:

Be independent of visualization and of the toolkit used to display information,

Be object oriented,

Be modular, componentized, and highly reusable,

Be compatible with existing code built using DFC.

Who will develop with Documentum Business Objects Framework?

Application developers who are familiar with Java and DFC can develop Documentum Business Objects without a steep learning curve.

Architectural Overview

Documentum Business Objects Framework (DBOF)

Chapter 2 Architectural Overview

This chapter provides a detailed overview of the architecture of the new Documentum framework for developing Documentum Business Objects, called Documentum Business Objects Framework (DBOF).

With DFC 5.1 and above, DFC includes a new framework for developing and executing reusable business logic components. This new framework is built in to the Documentum DFC and accessible from applications written using DFC.

Using this framework, you can write new content management services that can be plugged into applications. In addition, services can call upon other services and benefit from their implementation of other business rules. The changes to DFC that provide Business Objects support are compatible with existing applications.

DBOF Runtime Architecture

Develop a Documentum business object to implement some business logic for content management related activities. While service based objects can be designed to perform tasks not related to Docbase activities, the framework was designed with middle-tier content management support in mind and will be the focus of this manual.

The following DFC elements are those that were designed to provide runtime DBO support.

Core DFC support for DBOF

Object Factory Guarantee

Accessing Business Objects

Session Manager

Session Pooling

Session Transaction Processing

DBOR

Business Objects Class Hierarchy

Core DFC support for DBOF

The DBOF framework is integrated into the DFC core. This guarantees that everyone will access the business objects the same way. The DFC core integrates at a fundamental level the object factory and the object registry. It also supplies a session manager and principal support. The sections of this chapter describe these new elements of DFC and where they fit into the architecture of the DBOF.

Architectural Overview

Documentum Business Objects Framework (DBOF)

Object Factory Guarantee

The DFC 5.1 object factory guarantees the correct object will be constructed at runtime. This applies to Type based Business Objects, but not necessarily to Service-based Business Objects. The following paragraphs describe how this mechanism works with regular Docbase objects as well as TBOs, which are extensions of those types.

Documentum Business Objects Framework also allows you to extend certain existing DFC classes using Type based Business Objects, allowing you to enhance the behavior of existing methods, replacing them altogether, and even adding new methods. When a Type based business object (TBO) is developed and deployed on your system, the framework guarantees that all software accessing this object through previous means will now obtain the new extended object. For example, when a servlet obtains an object using the session.getObjectByQualification() method, the object is fetched from the Docbase. This has always been one of the hallmark features of the Documentum repository. For example, if the FROM clause of a query specifies dm_sysobject, but the WHERE clause indicates instances of your new custom Docbase types, the Documentum system has always been able to automatically fetch the custom subtype. However, the DFC system would construct an instance of the DfSysObject, DfDocument, and so on, limiting the functionality to the methods supplied by those standard DFC classes.

With TBOs, you are not limited to the methods and behaviors provided by the standard DFC classes. You can supply your own class, as a subclass of the DFC class. In this case, DFC dynamically constructs an instance of the new subclass at runtime. Even when accessed by programs unaware of the new subclass.

When the aforementioned servlet calls methods like checkout() and save(), and these methods are overridden by the business object tied to this type, the overridden methods are called instead. Through an object oriented mechanism, called polymorphism, the checkout() and save() methods are searched for in a bottom-up order, executing the first one that matches. If the new type overrides the save() method with new business logic, such as validation logic, the new method will perform its new save() operation.

Two things make this possible. One is the Documentum Business Objects "Registry" (DBOR). The other is that use of the registry is now an integral part of the DFC core. Whenever someone attempts to access a custom-type Docbase object, DFC first checks the registry for a mapping to a custom Java class, then loads and instantiates that class. DFC version 4 did not perform this mapping. (This is one of the reasons you should not use DFC 4 compliant clients with custom types that were designed for Version 5.1).

Figure 2-1 shows getting access to a Docbase object through a TBO after DFC has checked with the DBOR as to which Java class to construct that represents the Docbase subtype.

Architectural Overview

Documentum Business Objects Framework (DBOF)

TBO access TBO access Figure 2-1 - TBO Interaction Diagram Client Program Client Program Client
TBO access
TBO access
Figure 2-1 - TBO Interaction Diagram
Client Program
Client Program
Client Program
Client Program
DFC
DFC
session
session
fc.client
fc.client
Session Manager
Session Manager
session
session
pool
pool
pool
pool
DBO Factory
DBO Factory
Typed B.O.
Typed B.O.
Typed B.O.
Typed B.O.
DBO
DBO
DBO
DBO
Registry
Registry
Registry
Registry
Docbase
Docbase

Accessing Business Objects

Figure 2-2 shows a type based business object using another type based business object. When this happens, the consumer is considered the "client".

TTBBOO aacccceessss TTBBOO aacccceessss Figure 2-2 Business Object using - another Business Object TBO Client
TTBBOO aacccceessss
TTBBOO aacccceessss
Figure 2-2 Business Object using - another Business Object
TBO Client
TBO Client
DFC
DFC
session
session
fc.client
fc.client
Session Manager
Session Manager
session
session
pool
pool
pool
pool
DBO Factory
DBO Factory
Typed B.O.
Typed B.O.
Typed B.O.
Typed B.O.
DBO
DBO
DBO
DBO
Registry
Registry
Registry
Registry
Docbase
Docbase

Service based Business Objects (SBO)

Figure 2-2 shows how a service-based business object is different from the type based business objects shown in Figure 2-1. Each service based business object provides a generalized interface to a group of related operations that need to be performed. The operations may not need access to a Docbase, however, content management services are the focus of Documentum Business Objects. An SBO is obtained through the DFC

Architectural Overview

Documentum Business Objects Framework (DBOF)

IDfClient interface. When requesting access to a service, the IDfClient checks the DBO Registry for the service name and instantiates its associated Java class. The interface provides methods to the actual service that implements the business rules of the service. SBOs can access objects across several Docbases and are usually implemented such that they can be called by an application server component and the service can obtain and release the Docbase sessions dynamically as needed.

Figure 2-3 - SBO Interaction Diagram Client Program Client Program Client Program Client Program DFC
Figure 2-3 - SBO Interaction Diagram
Client Program
Client Program
Client Program
Client Program
DFC
DFC
fc.client
fc.client
DBO Factory
DBO Factory
Service B.O
Service B.O
Service B.O
Service B.O
DBO
DBO
DBO
DBO
Registry
Registry
Registry
Registry
SBO access
SBO access

Calling a Service based Object

At any level, a method of a business object can be called by other DFC based applications. A WDK component can call an SBO service just as easily as any stand- alone Java program could. JSP, ASP, Visual Basic, and other languages all have access to the business objects.

Business Objects are considered "clients" when accessing other Business Objects

The Java classes of the business object will be loaded and called by the DFC client factory methods using class-mapping information obtained from the DBOR. DBOF objects are a Java technology. Like all Java programs (with the exclusion of RMI), the Java classes are loaded into the process address space of the JVM.

When any Java programs, including type-based objects, access a Documentum server in this way, they too are clients, even if they are a service being called by another service. What this means is, that when an SBO calls another SBO or another TBO, the interaction between the clients, the DBOR, and the service classes load the same way as when a stand-alone program loads them. That is to say, that when a TBO calls an SBO or another TBO, it is treated like the client in Figure 2-1. Figure 2-4 shows a service based business object calling another service based business object. The DBOR is used to locate the Java class corresponding to the service name.

Architectural Overview

Documentum Business Objects Framework (DBOF)

Figure 2-4 - Any Business Object calling an SBO Business Object Business Object DFC DFC
Figure 2-4 - Any Business Object calling an SBO
Business Object
Business Object
DFC
DFC
fc.client
fc.client
DBO Factory
DBO Factory
Service B.O
Service B.O
Service B.O
Service B.O
DBO
DBO
DBO
DBO
Registry
Registry
Registry
Registry
SBO access
SBO access

Remote Execution of Business Objects

Documentum Business Objects run in local mode only. They currently do not support remote execution. Web Services and .NET could be two technologies the framework supports in the future but currently it only supports local mode.

Clients can use business objects

DBOF was designed for use by different clients, including Java, WDK, Servlet, JSP, Visual Basic, C++, and ASP. The current design, however, is that they are developed only in Java and accessible via clients based on these various technologies. All the non- Java clients currently use COM through the DFC 5.1 Documentum Java COM Bridge (DJCB).

Session manager

Whenever an application acquires any access to a Docbase, authentication is required. Another improvement supplied by DFC 5.1 is "managed sessions" using the session manager. It encapsulates the DFC session object and automatically manages the session pool. It also provides the transaction handling and authentication of multiple identities on multiple Docbases. For reestablishing a managed session, the session manager can hold several Docbase login "identities", one for each Docbase or a "principal" identity, an identity used by the service to authenticate the service as if the service is that principal identity. It also provides methods to get access to the DFC session handle and hooks to manage a session pool for stateless operation. It manages access to multiple Docbases and controls transaction processing across multiple services. For convenience to the web programmer, it also provides methods to associate state with the session to make session management more straightforward.

The main requirement for an SBO is for it to request a DFC session through the session manager and to release it as soon as it no longer needs to access a Docbase. With TBOs, a reference to the TBO's session is embedded inside the object by default. This session may become invalid if the requesting method releases the pooled session. There is a special case where the DFC session can be "separated" from the current DFC session and

Architectural Overview

Documentum Business Objects Framework (DBOF)

the TBO is put under session manager control. This is required in cases where a stateless SBO creates a TBO, which is stateful, that is returned to the caller.

Session Pooling

Session pooling provides for an application to connect and disconnect from a Docbase session many times without incurring the overhead of real sessions with the server. The general idea is to release the session back to the session pool often when acting in a stateless manner. The session manager does not disconnect the session with the server when a client releases the session. Rather, the session is put back into the session pool, free to be used by other requests for other sessions.

Session Transaction Processing

The DFC session manager provides "managed transactions" for "managed sessions". When session pooling is used, it is theoretically possible that DFC sessions are pooled between individual calls to services. Let’s say there are two services: the first service creates a few folders and the second service stores some documents in these folders. To make sure the folders are only created if the documents are successfully created, there must be a transaction across the two service calls. The DFC transaction is bound to one DFC session, therefore it is important to use the same DFC session when calling both services. Each service performs its own atomic operation. At the beginning, they request a DFC session, and at the end, they return this session back to the session pool. If any errors occur during either operation, the transaction is aborted and all Docbase updates since the beginning of the transaction are rolled back to their pre-transactional state.

The DFC 5.1 session manager provides several new methods that allow transaction processing with stateless sessions. Using the session manager transactions, you can now perform transaction processing across Docbases. (Two-phased commit is not supported by the Docbase since not all RDBMS support two-phased commit, therefore, the DFC supports single-phased commit.)

Documentum Business Objects Registry (DBOR)

The business object registry provides the following mapping at runtime:

Docbase Type name to Java Class mapping

When the DFC core loads a Docbase object, its type name is looked up in the registry. If the name is found, its corresponding Java class is loaded and instantiated.

Service Interface name to Java Class mapping

When requesting the client to load a service, the service is identified by its published interface name, such as com.documentum.IInbox. If DFC finds the interface name in the registry, the corresponding service class is loaded and instantiated and returned to the caller.

Architectural Overview

Documentum Business Objects Framework (DBOF)

Business Objects Class Hierarchy

Figure 2-5 shows a class diagram for a Service based Business Object. The Client object represents the consumer of the IAutoName service. The IAutoName service interface is implemented by the AutoName class. The IAutoName service interface has access to the DfService object extended by its AutoName implementation. The client gains access to the IAutoName service by using IDfClient to find the class mapping from the IDfDbor, and then instantiates the AutoName object.

Figure 2-5 - Class Diagram for Service based Business Objects

Client CClielienntt use use s s use use s s IDfClient IDIDfCfClielienntt use use s
Client
CClielienntt
use
use
s
s
use
use
s
s
IDfClient
IDIDfCfClielienntt
use
use
s
s
IIDDffSSesessisioonnMMananaaggerer
IDfSessionManager
crea
crea
te
te
s
s
use
use
s
s
i i
m
m
pl
pl
em e
em e
n
n
ts
ts
IIDDffDDborbor
IDfDbor
IIDDffSSerervviicece
IDfService
DDffSSeessssiionMonMaannageagerr
DfSessionManager
use s
use s
IIAAututoNoNamamee
IAutoName
IDfPrincipalSupport
IIDDffPPrriincnciippalalSupporSupportt
exte
exte
nd
nd
s
s
i i
m
m
pl
pl
em e nt s
em e nt s
IIDDffSSesessMsMggrrSSttatatiissttiicscs
IDfSessMgrStatistics
use s
use s
DfService
DfDfSSeerrvviiccee
i i
m
m
pl
pl
em e
em e
n ts
n ts
use
use
s
s
AutoName
AuAuttooNNaammee
exte nd s
exte nd s

Figure 2-6 show a class diagram for a Type based Business Object. The custom Product class extends the DFC DfSysObject class. The IProduct interface generalizes access to the Product object. The client gains access to the Product object by using the IDfSession.getObject(), which causes the IDfClient of the framework to query the DBOR registry for the class to instantiate.

Architectural Overview

Documentum Business Objects Framework (DBOF)

Figure 2-6 - Class Diagram for Type-based Business Objects

CliClieentnt Client uses uses uses uses IIDDfSefSessissioonn IDfSession uses uses creates creates
CliClieentnt
Client
uses
uses
uses
uses
IIDDfSefSessissioonn
IDfSession
uses
uses
creates
creates
IPIPrroodduucctt
IProduct
IDfBusinessObject
IIDDfBfBuussiinneessObssObjjectect
extends
extends
IDfIDfCClliieenntt IDfClient uses uses IDfIDfDBODBORR IDfDBOR
IDfIDfCClliieenntt
IDfClient
uses
uses
IDfIDfDBODBORR
IDfDBOR

iimmppllemenementtss

Product PPrroducoductt Summary
Product
PPrroducoductt
Summary
DDffSysObSysObjjectect DfSysObject
DDffSysObSysObjjectect
DfSysObject

extends

extends

DfPersistentObject DDffPerPerssiisstteennttObObjjectect
DfPersistentObject
DDffPerPerssiisstteennttObObjjectect

extends

extends

DDffTTyyppeeBBaasedsedObObjjectect DfTypeBasedObject
DDffTTyyppeeBBaasedsedObObjjectect
DfTypeBasedObject

extends

extends

When developing with Documentum Business Objects Framework, it is important to understand that DBOF is built-in to DFC 5.1 and is an integral part of DFC. Remember that DBOF was primarily designed to provide an environment for stateless access to Docbase data from middle-tier business objects. You should do your best to use the session manager and release sessions as soon as possible. You can rely on the session manager to manage connections and transactions with the Docbases. Using DBOF, you can implement business logic in reusable business object components that can be plugged in to your middle-tier applications.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Chapter 3 Developing Your First Business Objects

This chapter steps developers through the process of creating both service and type-based business objects (TBO) using a very simple example that illustrates the use of DBOF. One of the purposes of creating a TBO at this point is to demonstrate the basic principle of TBOs - that their Java class is automatically used whenever an object is accessed through normal, already existing programs. For example, Documentum Desktop Client and WDK will automatically start using the overridden methods of your extending class without making any changes to Documentum Desktop Client or its configuration. Remember, this will happen with Documentum 5.1systems.

The example used for the exercise is an auto-numbering service. The first section, Getting Started with DBOF, guides you through the initial set up of DBOF. There are two other sections; each including a test application designed as simple tutorial test case applications. The Simple_TBO test application allows you to practice building, deploying and testing a type based business object. The Simple_SBO test application allows you to practice building, deploying and testing a service based business object (SBO).

The Simple_xBO test applications are simplified examples of a real-world business problem, that of maintaining a business-wide sequential numbering system for a variety of purposes, like purchase orders, invoices, contract and application documents, and other purposes. The example will be overly simplified so the Simple_xBO application will be able to demonstrate the basic concepts of Documentum Business Objects without creating too much confusion specific to that particular issue. A more fully functional "AutoName" sample service ships with DFC 5.1.

This chapter contains the following main sections:

"Getting Started with DBOF" on page 3-1.

"A Simple Type-based Object Example" on page 3-4.

"A Simple Service-based Object Example" on page 3-21.

Getting Started with DBOF

This is a step-by-step guide on initial setup required to have DBOF ready to use. Perform the steps provided here before proceeding with the example exercise.

Be sure to perform the following steps before implementing the example:

1. Install DFC 5.1 on your client computer (i.e. Windows NT/2000/XP). Run the DFC installer as described in the DFC installation manual. This also includes setting up the Java runtime environment (JVM) on your client computer. Use Sun JDK1.2 or later. You may also use a compatible JVM from other vendors that are Java 1.2 compliant (or later). It is not possible to use the Microsoft JVM because it doesn't support JDK 1.2.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

2. Setup a new Docbase or get access to an existing test Docbase.

3. Configure DMCL.INI to both access your test Docbase and enable session pooling. For the latter, add the following entry to the [DMAPI_CONFIGURATION]

section: connect_pooling_enabled = T

4. Make sure you have a Java IDE installed. For example IntelliJ, Borland, WebGain, IBM, etc.

5. Make sure (a) dfc.jar is referenced by the CLASSPATH environment variable of your IDE or JVM running the application, and (b) dmcl40.dll is in a directory referenced by the PATH variable. Both files are installed by default in c:\Program Files\Documentum\shared. (The CLASSPATH should also contain a reference to the jar file of your new Business Objects. Optionally, you can place the files into your Java Standard Extension Library - " \lib\ext")

If you are running from within and IDE, like IntelliJ or Forte', the IDE usually requires additional CLASSPATH settings.

6. The DFC_DATA system variable must refer to the directory containing Documentum configuration information, usually c:\Documentum. This needs to be a directory that has an immediate subdirectory called c:\Documentum\config. This is where the dbor.properties file is located. (Future best practices might recommend using c:\Documentum\DFC_DATA\config)

Caution: The current implementation of the Documentum Business Objects Registry uses the dbor.properties file in the DFC_DATA\config directory. Documentum will change this in future releases. Both the implementation of the object registry as well as use of the config directory will change. The information regarding the use of the dbor.properties file is included in this manual in case you need to debug your business applications. You should not attempt to edit this file without using the DBOR maintenance tool.

Problem Scenario: Business-Wide Auto-numbering

The Simple_TBO and Simple_SBO test applications are a simplified solution to a real- world business problem, that of maintaining a business-wide sequential numbering system for a variety of purposes, like purchase orders, invoices, and other purposes.

In order for a business to be able to supply a centralized numbering system for all the employees who are performing similar tasks, the numeric value used to calculate the "next number" must be stored in the system and all the employees would need to base their numbering system on that number only. Locks are put into place to serialize access to the number so that it safely increments sequentially.

Solution: Documentum Business Objects

This scenario divides the problem into two solutions.

1. Type-based business object (TBO), the subject of the Simple_TBO example, provides the persistent storage. Use a Docbase as the central storage for the value

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

used to calculate the next number. A new Docbase type will be created (e.g.

"com_accelera_autonumber" that is a subtype of dm_sysobject) that will have an

attribute, "current_number", storing the value of the last number generated as a seed for the next number in that numbering type. (Note: Accelera.com is a fictitious domain name of a fictitious conglomerate that Documentum created for demonstration purposes.)

° In addition, a business rule might impose a restriction on the maximum value of a number for a given numbering type, or that the number is zero-filled to a certain number of digits.

° Different numbering sequences, like purchase orders and invoice numbers, would need a separate storage for each sequence since it is usually not desirable for to sequence numbers as, PO001, INV002, PO003, INV004.

° Additional rules might require that purchase order numbers are prefixed with "PO", whereas invoice numbers begin with "INV". In this simple example, this will be handled by the user of the IAutoNumber interface. A future subclass of the autonumber type could handle as well.

° The application of these business rules and validation would need to be performed each time the value for the "next number" would be calculated, stored, and fetched. This is accomplished by overriding the methods of dm_sysobject like checkin(), checkout(), save(), etc. that would be used to retrieve the number, increment the number, and save the object.

(A more elaborate kind of sequencing described above is the subject of a sample business object service, called "AutoName", that accompanies DFC 5.1 but is too complex to present in this manual.)

2. Service-based business object (SBO), the subject of the Simple_SBO example, will provide a simpler interface to obtaining the correct centralized number and saving it to the TBO. It provides methods for getting the value stored and saving the next number back into the Docbase. These methods can hide the details of locking and unlocking the TBO objects, fetching and saving the other attributes of the TBO objects, and so on.

° The most important method of this service is the getUniqueNumber() method that fetches and increments the number according to the number type (PO, INV, etc.). The other methods of this service are mainly for management purposes.

° Other methods will include setNumber(), used internally to set the initial number value for a given number type and to save the calculated value back to the Docbase.

° A fully functional service of this type will be designed generically enough to provide number formatting patterns and other filters.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Figure 3-1 - AutoNumber Schema

DfTypedObject DfPersistentObject +g et +g et DfService «interface» IAutoName +getVersion() DfSysObject +ge t
DfTypedObject
DfPersistentObject
+g
et
+g
et
DfService
«interface»
IAutoName
+getVersion()
DfSysObject
+ge t Next Numb er ()
«interface»
+getVendorString()
IAutoNameType
+isCompatible()
+checkin()
+g et U n i qu eN um b er ()
+save()
+s
et
N u m be r( )
AutoNameType
AutoName
-type_name
-type_name
-current_number
-current_number
-max_number
-max_number
+getUniqueNumber()
+getNextNumber()
+setNumber()
+checkin()
«uses»
+save()
#checkRange()
#validate()
-setNextNumber()

«interface»

IDfBusinessObject

Ver s i o n( ) Ver s i o nSt ri n g( )

+i s C om pa t i ble( ) +s up po rt s F e at ur e( )

«datatype» Docbase Type:

com_accelera_autonumber

A Simple Type-based Object Example

Introduction

As described in the "Solution: Documentum Business Objects" section, this Simple_TBO program will be an application that fetches the Docbase object containing the existing number, increments it, and saves the newly incremented value back to the Docbase. In order to accomplish this, the following must be implemented:

Assume that this example will work with a variety of separate, distinct numbering sequences.

A new Docbase type must be created, called "com_accelera_autonumber", that is a subtype of the Docbase "dm_sysobject" type. This new type defines the schema for the different numbering schemes, called numbering types in this example.

Each com_accelera_autonumber object will store in its "current_number"

field/attribute the last value returned from the getUniqueNumber() method. This "current_number" value will be used to calculate the next number in the sequence defined for that numbering type. The object will also store any other fields that require persistence for this example.

r_object_id

name

type_name

current_number

max_number

090000000101a8b7

Purchase Order

PO

590124

99999999999

090000000101a8cb

Invoice

INV

30822

99999999999

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

090000000101af58

Patent Application

DCMPAT

944

9999999

090000000101b032

Contract Document

DCMCON

730822

99999999

A

new Java class, called AutoNumberType, implements the business rules by

providing methods for incrementing the number as well as overriding operations, like

checkin() and save() to guarantee that the number is always within the bounds set

in

the number type.

This AutoNumberType class inherits from (extends) DfSysObject and will also provide the implementation for all the DfSysObject methods it needs to override and extend (like checkin(), save() and checkout()), as well as implementing new implementation specific methods, like getUniqueNumber(), checkRange(), etc.).

An interface for AutoNumberType, called, IAutoNumberType, will provide the means

to

publicly use the object. This interface could extend IDfSysObject (although, for

clarity purposes Documentum recommends against this, so you should just override only the necessary methods of the interface). (See page 7-4 for checklist for subclassing dm_document).

The AutoNumberType class will also be able to create an original com_accelera_autonumber Docbase object if it doesn't already exist using its static

addNewAutoNumberType() method. The addNewAutoNumberType() method uses

the standard IDfSession.newObject() factory method to create a new instance of

the com_accelera_autonumber type.

The Simple_TBO class will be a stand-alone Java application that tests the AutoNumberType by obtaining and outputting the current number, causing the number to increment and storing it back into the Docbase.

A

Simple_TBO test application is stateless from the TBOs perspective, in that it

executes and ends with each invocation. Running Simple_TBO from different computers will retrieve numbers in sequence relative to the com_accelera_autonumber Docbase object, instead of numbers relative to each computer or Simple_TBO instance.

Simple_TBO calls the static addNewAutoNumberType() method to create a new instance of the com_accelera_autonumber type if it can't find the specified type.

The files to create will be:

Simple_TBO.java

AutoNumberType.java

IAutoNumberType.java

Plus, the AutoNumberType class must be registered in the dbor.properties file.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Implementing the AutoNumberType TBO

This section will step you through the creation of the AutoNumberType business object a type-based business object (TBO). The "A Simple Service-based Object Example" section will step you through a service-based business object (SBO) to access this object.

1. Create the new IAutoNameType interface.

1.1. Define a new interface, called IAutoNameType that extends the

IDfBusinessObject interface. The IDfBusinessObject interface defines four

abstract methods for which its implementing concrete classes must provide. Remember, it is acceptable for the implementing class to inherit the overridden method implementations from its superclasses,

1.2. In the interface, prototype all the public methods that are new to the Docbase object extended class as well as any public or protected overriding methods that you wish publicly expose.

/* IAutoNumberType.java */ package com.accelera.autonumber;

import com.documentum.fc.client.*; import com.documentum.fc.common.DfException;

public interface IAutoNumberType extends IDfBusinessObject

{

public String getUniqueNumber( IDfSessionManager sMgr ) throws DfException;

}

2. Extend DfSysObject with the new AutoNumberType class

The AutoNumberType TBO class definition wraps a Docbase object of type "com_accelera_autonumber" and exposes getters and setters for the object's attributes as well as checkin() and save() method overrides. The AutoNumberType class inherits all the methods and properties of DfSysObject, IAutoNumberType, and IDfBusinessObject (inherently through IAutoNumberType), so there is no reason to rewrite or override inherited methods that will not alter the behavior of the existing type, so if the IAutoNumberType interface needs to allow users of the object to call the checkin() method on the interface, but is not providing any new behavior, all that is needed is to declare the checkin() method in the interface and let the class inherit the method from DfSysObject.

The AutoNumberType class extends the DFC DfSysObject class by changing the behavior of two of its methods (save(), and checkinEx()) and by adding six new private, protected and public methods related to auto-sequence numbering and its

management (getUniqueNumber(), setNextNumber(), setNumber(), checkRange(), validate(), and addNewAutoNumberType()).

2.1. Create a new class, AutoNumberType, and extend the desired DFC class that provides the closest behaviors and features to your needs. For example, extending DfSysObject allows your objects to inherit nearly 500 public methods

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

from its superclasses. Be sure to implement the TBO IAutoNumberType interface also.

/* AutoNumberType.java */ package com.accelera.autonumber;

import com.documentum.fc.client.*; import com.documentum.fc.common.*;

public class AutoNumberType extends DfSysObject implements IAutoNumberType

{

}

3. Implement the methods of IDfBusinessObject

3.1. In the AutoNumberType class, add the String constants that will be used for the

getVersion() and getVendorString() methods.

public static final String strCOPYRIGHT = "Copyright (c) Documentum, Inc., 2002"; public static final String strVERSION = "1.0";

3.2. Since the AutoNumberType class implements the IDfBusinessObect class, and the IDfBusinessObject interface defines four abstract methods, your new class must implement overrides for each of the four methods, getVersion(),

getVendorString(), isCompatible(), and supportsFeature(), as follows:

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

/* AutoNumberType.java */ package com.accelera.autonumber;

import com.documentum.fc.client.*; import com.documentum.fc.common.*;

public class AutoNumberType extends DfSysObject implements IAutoNumberType

{

 

public static final String strCOPYRIGHT = "Copyright (c) Documentum, Inc., 2002"; public static final String strVERSION = "1.0";

public String getVersion()

{

 

return strVERSION;

 

}

public String getVendorString()

{

 

return strCOPYRIGHT;

 

}

public boolean isCompatible( String s )

{

 

return s.equals("1.0");

 

}

public boolean supportsFeature( String s )

{

 

String strFeatures = "uniquenumber, subclassing";

if( strFeatures.indexOf( s )== -1 ) return false;

return true;

}

}

4. Override DfSysObject methods

4.1. Inside the AutoNumberType class, override any methods that require adherence to the business rules for the com_accelera_autonumber type. These are two methods, save() and checkinEx() as show below. Each method should call the validate() method before forwarding the call to its superclass implementation.

The save() and checkinEx() methods were chosen because they are the points at which the validation of the business rules need to be applied. The service, and any other user of the Docbase object will modify it using checkout() / save() or checkout() / checkin() combinations. Intuitively, you might have chosen the checkin() method instead of the checkinEx() method. However, in this case, all the DfSysObject.checkin() method does is call the checkinEx() method. So we have chosen to implement the checkinEx() method instead.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

(Note: Sometimes you call the superclass implementation first, and other times you call it after your extending code. There will even be times where the superclass implementation should not be called at all.)

public void save() throws DfException

{

 

validate();

super.save();

}

The checkin() method is final so you cannot override it. This is because the checkin() method just calls checkinEx() polymorphically. There is no reason to validate the object twice. The checkinEx() method performs a check in with additional application- specific attributes.

public IDfId checkinEx( boolean fRetainLock, String strVersionLabels, String strOldCompoundArchValue, String strOldSpecialAppValue, String strNewCompoundArchValue, String strNewSpecialAppValue ) throws DfException

{

validate(); return super.checkinEx( fRetainLock, strVersionLabels, strOldCompoundArchValue, strOldSpecialAppValue, strNewCompoundArchValue, strNewSpecialAppValue );

}

Note: Certain DFC methods forward their calls to other methods. When overriding methods, be sure to consider whether the method forwards its call to another method to avoid performing the same override twice. With this in mind, DFC has declared some of these methods as final to help you avoid overriding the method unnecessarily. This

includes methods like IDfSysObject.checkin() and checkout(), getContent(), and

several others.

5. Numbering Scheme methods

Now that you have finished overriding the methods of the superclasses, you can implement the six methods of the new AutoNumberType class related to the numbering scheme.

5.1. In the AutoNumberType class, implement the getUniqueNumber(), setNextNumber(), and setNumber() methods. The getUniqueNumber() simply

fetches the value of its "current_number" attribute. The setNextNumber() method increments its "current_number" attribute, validates that its value is within the business rules, and saves the new number into its "current_number" attribute. The setNumber() method is used to set the initial value of the "current_number" field. By default, Simple_TBO will set it to "1". Implement the methods as follows:

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Due to the fact that the three methods on lines 22, 23, and 24, listed below need to perform a checkout(), modify attributes, and save() as an atomic operation, they need to be part of a managed transaction. Since nesting session transactions is not supported, the setNumber() method throws an exception if either the caller has not supplied a managed transaction. The code on lines 13-18 performs this test. In other words, you need to make the user supply a transaction for this operation to function correctly. If the setNumber() fetches the next number, but it is not saved back into the Docbase, the next person calling getUniqueNumber() will get the same number. This is against the specified business rules.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

1

public String getUniqueNumber( IDfSessionManager sMgr )

2

throws DfException

3

{

4

return setNextNumber( sMgr );

5

}

6

7

8

private String setNextNumber( IDfSessionManager sMgr )

9

throws DfException

10

{

11

String strRetVal = null;

12

13

if( ! sMgr.isTransactionActive() )

14

{

15

DfException e = new DfException();

16

e.setMessage( "no transaction available" );

17

throw e;

18

}

19

20

try

21

{

22 checkout();

// lock

23 strRetVal = setNumber( null );

24 save();

// unlock and update

25

26

}

27

catch( DfException e )

28

{

29

30

sMgr.setTransactionRollbackOnly();

31

32

e.setMessage( strRetVal + e.getMessage());

33

34

throw e;

35

}

36

37

return strRetVal;

38

}//end setNextNumber()

39

40

41

public String setNumber( String strNewNumber ) throws DfException

42

{

43

if( strNewNumber != null )

44

{

45

setString( "current_number", strNewNumber );

46

}

47

else

48

{

49

strNewNumber = getString( "current_number" );

50

51

long n = Long.parseLong( strNewNumber );

52

checkRange( n+1 );

53

strNewNumber = String.valueOf( ++n );

54

55

setString( "current_number", strNewNumber );

56

}

57

58

return strNewNumber;

59

}

60

5.2. There are two methods related to the implementation of the business rules for this

type of object, validate() and checkRange(). The checkRange() method

checks a numeric value for validity before attempting to save it into the Docbase

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

object. The validate() method fetches the "current_number" from the object and forwards it to the checkRange() method for validation. Either of these methods will throw an exception if the number does not follow the business rules.

protected void validate() throws DfException

{

String s = getString( "current_number" ); checkRange( Long.parseLong(s) ); }//end validate()

protected void checkRange( long n ) throws DfServiceException

{

String strMsg = "checkRange() Docbase error"; try

{

long lMax = this.getLong( "max_number");

if(

(

n

<

0

)

||

(

n > lMax ) )

{

 

strMsg = "bad number or number out of range: "

 

+ String.valueOf( n ) + ", "

+ String.valueOf( lMax );

 

DfServiceException ex = new DfServiceException( this, strMsg ); DfLogger.error(this, strMsg, null, ex); throw ex;

}

} catch( DfException e )

{

DfLogger.error(this, strMsg, null, e); throw new DfServiceException( e, strMsg );

}

}//end checkRange()

6. Add a new Number sequencing Type - AutoNumberType instance

The last method to implement is the addNewAutoNumberType() method. This method is static so that it can be used as a utility to add new objects of this type. If it weren't static, it would require that an object of this type be instantiated before being able to create one, thus start a vicious cycle. The AutoNumberType is tied to a version of a Docbase object with its own r_object_id. If there isn't an object to fetch, then you can't call getObject() to instantiate an AutoNumberType. If you can't get an instance of AutoNumberType, then you can't call getUniqueNumber(). Therefore, call the addNewAutoNumberType() method whenever a new numbering sequence is needed. It will set the starting number and set the maximum range to the specified value. Another side effect of being static is that it is hidden from the public interface and would need to be used by maintenance programs only, or internal methods of the class can call it transparently.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

public static void addNewAutoNumberType(

throws DfException

{

IDfSession session; try

IDfSessionManager sMgr, String strTableName, String strObjectName, // long name String strAutoNumberType, String strStartingNumber, String strMaxNumber, String strDocbaseFolder )

{

 

session = sMgr.getSession( strDocbase ); AutoNumberType number = (AutoNumberType) session.newObject( strTableName );

number.setObjectName( strAutoNumberType ); number.setString( "number_type", strAutoNumberType ); number.setString( "max_number", strMaxNumber ); number.setNumber( strStartingNumber ); number.save();

DfLogger.error(number, "new %s instance added:%s", new String[]{ strTableName, strAutoNumberType }, null);

}

catch( Exception e )

{

 

// failed to create if( e instanceof DfException ) throw (DfException)e;

throw new DfException( DfException.DM_NOTDFC_E_JAVA, e.toString() );

}

}//end addNewAutoNumberType()

7. Create the new dm_type instance as "com_accelera_autonumber"

The new custom type is a subtype of dm_sysobject. Each different auto-numbering type will have its own instance of this new type.

There are several ways to create the new com_accelera_autonumber custom type.

7.1. Use Documentum Developer Studio to develop a portable DocApp:

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Figure 3-2 - Installing a new Docbase Type

Framework (DBOF) Figure 3-2 - Installing a new Docbase Type 7.2. Use the IDQL tool to

7.2. Use the IDQL tool to use DQL to manually create the new

com_accelera_autonumber type to a Docbase.

create type com_accelera_autonumber (number_type char(128), current_number char(18), max_number char(18)) with supertype dm_sysobject

7.3. Write a program that adds the new com_accelera_autonumber type to a Docbase.

IDfQuery query = new DfQuery(); query.setDQL( "create type com_accelera_autonumber"

+ " (number_type char(128), current_number char(18), "

+ " max_number char(18)) with supertype dm_sysobject" ); IDfCollection coll = query.execute( session, IDfQuery.DF_EXEC_QUERY );

coll.close();

8. Map the new com_accelera_autonumber Docbase Type to the New Business Object Class

In the "DFC_DATA\config" directory (usually "c:\Documentum\config"), add the following entry anywhere in the dbor.properties file:

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

com_accelera_autonumber=type,com.accelera.autonumber.AutoNumberType,1.0

This registers the new business object with Documentum 5.1so that any time any Docbase objects from this new table are fetched, the Docbase object is used to populate

the AutoNumberType object.

(see Caution regarding manually editing the DBOR on page 3-2.)

You should write a program the uses the new IDfDbor and IDfDborEntry interfaces to register the new AutoNumberType business object.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

boolean mapDocbaseTypeToClassName( IDfSession session, boolean bDborService, String strDocbaseTypeName, String strJavaClass )

{

 

boolean bRetVal = true;

IDfClient client = session.getClient() ;

IDfDbor dbor = client.getDbor();

String strLookup = null; try

{

System.out.println( "mapping " + strDocbaseTypeName ); if( ! bDborService )

{

strLookup = dbor.lookupObject( strDocbaseTypeName );

}

else

{

strLookup = dbor.lookupService( strDocbaseTypeName );

}

System.out.println( strDocbaseTypeName + " already mapped to " + strLookup );

bRetVal = true;

}

catch( Exception e )

{

try

{

String s = e.toString(); // if not already registered

IDfDborEntry entry = new DfDborEntry();

entry.setName( strDocbaseTypeName ); entry.setServiceBased( bDborService ); entry.setJavaClass( strJavaClass ); entry.setJavaClass( AutoNumberType.class.getName() ); entry.setVersion( "1.0" );

dbor.register( entry );

System.out.println( "New dbor registry entry successfull" );

}

catch( Exception e2 )

{

System.out.println( "Unable to map dbor entry" ); System.out.println( e2.toString() );

e2.printStackTrace();

bRetVal = false;

}

}//end catch( DfDborNotFoundException )

return bRetVal;

}

In the mapDocbaseTypeToClassName() method above, the dbor.register() method

signals that there is already an entry by throwing an exception. In other words, duplicate entries are not possible when the IDfDbor interface and should be the only mechanism used to manipulate the registry. An entry is duplicated when the name is the same. For TBOs, a duplicate entry when two or more entries have the same values left of the equals for the Docbase type. For services, it is the service interface name that must be unique.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Editing the DBOR by hand is strongly discouraged. Doing so could create serious runtime problems with the other Documentum based applications on your system.

If the dbor.properties file does not exist, the register() method will cause one to be created.

9. Deploy and Set up the new Business Object

Once the program successfully compiles, it needs to exist in the CLASSPATH or installed into the Java Extension Library.

Optionally, you can pass a CLASSPATH as a command-line argument as follows:

java -cp "%classpath%" Simple_TBO DocbaseName "PO" username password [domain]

Implementing the Simple_TBO Test program

This test program is designed to mimic a regular caller / consumer of a TBO object.

1. Create the new Simple_TBO class

2. Declare the private instance variables

/* Simple_TBO.java */

import java.util.Collection;

import com.documentum.fc.client.*; import com.documentum.fc.common.*; import com.documentum.com.*;

import com.accelera.autonumber.*;

public class Simple_TBO

{

private String m_strDocbaseName; private String m_strUserName; private String m_strPassword; private String m_strDomain;

private static final String m_strAutoNumberTable =

"com_accelera_autonumber";

private String m_strAutoNumberType;

)

3. Write the main() and begin() methods and instantiate the Simple_TBO class. This involves parsing the command line arguments into variables, instantiating the Simple_TBO class to prevent writing all the methods and variables as static, establishing a session manager identity, and calling the test routine.

3.1. In the begin() method, construct a new session manager object using the newSessionManager() method of IDfClient. Then register a user's credentials as an identity in the session manager, using the

IDfSessionManager.setIdentity() method.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

public static void main( String[] args )

{

new Simple_TBO().begin( args ); //xfer control to a non-static method

}

void begin( String[] args )

{

 

try

{

// check cmd args

if( !parseCmdLine( args ) )

return;

IDfClient client=null; client = DfClient.getLocalClient(); IDfClientX clientx = new DfClientX(); IDfLoginInfo login = clientx.getLoginInfo(); login.setUser( m_strUserName ); login.setPassword( m_strPassword );

if( m_strDomain != null ) login.setDomain( m_strDomain );

// connect to session mgr

IDfSessionManager sMgr = client.newSessionManager(); sMgr.setIdentity( m_strDocbaseName, login);

test( sMgr,

m_strDocbaseName, m_strAutoNumberTable, m_strAutoNumberType );

}

catch( Exception e )

{

DfLogger.error(this, e.toString(), null, e);

}

}

4. Parse the command line arguments into private variables

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

private boolean parseCmdLine( String[] args ) {

try

{

 

m_strDocbaseName = args[0];

// check DocbaseName

m_strAutoNumberType = args[1]; m_strUserName = args[2]; m_strPassword = args[3];

// check AutoNameType // check Java class name

if( args.length > 4 )

{

m_strDomain = args[4];

}

}

catch( Exception e ) // array bounds exceptions, etc.

{

System.out.println( "Error parsing command line arguments.\n" ); System.out.println( "Usage: java Simple_TBO " + "<docbase> <newAutoNumberType> " +

"<user> <password> [<domain>]\n\n" ); System.out.println( "Be sure that the following DMCL.INI file " + "has the following settings:" );

System.out.println( " System.out.println( "

[DMAPI_CONFIGURATION]" ); connect_pool_enabled=T\n\n" );

}

return true;

}

5. Test the new object type.

5.1. To test the new business object, fetch a specified instance of a "com_accelera_autonumber" type (like PO, or INV). If no matching "number_type" exists, then a new one is added for you with its starting number set to "1".

5.2. Then call the getUniqueNumber() method.

5.3. Display the number you retrieved.

5.4. Set the next number back into the Docbase and release any locks you may have established on the object.

5.5. Save the object with the overridden save() method.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

void test( IDfSessionManager sMgr, String strDocbaseName, String strAutoNumberTable, String strAutoNumberType ) throws DfException

{

sMgr.beginTransaction();

try

{

IAutoNumberType number = null; IDfSession session = sMgr.getSession( strDocbaseName );

try

{

String strDQL = strAutoNumberTable

+ " where number_type='"

+ strAutoNumberType

+ "'";

// GOOD EXPERIMENT!

// Find the r_object_id of the AutoNumberType record and use it in // the query below as follows:

//

String strDQL = "dm_sysobject where r_object_id = '09

'";

number = (IAutoNumberType)

session.getObjectByQualification( strDQL );

// If it doesn't exist, tell the class to add one for you. if( number == null )

{

AutoNumberType.addNewAutoNumberType( sMgr,

strDocbaseName, strAutoNumberTable, strAutoNumberType, strAutoNumberType,

"1",

"999999999999",

"/System/com_accelera_autonumber" );

number = (IAutoNumberType)

session.getObjectByQualification( strDQL );

}

String strNewNumber = number.getUniqueNumber( sMgr ); System.out.println( "Current number for '" + strAutoNumberType + "' is: " + strNewNumber );

}

finally

{

sMgr.release( session );

}

sMgr.commitTransaction();

}

catch( Exception e )

{

 

DfLogger.error(this, "failed to update", null, e); DfLogger.error(this, e.toString(), null, e);

sMgr.abortTransaction();

// failed to create or update if( e instanceof DfException ) throw (DfException)e;

DfException e2 = new DfException(); e2.setMessage( e.toString() ); throw e2;

}

}

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

Executing this command line several times for different numbering types will prove that the service is producing sequential numbers by type:

Figure 3-3 - Run the test TBO program

numbers by type: Figure 3-3 - Run the test TBO program A Simple Service-ba sed Object

A Simple Service-based Object Example

Introduction

As described in the "Solution: Documentum Business Objects" section, this Simple_SBO program will be an application that fetches the next sequence number according to the specified number type in a given Docbase and increments it. In order to accomplish this, the following issues must be implemented:

Assume that this example will work with a variety of separate, distinct numbering sequence types ("PO", "INV", etc.).

A

new DBOF service interface will be created, called IAutoNumber, which is

implemented by the AutoNumber class, and provides the public access to the numbering service for the given types.

A

Simple_SBO test application will be created to call the service and fetch the next

number in sequence of the given type if an instance of that type exists in the Docbase. Trying it from different computers will still obtain the correct number in sequence.

Implementing the AutoNumber Service Based Object (SBO)

This section will step you through the creation of the AutoNumber service. It will use the values stored in the AutoNumberType created in the previous section.

1. Create the new IAutoName service interface

1.1. Define a new interface, called IAutoNumber, which extends the IDfService interface. The IDfService interface defines three abstract methods the must be implemented in the AutoNumber class.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

1.2. In the IAutoNumber interface, prototype the minimal number of methods that abstract the details of the service. In this case, you will prototype the

getNextNumber() method only.

/* IAutoNumber.java */ package com.accelera.autonumber;

import com.documentum.fc.client.*; import com.documentum.fc.common.DfException;

public interface IAutoNumber extends IDfService

{

public String getNextNumber( String strDocbase, String strAutoNumberType )

throws DfException;

}

2. Extend DfService with the new AutoNumber class

The AutoNumber SBO class definition provides a very simple generalized interface to the TBOs stored in the Docbase. Aside from Docbase session and synchronization issues, the caller need not be aware of the underlying details as to how the service performs its duty. The caller just calls getNextNumber() and the service takes care of the rest. Before implementing the getNextNumber() method, override the three abstract methods from DfService that you must implement.

2.1. Create a new class, AutoNumber, and extend DfService class and implement its

IAutoNumber interface.

public class AutoNumber extends DfService implements IAutoNumber

{

}

2.2. In the AutoNumber class, add the String constants that will be used for the

getVersion() and getVendorString() methods.

public static final String strCOPYRIGHT = "Copyright (c) Documentum, Inc., 2002"; public static final String strVERSION = "1.0";

2.3. Since the AutoNumber class extends the DfService class, and the DfService class defines three abstract methods, your new class must implement overrides

for each of those methods, getVersion(), getVendorString(), isCompatibile() as follows:

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

/* AutoNumber.java */ package com.accelera.autonumber;

import com.documentum.fc.client.*; import com.documentum.fc.common.DfException;

public class AutoNumber extends DfService implements IAutoNumber

{

public static final String strCOPYRIGHT = "Copyright (c) Documentum, Inc., 2002"; public static final String strVERSION = "1.0";

public String getVersion()

{

return strVERSION;

}

public String getVendorString()

{

return strCOPYRIGHT;

}

public boolean isCompatible( String strVersion )

{

 

int i = strVersion.compareTo( getVersion() ); if( i <= 0 ) return true;

else return false;

}

} //end: class AutoNumber

3. Numbering Scheme methods

Now that you have finished overriding the methods of its superclass, you can implement the public interface for the service. In this case the service only has one method, the

getNextNumber() method.

3.1. In the AutoNumber class, implement the getNextNumber() method. The getNextNumber() method needs to be as stateless as possible, so pass the Docbase name to it each time it is called. A second argument is the numbering type (e.g. "PO", "INV", etc.). The method will need to perform a Docbase query to obtain the matching AutoNumberType object, if it exists, return the currently stored number, and store next number back into the Docbase.

3.2. Each time the getNextNumber() service method is called, it assumes that the caller has established a session manager and uses that session manager to obtain a session for Docbase access.

3.3. The getNextNumber() service method fetches an AutoNumberType Docbase

object, using the session.getObjectByQualification() method, and updates

it.

3.4. Since it is mandatory that releaseSession() is called when its matching getSession() method is used, releaseSession() is put in a finally block as shown below in order to guarantee it executes.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

public String getNextNumber( String strDocbase,

throws DfException

String strAutoNumberType )

{

 

String strRetVal = null; IDfSession session = null; boolean bNewTransaction = false;

String strPrefix = "com_accelera_autonumber where number_type='"; String strSuffix = "'";

StringBuffer strbDql = new StringBuffer( strPrefix.length()

+ strAutoNumberType.length()

+ strSuffix.length() );

String strDql = strbDql.append( strPrefix ) .append( strAutoNumberType ) .append( strSuffix ) .toString();

IDfSessionManager sMgr = getSessionManager();

if( ! isTransactionActive() )

{

sMgr.beginTransaction();

bNewTransaction = true;

}

try

{

session = getSession( strDocbase ); //managed session try

{

IAutoNumberType numType = (IAutoNumberType)

session.getObjectByQualification( strDql );

strRetVal = numType.getUniqueNumber( sMgr );

}

finally

{

releaseSession( session );

}

if( bNewTransaction )

sMgr.commitTransaction();

}

catch( Exception e )

{

if( bNewTransaction )

sMgr.abortTransaction();

 

}

 

return strRetVal;

}

4. Map the new IAutoNumber service interface to the AutoNumber service class.

Better known as "registering the service with the DBOR", you need to map the interface to the class so that the newService() method will know how to construct an AutoNumber object as opposed to any others. This registration can be done manually, or you can write a program to perform the installation of the service.

Developing Your First Business Objects

Documentum Business Objects Framework (DBOF)

4.1. To register by hand, in the "DFC_DATA\config" directory (usually "c:\Documentum\config"), add the following entry anywhere in the

dbor.properties file:

com.accelera.autonumber.IAutoNumber=service,com.accelera.autonumber.AutoNumber,1.0

4.2. More appropriately, you should allow IDfDbor do this work since it will not allow duplicate entries. Writing a method that calls the

mapDocbaseTypeToClassName() method on page 3-16. The beginInstall()

method below is designed to register either TBO or SBO entries. If it is called with bService set to true, then the strNewDocbaseType parameter represents the

service interface (e.g. com.accelera.autonumber.IAutoNumber).

private boolean beginInstall( IDfSessionManager sMgr, boolean bService, String strDocbaseName, String strNewDocbaseType, String strJavaClass )

{

 

boolean bRetVal = true; IDfSession session = null; try

 

{

//setupLog();

 

session = sMgr.getSession( strDocbaseName );

if( ! bService )

 

{

 

if( addDocbaseType( sMgr, session, strNewDocbaseType ) )

{