Java: A platform for platforms
Sun's reorg may seem promising to shareholders but it's also a scramble for position. The question now is whether Sun can, or wants to, maintain its hold on Java technology. Especially with enterprise leaders like SpringSource and RedHat investing heavily in Java's future as a platform for platforms

Also see:

Discuss: Tim Bray on 'What Sun Should Do'

Newsletter sign-up
View all newsletters

Sign up for our technology specific newsletters.

Enterprise Java
Email Address:

A well-behaved Jetspeed portlet

Design and construct a Jetspeed portlet that plays well with others

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

Page 4 of 5

Figure 2. Jetspeed standard customization view. Click on thumbnail to view full-sized image.

Our second view, the AttributesCustomization view, is provided for free from the Jetspeed framework and allows users with proper security to edit parameter attributes not marked as "hidden." (For more on registry attributes, see Resources.) In our example, we expose columns, view, and editable—see the MyPortlets.xreg file in the source code:

 <parameter name="columns" value="4" type="int" hidden="false" 
       cachedOnName="true" cachedOnValue="true"/>
<parameter name="editable" value="true" type="boolean" hidden="false" 
       cachedOnName="true" cachedOnValue="true"/>
<parameter name="view" value="condensed" type="style" hidden="false" 
       cachedOnName="true" cachedOnValue="true">



Actually, our view attribute is a bit more complicated then shown here. We want to use a drop-down list-box on the Customize form. See the properties file for a complete example of how to set up the parameters for the drop-down function. A user with proper security can select the small pencil icon in the portlet's upper right-hand corner to bring up the AttributesConfiguration screen.

The DataConfiguration view is where the actual link data is displayed for editing, see Figure 3.

Figure 3. Our portlet in configuration mode. Notice the icons for up, down, edit, and delete. Click on thumbnail to view full-sized image.

In addition to merely displaying the data, this view also contains icons for moving the links up and down, editing, and deleting. Plus, another button adds new links.

Finally, we have the SingleLink view. Just as it sounds, this view presents and collects data on a single link, see Figure 4.

Figure 4. Adding and editing information for one link. Click on thumbnail to view full-sized image.

We could have combined several of these views in the same Velocity file and controlled the output with various #IF, #ELSE, and #END statements. But doing so is simply not good, clean design and would have violated another of the basic commandments: "Thou shall keep the simple things simple. There shall be no more complexity than required."

Controller

Our portlet's controller has a critical job that it implements on class MyLinkFarmAction, which is inherited from GenericMVCAction. If you are unfamiliar with actions, see Resources. In brief, actions are classes that fulfill the controller role in the Model 2 architecture. Our simple portlet has a single controller, which, via a switchboard and some other techniques, selects the proper view and assembles the models for presentation. A more detailed explanation of this class follows below.

Putting it all together

Now the fun begins. We know our environment, we've documented our business problem, and we've outlined our design. It's time to begin construction.

Maven

Maven supports a Jetspeed plug-in for generating the basic framework for creating a new portlet. See Resources for detailed instructions on setting up and using Maven. This article's source code is based upon the directory structure and files created by the Maven plug-in. If you want to follow along with our code, name your instance HomeSpot.

Before we start dissecting the code, let's cover some best practices for constructing portlets.

Logging

Good coding, good code maintenance, and easy debugging all rely on good information. The best way in a Jetspeed portlet to gather information about what the portlet is doing is to use the logging systems. Many are tempted to use System.out to send messages to the console. Don't. While that approach may appear easy, it hogs resources, quickly leads to overly confusing output, and, under the service-based servlet containers such as Tomcat 5.x, no traditional console exists. All of the System.out traffic is captured in a file. So, if you have to find and open a file anyway, use a log file.

Using a log file in Jetspeed is easy. Follow these four steps:

  1. Create a log4j properties.merge file
  2. Import the correct units into your class
  3. Instantiate the logger
  4. Make log calls


The Jetspeed Maven plug-in merges files in the WEB-INF/conf with a .merge extension. For example, the file log4j.properties.merge will be combined with the Jetspeed log4j.properties file in the final configuration.

Here is our log4j.properties.merge file:

 #
# Filter OneStop Logging
#
log4j.category.com.automateddocsys = DEBUG, linkfarm, stdout
log4j.additivity.com.automateddocsys = false
#
# linkfarm.log
#
log4j.appender.linkfarm = org.apache.log4j.FileAppender
log4j.appender.linkfarm.file = ${webappRoot}/WEB-INF/log/linkfarm.log
log4j.appender.linkfarm.layout = org.apache.log4j.PatternLayout
log4j.appender.linkfarm.layout.conversionPattern = %d [%t] %-5p (%F:%L) - %m%n
log4j.appender.linkfarm.append = false



Include the following lines in your action class, or any other class where you need logging:

 // The two imports needed
import org.apache.jetspeed.services.logging.JetspeedLogFactoryService;
import org.apache.jetspeed.services.logging.JetspeedLogger;


Then add this code to your class:

 Private static final JetspeedLogger logger = JetspeedLogFactoryService.getLogger("com.automateddocsys");


Insert the name of your class or your company in place of com.automateddocsys. This name should match the name in your log4j.properties file.

Finally, to place entries in the log, use the following code:

 logger.debug("in addOne") or logger.error("Error in adding link");


The JetspeedLogFactoryService, which appears in the code above, is the default implementation of Jetspeed's logging service. According to the comments in its source code, it "initializes the underlying logging implementation and acts as a factory for loggers."

Understand the logging levels—error, warn, info, debug—and use them carefully and correctly. The log4J.properties file specifies what level of logging to commit to the logs and which output device(s) you want to use. Only logging at or above the level specified will actually be written to the log files.

Log files are kept in \WEB-INF\logs.

Caching

Jetspeed, Turbine, and the Servlet API offer several options for storing objects in memory for quick and easy retrieval of instantiated objects. The LinkFarm portlet has simple caching needs: Collect the links from the PSML page and hold them in the LinkFarmLinks object during the life of the session. In addition, we must pass information, such as portlet state and error messages, between iterations of the portlet rendering.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comment
Login
Forgot your account info?
Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources