Sometimes you might want a BOF module to be configured externally post deployment. You might want to use an XML file or a properties file for this purpose.
The naive way would be to checkout the implementation jar, unzip it, edit the config file, rezip it, and check in the updated jar. That’s too horrible to contemplate, for too many reasons to list.
There is another way. BOF anticipated the need for external, non-jar files to be accessible in the module classpath. Such external files are called downloadable attachments. Attachments in general are any non-jar files that the module author wants to be deployed with the module – say a javadoc zip, or license files. Typically you want these in the docbase, but you don’t want them in the module classpath. If you flag an attachment as downloadable though, it goes all the way to the class loader.
So, if you want a config file to be externally accessible and yet visible in the classpath you make it a downloadable attachment. In Composer you would go to your module’s “Deployment” tab, add the file as an attachment and check the downloadable option.

Downloadable Attachment in Composer
Then, at any time post deployment, you just need to check out, edit, and check back in the config file. The updated version will be hot deployed to the BOF module. You have to control the security of the attachment, but the rest of your module preserves its integrity.
Remember that hot deployment is only revealed to subsequent module instantiations, so don’t hold a cached reference to your module or you won’t see any updates. Prefer newModule or newService on demand – they’re quick.
Categories: bof · composer
Smart Containers are templates for the repeated construction of composite objects. Objects within a smart container are linked by folder membership and/or dm_relations and can form an object graph. One of the objects within the template is identified as the primary object – this is the object returned by the factory method invocation.
What kind of objects can be composed? Let’s take a look.
- Documents. These are documents that already exist prior to the construction of the smart container being templated. If they already exist what are they doing in the template? In many use cases the introduction of a single object initiates a workflow that eventually results in a smart container and that document is often part of the smart container. For example, a claim document might be scanned or imported from the web and this document might form the basis of a claim folder with a predefined structure. This claim document then exists before the claim folder, but is part of it. This is one example of an existing document that might be part of a template. In this case its identity would be parameterized (see later).
- Folders. These are part of templates for similar reasons to Documents. A common example might be a pre-existing folder into which you want all the smart container instances to go.
- New Documents. These are documents that you want to be newly created for each smart container instance. You can establish document state such as attribute values in the template.
- New Folders. These are part of templates for similar reasons to New Documents.
- Templates. These define existing objects that are prototypes for a new document in the smart container. For example an empty PDF form – perhaps a questionnaire. A copy of the Template will be created in the smart container.
- Placeholders. Now we enter the ranks of the exotic. Placeholders are objects that have the potential to exist post-construction, but which will not be created at construction of the smart container. They are ghost objects. It is still useful for the smart container designer to be able to model their future presence and specify their location within the smart container. Post construction, placeholders are manipulated with a special interface (IDfSmartObject) available off the primary object. An example might be an approval document.
Templates can have parameterized elements. This is necessary to support parts of the template that can only be resolved at runtime (like the identity of the claim document mentioned above). You refer to runtime parameters within the template using a string substitution syntax – ${foo} resolves to the value of parameter ‘foo’ (the braces are required). At runtime, the values for parameters are provided by the invoker of the factory method in a Map.
Smart containers need to be anchored in a repository somewhere. By default, of course, any sysobject or folder will be created in the user’s home cabinet. If you want an explicit location then you can model this by including a Folder element in the template and linking the object(s) to it. If the folder to which objects are to be anchored is determined at runtime, then the identity of the Folder element would be parameterized. By the way, this is an example of when the root of a hierarchy is not the primary object.
That’s about the whole story. The rest is detail.
Categories: smartcontainer
-
Find the internal name of the “aspect table”
select i_attr_def from dmc_aspect_type where object_name = ‘your aspect name’
-
Make the index
execute make_index with type_name='the returned i_attr_def value', attribute='your attribute name'
Note that the attribute name in this context is unqualified – you don’t precede it with the aspect name and a period.
Hat tip: Venkat
Categories: bof
In Documentum 6.5 release there is a new capability called Smart Container. What’s that about?
In many applications there is a need for the repeated construction of composite objects. For example, in a police application there might be an incident folder which contains a subfolder for affidavits, another for officer reports, perhaps a structured interview form. Typically you would program the construction of this composite structure by hand using DFC or DFS primitives. This can take considerable time and requires a strong skillset. Smart Containers offer a way to declaratively specify a template for such composite structures and provides a runtime factory that observes the declarative specification.
In Composer there is a graphical editor with which you can define your template (give it a try). The template is built in terms of objects and relationships. Once you have completed your template you can install it into the docbase using normal Composer install procedures. The result will be an instance of dmc_class whose content is an XML representation of the template. Attached to the object is an aspect that contains the logic to interpret the template. In effect it is a factory object.
In order to construct a new composite, as declared in your template, you would do the following …
IObjectFactory factory = (IObjectFactory) session.getObjectByQualification("dmc_class where object_name='myTemplateName'");
IDfPersistentObject myCompositePrimaryObject = factory.newObject();
myCompositePrimaryObject.save();
That’s it. There is no more code.
You get the primary object returned and all the others are linked (in folders or by dm_relations) according to your declarative template once you save the primary object.
IObjectFactory also has a signature that allows you to provide a Map of parameter values if your template is parameterized. Template parameterization is important to allow for runtime context – the identity of a Captiva-scanned initial incident report maybe.
The IObjectFactory interface is defined in the dmc_class.jar which you can extract from the dmc_class TBO module in the docbase.
Categories: composer · smartcontainer
If you are planning on using a BOF module you can find the jar containing its interface in the docbase as the contents of a dmc_jar object that is a member of the module’s folder (dmc_module and dmc_aspect_type are dm_folder subtypes) . If the object_name of the dmc_jar object doesn’t make it clear look for the dmc_jar with jar_type=1.
Categories: bof
Composer is not officially supported on the Mac, but since I develop on a Mac I make sure it works. However, there is no installation prebuilt, so you have to set it up manually.
Here is my recommendation for how to do this…
- Download Eclipse IDE for Java EE Developers from the Eclipse 3.4 site (Ganymede – not SR1)
- Go to Help/Software Updates, go to the Ganymede update site and install Enabling Features/EMF Validation Framework
- Unzip your Windows zip of Composer
- Copy all com.emc.* jars and folders from its plugins folder into your Eclipse’s dropins folder (not plugins)
- You are now ready to configure your instance as if it were a regular installation (except that the plugins are in the dropins folder)
Note that there is restricted functionality because no command line executables work (like dmbasic), but you can do all design time activities just fine. Also note that the Core Project won’t be read only, but you should treat it as such. You are not allowed to modify it – there be dragons.
Incidentally, these instructions work for integration of Composer plugins into any Eclipse 3.4 platform – not just the Mac.
Categories: composer · mac
There are a couple of reasons you might want to deploy Java server methods as BOF modules.
- You want to deploy the implementation in the same dar/docapp as the dm_method definition
- You want to avoid jar hell by avoiding the java_methods directory
- You want hot deployment for your method implementation
In order to deploy your method as a module you have to do the following:
- Define a module by subclassing DfSingleDocbaseModule or have your module implement the marker interface IDfModule directly
- Have your module implement IDfMethod – not IDmMethod (no interface jar)
- Put the module name – not the class name – in the command_verb of the dm_method object
- Make your module self-contained. You have no visibility to classes in the java_methods directory so you must be able to find anything you need in one or more BOF modules.
That’s it.
Categories: bof · methodserver
The method server has a unique class loader arrangement because it has it’s own load directory (java_methods) and also allows for methods to be written and deployed as BOF modules. The following diagram illustrates the method server class loader configuration.
Categories: methodserver
To make your life easier writing BOF modules here are some recommendations.
- Create an Eclipse project or IntelliJ module for each BOF module, TBO, aspect or service. This will not suit all tastes (and indeed I never did this until recently) but it will make your life easier.
- Create a separate source tree for interface classes and implementation classes. This allows you to be very clear about what will be exposed to consumers versus what will be sandboxed as implementation. It also makes it trivial to build the jars by directory.
- Do not share Java packages between interface and implementation. This is not strictly necessary for BOF purposes but it will be necessary for any subsequent OSGi compatibility that might arise (no guarantees).
- Avoid using Eclipse project references/IntelliJ module references to pick up interfaces from modules you consume, because you will pick up their implementation too, which you can’t do in production. If you really want to do this kind of interface sharing then you would need to factor out the interfaces into their own Eclipse projects/IntelliJ modules.
Here are some explicit negative recommendations …
- Do not use a single source tree for multiple modules. This is very likely to mask dependency issues that might not manifest until later in your product lifecycle. I speak from experience.
- Do not attempt to build your jars from ant jar tasks that explicitly itemize the classes to include. This is an accident waiting to happen. You can get runtime class loader exceptions that can be very difficult to diagnose when you screw it up.
All of these recommendations can be ignored and you might still succeed in developing and deploying your BOF modules but your life will be made easier if you adopt them, or at least those that you find least offensive.
Categories: bof
September 19, 2008 · 1 Comment
In BOF 2, the class loading is performed under control of DFC using a custom class loader structure (see BOF class loaders). For IDE debugging purposes this can be a nuisance. To assist during development there is a feature built in to DFC that allows you to configure various modules to be loaded from your application class loader.
You define a properties file, say devbofregistry.properties, of the form …
my_type=type,com.myco.MyType
my_aspect=aspect,com.myco.MyAspect
com.myco.IMyModule=module,com.myco.MyModule
com.myco.IMyService=service,com.myco.MyService
and set a system property, dfc.development.bof.registry_file, to the full path of the file. Note that you have to install some version of the BOF module to the docbase before you try this – only then can you hijack the class loading mechanism.
Be aware that you are cheating though, and that this usage can mask packaging problems. The fact that a class is visible in your IDE does not mean it will be visible with proper BOF class loading. You might, for example, simply forget to include it in your implementation jar (missing from an ant file jar task perhaps).
Categories: bof · dfc