Print Header

Related Topics

Related Case Studies

Contact Blue Fish

Blue Fish Development Group
701 Brazos St. #700
Austin, TX 78701
(512) 469-9300

Custom WDK 4.2 Widgets

December 3, 2002 - Article by Fabian Lee

Learn how to use and customize Documentum’s WDK components for building web-based applications. Applies to WDK 4.2.

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 myview\DwCustomObjectNameRenderer.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).

Fig. 1: Screenshot of new view in action

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.

 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 (0 votes, average: 0 out of 5)
Loading ... Loading ...

Comment on this article:

You must be logged in to post a comment.

Notification

Subscribe to our newsletter to be notified when new articles are posted. You can unsubscribe at any time.