Using Java reflection to reduce Code and Development time in DFS


 

Java reflections are one of the most powerful API’s of Java Language, this can be used to reduce code significantly.

Most of the Current Enterprise application consists of different layers and they use Value objects to transfer data from one layer to another. An inefficient way of using getters and setters of the attributes of Value objects can increase code and development time of application. Effective use of reflection can reduce code and development time significantly.

So let’s take a Scenario,  I have an Object type MyObjectType extending from dm_document with 50 additional attributes, so dm_document as of Documentum 6.5 has 86 attributes adding additional 50 attributes that means we have 139 attributes for this object type. Consider a standard Web Application using DFS behind which needs to manipulate (add or edit) instances of this object type, The Service needs to add all these attributes to the PropertySet  of the DataObject representing that instance. Then need to call the appropriate service.

 

Considering that the bean instance name of MyObjectType is myObjectBean the Standard code will  be something like this

  ObjectIdentity objIdentity = new ObjectIdentity("myRepository");
  DataObject dataObject = new DataObject(objIdentity, "dm_document");
  PropertySet properties = dataObject.getProperties();
  properties.set("object_name", myObjectBean.getObject_Name());
  properties.set("title", myObjectBean.getTitle()); 
  // omited for simplicity


  objectService.create(new DataPackage(dataObject), operationOptions);

 

In the above code you have to explicitly set individual attributes for the object, the more the number of attributes the more complex and messy code.

Take another Example, where you have to retrieve an Object information and pass it over to the UI layer.

 myObjectBean.setObject_name(properties.get("object_name").getValueAsString());
 myObjectBean.setTitle(properties.get("title").getValueAsString());
 myObjectBean.setMy_Custom_Property(properties.get("my_custom_property").getValueAsString());

This operation can be more complex if you decide to use match the Data Type of your bean with the Object type.

 

So what is the best approach to reducing this complexity? the answer is the effective use of reflection API.

Let’s take a step to step approach to handle this issue.

To understand this better consider the below as the attributes of mycustomobjecttype

 

Attribute Name Attribute Type
first_name String
last_name String
age integer
date_purchased time
amount_due double
local_buyer boolean

 

Java Bean

Create a Java Bean that matches the Object Type

 public class Mycustomobjecttype {
  protected String first_name ;
  protected String last_name  ;
  protected int age;
  protected Date date_purchased  ;
  protected double amount_due  ;
  protected boolean local_buyer ;
  public int getAge() {
    return age;
  }
  public void setAge(int age) {
    this.age = age;
  }
  public double getAmount_due() {
    return amount_due;
  }
  public void setAmount_due(double amount_due) {
    this.amount_due = amount_due;
  }
  public Date getDate_purchased() {
    return date_purchased;
  }
  public void setDate_purchased(Date date_purchased) {
    this.date_purchased = date_purchased;
  }
  public String getFirst_name() {
    return first_name;
  }
  public void setFirst_name(String first_name) {
    this.first_name = first_name;
  }
  public String getLast_name() {
    return last_name;
  }
  public void setLast_name(String last_name) {
    this.last_name = last_name;
  }
  public boolean isLocal_buyer() {
    return local_buyer;
  }
  public void setLocal_buyer(boolean local_buyer) {
    this.local_buyer = local_buyer;
  }
}

Getting the Values from PropertySet (Loading Java Bean)

……

List<DataObject> dataObjectList = dataPackage.getDataObjects();
DataObject dObject = dataObjectList.get(0);
Mycustomobjecttype myCustomObject = new Mycustomobjecttype();
populateBeanFromPropertySet(dObject.getProperties(),myCustomObject);

……

// See the Reflection in Action here 
public void populateBeanFromPropertySet(PropertySet propertySet, Object bean)
  throws Exception {
 BeanInfo beaninformation;
 beaninformation = Introspector.getBeanInfo(bean.getClass());
 PropertyDescriptor[] sourceDescriptors = beaninformation.getPropertyDescriptors();
 for (PropertyDescriptor descriptor : sourceDescriptors) {
     Object result = null;
     String name = descriptor.getName();
    if (!name.equals("class")) {
      if (propertySet.get(name) != null) {
        if (descriptor.getPropertyType().getName().equals("int")) {
          result = new Integer(propertySet.get(name)
              .getValueAsString());
        } else if (descriptor.getPropertyType().getName().equals("double")) {
          result = new Double(propertySet.get(name).getValueAsString());
         } else if (descriptor.getPropertyType().getName().equals("boolean")) {
          result = new Boolean(propertySet.get(name).getValueAsString());
         } else if (descriptor.getPropertyType().getName().equals("java.util.Date")) {
          DateProperty dat = (DateProperty)propertySet.get(name);
          result = dat.getValue();
        }else {
          // none of the other possible types, so assume it as String
          result = propertySet.get(name).getValueAsString();
        }
        if (result != null)
          descriptor.getWriteMethod().invoke(bean, result);
      }
     }
  }
}

Setting Values to Property Set

 

public DataPackage createContentLessObject(Mycustomobjecttype myCustomType) throws Exception {
ObjectIdentity objectIdentity = new ObjectIdentity("testRepositoryName");
DataObject dataObject = new DataObject(objectIdentity, myCustomType.getClass().getName());
PropertySet properties = populateProperties(myCustomType);
properties.set("object_name",myCustomType.getFirst_name()+myCustomType.getLast_name() );
dataObject.setProperties(properties);
DataPackage dataPackage = new DataPackage(dataObject);
OperationOptions operationOptions = new OperationOptions();
return objectService.create(dataPackage, operationOptions);
}

 

// Reflection in Action  
public PropertySet populateProperties(Object bean)throws Exception {
BeanInfo beaninfo;
PropertySet myPropertyset = new PropertySet();
beaninfo = Introspector.getBeanInfo(bean.getClass());  
PropertyDescriptor[] sourceDescriptors = beaninfo
      .getPropertyDescriptors();
  for (PropertyDescriptor descriptor : sourceDescriptors) {
    String propertyName = descriptor.getName();
    if (!propertyName.equals("class")) {
        // dont set read only attributes if any
       // example r_object_id 
       if (!propertyName.startsWith("r")) {
        Object value = descriptor.getReadMethod().invoke(bean);
       if (value != null) {
          myPropertyset.set(propertyName, value);
        }
      }
   }
 }
  return myPropertyset;
}

Chaining of Custom Services in DFS


 

There is an interesting drawback in Documentum Foundation Services Version 6.5,

Issue:

When you chain custom services and try to build the Services the build fails lets see a Scenario from the DFS sample code itself

@DfsPojoService(targetNamespace = http://common.samples.services.emc.com&#8221;, requiresAuthentication = true

) public class HelloWorldService

{

public String sayHello(String name)

{

ServiceFactory serviceFactory = ServiceFactory.getInstance();

IServiceContext context = ContextFactory.getInstance().getContext();

try {

IAcmeCustomService secondService = serviceFactory.getService(IAcmeCustomService.class, context);

secondService.testExceptionHandling();

} catch (ServiceInvocationException e) {

e.printStackTrace();

} catch (CustomException e) {

e.printStackTrace();

} catch (ServiceException e) {

e.printStackTrace();

}

return “Hello “ + name;

}

}

Here in the sample code of DFS I am chaining the services, Here everything looks fine and when you now you build this service during the genarateArtifacts ant task the Build will fail with a will get a ClassNotFound compiler error at

IAcmeCustomService secondService = serviceFactory.getService(IAcmeCustomService.class, context);

What happens here is when the build does the initial clean up all the generated Client interfaces are deleted and DFS currently not checking for any dependencies.

Let me take the example of dfs-build.xml that’s the part of CoreDocumentumProject in composer

<generateArtifacts serviceModel=“${gen.src.dir}/${context.root}-${module.name}-service-model.xml” destdir=“${gen.src.dir}/”>

<src location=“${src.dir}” />

<classpath>

<path refid=“projectclasspath.path” />

</classpath>

</generateArtifacts>

</target>

 

In this we cannot set any exclusion path in <src location=“${src.dir}” />

Simply because it even if you provide <fileset/> or <direst/> with pattern set its not recognizing it.

I had raised a support case with EMC and they told me that this is not currently supported!!!! And they will add this as a feature request

This means we cannot Chain Custom Services unless EMC fix this or we do a semi manual workaround to overcome this issue.

The Work-around that I found

Follow these steps to overcome this issue

Step 1,

Identify the Services those will call the custom services, and create a new source directory for it in composer, here I am calling them as depended_src and move the services that calls the custom services to there, the depended src should be in a separate path than the webservices- src

src-img1

Step 2

1) Now Edit the Build file and add these two properties

 

<property name=“my.core.services.classes” value=“${service.projectdir}/Web Services/bin/classes” />

 

<property name=“dep.src.dir” value=“${service.projectdir}/depended_src” />

The dep.src.dir should point to the depended src location mentioned in step 1

2) Create an additional target for generatemodel and generate artifacts

<target name=“generateDependencies” depends=“generate”>

<echo message=“Calling generateDependencies” />

<generateModel contextRoot=“${context.root}” moduleName=“${module.name}” destdir=“${gen.src.dir}/”>

<services>

<fileset dir=“${dep.src.dir}”>

<include name=“**/*.java” />

</fileset>

</services>

<classpath>

<pathelement location=“${my.core.services.classes}” />

<path refid=“projectclasspath.path” />

</classpath>

</generateModel>

<generateArtifacts serviceModel=“${gen.src.dir}/${context.root}-${module.name}-service-model.xml” destdir=“${gen.src.dir}/”>

<src location=“${dep.src.dir}” />

<classpath>

<pathelement location=“${my.core.services.classes}”/>

<path refid=“projectclasspath.path” />

</classpath>

</generateArtifacts>

<!– signal build is done –>

<!– used by DFSBuilder.java –>

<copy todir=“${src.dir}/../” file=“${basedir}/dfs-builddone.flag” />

</target>

3) Now edit dfs-build.properteis and add the following property

service.projectdir= <absolute path to the project>

Step 3

1) Run the generate task,

2) Copy all the service entries from (between <module> and </module><context-root>-<module-name>-service-model.xml you can find this in <project_dir>\Web Services\bin\gen-src folder

3) Now run the generateDependencies task that was created on Step 2

4) Now Edit <context-root>-<module-name>-service-model.xml and add the copied services to this file

5) If you want to create the jar files now you can call the package task after this.

This should help you to chain custom services , and if you found any alternate ways please comment.

 

Aliases and Alias sets in Documentum


 

In Simple words Aliases are placeholders that can hold any of the following

1)      A User or a Group Name

2)      Folder information

Alias is a key value pair where key is the alias name and value is the actual value.

 

Alias Sets are the Collection of Aliases (Which has alias names and its values)

 

Typical uses of Aliases

1)      Dynamically Resolve task performers in a Workflow

2)      Set up ACL, ACL Domain, and Owner name in a Sys Object or its subtypes.

3)      Dynamically link or unlink an object of Sys object or its subtype with a Folder path

4)      Also used in Template ACL’s (I will explain more about Template ACL in another study note soon)

 

Internals of an Alias and Alias sets

Documentum uses an Object type named dm_aliase_set to store the aliases and its values. All the objects of this type will have a r_object_id starting with “66”

Let’s see the attributes of this object type 

 

 

Name

Info

Description

alias_category

Integer (Repeating)

This defines the category of the aliases value in the corresponding index.   These are the possible values and its corresponding categories

Value

Category

0

Unknown

1

User

2

Group

3

User or Group

4

Path of Cabinet

5

Path of Folder

6

Name of ACL

alias_description

String (255) (Repeating)

This defines the option description for individual alias values that correspond to the index in alias names.

alias_names

String (32) (Repeating)

The name of alias for the corresponding index in the alias values. (This Sting cannot have (.))

alias_usr_ category

Integer (Repeating)

Placeholder for defining user-defined categories for alias values.

alias_value                      

String (255) (Repeating)

The corresponding values for the Aliases defined the corresponding index in the alias names]

object_name

String (32) (Single)

Name of the Alias set

  • Has to be Unique among the alias sets in the repository

object_description

String (128 ) (Single)

Description of the alias sets

owner_name

String (32) (Single)

The name of the user who owns this alias sets.

 

So now you have seen what makes a dm_alias_set object, now let’s clarify how an Alias is defined within an Alias set.

Alias_names stores the name of the Alias and Alias_value stores the corresponding value for the Alias and it’s stored as a repeatable attribute. Means value of an index position defines an Alias Category, Alias Name and Alias Value

 

In an example of an Alias manager = John Smith the index of listing manager in attribute alias_name and index of listing John Smith in attribute alias_value will be same

 

Alias Reference and Scope of Alias

 

Alias is referenced used %alias_name

Referencing an Alias can also include Object_name of Alias Set; in that case, the reference will be %alias_set_object_name.alias_name

 

So if the alias is referenced with the Alias set names (%alias_set_object_name.alias_name

) Server finds the Alias set by name and picks up the Alias name and resolve its Alias value, this is pretty much a straightforward job for the server to do.

 

But where the Alias name is referred without Alias set name the Server searches for the Alias in some specific scopes, This Order, and location, where the search is made for alias, depends upon where that alias is referenced.

 

The following table describes few important Scopes, underlying object type and attribute of that object that helps server to identify the alias set to resolve the alias names.

 

Scope

Object type

Attribute

Notes

User

dm_user

alias_set_id

Server user alias_set_id property of the user who has done the action that resulted in alias resolution.

Group

Dm_group

alias_set_id

Default group of the user who performed the action

Lifecycle

Dm_sysobject

R_alias_set_id

R_alias_set_id is set by the server when the object is attached to a lifecycle.

Server Configuration

Dm_server_config

Alias_set_id

This alias set object represents the alias set that’s used as the default system-level

Alias set.

 

Difference between Super User and Sysadmin


Most of the budding Documentum developers get confused about the differences between a Super User and a Sysadmin. Though I had mentioned these points on my Documentum Security notes PDF file, I feel this needs a separate entry here. So just listing few important privileges of Sysadmin and Super User here. This list is not exhaustive but I guess I have most of it here, if you feel that I missed some important please feel free to add it as a comment.

Sysadmin

  • Create, alter, and drop users and groups
  • Create, modify, and delete system-level ACLs
  • Grant and revoke Create Type, Create Cabinet, and Create Group privileges
  • Create types, cabinets, and printers
  • Manipulate workflows or work items, regardless of ownership
  • Manage any object’s lifecycle
  • Set the a_full_text attribute

 The Sysadmin privilege does not override object-level permissions

 Super User

  • Perform all the functions of a user with Sysadmin privileges
  • Unlock objects in the repository
  • Modify or drop another user’s user-defined object type
  • Create subtypes that have no supertype
  • Register and unregister another user’s tables
  • Select from any underlying RDBMS table regardless of whether it is registered or not
  • Modify or remove another user’s groups or private ACLs
  • Create, modify, or remove system ACLs
  • Grant and revoke Superuser and Sysadmin privileges
  • Grant and revoke extended privileges
  • View audit trail entries

Download this Study Note (PDF)

Federation in Documentum


Federation is one among the most common distributed Documentum model. This means multiple Documentum repositories run as a federation. There will be a Governing repository and multiple member repositories in this model. Lets try to find out more about Federation

 

Take this typical scenario A Major Pharmaceutical Company ABC Corporation has multiple research centers and production plants across the glob and they have multiple Documentum repositories used for storing various information. A user logged into a corporate application needs to fetch documents from these various repositories in a Single session. Each repository in this scenario should have same set of users, groups and ACL for this architecture to work, manually managing these kind of scenario is trouble some and error prone.

 

Now lets see what a federation can do to make it less complex.

As I mentioned above Federations consists of Governing and Member repositories all the changes that has been made to global users and groups and external ACLS in the governing repository are automatically reproduced in the member Repository.

 

Requirements for Federation

·         Object types definition should be same in the all participating repositories.

·         User and group definition should be same in all participating repositories.

·         The server on which governing repository runs must project to the connection brokers at the servers where member repository runs

·         The server on which member repositories runs must project to the connection brokers at the servers where governing repository runs

·         If any of the participating Content Servers are with trusted server licenses Either
The servers should be configured to listen on both secure and native port or
The secure connection default for clients allows the clients to request a connection on a native or secure port

 

Few Bullet points about Federation

·         Any alteration done to any of the object type will not be automatically pushed to the participating repositories

·         Only users or groups marked as Global while creating them will be pushed / synchronized with participating repositories

·         The users those are part of any object types that are extended from dm_user will not automatically pushed. This will happen only if you specify this type in the Federation configuration.

·         Each repositories can be part of a single federation

·         A federation may contain different Content Server versions

·         A federation may contain a mix of trusted and non-trusted Content Servers.

 

 Download this Study Note (PDF)

Few Important Object Types in Documentum


 

 

Documentum is an Object Oriented Content Management Systems. Everything in Documentum is considered as Objects, This includes all the things that user manipulates, or the content server saves. From the User to Document, everything in Documentum is different type of Object. The whole Object types in Documentum has been structured in a Hierarchal model. Means All the Attributes from the super types are extended to the sub types. In other sense the attributes of Super types are visible and accessible from the Subtypes.

 

Lets see some of the important and most commonly used object types here. 

 

Note: This is just to give an insight of Documentum Object model. Please read Object Reference Manual for very detailed information on All Object types and its attributes.

Persistence Object 

This type is the super type of all the object types that are saved in Documentum. Each time user creates an object instance of Persistence object type they are objects stored in the repository, this can be retrieved at a later point of time from the Content server.

 

This Object type is an internal type and you cannot create an instance of it.  There are only 3 attributes for this object type they are. These attributes are extended to all the object types across the Documentum.

 

1)      r_object_id
A Unique ID of an object. Content server generates this ID when you create an object of any type. There are some interesting aspects about r_object_id. r_object_id is 16 characters long and its alpha numeric.

The characters from position 01 to 02 indicate the object type tag (09 = document, 0b = folder, etc.).

The characters from position 03 to 08            Repository id (Same for every object in a Repository, but different for each Repository)     

The characters from position 09 -to 16            is unique identifier for this object

 

Consider the following r_object_id 09012a5b80075dc2 in this 09 is the Object type Tag, 012a5b is the repository ID and 80075dc2 is the unique id that represents this object.

2)      i_vstamp
This property is basically used for versioning, each time you save changes to the object the value of this property increases by 1 and this also helps to check the concurrent modification of object.

3)      i_is_replica
This property of object that indicates whether that object is replica of  an object in a remote repository

 

Sys Object (extended from Persistence Object) (dm_sysobject)

Most of the commonly used object types are extended from this object type. Most common Subtypes include Document, Folder, and Cabinet etc.

There are 4 important characteristics for this Object type. They are

1)      Only dm_sysobject and its subtypes can be defined as shareable

2)      They can have permissions associated (Attach ACL).

3)      Sys object can belongs to a folder (Exception Cabinet – Cabinet cannot belong to a folder)

4)      Sys object can have content attached to it.

ACL  (extended from Persistence Object) (dm_acl)

This object type plays a very vital role in implementing security to the Documentum server if the security model of Content Server is set to ACL. All ACL objects r_object_id starts with letters 45

User (extended from Persistence Object)(dm_user)

This stores all the information about user in a Documentum repository, Only a Super user or Sys Admin can create/activate/delete/deactivate a user. All User Object’s r_object_id starts with letters 11

Group (extended from Persistence Object)(dm_group)

A group is the group of users and it can include another groups also.  This object stores information about a specific group, which includes r_object_id of all the member users, groups. This has identifier which determines whether it’s a group or a role. All the group objects has r_object_id starting with 12

Document (extended from Sys Object)(dm_document)

Documents represent a real document in Repository; it can be associated with 0 or more content objects also.  A Document may be a real document or virtual document. All objects of this type has a r_object_id starting with 09

Folder (extended from Sys Object)(dm_folder)

Folders are basically used to organize contents. All the sys objects that are created should be linked with at least one folder or a Cabinet. An Object can be linked with multiple folders also. All objects of this type has a r_object_id starting with 0b

Cabinet (extended from Sys Object)(dm_cabinet)

Cabinet is a special type of folders and its used to organize sys object in a repository. Cabinets are the highest in the Folder Hierarchy in Documentum. A Cabinet cannot be placed inside a Cabinet or a Folder and that makes it special. All objects of this type has a r_object_id starting with 0c

Registered (extended from Sys Object)(dm_registered)

Represents a Registered table in a RDBMS in Documentum. It has the table, name, column names and it s data type saved.  All objects of this type has a r_object_id starting with 19

  

Object types that are not saved in Repository

There are few Object types in Documentum, which are not to be saved in the repository. These are some object types that are created on runtime and destroyed as its use is over. Here is the list of those object types.

 

Client config (New in D6)

A Client config object is created at every time when DFC is initialized. This has all the properties in the dfc.properties file.

Connection Config

This type describes a session’s connection to a specific repository

Docbroker Locator

A docbroker locator object contains information about each connection broker that the

client DMCL can access

Docbase Locator

This has information all repositories registered with a connection broker

Server Locator

A server locator object has information about all the servers registered to a connection broker

Session Config

Contains information about an open repository session

 

Download this Study Note (PDF)

Object Types involved in WorkFlow


Below is the table with different object types that has some role in workflow (5.3) with its description from Documentum Object Reference Manual

Object Type

Short Description

Detailed Information

dm_workflow

Contains the runtime information about a workflow.

A workflow object contains the runtime information about a workflow.

dm_activity

An activity object defines a workflow activity.

The attributes in an activity object define who performs the activity and the packages and work items generated from the activity.

dm_process

A process object contains the definition of a workflow process.

A process object is created when a user creates a workflow definition in either Workflow Manager or Business Process Manager. There are three inherited attributes that are reserved for internal use for process objects: a_special_app, a_status, and a_application_type.

dmi_workitem

Stores information about a task for a human or automatic performer.

Work items are generated by Content Server from an activity object. Users cannot create work items. Users can modify only the following attributes: a_held_by, a_wq_doc_profile, a_wq_flag, a_wq_name, and a_wq_policy_id.

dmc_workqueue

Represents a work queue for work items generated from a workflow

A work queue object represents a work queue for workflow tasks. The workqueue object type is installed by a script when Content Server is installed. However, work queues (instances of the type) are created and managed using Webtop.

dmc_workqueue_category

Defines a category for a work queue.

A work queue category object represents a category of work queues. The object type has no attributes defined for it. It inherits all its attributes from its supertype, dm_folder. It uses only the object_name, acl_name, and acl_domain attributes. The object_name attribute stores the work queue category name

dmc_workqueue_policy

Defines configuration information for a work queue.

A work queue policy object defines configuration parameters for handling a task in a  workqueue. The parameters control how the items are handled. Each work queue has one associated work queue policy. If a document associated with a task has a defined work queue policy, that policy overrides the work queue’s policy.

dmi_wf_timer

Records the configuration of a timer for a workflow activity.

A wf timer object describes a timer for a workflow activity. The wf timer objects are created automatically when the timer is instantiated.

Download This Study Note (PDF)

Object Relationships in Documentum


Objects in the Documentum repository can be associated with Relationships. Lets explore the basics of Object Relationships here. There are 2 major object types that you need to know in

1) dm_relation_typeThis defines a relation, means this object type holds the information about the relation like its name, security type, parent type, child type etc. We will get into the details of this soon. User must have SysAdmin or Super User privileges to create object of this type. All the objects of this type will have r_object_id starting with 38

2) dm_relation This defines each individual relationship between the objects. Means this type has ID’s of the both parent and child object which makes the relation, the name of the relation etc. All the objects of this type will have r_object_id starting with 37

Now lest see the attributes of each object type and understand what each attributes is meant for and how these objects are related.

Lets list the attributes of type dm_relation_type

Name

Info Description
relation_name Char (32) Single Name of the relation, This must be a Unique name.
security_type Char (10) Single This defines who can add, delete, drop or modify a relationship. The possible values are SYSTEM
PARENTCHILDNONE(I will explain this in detail below)
parent_type Char (32) Single The valid object type of parent in this relationship
child_type Char (32) Single The valid object type of child in this relationship
description Char (250) Single Description of the relationship (User defined)
direction_kind Integer Single The Direction of the relation There are 3 Possible values for it. And they are
0 – This relation is parent to child
1 – This relation is child to parent
2 – This relation is bidirectional (means these objects are siblings)
The default value is always 0
integrity_kind Integer Single This determines the referential integrity of this relation. There are 3 Possible values for it. And they are
0 – Allow Delete
1 – Disallow delete
2 – Cascade Delete (This means when a user deletes an object participating in a relationship instance, Server will also destroy the participating partner in the relationship)
The default value is always 0
parent_child_label Char (255) Repeating User defined name for the parent child relationship
child_parent_label Char (255) Repeating User defined name for the child to parent relationship
permanent_link Boolean Single This defines what happens to the relation when the parent is copied or versioned.
If set to True relation is maintained with new parent object.If set false the relation is not maintained. The Default value is False
copy_child Integer Single Specifies whether to copy the child in a relationship when the parent is copied and permanent_link is True. . There are 2 Possible values for it. And they are
0 – Do not copy Child
1 – Copy Child
a_controlling_kind Char (32) Single This indicates whether relationships of this type are created by users or internally.

Lets list the attributes of type dm_relation

 

Name

Info Description
relation_name Char (32) Single Name of the relation that’s specified for the dm_relation_type object
parent_id ID Single ID of the parent object
child_id ID Single ID of the child object.
child_label Char (32) Single Optional version label of the child object. If this value is provided then I_chronicle_id of the object should be given as the id of the child in the child_id attribute.
permanent_link Boolean Single <Deprecated>
order_no Integer Single Not used, but can be used for custom purpose
effective_date Date Single Not used, but can be used for custom purpose
expiration_date Date Single Not used, but can be used for custom purpose
description Char (255) Single Description of the relationship (User defined)

 

The relation between dm_relation_type and dm_relation type objects is illustrated below

Relation Dig-1

Few bullets points about dm_relation and dm_relation_type

  1. Niether dm_relation nor dm_relation_Tupe can be versioned

  2. Object level security (ACL) cannot be set on these object types

  3. You cannot delete a dm_relation_type object if any of the dm_relation with its relation_name exists.

  4. You need super user privileges to delete a dm_relation_type object

  5. Destroying a dm_relation object does not destroy the parent or child objects.

  6. When you destroy an object all the dm_relation associated with that object also gets deleted.

Security and Relations

 

When we saw the attributes of dm_relation_type object I had mentioned about security_type. Lets see this in detail. As mentioned above security_type defines who can add, delete, drop or modify an object of dm_relation object, which has a relation name that of the relation_name in the dm_relation_type. Lets see what the individual possible values means here

 

  1. SYSTEM
    This means only SuperUsers and SysAdmins can create, edit or delete a relation with the relation_name in this type. This does not prevent an owner of an object from destroying an object that participates in the relationship. When a Objectis destroyed content server also destroys all relation objects associated with the object. The owner of that Object is not required to be a superuser or system administrator.
  2. PARENT
    This means create, delete or edit a Relation will depend upon the users permissions on the parent object. I.e. if the object that’s getting related is of object type dm_sysobject or its child user should at least have RELATE permission.
  3. CHILD
    This means create, delete or edit a Relation will depend upon the users permissions on the Child object. I.e. if the object that’s getting related is of object type dm_sysobject or its child user should at least have RELATE permission.
  4. NONE
    This means Any user can create, delete or edit a Relation of this type.

Download this Study Note (PDF)

Virtual Documents in Documentum


What is a Virtual Document

Simplistically speaking Virtual document is a document that can contain another documents.

After reading the above statement first question that might arise to all is if it can contain documents how is it different from a folder?

Let me make few bullet points about Virtual Document here, which will clear most of the confusions that you might have about virtual documents.

 

· A Virtual Document is a Document which can contain the type or the sub type of SysObjects with an exception given below

· A Virtual Document cannot contain any folders or cabinets, or any sub types of these.

· A Virtual Document object may or may not have a content (dmr_content) attached to it but a folder or a cabinet will never have any content attached to it. Though most of the time a Virtual Document might not be having a Content file attached to it.

· Any Object type that extents from SysObject can be converted as a Virtual Document. The Attribute r_is_virtual_doc (integer not a Boolean) of SysObject determines whether that object is a virtual document or not. If the value is 1 then it’s a Virtual document. If its value is 0 and the property r_link_cnt value is not higher than 0 then that object is not a Virtual Document
The Content Server Fundamental is misleading in this aspect, Page number 199 of guide says it’s a Boolean property but in reality its not

· The Contents of the Virtual document can be of different object types.

· The Virtual Documents can be versioned and managed in the same way as you do with any other objects.

 

Components and Containment, the elements of Virtual Document

 

The Virtual documents are composed of various components, each components are nothing but individual objects. In other sense a component is a child of a Virtual Document. The containment objects (dmr_containtment) stores the information about the individual components of a Virtual Document. Every time when you add a new component to a virtual document a new dmr_containtment object will be created.

 

Now lets see the attributes of a dmr_containment object. This will give you a clear idea about what it does.

 

 

Name Info Description
parent_id ID – Single Object ID of the object that directly contains the component.
component_id ID – Single The Object Id of the Initial Object of the component. (I_chronicle_id). If the object has no versions, then its object ID and chronicle ID are the same.
copy_child Integer – Single Defines what a client should when the document containing the component is copied.
Possible Values Meaning
0 The decision whether to copy or reference the component is left to the user when the document is copied
1 When the document is copied, the component is referenced In the new copy rather than actually copied
2 When the document is copied, the component is also copied
follow_assembly Boolean – Single If set to TRUE, directs the system to resolve a component using the component’s assembly
i_partition Integer – Single Not Currently used
order_no Double -Single Number representing the component’s position within the components of the virtual document identified by parent_id
a_contain_desc string(255) Single User-defined. Used by clients to manage XML documents
a_contain_type string(255) Single User-defined. Used by clients to manage XML documents
use_node_ver_label Boolean – Single If set to TRUE for early-bound components, the server uses the early-bound symbolic label to resolve late-bound descendants of the component during assembly
Version_label string(32) Single Version label for the component.

 

 

Now as you had seen the dmr_containment object attributes lets get into more details of Virtual Documents.

The component can be associated with Virtual documents in 2 ways with respect to its versions

You can either associate a particular version of component with the virtual document or you can attach the entire version tree of the component with Virtual document.

 

If you attach the entire version of a document you have a choice of selecting the version of component to attach with virtual document at the time of assembling a virtual document.

Another important part of the Virtual document is the order of components in the Virtual Document; Content Server manages this ordering by default by adding for removing numbers while adding or removing components. If you wish do this part you can do it manually too.

 

Component referential integrity

The Boolean property compound_integrity of server configuration object dm_server_config manage the referential integrity of virtual document. If this attribute is set to true the content server will not allow deleting an object, which is contained in a Virtual Document. This attribute is set to true by default. You have to have minimum SysAdmin privileges to change this value.

If this attribute is set to false one can destroy the components of an unfrozen Virtual Documents. In any case you can never destroy components of a frozen virtual document.

 

Assembly, Conditional Assembly and Snapshots

Selecting the set of components for a Virtual document for a operation is known as Assembly, Conditional assembly allows the user to choose to include all components or some of them. As mentioned above if the entire versions of a component we can choose which all documents and also which versions of document to be included in the assembly.

 

A snapshot is the state of a Virtual document at the time when it was taken. This means it has the components that were selected during the creation of the snapshot. Each Snapshot is saved in repository as an assembly (dm_assembly) object.

Assembly objects are created when a user creates an assembly, a snapshot of the virtual document at particular point in time. Users must have at least Version permission for the object identified in the book_id property to modify an assembly object.

 

Binding a component (Early and Late)

Attaching a component to a Virtual Document is known as binding. There are 2 ways of binding a component to Virtual Document. They are Early binding and Late Binding

1) Early Binding
If you bind a specific version of a Component to the Virtual Document when you create a virtual document then it’s known as Early Binding. This makes sure that all the snapshots of virtual document have the same version of the component.
Links – Absolute and Symbolic

     Absolute Link

Before getting into Absolute links let’s see what an implicit version label is? An Implicit version label is the version label assigned to a document when you version by the content server. An implicit version label of the version of a document remains as it till that version is destroyed. Using an implicit version label to link component with a Virtual Document creates an Absolute link between component and Virtual Document.

     Symbolic Link

Symbolic version label is the version label, which are user –defined. This allows a user to give meaningful labels to a document. This can be moved from one version to another of a object.

When you use this type of linking no matter what the Virtual Document will have component, which has the specified symbolic version label. E.g. You define a Virtual Document to have a component which has a version label Published, the Virtual document will always have the published version of the component.

2) Late Binding
When you don’t specify a version label of a component when u add it to a virtual document its known as late binding. In this case the Content server attach the entire version tree of the specified component to the virtual document. And when you assemble the document you specify which version of component you should use.

Freezing and Unfreezing a Virtual Document.

Frozen Virtual Documents are virtual documents, which are immutable. Once you make a Virtual Document or a snapshot frozen you cannot change or delete any attributes of the virtual document and you can also not add or remove components of virtual document. You can explicitly make a Virtual Document immutable by calling IDfSysObject.freeze()

When you call the freeze () r_immutable_flag will be set to true by content server also r_frozen_flag will also be set to true by the content server.

 

Calling IDfSysObject.unfreeze() on a frozen virtual document unfreezes the Virtual Document and make it modifiable again. In that case the content server sets the above-mentioned flags to false.

 

Virtual Document related DQLS

Consider this model All the queries explained below will be based on this model

VirtualDocumentIllustration1

To find all direct components in this Virtual document SELECT ‘object_name’ in dm_sysobject IN DOCUMENT ID (‘r_object_id_of_virtual_document’)

This will returns the following in the exact same order VirtualDocument, Component1, Component2 and Component3 (VirtualDocument is returned because Virtual Document itself is considered as a Component)

 

To Filter Object Types in the above Query

SELECT r_object_id in dm_document IN DOCUMENT ID (‘r_object_id_of_virtual_document’)

This will return only dm_documents in the Virtual Document specified

Usage of DESCENT

Descent is used to return all components that contained in a virtual document.

SELECT ‘object_name’ in dm_sysobject IN DOCUMENT ID (‘r_object_id_of_virtual_document’) DESCENT

This returns the components in the following order

VirtualDocument, Component1, Child1, Child2, Child3, Component2, Child4, Child5, Component3, Child6,

Use the IN DOCUMENT clause with the ID scalar function to identify a particular virtual document in the query. The keyword DESCEND searches the virtual document’s full hierarchy.

Usage of VERSION

The VERSION Keyword finds the components of a specific version of a virtual document.

 

SELECT ‘object_name’ in dm_sysobject IN DOCUMENT ID (‘r_object_id_of_virtual_document’) VERSION 1.1

 

 

Download this Note (PDF)

 

Renditions in Documentum


A couple of days ago someone had asked me about Renditions in Documentum, Let me try to explain very briefly what renditions are.

Renditions are Representations of a Document in a different format.  In other ways, the only difference between a document and its rendition is only its format.   When you create a document in Documentum you specify the file format for that object, this file format is the Original format of that object.  The renditions of this object have the same properties of the original format object but it’s in a different format. These renditions are made either using Documentum Media Transformation Service or the supported Converters.    

The Converters are basically for Transform one type of graphic image to another type (e.g.: TIFF to JPG) or one-word processing format to another word processing format (e.g.: PDF to MSWord). There are few converters that come with the Content server, you can either buy or make your own custom converters. I am not getting into details of Converters here.

When you request for a rendition that uses converters Content Server creates and manages the Renditions automatically. You can also add renditions manually.
If you wanted to add renditions manually you can create the rendition by your own means and use addRendition() IDfSysObject interface.
For removing a rendition use removeRenditon() of the same IdfSysObject interface.
You have to have at least write permission to remove rendition of a Document.