2.9 Core portlet objects
This section will cover many of the objects you will use in day-to-day portlet development.
2.9.1 Portlet
The abstract class Portlet defines the abstract methods that comprise the base functionality of each portlet. All life cycle
methods
such as init, service and destroy are defined in this class.
For convenience, these abstract methods have been implemented in the PortletAdapter class. The PortletAdapter implements the service method with the basic functionality to determine the type of request and delegate the request to the appropriate do method. As such, it also defines the doView, doConfigure, doHelp and doEdit methods. Most portlet development will extend from the PortletAdapter class.
2.9.2 PortletAdapter
This class is provided as a default implementation of the Portlet class. It is recommended that your portlet classed extend from this abstract class rather than from the Portlet class. The adapter only provides
implementations
of the portlet-specific methods. It does not provide an implementation for the doXXX methods of the servlet parent (for example, doPost, doGet, etc.). In addition to the methods of the Portlet class, this class defines several additional methods.
The methods getVariable, setVariable and removeVariable provide access to the variables you can set on the concrete portlet. It is important to remember that these variables are at the concrete level and therefore will not be shared with other concrete portlets even though they may be based upon the same abstract portlet. These
variables
are available only in code and are not presented in portal administration, nor are they configurable in the portlet.xml deployment descriptor. Example 2-5 illustrates the usage of these methods.
Example 2-5. Setting and Accessing the concrete portlet variable
setVariable("var", "Some Value");
String var = (String) getVariable("var");
2.9.3 PortletRequest
The PortletRequest interface inherits from the HttpServletRequest and ServletRequest interfaces. It represents the user's request and like ServletRequest, encapsulates information about the user and the client. An implementation of PortletRequest is passed to the service method and subsequently to the delegated do methods (doView, doEdit and so on). In addition to client and
user
information, the PortletRequest object can be used as a short
term
bucket for storing information, such as JavaBeans. JSPs then have access to the information stored in the PortletRequest to create dynamic presentations. Some of the more frequently used methods of this object are listed below. Example 2-6 on page 85 illustrates some common usage of the PortletRequest object.
-
getAttribute/setAttribute/removeAttribute
These methods allow you to store data in a short term bucket. The PortletRequest is portlet-specific and therefore data stored in this object is not available to other portlets. The storage is only valid during the single request. All objects placed in this scope should be serializable.
-
getParameter
This method provides access to the parameters passed as part of the HttpServletRequest. There is no need to distinguish whether the parameter is passed via an HTTP get or post method. This method is often used in event-handling.
-
getCookies
This method provides access to the cookies stored by the current domain on the client's machine. An array of cookie objects is returned and the portlet is responsible for iterating through the collection.
-
getHeader
This method provides access to the headers supplied by the client. Some of the more common headers you may want to access include accept, accept-encoding and
cache-control
.
-
getLocale
This method returns the preferred locale for the user. The Portal Server determines the locale by first retrieving the user's preferred language set during registration. If the preferred language is not set, the locale is retrieved from the accept-language header supplied by the client.
-
getPreviousMode
This method is intended to return the previous mode visited by the user. In WebSphere Portal V4.1.2, this method always returns null. Look for updates to this functionality in future releases.
Example 2-6. Working with the PortletRequest
request.setAttribute("uri", uri);
String fNmame = request.getParameter("f_name");
java.util.Locale locale = request.getLocale();
2.9.4 PortletResponse
The PortletResponse interface extends from the HttpServletResponse and ServletResponse interfaces. This object encapsulates the response sent to the Portal Server for aggregation. Unlike the ServletResponse, the response is sent to the Portal Server, not the client machine directly. Therefore, attempting to influence the overall request, such as setting a status code, will have no effect. Some of the most commonly used methods of this object are listed below:
-
getWriter
This method returns a java.io.PrintWriter object that can be used to return markup to the Portal Server. The content returned by the PrintWriter is aggregated into the entire portal page. While it is possible to use a PrintWriter as well as include a JSP, it is
generally
considered
bad practice to do so.
-
encodeNamespace
This method takes a String and attaches the
name
of the portlet application as a prefix. For example, the value
"variable_one"
when encoded would be returned as
"PC_175_variable_one"
. Any variables that will become part of the aggregated portal page should be encoded. JavaScript functions and variables are good examples of values that should be encoded to prevent name collisions.
-
addCookie
This method allows you to add a cookie to the ultimate HTTP response that is sent by the Portal Server to the client. In order to ensure the name of cookie is unique throughout the portal, it is recommended that you use the encodeNameSpace method.
-
addHeader/setHeader/containsHeader
This method provides access to the headers sent back to the client via the portal server.
-
encodeURL
This method will append the passed string to the complete URL of the Portal Server. For example, the string
"example.gif"
becomes "
http://www.yourco.com/wps/WPS_PA_351/example.gif
" when passed to the encodeURL method.
-
createURI/createReturnURI
These methods will create URI object that contains a URL pointing the portlet in particular mode. For more information see 2.9.17, "PortletURI" on page 94.
Example 2-7. Working with the PortletResponse
java.io.PrintWriter out = response.getWriter();
out.println("Hello World");
PortletURI uri = response.createURI();
String functionName = response.encodeNamespace("myFunction");
2.9.5 PortletSession object
The PortletSession object extends from HttpSession and serves much the same purpose. The PortletSession is intended to represent an ongoing conversation between the client and the portlet. To this end, the PortletSession can be used to store information needed between requests. The PortletSession is intended to store data between
requests
, not between portlets. As such, data stored in the session by one portlet is not accessible by another. The PortletSession is retrieved from the request object as
illustrated
in Example 2-8. Since a PortletSession object is created when a user logs in, there is no need to create one. However, the getPortletSession(boolean) can be used to create a session for an anonymous user.
Example 2-8. Retrieving a PortletSession
PortletSession session = request.getPortletSession();
The most important methods of the PortletSession are getAttribute/setAttribute/removeAttribute: these methods allow you to store, retrieve and delete objects in the PortletSession. Objects stored in the PortletSession must be serializable.
2.9.6 Client
The Client interface represents the device making the request, not the user. The Client object can be retrieved from the PortletRequest object as illustrated in Example 2-9. Figure 2-12 illustrates the result of most of the methods of the client object when
requested
via Internet Explorer and a Nokia WAP emulator.
Figure 2-12. Client Information displayed on various
clients
Example 2-9. Working with the client object
Client client = request.getClient();
out.print("<P>Manufacturer: " + client.getManufacturer() + "<br/>");
out.print("MarkupName:" + client.getMarkupName() + "<br/>");
out.print("MimeType " + client.getMimeType() + "<br/>");
out.print("Model: " + client.getModel() + "<br/>");
out.print("UserAgent: " + client.getUserAgent() + "<br/>");
out.print("Version: " + client.getVersion() + "</P>");
Generally, the client object is used to determine the markup language to which the device is mapped. Based on that information, device-specific markup can be generated.
2.9.7 PortletConfig object
The PortletConfig object represents the abstract portlet. Therefore, any information contained in the PortletConfig is shared by all concrete portlets deployed based on the same abstract portlet. This object can be used to access the initialization parameters set in the web.xml deployment descriptor's servlet definition. Unlike other parameters, these are read-only and cannot be
altered
dynamically. This object can also be used to determine which modes and states are supported. Furthermore, this object provides access to the PortletContext object. The PortletConfig is retrieved via the getPortletConfig method of the PortletAdapter class or the getConfig method of the AbstractPortlet class. There are some useful methods available in this object. They are listed below and illustrated in Example 2-10.
-
supports
This method can accept a PortletWindow.State object or a Portlet.Mode object and return a boolean indicating whether or not the state or mode is supported by the portlet.
-
getContext
This method will return a PortletContext object. For more information on the PortletContexr, refer to 2.9.8, "PortletContext object" on page 88.
Example 2-10. Working with PortletConfig
boolean maxSup = getPortletConfig().supports(PortletWindow.State.MAXIMIZED);
boolean minSup = getPortletConfig().supports(PortletWindow.State.MINIMIZED);
boolean viewSup = getPortletConfig().supports(Portlet.Mode.VIEW,
request.getClient());
boolean editSup = getPortletConfig().supports(Portlet.Mode.EDIT,
request.getClient());
boolean configureSup = getPortletConfig().supports(Portlet.Mode.CONFIGURE,
request.getClient());
boolean helpSup = getPortletConfig().supports(Portlet.Mode.HELP,
request.getClient());
PortletContext context = getPortletConfig().getContext();
2.9.8 PortletContext object
The PortletContext provides a mechanism for the portlet to access the services of the portlet container in which it is running. For example, the Context provides access to the PortletLog, servlet context parameters as well as any services hosted by the portal such as Credentials Vault, PersistentConnection and possibly other custom services. The parameters accessed by the PortletContext are the context parameters set in the web.xml. These parameters are common to all portlets deployed in the same web.xml, regardless of their organization into various portlet applications. The PortletContext object is retrieved from the PortletConfig object as illustrated in Example 2-11.
Example 2-11. Accessing Context Parameters via the PortletContext
PortletContext context = getPortletConfig().getContext();
String webmaster = context.getInitParameter("webmaster");
The PortletContext can also be used to store attributes that will be shared by all portlets deployed via the same web.xml regardless of concrete portlet application. These attributes are not distributed in a clustered environment.
-
include
This is the most commonly used method of the PortletContext object. In a well-designed MVC architecture, the portlet executes one or more business objects to
satisfy
the logic of the request. Once the logic has completed, the include method generally calls a JSP to produce the output. Unlike Servlets, there is no ability to forward to a JSP. Example 2-12 illustrates this approach.
-
getContainerInfo
This method indicates the Portal Server version the portlet is executing. It only indicates the major version, not the minor one. In WebSphere Portal Server V4.1.2, this method returns the String
'IBM WebSphere Portal Server/4.1'
.
-
getText
This method provides access to Resource Bundles to use in providing National Language Support (NLS). For more information on NLS, see Chapter 8., "National Language Support (NLS)" on page 249.
Example 2-12. Including a JSP
public void
doView
(PortletRequest request, PortletResponse response)
throws PortletException, IOException {
//Business logic completed
getPortletConfig().getContext().include("/jsp/View.jsp",
request, response);
}
2.9.9 PortletSettings object
This object is best thought of as wrapping the information defined in the
<concrete-portlet>
section of the portlet.xml deployment descriptor. The PortletSettings object encapsulates the configuration information of the concrete portlet instance. The parameter information is retrieved from the portlet.xml but can be modified at runtime while the portlet is in Configure mode. Therefore, the PortletSettings object can be used as a storage for attributes to be shared by all the concrete portlet instances. When attributes are adjusted or added, be sure to call the store method to persist the new values. The administrator can add new parameters and alter existing parameter values via the Manage Portlets portlet in Administration place. The PortletSettings object also provides access to configuration information such as the title of the concrete portlet and the default locale. This object can be retrieved from the PortletRequest object or is passed as a parameter to the initConcrete and destroyConcrete methods of the portlet. The main methods are:
-
getAttribute/setAttribute/removeAttribute
: these methods provide access to attributes.
-
getTitle
: this returns a string indicating the title of the portlet for the current client and the specified locale. Note that this method returns the active title, not
necessarily
the title specified in the deployment descriptor. If the administrator has changed the title at runtime for example, that value is returned.
-
getDefaultLocale
: this method returns a Locale object specifying the default locale as determined by the portlet.xml.
-
getPortletApplicationSettings
: this method will return the PortletApplicationSettings object discussed in 2.9.10, "PortletApplicationSettings object" on page 90.
Example 2-13. Working with PortletSettings
String title = request.getPortletSettings().getTitle(
request.getLocale(),
request.getClient()));
java.util.Locale locale = request.getPortletSettings().getDefaultLocale());
PortletApplicationSettings portletAppSettings =
request.getPortletSettings().getApplicationSettings();
String attribute = request.getSettings().getAttribute("attName");
//Only available in doConfigure:
request.getSettings().setAttribute("attribute", "Some Value");
request.getSettings().store();
2.9.10 PortletApplicationSettings object
This object is best thought of as wrapping the information defined in the
<concrete-portlet-app>
section of the portlet.xml deployment descriptor. It is used to encapsulate the information pertaining to all concrete portlets\ deployed as part of the same concrete portlet application. The context parameters defined in the concrete portlet application section of the portlet.xml are available through this object's getAttribute method. These parameters can be adjusted and new ones added only while a portlet is in configure mode.
Example 2-14. Working with PortletApplicationSettings
PortletApplicationSettings portletAppSettings =
request.getPortletSettings().getApplicationSettings();
String attribute = portletAppSettings.getAttribute("attribute"):
//Only available in doConfigure:
portletAppSettings.setAttribute("attribute", "Some Value");
portletAppSettings.store();
2.9.11 PortletData object
The PortletData object represents a ConcretePortlet instance on a users page. It provides a quick, secure and effective method of attribute persistence with no JDBC code required. The PortletData is not dependent on the life cycle of the portlet. The PortletData is
user-specific
. However, when a user first
accesses
a portlet
utilizing
the PortletData object, the PortletData is not unique. In fact, until the user sets some value in the PortletData, they continue to use a shared Data. This PortletData is shared with the administrative user who first place the portlet on the page. All values stored in the PortletData must be serializable. Since a null object is not serializable, be sure to test the validity of your object prior to setting them into the PortletData object.
For example, the HelloWorld portlet uses PortletData to persist the greeting String and the moniker the user wishes to be addressed by. The Administrator
installs
this portlet, grants edit permissions to the All Authenticated Users
group
and places it on the Welcome page. The Administrator chooses to edit the portlet and enters
"hello there"
as the greeting String and
"admin"
as the moniker. When user JohnSmith logs into the portal page and opens the welcome page, he sees the name admin and the greeting
"hello there"
. The administrator decides to change the greeting to
"Greetings"
. Since JohnSmith has not edited the PortletData, he continues to share the PortletData and sees the changes the admin has made. JohnSmith chooses to edit the PortletData to use his name instead of admin. Once he edits the PortletData, he has his own PortletData object. Changes he makes will be seen by no one else. Furthermore, he will no longer see any changes to the PortletData made by the administrator.
Example 2-15. Working with PortletData
PortletData data = request.getData();
String greeting = (String) data.getAttribute("greeting");
String moniker = (String ) data.getAttribute("moniker");
//Only available in doEdit or possibly actionPerformed:
PortletData data = request.getData();
data.setAttribute("greeting", greeting);
data.setAttribute("moniker", moniker);
2.9.12 PortletLog object
This allows you to quickly write error messages or other information to the log files. All messages are written to the same file location regardless of the level currently enabled. The log file is named wps_<
time-stamp
>. log where the <
time-stamp
> is formatted as YYYY.MM.DD-HH.MM.SS. For example: wps_2002.10.14-12.32.41.log. The time stamp reflects the time the log file was created, typically when the server was first started. The log file is stored in <WPS-ROOT>\log. To change the location of the directory, uncomment the baseGroup.FileHandler.fileName attribute in jLog.properties and enter the new location. If the directory does not exist, it will be created for you.
There are four levels of severity when writing to the log: info, debug, warn and error. By default, error and warn are enabled. Debug and
info
levels are enabled for your portlets by enabling the PortletTraceLogger in the EnableTracing portlet in the Portal Administration. Since there is an associated expense with logging, the API provides a mechanism to determine if a logging level is currently enabled prior to writing the message. Example 2-16 illustrates this approach. Finally, if you pass an exception to a particular write method such as error or debug, the portlet container will print out the stack trace to the log file.
Example 2-16. Simple Logging
PortletLog log = getPortletConfig().getContext().getLog();
if (log.isDebugEnabled())log.debug("debug enabled:" + someMsg);
if (log.isWarnEnabled()) log.warn("warn enabled:" + someMsg);
if (log.isInfoEnabled()) log.info("info enabled:" + someMsg);
if (log.isErrorEnabled())log.error("error enabled:" + someMsg);
If the portlet you are writing extends PortletAdapter, a convenience method has been provided for you as illustrated in Example 2-17 on page 93.
Example 2-17. Accessing the PortletLog in PortletAdapter
PortletLog log = getPortletLog();
2.9.13 PortletException
The Portlet Exception inherits from the ServletException and is used as the basis for most exceptions thrown in the Portal environment, including UnavailableException
2.9.14 UnavailableException
This exception is thrown if the portlet fails to initialize. Generally, your portlets will include an init method which calls the super.init. Since this call may produce an UnavailableException, the functionality is provided to evaluate what to do if the initialization fails.
-
getUnavailableSeconds
:this method returns an int (integer) indicating how long this portlet is unavailable for.
-
isPermament
:this method returns a boolean indicating this portlet is no permanently unavailable.
The length of time the portlet is unavailable is determined when the exception is first created.
-
UnavailableException(String msg)
:this constructor indicates the portlet is permanently unavailable.
-
UnavailableException(String msg, int time)
: this constructor will reflect the length of time for which this portlet is unavailable.
2.9.15 PortletWindow object
This object represents the window
surrounding
the portlet only. Generally, this class is useful when determining the real state a portlet has to work with. Example 2-18 on page 94 illustrates this approach. Minimized, Normal and Maximized are defined as constants in the PortletWindow.State class.
Example 2-18. Determining portlet window state
PortletWindow.State state = request.getWindow().getWindowState();
if (state.equals(PortletWindow.State.NORMAL)){
getPortletConfig().getContext().include("/jsp/View.jsp", req, resp);
} else if (state.equals(PortletWindow.State.MAXIMIZED)){
getPortletConfig().getContext().include("/jsp/MaxView.jsp", req, resp);
} else {
//Window is minimized, no need to generate content.
}
2.9.16 User object
The User object represents the authenticated user and is retrieved from the PortletRequest object. The API provides predicable getters and setters for the most common attributes of the user such as GivenName, FamilyName and UserID. This class provides access to both Basic and Extended attributes of the user. Basic attributes are those stored in the LDAP directory as part of the schema used throughout the portal. Extended attributes are those attributes stored in the Portal Server database. Example 2-19 illustrates accessing both basic and extended attributes.
Example 2-19. Working with User attributes
User user = request.getUser();
String familyName = user.getFamilyName();
String favoriteColor = user.getAttribute("favColor");
String phoneNumber = user.getAttribute("phoneNumber");
The getID returns as a String the complete DN of the user. For example, wpsadmin in a typical SecureWay environment would return
uid=wpsadmin, cn=users, dc=<domain>,dc>=<com> ''
There are two User interfaces defined in the Portlet API. The org.apache.jetspeed.portlet.User class represents the logged in user and is the User object you will use day-to-day. The com.ibm.wps.puma.beans.User interface is an EJB and is not used to access individual user information
2.9.17 PortletURI
The PortletURI is used in organizing navigation through the portal as a user moves from mode to mode in a portlet. When a user is on a normal page (for example when the portlets are presented in View mode), the page is an aggregation of all the portlets. In order for any one portlet to be able to navigate back to that aggregated state, the PortletURI can store the URL. The PortletURI is then placed in a bucket such as the request or session object. For more information on the PortletURI object, see 2.12.3, "PortletURI" on page 100.
|