Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

IBM WebSphere Developer Technical Journal: WebSphere Portal Programming

Pervasive Portlet Development

Michael Wanderski (mwanders@us.ibm.com), IBM Pervasive Computing Development, IBM
Michael Wanderski is a developer and architect for WebSphere Portal and related products. You can contact Michael at mwanders@us.ibm.com.

Summary:  This introduction to portlet programming in a pervasive environment builds on the fundamental concepts of portlet design to facilitate easy application development using IBM WebSphere Portal for devices such as Palm handhelds, Pocket PCs, and SmartPhones.

Date:  25 Jul 2002
Level:  Intermediate

Activity:  4889 views
Comments:  

Introduction to pervasive portals

Portals are very popular today with Internet users and Web content developers. Portals have become the place where both end-users and business-users alike come to use applications and access information. Through customization, portals offer users the flexibility to self-tailor their own views and layouts, and even personalize content to the topics that interest them most, such as stock quotes, weather, or travel.

Businesses especially have taken to the portal craze, since portals offer a manageable, consolidated interface to business-critical information. Internally, companies can dictate the content and applications (called portlets ) that are available to employees and customize this content based on an employee's position. Other users can take advantage of the easy-to-use interface for accessing the often overwhelming amount of information companies make available to them.

Portals are traditionally viewed through a Web browser interface, like Microsoft® Internet Explorer (IE) or Netscape Navigator®, which are rich clients that allow users to simultaneously view multiple applications and allow for client-side processing using Java Applets or rich media, such as Macromedia Flash®. Web developers, therefore, have a vast assortment of tools with which to bring content to users through a portal interface.


Figure 1. IBM WebSphere Portal on a browser
IBM WebSphere Portal on a browser

Over time, businesses have steadily pushed to make their workforce more mobile, particularly in professions where employees must travel to customer locations, such as delivery or appliance repair services. Additionally, consumers continue to embrace mobile personal devices. The blend of these two needs has helped drive the demand for mobile Personal Data Assistant (PDA) devices like Palm® handhelds and the PocketPC, as well as other more limited devices, like the SmartPhone. As these devices become more prevalent, and the demand for access to desktop-like applications from these devices continues to rise, portals will become the prominent method used for bringing applications and information to the mobile users who need it.


Figure 2. IBM WebSphere Portal on a SmartPhone
IBM WebSphere Portal on a SmartPhone

This article introduces the Web developer to portlet programming in a pervasive environment, meaning we will discuss creating portlet applications for devices other than traditional browsers like IE or Netscape®. Devices targeted in this article include Palm handhelds, Pocket PCs, and SmartPhones. This article is intended for developers with at least some level of IBM® WebSphere® Portal portlet development experience, and builds on the fundamental concepts of portlet design to facilitate easy development of applications for pervasive devices.


Portlet programming review

Let's review the portlet API by taking a quick look at a simple portlet that displays static content (Figure 3). If you are completely unfamiliar with the portlet API, or with portlet deployment within the portal server, refer to the documentation in the WebSphere Portal InfoCenter (see Resources ) for complete descriptions of the APIs, each tag, and related tag values.

Figure 3. Simple Static Weather Portlet code sample

package com.ibm.wps.samples.weather;
import java.io.*; import
org.apache.jetspeed.portlet.*; import
org.apache.jetspeed.portlets.*;

/** * WeatherPortlet.java -- Simple Example
to display weather. */ public class
WeatherPortlet extends AbstractPortlet {

public void init(PortletConfig portletConfig)
throws UnavailableException {
super.init(portletConfig); }

public void service(PortletRequest request,
PortletResponse response) throws
PortletException, IOException {

PrintWriter writer = response.getWriter();
writer.println("<p>The
weather is 78
degress.</p>");
						} }
					

This is an extremely basic portlet that simply outputs the static message, "The weather is 78 degrees". It shows the basic class interface, AbstractPortlet, that needs to be extended in order to create a new portlet application. Like servlets, a portlet has a service method that must be overridden in order to return the content for the portlet window. This example shows how to get PrintWriter from the PortletResponse object to write the HTML content to the output stream.


Figure 4. Simple Static Weather Portlet Output
Simple Static Weather Portlet Output

Our next example is more advanced. In Figure 5, the portlet dynamically retrieves the weather from a weather service for a specified zip code. Additionally, the message is no longer hard coded, but instead is deferred to a JSP for rendering.

Figure 5. Enhanced Weather Portlet code sample

package com.ibm.wps.samples.weather;

import java.io.*; import
vendor.service.weather.*; import
org.apache.jetspeed.portlet.*; import
org.apache.jetspeed.portlets.*; import
org.apache.jetspeed.portlet.service.*;

/** * WeatherPortlet.java -- A more
extensive example to display weather. */ public
class WeatherPortlet extends PortletAdapter {

protected static final String jsp =
"/WEB-INF/weather/html/DisplayWeather.jsp"

public void init(PortletConfig portletConfig)
throws UnavailableException {
super.init(portletConfig); }

public void doView(PortletRequest request,
PortletResponse response) throws
PortletException, IOException {

// Create a Weather Bean. WeatherBean
weatherBean = new WeatherBean();

// Get the portlet session. PortletSession
session = request.getPortletSession();

// Get the portlet configuration. PortletConfig
config = getPortletConfig();

// Get the portlet context. PortletContext
context = config.getContext();

// Get portal user object. User user =
session.getUser();

// Get the user's full name or null if not
available.
weatherBean.setFullName(user.getFullName());

// Get the weather service for determining the
temperature. WeatherService weatherService =
(WeatherService)context.getService(WeatherService.class);

// Get the current temperature for the
specified zip code. weatherBean.setTemperature(
weatherService.getTemperature(
Integer.parseInt(config.getInitParameter("ZipCode"))));

// Put the bean in the request.
request.setAttribute("weatherBean",
weatherBean);

// Invoke the JSP to do the actual rendering
for the portlet view. context.include(jsp,
request, response); } }
			

Let's dissect this example to examine the important components. The first thing to notice is that the WeatherPortlet class no longer extends the AbstractPortlet class, but instead extends the PortletAdapter class. The PortletAdapter class is an implementation of the central portlet abstraction, the portlet interface. It provides default empty implementations for the following portlet methods: init, login, service, logout and destroy.

Next, notice that the class no longer directly overrides the service method. Instead, it overrides a method associated with a particular portlet mode. Portlets have four modes of operation:

  • Portlet.Mode.VIEW
  • Portlet.Mode.EDIT
  • Portlet.Mode.HELP
  • Portlet.Mode.CONFIGURE

The operation of these modes is indicated by their names. For each mode, the PortletAdapter class provides a default empty implementation method. In Figure 5, the portlet only supports the VIEW mode, so only the one corresponding doView method has been overridden. It is the default implementation of the service method that determines the portlet mode and calls the appropriate mode method, as indicated by the code fragment in Figure 6, below:

Figure 6. Determining portlet mode

public void service(PortletRequest request,
PortletResponse response) throws
PortletException, IOException {

// Get the mode of the portlet. Portlet.Mode
mode = request.getMode();

if (mode == Portlet.Mode.VIEW) doView(request,
response); else if (mode == Portlet.Mode.EDIT)
doEdit(request, response); else if (mode ==
Portlet.Mode.HELP) doHelp(request, response);
else if (mode == Portlet.Mode.CONFIGURE)
doConfigure(request, response); }

					

Let's examine what occurs when the portlet is called to render its VIEW mode.

The first thing that happens is the creation of an instance of a WeatherBean (Figure 7) that will contain all relevant data necessary to render the display, which in this case is the user name and the weather for the preconfigured zip code. The user name is retrieved from the user object as shown. In order to determine the temperature, the zip code is first retrieved from the PortletConfig object (our simplifying assumption here is that the portlet is configured by an administrator for a certain zip code for all users). Second, a reference to a PortletService is obtained (in particular, this example references a WeatherService object). To limit the complexity of this example, we will assume a weather service has been registered with the portal server and portlets can obtain the current weather for a certain zip code utilizing this service. Once these two pieces of information are obtained, they are stored in the WeatherBean.

Figure 7. WeatherBean code sample

package com.ibm.wps.samples.weather;

/** * WeatherBean.java -- A bean used to
pass data to the JSP display. */ public class
WeatherBean {

/** The user's full name. */ private String
fullName = "";

/** The current temperature. */ private int
degrees = 0;

public void setFullName(String name) { fullName
= name; }

public String getFullName() { return fullName;
}

public void setTemperature(int degrees) {
this.degrees = degrees; }

public int getTemperature() { return degrees; }
}
					

The bean is passed from the PortletAdapter class to the JSP that will ultimately render the display. This is done through the setAttribute method on the PortletRequest object. The JSP then establishes a reference to the bean using the useBean tag and embeds the value of the user's full name and the current temperature in the HTML output markup.

Figure 8. DisplayWeather code sample

<!----------------------------------------------------------------------------->
<!-- --> <!-->
DisplayWeather.jsp - A JSP used to render the
data for the weather --&gt;
&lt;!-- portlet. -->
<!-- -->
<!----------------------------------------------------------------------------->

<%@ page
contentType="text/html"
errorPage=""
%>

<jsp:useBean
id="weatherBean"
class="com.ibm.wps.samples.weather.WeatherBean"
scope="request"/>

<p> Hi <%=
weatherBean.getFullName() == null ?
"" :
weatherBean.getFullName() %>!
<br> The current
temperature in your area is <%=
weatherBean.getTemperature() %>.
					

The output for this portlet (Figure 9) looks similar to our previous example.


Figure 9. Enhanced Weather Portlet
Enhanced Weather Portlet

So far, we've only examined a portlet that renders its display strictly for browsers like IE and Netscape, which implement the full HTML specification. But what if you want to extend the portlets beyond these rich clients and make the content available to constrained devices such as a PocketPC, a Palm handheld or a SmartPhone? In the sections that follow, we will investigate the additional APIs provided by IBM WebSphere Portal that help with development for these devices. We will also examine more advanced topics that are not currently addressed in these APIs, and even demonstrate ways to augment the published methods.

For details on some of the more advanced portlet API topics not covered in this example, such as windowing states, event handling, instance data, etc., consult the WebSphere Portal InfoCenter (see Resources ).


Introduction to pervasive programming

One of the design patterns of object-oriented design is Model-View-Controller, or MVC. MVC is a surprisingly simple, yet incredibly useful pattern that forces the developer to envision an application in terms of three fundamental components:

  • The model is the main component that maintains the state and data model that the application represents.
  • The controller is a bridge between the model and its views. It is the component that a user can manipulate to change the underlying data model.
  • The view is a graphical representation of the data model to the user.

The power in this design is that it provides for:

  • Clarity -- the logical components of a design are distinctly separated.
  • Modularity -- the various components of the application can be swapped in and out as desired, making debugging much easier.
  • Multiple views -- views are scalable in that multiple implementations can be made to represent the same data model.
  • Scalable design -- as the application grows, so too can the various components without affecting the underlying application logic.

Figure 10. Model-View-Controller (MVC) Design Pattern
Model-View-Controller (MVC) Design Pattern

Pervasive portlet programming techniques

Now that we have a background for a modular approach to application development, let's apply it to pervasive programming. We can break down the components in our weather example as follows:

model: The core weather application, such as accessing to the user's full name or the weather service to retrieve the current temperature.
controller: The provisioning of the bean that bridges data between the portlet code and the JSP.
view: The DisplayWeather JSP that renders the graphical display for the portlet content.

It is now easy to see how the model remains the same regardless of the actual display that is rendered. The controller will essentially remain the same between views, but may need to perform some special customization of data based on the intended view. The view component has the flexibility to render the data for a best fit on the destination display. For example, SmartPhones display content in WML (Wireless Markup Language). For our Weather example, then, we can define a separate view JSP for each intended device: an HTML JSP for browsers, and a WML JSP for SmartPhones. Look at the sample portlet in Figure 11, which uses this design scheme and the WebSphere Portal pervasive APIs.

Figure 11. Defining separate views for each device

package com.ibm.wps.samples.weather;

import java.io.*; import
com.ibm.wps.portlets.*; import
vendor.service.weather.*; import
org.apache.jetspeed.portlet.*; import
org.apache.jetspeed.portlets.*; import
org.apache.jetspeed.portlet.service.*;

/** * WeatherBaseController.java * Base
controller class containing common controller
functionality. */ public class
WeatherBaseController extends
AbstractPortletController {

/** The View for HTML devices (e.g. Internet
Explorer, Netscape). */ protected String
jspHTML =
"/WEB-INF/weather/html/";

/** The View for WML devices (e.g.
SmartPhones). */ protected String jspWML =
"/WEB-INF/weather/wml/";

public void init(PortletConfig config) throw
UnavailableException {

super.init(config);

// Load the HTML View from the configuration
jspHTML +=
config.getInitParameter("view.HTML");

// Load the WML View from the configuration.
jspWML +=
config.getInitParameter("view.WML");
}

protected void createBean(PortletRequest
request, PortletResponse response) {

// Get the portlet configuration object.
PortletConfig config = getPortletConfig();

// Create a Weather Bean. WeatherBean
weatherBean = new WeatherBean();

// Set the user's full name or null if not
available. weatherBean.setFullName(
request.getPortletSession().getUser().getFullName());

// Get the weather service for determining the
temperature. WeatherService weatherService =
(WeatherService)config.getContext().getService(WeatherService.class);

// Get the current temperature for the
specified zip code. weatherBean.setTemperature(
weatherService.getTemperature(
integer.parseInt(config.getInitParameter("ZipCode"))));

// Insert bean into the request for the JSP to
use.
request.setAttribute("weatherBean",
weatherBean); } }
					

package com.ibm.wps.samples.weather;

import java.io.*; import
com.ibm.wps.portlets.*; import
org.apache.jetspeed.portlet.*;

/** * WeatherHTMLController.java * Controller
for calling the HTML View. */ public class
WeatherHTMLController extends
WeatherBaseController {

public void doView(PortletRequest request,
PortletResponse response) throws
PortletException, IOException {

createBean(request, response);

getPortletConfig().getContext().include(jspHTML,
request, response); } 

package com.ibm.wps.samples.weather;

import java.io.*; import
com.ibm.wps.portlets.*; import
org.apache.jetspeed.portlet.*;

/** * WeatherWMLController.java * Controller
for calling the WML View. */ public class
WeatherWMLController extends
WeatherBaseController {

public void doView(PortletRequest request,
PortletResponse response) throws
PortletException, IOException {

createBean(request, response);

getPortletConfig().getContext().include(jspWML,
request, response); } }
					

This example shows a base controller that contains common function for both the HTML and WML views. First, in the init method, the name of the HTML and WML view JSPs from the portlet configuration are loaded. Second, a method called createBean is provided that creates an instance of the WeatherBean and populates it with the model data. Last, the createBean method inserts the bean into the request, making it available to a view JSP.

The next two classes (Figure 12) represent controllers for each of the view types. The first is the HTML controller and the second is the WML controller. Both controller classes extend the base controller class to inherit the common functionality it provides. For simplicity, there is not much difference between the two controllers except for what view they call. However, you can imagine providing special functions tailored to each device type depending on the actions taken by the user. For example, a rich client controller may provide drag and drop controls for icons, whereas a thin client controller would not.

In order for these controllers to work, you need to register them with the portlet web.xml file by adding the following configuration markup. (Details of the web.xml and portlet.xml files have been left out of this example. For more information, consult the Resources section for WebSphere Portal InfoCenter documentation.)

Figure 12. HTML & WML controllers

<servlet-name>WeatherPortlet</servlet-name>
<servlet-class>com.ibm.wps.portlets.MVCPortlet</servlet-class>

<init-param>
<param-name>controller.html</param-name>
<param-value>com.ibm.wps.samples.weather.WeatherHTMLController</param-value>
</init-param>

<init-param>
<param-name>controller.wml</param-name>
<param-value>com.ibm.wps.samples.weather.WeatherWMLController</param-value>
</init-param>

<init-param>
<param-name>view.HTML</param-name>
<param-value>DisplayWeatherHTML.jsp</param-value>
</init-param&gt;

<init-param&gt;
<param-name&gt;view.WML</param-name&gt;
<param-value&gt;DisplayWeatherWML.jsp</param-value>
</init-param>
<init-param>
<param-name>ZipCode</param-name>
<param-value>27709</param-value>
</init-param>


Now we need to supply the two view JSPs, one for HTML, the other for WML (Figure 13). Since the HTML view is intended for a rich client, we will show the user name, but omit it from the WML view since this is a more constrained client.

Figure 13. HTML and WML JSPs

<!----------------------------------------------------------------------------->
<!-- DisplayWeatherHTML.jsp - A JSP
view for rendering HTML. -->
<!----------------------------------------------------------------------------->

<%@ page
contentType="text/html"
errorPage=""
%>

<jsp:useBean
id="weatherBean"
class=";com.ibm.wps.samples.weather.WeatherBean"
scope="request"/>

<p> Hi <%=
weatherBean.getFullName() == null ?
"" :
weatherBean.getFullName() %>!
<br> The current
temperature in your area is <%=
weatherBean.getTemperature() %>.
					

<!----------------------------------------------------------------------------->
<!-- DisplayWeatherWML.jsp - A JSP
view for rendering WML. -->
<!----------------------------------------------------------------------------->

<%@ page
contentType="text/wml"
errorPage=""
%>

<jsp:useBean
id="weatherBean"
class="com.ibm.wps.samples.weather.WeatherBean"
scope="request"/>

<p
align="left">
Current temperature is <%=
weatherBean.getTemperature() %>.
</p>

Figures 14 and 15 show how these portlets are rendered on a browser and a SmartPhone, respectively:


Figure 14. Weather Portlet using HTML JSP
Weather Portlet using HTML JSP

Figure 15. Weather Portlet using WML JSP
Weather Portlet using WML JSP

Device capabilities

So far, this article has only described how to provide views for a large categorization of devices. Assuming that a broad range of devices will possess the same capabilities, however, is not usually appropriate, particularly when referring to mobile devices. For example, some SmartPhones support WML version 1.1, others support a subset of WML 1.2 (e.g. no tables), and still others support the whole WML 1.2 specification. How, then, do you provide a view that is intelligent enough to take into account all these device variations without resorting to one that supports only the least common denominator of capabilities?

The IBM WebSphere Portal API provides a mechanism for a portlet to query the capabilities of the device for which the portlet view is intended. Instead of requiring every portlet to understand the capabilities of all User-Agent types, the portal provides an abstraction between the User-Agent and device capabilities. How does the portal determine device capabilities? When an HTTP request is made to the portal, the requesting device sends an HTTP field, User-Agent, that contains tokens of information about the requesting device. For example, a Nokia Communicator 9110 sends the following User-Agent field:

Figure 16. User-Agent field sample

Nokia-Communicator-WWW-browser/3.0 (Geos 3.0 Nokia-9110)

The portal internally maintains mapping from the User-Agent field to the expected capabilities of the device (see the WebSphere Portal InfoCenter in the Resources section). Thus, the portal can infer the capabilities of a device and provide that information to a portlet. This allows for a scalable design in that new User-Agent mappings can be added to the portal as new devices become available, but portlets need not change their behavior. Rather, they use the same device capabilities abstraction to infer how a particular view should be rendered.

This capabilities abstraction class, appropriately called Capability, is a part of the org.apache.jetspeed.portlet package. It provides generic capability attributes, such as what level of markup is supported (e.g. WML 1.1 vs. WML 1.2), as well as more specific capabilities, like what specific type of function is supported (e.g. JavaScript vs. no JavaScript). In our weather example, we can modify the WML JSP to take into account the capabilities of the WML client. If the client does not support WML tables, then we will output straight text. Otherwise, a table that lists the user name as well as the current temperature in separate rows will be output, as in Figure 17.

Figure 17. WML JSP using device capabilities

<!----------------------------------------------------------------------------->
<!-- DisplayWeatherWML.jsp - A JSP
view for rendering WML using the -->
<!-- capabilities of the device.
-->
<!----------------------------------------------------------------------------->

<%@ page
contentType="text/wml"
errorPage=""
%> <%@ page
import="org.apache.jetspeed.portlet.*"
%>

<jsp:useBean
id="weatherBean"
class="com.ibm.wps.samples.weather.WeatherBean"
scope="request"/>

<!-- Add statements so that we can
access the portlet request/response.
--> <%@ taglib
uri="/WEB-INF/tld/portlet.tld"
prefix="portletAPI"
%> <portletAPI:init
/>

<p
align="left">
<% if
(portletRequest.getClient().isCapableOf(Capability.WML_TABLE))
{ %>

<table
columns="1">
<tr><td>
Hi <%= weatherBean.getFullName() ==
null ? "" :
weatherBean.getFullName() %>!
</td></tr>
<tr><td>
Current temperature is <%=
weatherBean.getTemperature() %>.
</td></tr>
</table>

<% } else { %>

Current temperature is <%=
weatherBean.getTemperature() %>.

<% } %>
</p>

For a client phone that does not support WML tables, the output will be the same as our previous JSP example. For phones that do support WML tables, the output will now look similar to Figure 18.


Figure 18. Weather Portlet using WML JSP with tables
Weather Portlet using WML JSP with tables

A style bean solution

The final topic of this article focuses on a solution for more advanced capability attributes. The example we will use has to do with whether or not a client device supports Cascading Style Sheets (CSS). This attribute is important because the portal uses CSS for applying the theme and skin for the overall portal look-and-feel. It is recommended that portlet developers adhere to the published portlet style guidelines (see Resources ) by placing CSS class identifiers in their HTML so that, for example, when a font color is changed, the portlet will pick up that change in color. The HTML content fragment in Figure 19 demonstrates using the style guidelines for the font style of portlet text:

Figure 19. Using style guidelines


<font
class="wpsPortletText">
Current temperature is <%=
weatherBean.getTemperature() %>.
</font>
			

Using the CSS class identifier wpsPortletText, the portlet will inheret the style of the CSS when the client device applies it.

The problem with many new medium-rich clients is that they currently support only a limited subset of HTML that does not include support for CSS, making it not possible to apply a style sheet at the client. Thus, portlets written using this guideline will not display correctly.

One possible solution is to provide another level of abstraction for the view. This abstraction can take the form of a style bean that a view can use to appropriately format the content based on the client capabilities. In our example device, which does not support CSS, what needs to be done is that the values of the style need to be directly inserted into the JSP. However, when the device does support CSS, the view should add the recommended style guideline class identifier, as in Figure 20.

Figure 20. Style bean based on client capabilities


<!-- For a device that supports CSS.
-->

<font
class="wpsPortletText">
Current temperature is <%=
weatherBean.getTemperature() %>.
</font>


<!-- For a device that does NOT
support CSS. -->

<font
size="1"
face="sans-serif">
Current temperature is <%=
weatherBean.getTemperature() %>.
</font>

To create this level of abstraction, the bean API in Figure 21 is defined for use by a portlet view JSP to determine what font style should be used for content.

Figure 21. Sample API for portlet view JSP

/** * StyleBean.java * An abstraction layer
for creating a views based on the capabilities
of a * client. For example, CSS support vs. no
CSS support. */ public abstract class StyleBean
{

/** * Initialize the bean. * @param request The
portlet request object. */ public abstract void
init(PortletRequest request);

/** * Method to call to insert the font style
guideline content. * @param styleClass The name
of the style class. * @return The markup to
insert into the JSP for starting a font. */
public abstract String startFont(String
styleClass);

/** * Method to call to insert the font style
guideline content. * @param styleClass The name
of the style class. * @return The markup to
insert into the JSP for ending a font. */
public abstract String endFont(String
styleClass); }

Now, an HTML view can simply use this bean to render the necessary content, as shown in Figure 22.

Figure 22. DisplayWeather code sample

<!----------------------------------------------------------------------------->
<!-- DisplayWeatherHTML.jsp - A JSP
view for rendering HTML for both -->
<!-- browsers and Pocket PC devices.
-->
<!----------------------------------------------------------------------------->

<%@ page
contentType="text/html"
errorPage=""
%>

<%@ page
import="org.apache.jetspeed.portlet.*"
%> <%@ page
import="com.ibm.wps.style.*"
%>

<jsp:useBean
id="weatherBean"
class="com.ibm.wps.samples.weather.WeatherBean"
scope="request"/>

<jsp:useBean
id="styleBean"
class="com.ibm.wps.style.StyleBean"
scope="request"/>

<!-- Add statements so that we can
access the portlet request/response.
--> <%@ taglib
uri="/WEB-INF/tld/portlet.tld"
prefix="portletAPI"
%> <portletAPI:init
/>

<!-- Initialize the style bean.
--> <%
styleBean.init(portletRequest); %>


<!----------------------------------------------------------------------------->

<p> <%=
styleBean.startFont("wpsPortletText")
%> The current temperature in your
area is <%=
weatherBean.getTemperature() %>.
<%=
styleBean.endFont("wpsPortletText")
%> </p>

The bean itself will take care of deciding which content to render, based on whether the client supports CSS or not. This is only one example of what the bean can be used for. The bean API can be extended to support more markup tags, like table headers, background colors, etc. The code in Figure 23 shows how to implement the StyleBean using the portal APIs.

Figure 23. Implementing the StyleBean using the portal APIs

package com.ibm.wps.style;

import java.io.*; import java.util.*; import
org.apache.jetspeed.portlet.*;

public class StyleBean {

/** The resource that defines the style values.
*/ private ResourceBundle resource = null;

public void init(PortletRequest request) {

// Determine whether the client device supports
CSS and if not, // then load the resource style
values. if
(!request.getClient().isCapableOf(Capability.HTML_CSS))
{

try {

// Retrieve the resource bundle from the
classpath. resource =
ResourceBundle.getBundle("com.ibm.wps.style.NoCSS");
} catch (Exception e) {

// Resource bundle not available. resource =
null; }} }

public String startFont(String styleClass) {

// If the client supports CSS, use class
identifier. if (resource == null) { return
"<font
class=\"" +
styleClass +
"\">";
}

// If the client does not support CSS, use the
style values. String markup =
"<font
size=\"" +
resource.getString(styleClass +
".font.size") +
"\"
face=\"" +
resource.getString(styleClass +
".font.face") +
"\">";

return markup; }

public String endFont(String styleClass) {

return
"</font>";
} }
					

StyleBean makes use of a properties file loaded as a Java resource bundle in order to determine the values for the style attributes. This means that the resource bundle must be packaged with StyleBean or at least in the same classpath. The following is the NoCSS.properties file contents:

Figure 24. NoCSS properties file

wpsPortletText.font.size = 1 wpsPortletText.font.face = sans-serif

The NoCSS.properties file can be modified without code changes to make style modifications for a device that does not support CSS. The bean only currently provides an abstraction for font styles, but it would be easy to extend the interface for other style types. Although not shown in this example, it is also possible to modify the StyleBean class so that the init method could open the appropriate CSS, instead of referencing the properties resource bundle. It would then parse out the wpsPortletText style attributes directly and use those instead, ensuring that the styles being used in the portlets are always consistent with the other HTML devices that also support CSS.


Conclusion

This article just touches on the vast potential of pervasive portlet programming. Between getting started with portlet development, using the Model-View-Controller paradigm and the pervasive MVC API, and discussing how to deal with fine-grained device capabilities and a possible solution for the problem associated with the lack of support for Cascading Style Sheets, the concepts in this article were designed to give you a feel for the basic structure of pervasive portlet programming. I wish you luck in extending these ideas into your own development projects.

IBM, DB2, and WebSphere are trademarks or registered trademarks of IBM Corporation in the United States, other countries, or both.

Windows and Windows NT are registered trademarks of Microsoft Corporation in the United States, other countries, or both.

Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Other company, product, and service names may be trademarks or service marks of others.

IBM copyright and trademark information


Resources

About the author

Michael Wanderski is a developer and architect for WebSphere Portal and related products. You can contact Michael at mwanders@us.ibm.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=13542
ArticleTitle=IBM WebSphere Developer Technical Journal: WebSphere Portal Programming
publish-date=07252002
author1-email=mwanders@us.ibm.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Try IBM PureSystems. No charge.

Special offers