Share This Post

Custom WDK 4.2 Widgets

What is the WDK?

The WDK is a set of components distributed and supported by Documentum. These components
are used to build web-based applications. Although that definition sounds like it comes
straight from Webster’s Dictionary, it actually makes a lot of sense for Documentum to
build some reusable components that DCTM developers can leverage in their applications.

Just a few of the quick advantages to using these components:

  • Supported by DCTM – if there is an issue in the component, you have Documentum Support
  • Upgraded by DCTM – when they upgrade the performance or capabilities, your application
    now accepts those enhancements seamlessly
  • Saves development time – all you have to learn is the interfacing methods
  • Invest in the future – Documentum’s future web clients will all be using these
    components

I am going to make a bit of a jump here, but this article is not targeted at those beginning to use
the WDK. I am assuming you have already downloaded the WDK, and have played around with
the sample application. If you have, then you have probably wondered how you can customize
the default behaviors and rendering of components.

By the way, the WDK is available from the DCTM ftp site.
As always, you need a valid customer user/password to enter the site.

What is a model/view architecture?

The model/view architecture is simply a way of describing the separation of data from
presentation. It is a design frequently used by software designers, and is quite robust.
It allows the data (model) to be from any source, as long as it is accessed in a uniform manner.
Therefore, any client (view), can be used to display this data, as long as it knows the
uniform manner in which to access the data.

To be specific to the WDK, there are certain models in the WDK world. These models contain
data like the: contents of a folder, docbases available, results of a query, etc… There are
also components that are capable of rendering HTML, and they use these models as the source
of their data.

When you do no customization to the WDK sample application, what you are seeing is
a standard view rendering with a standard model. If instead of a checkbox for an object
selection, you would rather have a link, then it is simply a matter of writing your
own view.

How can I customize the WDK?

Especially for those of you accustomed to another component model, this will be an easy
exercise. Each WDK component, by default, behaves and renders itself a certain way. So,
the easy way to use WDK components is by the minimal instantiation and then calling the rendering method.

As you get more advanced, and need to customize, you need to dig a little deeper into
the WDK javadocs, and explore the methods available that can change certain properties.
But without a doubt, many of you will feel as though you have outgrown the limited
customization that is allowed by these components by default. This article’s goal is to address
these advanced needs.

By writing your own view for a standard widget, you can display the data in any
way you choose. What was displayed as a radio box, can now be a plain link, or
a pulldown combo box, or anything else, if you write your own view.

How can I create a different view for the WDK?

Let’s go through an example. I’m assuming that you have already downloaded, installed, and have the WDK sample
application running. Go into the sample application, and then login and go into a folder listing.
You’ll notice how the name of each object is a link to a javascript event. This javascript event
propogates to each frame of the browser as part of the whole WDK event model scheme. In
this article we are going to explore how we can change this to our own custom HTML rendering.

Setting

The first step is to know the JSP page where this view is rendered. You can find this file at:

<wdk sample app dir>/wdk/component/contents/folderBody.jsp
Open this jsp page and notice the line that looks like this:

folderContentsView.addRenderedColumn(“Name”, lookup.getString(DwNLSDocbaseComponent.MSG_NAME), nameRenderer, “55%”);

This line is where the column is added that renders (as HTML) the names of the objects.
Let’s do a little investigation before we get serious, you’ll find that having an open window
to the WDK javadocs is going to be mandatory. First, let’s find out what this folderContentView object is.
Look about 8 lines above to find a line that looks like this:

<jsp:useBean id="folderContentsView" class="com.documentum.wc.widget.DwTableView" />

From this, we can see that the folderContentsView object is an instance of
a DwTableView. Check your javadocs for this class, and go down to the addRenderedColumn()
method, there are several overloaded methods here, the one you are looking for has 4 arguments,
which matches the invocation in our jsp page. Take careful note of the 3rd argument to this
methods, which takes an object of type IDwCellRenderer.

The key here is that IDwCellRenderer is an interface. This means that we
can use any object that implements this interface to call this method. At the moment, the
nameRenderer object referenced in the jsp is of type DwObjectNameCellRenderer, but we plan on replacing
it with our own custom class which also implements the IDwCellRenderer class.

Replacement Class

The next step is to write a java class that implements the IDwCellRenderer interface.
First, let’s refer back to the javadocs, and the IDwCellRenderer interface. Notice that
the interface consists of 2 methods:render(IDwPropertyBag,boolean,string) and
setEnableSelect(boolean)

Our goal in this section is to write a java class that contains these 2 methods and renders
custom HTML for a column of a table that contains the object name.

Once again, let’s explore. What is really happening? The most important thing is remembering
your station in life. The job of your IDwCellRenderer is to return a String from your render method
that contains HTML. You will called upon to do your work by another component (in this case the DwTableView), and
all it knows is that you are IDwCellRenderer. Therefore, the only thing it knows about
your class is that is has a render() and setEnableSelect() method. When it
invokes your render() method it expects a String based up the arguments that is passes to you.

Which begs the question, what are the arguments that this controlling class is passing to you? The first argument
is an IDwPropertyBag. This is also an interface. A bag is usually implemented with a hashtable,
there are objects in this bag, and each has a name. If you want to get something out, ask for it by
name, and you’ll get it.

So, now you know that every time someone calls your render method, they will also pass
you data that is accessible as an IDwPropertyBag. The only thing you have to
figure out is what the name is that you need to use to get at this data.
In order to know the name of the objects
in the bag, you have to know what objects the model contains. I will tell you that this is the folder
model, and as such it has objects called: “r_object_id”,”r_object_type”,”r_link_cnt”,”object_name”, etc…

I think we have all the background necessary to write the simplest example possible for a replacement
IDwCellRenderer. I’ll list the code, and then step through the lines.

package myview;

import com.documentum.fc.client.*;
import com.documentum.fc.common.*;
import com.documentum.wc.env.*;
import com.documentum.wc.env.docbase.*;
import com.documentum.wc.widget.*;
import com.documentum.wc.widget.docbase.*;
import com.documentum.wc.util.*;
public class DwCustomObjectNameRenderer
extends DwObject
implements IDwCellRenderer {
public void setEnableSelect(boolean bEnableSelect) {
// dummy function used to satisfy interface
}
public String render(IDwPropertyBag cellProperties, boolean bIsSelected, String strSelectCmd) {
// just handed a bag, want the r_object_type,r_object_id,object_name objects
String type = cellProperties.getProperty("r_object_type");
String rid = cellProperties.getProperty("r_object_id");
String name = cellProperties.getProperty("object_name");
// output looks like:
// <a href="JavaScript:alert('object_name (r_object_id) is of type xxxxx)">object_name</a>
String retVal = "<a href="JavaScript:alert(";
retVal = retVal + "'" + name + " (" + rid + ") is of type " + type + "');">" + name + "</a>";
return retVal;
}
}
// DwCustomObjectNameRenderer

The first few lines are just the imports needed to compile. The first method,setEnableSelect() is only
stubbed out to satisfy the requirements of the interface, and we don’t implement any functionality
for it in this example because we will not use it.

The render() interface on the other hand, is the meat of this entire class.
This is the method invoked by some controller, which also hands us a bag containing data, and
expects back a String containing HTML. First, we take the the IDwPropertyBag object
and ask for the objects in the bag by name. You’ll notice there are objects in the bag called:
“r_object_type”, “r_object_id”, and “object_name”. These names are based upon the fact
that we are using a folder model.

We’ll use these pieces of data to construct a HTML string. You can render the data any way
you choose, but I choose to show the name as a link, and when the link is pressed, I popup a
javascript window that shows you the object id as well as the type.

Compilation: Start by putting the sample code in a directory called myview,
which is necessary because that is the name of the package that this code will be in. Make sure
that the file is called DwCustomObjectNameRenderer.java, which is case sensitive.
Compile the code with the following line:

javac DwCustomObjectNameRenderer.java

Note: You are going to need to include the dfc.jar and wdk.jar in your classpath in order
to successfully compile this.

This class needs to be put in its own jar file so that the jar
can be included in the classpath of the webserver as well as imported into the jsp page.
From the parent directory of myview
we are going to need to invoke the jar utility like this:

jar -cvf myview.jar myviewDwCustomObjectNameRenderer.class

Which will create a jar file called myview.jar

Web Server Deployment: Before you can use the myview.jar file from a jsp page,
you are going to need to include it in the classpath of the webserver. Using JRun3.0,
you can simply stick the myview.jar file into the WEB-INF/classes directory.
If you are using IPlanet, then you are going to need to go into the
config/jvm12.conf file and edit the classpath to include this jar file.

Patching the JSP

The only thing left to do now is modify the JSP so that the folderView object
uses our class instead of the nameRenderer object. Find the following code in
the jsp:

DwObjectNameCellRenderer nameRenderer = (DwObjectNameCellRenderer) app.createInstance( DwObjectNameCellRenderer.class.getName() );
nameRenderer.setEventDictionary(actionDict);

Now, right underneath this code, add this single line of code, which creates an instance of our
new class.

DwCustomObjectNameRenderer myNameRenderer = (DwCustomObjectNameRenderer) app.createInstance( DwCustomObjectNameRenderer.class.getName() );

Once again, find the following line:

folderContentsView.addRenderedColumn("Name", lookup.getString(DwNLSDocbaseComponent.MSG_NAME), nameRenderer, "55%");

and change it to read this:

folderContentsView.addRenderedColumn("Name", lookup.getString(DwNLSDocbaseComponent.MSG_NAME), myNameRenderer, "55%");

One last piece…we need to import the class into our jsp, which we can do by adding this line
at the top of the jsp with all the other import statements.

<%@ page import="myview.DwCustomObjectNameRenderer"%>
Done! You may need to restart your web server for these changes to take effect, but when you
pull up this page now, instead of the standard WDK event, you should receive a popup javascript
window with your custom message (as seen below).

wdkwidget-wdkimage01

Figure 1:

Screenshot of new view in action

Summary

The WDK is a set of DCTM supported components that will allow you to rapidly deploy web-based
applications. Although they offer many methods that can customize their behavior and rendering,
sometimes it may be necessary to completely override these to your own objectives. In such
a case, writing your own view is a powerful option.

Custom WDK 4.2 Widgets

More To Explore

AI to Write Requirements

How We Use AI to Write Requirements

At ArgonDigital, we’ve been writing requirements for 22 years. I’ve watched our teams waste hours translating notes into requirements. Now, we’ve cut the nonsense with AI. Our teams can spend

ArgonDigital | Making Technology a Strategic Advantage