NEW!! FREE MOCK EXAM SIMULATORS FOR IBM PORTAL TEST 399 & IBM PORTLET CERTIFICATION EXAM TEST 829!!!
Everything You Ever Wanted To Know About JSR-168 Portlet Development . . . PORTAL + TUTORIAL = www.portorials.com
Google

The Config Objects: Templatizing Portlets

Many textbooks and references that talk about ServletConfig and ServletContext objects, which essentially correspond to the PortletConfig and PortletContext objects, gloss over the power of these objects, and simply give lip-service to the act of reading parameter values from deployment descriptors. Well, I?m not going to do that. I?m going to show you a very simple example of a templatized portlet, that can have a profound effect on a developer?s ability to generate a multitude of useful and configurable portlets.

This is a very kewl tutorial. I highly recommend it!

Please support our site, link to us, buy some books, and remember: Happy Java!

Download the Code!!! (Scroll down and view the code)

Here's a link to download the completed solution:GenericTaxPortlet.war

The war file was created using IRAD 6, but it's a JSR-168 compliant portlet application, so feel free to deploy it anywhere.

The GenericTaxPortlet

package com.examscam.portlet;

import java.io.*;import javax.portlet.*;

public class GenericTaxPortlet extends GenericPortlet {

protected void doView(RenderRequest request, RenderResponse response)
throws PortletException, IOException {

response.setContentType("text/html");
PrintWriter out = response.getWriter();
PortletContext context = this.getPortletContext();
PortletConfig config = this.getPortletConfig();


String fedRate = context.getInitParameter("fedrate");
String regionName = context.getInitParameter("regionname");

String regionalRate = config.getInitParameter("regionalrate");


out.print("<BR>The federal tax rate is: " + fedRate);
out.print("<BR>The " + regionName + " tax rate is: ");
out.print(regionalRate);

}
}



The Portlet Deployment Descriptor (portlet.xml)

<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" id="com.examscam.portlet.CustomModePortlet.051cf00ef0">
<portlet>
<portlet-name>CustomModePortlet</portlet-name>
<display-name>CustomModePortlet</display-name>
<display-name xml:lang="en">CustomModePortlet</display-name>
<portlet-class>com.examscam.portlet.CustomModePortlet</portlet-class>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
<portlet-mode>config</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.examscam.portlet.nl.CustomModePortletResource</resource-bundle>
<portlet-info>
<title>CustomModePortlet</title>
</portlet-info>
</portlet>
<custom-portlet-mode>
<portlet-mode>config</portlet-mode>
</custom-portlet-mode>
</portlet-app>





The Web Deployment Descriptor (web)


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="WebApp_ID">
<display-name>CustomModeProject</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<taglib id="PortletTLD"> <taglib-uri>http://java.sun.com/portlet</taglib-uri> <taglib-location>/WEB-INF/tld/std-portlet.tld</taglib-location> </taglib>
</web-app>





Config Objects We?ve covered just about every object in the Portlet API, with the exception of two of the most important ones. It?s hard to believe we?ve made it this far without touching upon them. The JSR-168 API defines two configuration objects, namely the PortletContext and the PortletConfig objects. In this chapter, I?m also going to throw the PortalContext into the mix as well, as it is phonetically pretty close to PortletContext. J It?s pretty easy to get the two of them confused. The PortalContext The PortalContext is a relatively straight forward object containing five important methods. These methods basically represent a handle from the portlet we code, bac to the Portal Server. From the PortalContext, we can discover the supported modes of the portal (just in case we want to code a custom portlet mode), along with the supported window states. This is good information to know when creating a portlet that may be deployed to a variety of different portal servers. The PortletConfig Interface The PortletConfig object is really just a handle back to the information about a portlet that is configured in the portlet.xml file. Methods like getPortletName(), getResourceBundle() and getInitParameters() are all methods that essentially read information that is written about the portlet in the portlet.xml deployment descriptor. Since all of these parameters come from a text file that cannot be edited at runtime, all of these parameters are read-only. If you want to change the data obtained by PortletConfig, you need to edit the portlet.xml file and bounce your portlet application. The PortletConfig becomes most interesting when you use it for initialization parameters. The method getInitParameters() can pull data from the portlet.xml deployment descriptor based upon the name of a name-value pair. The data is always returned as a string; after all, you can?t exactly code objects into the portlet.xml file. The neat thing about the PortletConfig is that it is common to the Portlet, regardless of the user interacting with the portlet. Unike the PortletSession object, where data is unique to the user, and not persisted, or the PotletRequest, where data is unique to a user, but purged after every request-response cycle, data obtained from the PortletConfig is always the same, regardless of the user invoking the Portlet. The only way to change the data pulled from the PortletConfig object is to phycially edit the portlet.xml file, which isn?t possible while an application is running. The PortletContext and the ServletContext Similar to the PortletConfig interface, the PortletContext has a method called getInitParameters(), which can spit out read-only String values that are configured in a deployment descriptor. Which deployment descriptor, you ask? Well, that?s a very good question. The PortletContext is really just a wrapper placed around the glorious ServletContext from the Servlet and JSP API. The true nature of the PortletContext is revealed when you discover that the init-parameters the PortletContext reads, are actually pulled from the same place the ServletContext init-parameters are pulled: the web.xml file. Yes, init-parameters for the PortletContext are actually configured in the deployment descriptor of the web module. So, what exactly is the PortletContext? Well, essentially, the PortletContext represents the shared space in which all of the portlets associated with a common war file reside. So, if information is stored in the PortletContext of a portlet application, any portlet that is deployed as part of that portlet application can access that information. The PortletContext and the Portlet Application So, any portlet deployed as part of a common war file can share and access information made available through the PortletContext. Now, this doesn?t mean every portlet running on a portal server has access to the same portlet context. Every portlet application, which essentially means all of the portlets that are defined in a common portlet.xml file, has a common PortletContext. However, a portlet defined in one portlet.xml file will never be able to access the PortletContext of a portlet defined in a different portlet application. For example, one resource that all Portlets and JSPs in a portlet application need access to is the PortletRequestDispatcher, which has been used many times to allow a portlet delegate to a JSP for markup generation. The PortletRequestDispatcher is a service that must be available to all portlets running in a portlet application, so it only makes sense that it be made available through the PortletContext. Another helpful service made available through the PortletContext is the logging service. Two overloaded log() methods are available to portlets through the PortletContext. Messages written through this logging service are written to a special log file, as defined by the portlet container vendor. The PortletContext also provides utility methods, such as getMajorVersion() and getMinorVersion(), for figuring out what version of the Portlet API your application is using; but by far, the most powerful methods of the PortletContext are the ones that provide access to the read-only initialization parameters, and the editable runtime attributes that can be added and deleted from the PortletContext. Class Diagram for he PortletContext Interface Templatized Portlets Many textbooks and references that talk about ServletConfig and ServletContext objects, which essentially correspond to the PortletConfig and PortletContext objects, gloss over the power of these objects, and simply give lip-service to the act of reading parameter values from deployment descriptors. Well, I?m not going to do that. I?m going to show you a very simple example of a templatized portlet, that can have a profound effect on a developer?s ability to generate a multitude of useful and configurable portlets. Take a look at the following GenericTaxPortlet. How many portlets do you see there? One? Well, you?re wrong ? there are hundreds. package com.examscam.portlet; import java.io.*;import javax.portlet.*; public class GenericTaxPortlet extends GenericPortlet { protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType(?text/html?); PrintWriter out = response.getWriter(); PortletContext context = this.getPortletContext(); PortletConfig config = this.getPortletConfig(); String fedRate = context.getInitParameter("fedrate"); String regionName = context.getInitParameter("regionname"); String regionalRate = config.getInitParameter("regionalrate"); out.print(" <BR>The federal tax rate is: " + fedRate); out.print(" <BR>The " + regionName + " tax rate is: "); out.print(regionalRate); } } Deployment Descriptors and InitParameters The GenericTaxPortlet reads in three values from the deployment descriptors, namely fedrate and regionname from the web.xml file, and regionalrate from the portlet.xml file. But imagine if we wanted to create a bunch of portlets, based on the GenericTaxPortlet, that displayed the federal and state tax obligations for each of the fifty U.S. states? Well, we could create an entry in the portlet.xml file for each state, and configure each state with a different tax rate. We could have one entry for the FloridaTaxPortlet, another for the TexasTaxPortlet, and a third for the NevadaTaxPortlet. We could configure each as a separate portlet in the portlet.xml file, point to the same GenericTaxPortlet as the implementing class, and provide a unique value for each state?s tax rate. Okay, these three states are bad examples, because none of them actually have a state tax, but you get the point! """ <portlet> <description>OhioTaxPortlet</description><portlet-name>OhioTaxPortlet</portlet-name> <display-name>OhioTaxPortlet</display-name> <portlet-class> com.examscam.portlet.GenericTaxPortlet </portlet-class> <init-param> <name>regionalrate</name><value>4</value> </init-param> <supports><mime-type>text/html</mime-type><portlet-mode>view</portlet-mode></supports> <supported-locale>en</supported-locale> <portlet-info> <title>Ohio</title> </portlet-info> </portlet> <!-- You can make as many portlets as you like!!!--> <portlet> <description>FloridaTaxPortlet</description><portlet-name>FloridaTaxPortlet</portlet-name> <display-name>FloridaTaxPortlet</display-name> <portlet-class> com.examscam.portlet.GenericTaxPortlet </portlet-class> <init-param> <name>regionalrate</name><value>5</value> </init-param> <supports><mime-type>text/html</mime-type><portlet-mode>view</portlet-mode></supports> <supported-locale>en</supported-locale> <portlet-info> <title>FloridaTaxPortlet</title> </portlet-info> </portlet> <portlet>""<name>regionalrate</name><value>5</value></portlet> "" Web Deployment Descriptor (web.xml) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp_ID"> <display-name>US TaxProject</display-name> <context-param> <param-name>fedrate</param-name> <param-value>35</param-value> <description>Federal Tax Rate</description> </context-param> <context-param> <param-name>regionname</param-name> <param-value>state</param-value> <description>Region Name</description> </context-param> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> Portlet Deployment Descriptor (portlet.xml) <?xml version="1.0" encoding="UTF-8"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" id="com.examscam.portlet.GenericTaxPortlet.fb9b06d0f0"> <portlet> <description>GenericTaxPortlet</description> <portlet-name>GenericTaxPortlet</portlet-name> <display-name>GenericTaxPortlet</display-name> <portlet-class> com.examscam.portlet.GenericTaxPortlet </portlet-class> <init-param> <name>regionalrate</name> <value>5</value> </init-param> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <supported-locale>en</supported-locale> <portlet-info> <title>GenericTaxPortlet</title> </portlet-info> </portlet> </portlet-app> Repackaging the WAR So, by creating multiple entries in the portlet.xml file, we can create a multitude of portlets based upon the GenericTaxPortlet. But all of these portlets are really focused on the United States. What about other countries? Well, we could configure all of the American states in one portlet.xml file, and export that entire portlet application as a single war file, perhaps called USTaxesPortletApp.war. We could then create a second portlet application for Canada, called the CanadianTaxesPortletApp.war. And if people outside of North American started buying my books, we could create portlet applications for those countries too. For the CanadianTaxesPortletApp, our portlet.xml file would have entries for each of the Canadian provinces, and the web.xml file, where PortletContext parameters are configured, would look like this: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp_ID"> <display-name>Canadian TaxProject</display-name> <context-param> <param-name>fedrate</param-name> <param-value>45</param-value> <description>Federal Tax Rate</description> </context-param> <context-param> <param-name>regionname</param-name> <param-value>provincial</param-value> <description>Region Name</description> </context-param> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> PortletContext Attributes Both the PortletContext and PortletConfig objects can read information from deployment descriptors, but only the PortletContext provides a scope for storing readable and writable properties. The PortletRequest provides a scope for storing user centric information that is purges as soon as the current request-response cycle is completed. The PortletSession provides a transient data storage mechanism that can store user-centric data for as long as the user is visiting our website. The PortletPreferences object provides permanent storage for user preferences. But each of these mechanisms work on a per-user basis. How can information be shared across all users, and all portlets, that are part of the same portlet application (aka, packaged in the same war file) ? Well, the PortletContext provides a getAttribute() and setAttribute() method that allows objects to be stored, and shared across all users and all portlets in a portlet application. The PortletContext, and its close cousin, the ServletContext, are two incredibly powerful scope storage mechanisms, and unfortunately, two of the most under-utilized. I love the PortletContext, and believe that it should be used more often in applications. There is one drawback to the PortletContext though. The PortletContext is not always synchronized across JVMs in a cluster. As a result, objects placed in the PortletContext should be largely read from, and rarely written to. On my websites, I provide a variety of online mock exams for certification preparation. In my Java apps, I always store the set of questions in the PortletContext or ServletContext. The questions are loaded into the context as soon as the application starts up, and are not really ever changed at runtime. Of course, almost every JSP, Servlet, Portlet, Filter, or other web artifact must access the exam object, so having it in the context is very convenient. Use the PortalContext when it makes sense. Your users will love you for it! Question 7-1 For a given portlet definition, how many instances of that portlet should run on a portal server? ˇ a) one instance per JVMˇ b) one instance per userˇ c) one instance per pageˇ d) one instance every time the portlet is rendered Answer a) is correct. Given a portlet definition, only one instance of that portlet should ever be instantiated. In a distributed environment, where multiple JVMs service an application, the specification allows for one instance per JVM. Question 7-2 When developing an application that needs to be customized by the user, but will also need data to be formatted for printing what type of solution is best? ˇ a) a single portlet supporting multiple portlet statesˇ b) a Portlet solution based on the Struts portal frameworkˇ c) a single portlet supporting multiple portlet modesˇ d) a portlet solution that relies heavily on portlet services Answer c) is correct. Custom portlet modes can be used for such features as printing or providing custom about message. Be aware though that not only must your portlet provide an implementation for the custom mode, but you portal server must support the custom mode as well. Question 7-3 If a PortletException is thrown during the init method of a portlet ¨ a) the portal container may re-attempt to initialize the portlet¨ b) the portlet container my not attempt to re-initialize the portlet¨ c) the destroy method will not be called¨ d) the destroy method will be called to clean up any initialized resources Answers a) and c) are correct. If a PortletException is thrown during the init method, the destroy method is not called, because initialization is considered to be unsuccessful. Furthermore, the container may attempt to re-initialize the Portlet. Question 7-4 PortletConfig initialization parameters are: ¨ a) defined in the web.xml file¨ b) defined in the portlet.xml file¨ c) read only and cannot be changed at runtime¨ d) read/write, but may get out of sync across multiple JVMs Answers b) and c) are correct. In the old IBM API, PortletConfig was defined in the web.xml file, but with JSR-168, initialization parameters are all maintained in the portlet.xml file. Also, initialization parameters for a portlet are read only. PortletConfig does not have a problem being managed across JVMs. Synchronization across JVMs is only a problem with the PortletContext. Question 7-5 The PortletConfig object is ˇ a) shared amongst all portlet instancesˇ b) unique to a particular portlet instanceˇ c) unique to a particular userˇ d) is unique to a particular session Answer b) is correct. PortletConfig provides initialization parameters to a particular portlet instance. That data is then available to any user, session or any method call made at any time to that particular portlet. Question 7-6 Which of the following statements are true: ¨ a) the PortletContext is accessed through the this of a portlet¨ b) the PortletConfig is accessed through the this of a portlet¨ c) the PortletContext is accessible through the PortletConfig¨ d) the PortletConfig is accessible through the PortletContext Answers a), b) and d) are the correct answers. There is a getPortletContext() method in the PortletConfig object, but the PortletContext method has not facilities for accessing the PortletConfig object. Question 7-7 Where is a PortletPreference defined as being read only. ˇ a) programmatically through the PortletPreferences objectˇ b) by adding a read-only parameter to the portlet.xml fileˇ c) by adding a read-only parameter to the web.xml fileˇ d) PortletPreferences are always editable Answer b) is correct. There is no programmatic way to set a PortletPreference to be read-on; this can only be done by setting the preference through the portlet.xml file, and subsequently adding a tag indicating that the preference is read only. Question 7-8 Which of the following methods is triggered every time a portlet is displayed in view mode? ˇ a) initˇ b) destroyˇ c) doViewˇ d) processAction Answer c), doView, is correct. Init and destroy are only called once in the lifecycle of a portlet. The doView method is invoked every time a portlet is viewed in view mode. The processAction is only invoked when an action URL is used by the client, which may or may not happen when a portlet is asked to be displayed in view mode. Answer 4xxx-1xxx The PortalContext: ¨ a) can provide a list of window states supported by the portal¨ b) can provide a list of portlet modes supported by the portal¨ c) provides access to the RequestDispatcher¨ d) provides access to the portal logging mechanism Options a) and b) are correct. The PortalContext has five methods, including getPortalInfo, getPropertyNames, getProperty, getSupportedPortletModes and getSupportedWindowStates. The object used to access the PortletRequestDispatcher and the portal logging mechanism is the similarly named PortletContext object. Answer 7-1 For a given portlet definition, how many instances of that portlet should run on a portal server? ˇ a) one instance per JVMˇ b) one instance per userˇ c) one instance per pageˇ d) one instance every time the portlet is rendered Answer a) is correct. Given a portlet definition, only one instance of that portlet should ever be instantiated. In a distributed environment, where multiple JVMs service an application, the specification allows for one instance per JVM. Answer 7-2 When developing an application that needs to be customized by the user, but will also need data to be formatted for printing what type of solution is best? ˇ a) a single portlet supporting multiple portlet statesˇ b) a Portlet solution based on the Struts portal frameworkˇ c) a single portlet supporting multiple portlet modesˇ d) a portlet solution that relies heavily on portlet services Answer c) is correct. Custom portlet modes can be used for such features as printing or providing custom about message. Be aware though that not only must your portlet provide an implementation for the custom mode, but you portal server must support the custom mode as well. Answer 7-3 If a PortletException is thrown during the init method of a portlet ¨ a) the portal container may re-attempt to initialize the portlet¨ b) the portlet container my not attempt to re-initialize the portlet¨ c) the destroy method will not be called¨ d) the destroy method will be called to clean up any initialized resources Answers a) and c) are correct. If a PortletException is thrown during the init method, the destroy method is not called, because initialization is considered to be unsuccessful. Furthermore, the container may attempt to re-initialize the Portlet. Answer 7-4 PortletConfig initialization parameters are: ¨ a) defined in the web.xml file¨ b) defined in the portlet.xml file¨ c) read only and cannot be changed at runtime¨ d) read/write, but may get out of sync across multiple JVMs Answers b) and c) are correct. In the old IBM API, PortletConfig was defined in the web.xml file, but with JSR-168, initialization parameters are all maintained in the portlet.xml file. Also, initialization parameters for a portlet are read only. PortletConfig does not have a problem being managed across JVMs. Synchronization across JVMs is only a problem with the PortletContext. Answer 7-5 The PortletConfig object is ˇ a) shared amongst all portlet instancesˇ b) unique to a particular portlet instanceˇ c) unique to a particular userˇ d) is unique to a particular session Answer b) is correct. PortletConfig provides initialization parameters to a particular portlet instance. That data is then available to any user, session or any method call made at any time to that particular portlet. Answer 7-6 Which of the following statements are true: ¨ a) the PortletContext is accessed through the this of a portlet¨ b) the PortletConfig is accessed through the this of a portlet¨ c) the PortletContext is accessible through the PortletConfig¨ d) the PortletConfig is accessible through the PortletContext Answers a), b) and d) are the correct answers. There is a getPortletContext() method in the PortletConfig object, but the PortletContext method has not facilities for accessing the PortletConfig object. Answer 7-8 Which of the following methods is triggered every time a portlet is displayed in view mode? ˇ a) initˇ b) destroyˇ c) doViewˇ d) processAction Answer c), doView, is correct. Init and destroy are only called once in the lifecycle of a portlet. The doView method is invoked every time a portlet is viewed in view mode. The processAction is only invoked when an action URL is used by the client, which may or may not happen when a portlet is asked to be displayed in view mode. Answer 4xxx-1xxx The PortalContext: ¨ a) can provide a list of window states supported by the portal¨ b) can provide a list of portlet modes supported by the portal¨ c) provides access to the RequestDispatcher¨ d) provides access to the portal logging mechanism Options a) and b) are correct. The PortalContext has five methods, including getPortalInfo, getPropertyNames, getProperty, getSupportedPortletModes and getSupportedWindowStates. The object used to access the PortletRequestDispatcher and the portal logging mechanism is the similarly named PortletContext object.
Google



eXTReMe Tracker

ActionRequest ActionResponse GenericPortlet PortletRequestDispatcher . Portlet ..... PortletURL
PortletContext PortletException PortletMode a PortletModeException PortletPreferences
PortalContext PortletResponse PortletSession PortletSecurityException PreferencesValidator
PortletConfig RenderRequest RenderResponse UnavailableException PortletSessionUtil
PortletRequest ValidatorException WindowState WindowStateException UnmodifiableException