IBM WebSphere Portal V4 Developer’s Handbook Front cover
by user
Comments
Transcript
IBM WebSphere Portal V4 Developer’s Handbook Front cover
Front cover IBM WebSphere Portal V4 Developer’s Handbook Deliver additional functions such as personalization and search capabilities Understand portlet development using WebSphere Portal Toolkit Learn about portlet event handling and messaging Juan R. Rodriguez Jerome Curlier Werner Frei Denise Hatzidakis Juergen Moetzel Nancy Ting Shawn VanRaay ibm.com/redbooks International Technical Support Organization IBM WebSphere Portal V4 Developer’s Handbook March 2003 SG24-6897-00 Note: Before using this information and the product it supports, read the information in “Notices” on page xi. First Edition (March 2003) This edition applies to Version 4, Release 1, Modification 4 of IBM WebSphere Portal for Multiplatforms. © Copyright International Business Machines Corporation 2003. All rights reserved. Note to U.S. Government Users Restricted Rights -- Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. Contents Notices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi Trademarks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xii Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii The team that wrote this redbook . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xv Comments welcome . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Chapter 1. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.1 Portal evolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.1.1 The three generations of portal technology. . . . . . . . . . . . . . . . . . . . . 3 1.2 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2.1 WebSphere Portal architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2.2 WebSphere Portal tooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.3 WebSphere Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.1 Portal concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 1.3.2 Portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.3.3 Portlet Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.3.4 Portlet states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.3.5 Portlets and the Model-View-Controller (MVC) design pattern . . . . . 16 1.3.6 WebSphere Portal Runtime: the Portlet Container . . . . . . . . . . . . . . 17 1.3.7 Portlet lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.3.8 Portlet events and messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.3.9 Page aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.4 Portlet solution patterns. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 Chapter 2. Portlets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.1 What is a portlet? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.2 Basic portlet terms. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.3 MVC architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 2.3.1 Standard MVC architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.3.2 Portlet MVC architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 2.3.3 Portlet MVC sample . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 2.4 Servlets versus portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 2.5 What is a portlet application? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 2.6 Portlet deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 2.6.1 web.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 2.6.2 portlet.xml . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 2.6.3 Parameter summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 © Copyright IBM Corp. 2003. All rights reserved. iii 2.6.4 Web.xml and Portlet.xml relationship . . . . . . . . . . . . . . . . . . . . . . . . 54 2.6.5 UID guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 2.6.6 Building a war file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 2.6.7 Creating a development environment . . . . . . . . . . . . . . . . . . . . . . . . 58 2.7 Portlet lifecycle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 2.8 Portlet API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 2.8.1 Hierarchy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 2.9 Core portlet objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 2.9.1 Portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 2.9.2 PortletAdapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 2.9.3 PortletRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 2.9.4 PortletResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 2.9.5 PortletSession object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 2.9.6 Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 2.9.7 PortletConfig object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 2.9.8 PortletContext object. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 2.9.9 PortletSettings object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 2.9.10 PortletApplicationSettings object. . . . . . . . . . . . . . . . . . . . . . . . . . . 69 2.9.11 PortletData object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 2.9.12 PortletLog object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 2.9.13 PortletException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.9.14 UnavailableException . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.9.15 PortletWindow object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 2.9.16 User object . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 2.9.17 PortletURI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73 2.10 Listeners . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.10.1 PortletTitleListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.10.2 PortletPageListener. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.10.3 PortletSessionListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 2.10.4 WindowListener. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 2.10.5 PortletSettingsAttributesListener . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 2.10.6 PortletApplicationSettingsAttributesListener . . . . . . . . . . . . . . . . . . 77 2.11 Action event handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 2.12 Core event objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.12.1 ActionListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.12.2 ActionEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.12.3 PortletURI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.12.4 PortletAction and DefaultPortletAction . . . . . . . . . . . . . . . . . . . . . . 80 2.12.5 ModeModifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 2.13 Event examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 2.13.1 Multi-part form event handling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 2.13.2 Multi-mode event handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 2.14 Portlet messaging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 iv IBM WebSphere Portal V4 Developer’s Handbook 2.15 Core messaging objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 2.15.1 MessageListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 2.15.2 MessageEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 2.15.3 DefaultPortletMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90 2.15.4 PortletMessage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 2.15.5 ActionListener/WindowListener . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 2.16 Messaging examples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 2.16.1 Portlet messaging example 1: navigation control . . . . . . . . . . . . . . 92 2.16.2 Portlet messaging example 2: sharing configuration information . . 95 2.17 Attribute storage summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 2.18 Portlet services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 2.18.1 ContentAccessService . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 2.18.2 Custom services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 2.19 Credential Vault. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 2.20 Core Credential Vault objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107 2.20.1 Vault . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 2.20.2 Segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 2.20.3 Slot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 108 2.20.4 Credential . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 2.21 Portlet JSPs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 2.21.1 Portlet Tag Library. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112 2.22 Resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 Chapter 3. Using the Portal Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119 3.1 Portal Toolkit installation introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 120 3.2 Installing the WebSphere Portal Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . 120 3.3 Portlet Application wizard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 3.4 Developing portlet applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130 3.4.1 Portlet application contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 3.4.2 Generated classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 3.5 Portlet.xml interface. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 3.6 Deploying portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 3.6.1 Deploying to an independent WebSphere Application Server . . . . 139 3.6.2 Deploying to a connected WebSphere Application Server . . . . . . . 141 3.7 Adding portlets to applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 3.8 Configuring Studio for portlet development . . . . . . . . . . . . . . . . . . . . . . . 148 3.8.1 JSP heads and metadata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 3.8.2 Default files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 3.8.3 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 Chapter 4. Portlet testing and debugging . . . . . . . . . . . . . . . . . . . . . . . . 153 4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 4.1.1 Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Contents v 4.1.2 Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 4.1.3 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155 4.2 Installing the components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159 4.2.1 WebSphere Studio Application Developer . . . . . . . . . . . . . . . . . . . 159 4.2.2 Portal Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 4.2.3 Personalization Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 4.2.4 DB2 Universal Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 4.2.5 WebSphere Application Server Advanced Single Server . . . . . . . . 163 4.2.6 Portal server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 4.3 Configuring the environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200 4.3.1 Preparation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 4.3.2 Defining the Server in WebSphere Studio Application Developer . 203 4.3.3 Testing the server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 4.4 Testing and debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 4.4.1 Debugging the first portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 4.4.2 Debugging portlet JSPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230 4.4.3 Adding portal server portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233 4.4.4 Adding the sample YourCo portlets . . . . . . . . . . . . . . . . . . . . . . . . 238 4.4.5 Hints and tips . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242 Chapter 5. National Language Support . . . . . . . . . . . . . . . . . . . . . . . . . . . 245 5.1 Resource bundles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 5.1.1 Creating resource bundles in WebSphere Studio . . . . . . . . . . . . . . 247 5.1.2 Translating resource bundles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 5.1.3 Accessing resource bundles in portlets. . . . . . . . . . . . . . . . . . . . . . 251 5.1.4 Accessing resource bundles in JSPs . . . . . . . . . . . . . . . . . . . . . . . 251 5.2 Translating whole resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252 5.3 NLS administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 5.3.1 Portlet NLS administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 5.3.2 Portal NLS administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 5.3.3 Setting NLS titles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257 5.3.4 Adjusting Portal resource bundles . . . . . . . . . . . . . . . . . . . . . . . . . 258 5.4 Working with characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 5.5 NLS best practices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259 Chapter 6. Portal customization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261 6.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 6.2 Guided tour of the portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 6.2.1 Portal overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267 6.2.2 Portal resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 6.2.3 Welcome page aggregation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 6.2.4 Extend Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 6.3 Portal customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 vi IBM WebSphere Portal V4 Developer’s Handbook 6.3.1 Basic customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299 6.3.2 Advanced customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 6.3.3 WebSphere Portal Extend. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341 6.4 Building a virtual portal: the YourCo portal . . . . . . . . . . . . . . . . . . . . . . . 347 6.4.1 YourCo sample overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 6.4.2 Building the YourCo portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 6.4.3 Adding features to the YourCo portal . . . . . . . . . . . . . . . . . . . . . . . 373 6.5 JSP tags reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386 6.5.1 <wps:bidi> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 6.5.2 <wps:componentLoop> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388 6.5.3 <wps:componentRender> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 6.5.4 <wps:constants> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 6.5.5 <wps:date> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 6.5.6 <wps:if> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 390 6.5.7 <wps:page>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 6.5.8 <wps:pageGroup>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 6.5.9 <wps:pageGroupLoop>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 6.5.10 <wps:pageLoop>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398 6.5.11 <wps:pageLoopInit> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 6.5.12 <wps:pageLoopShift> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 6.5.13 <wps:pageRender>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 6.5.14 <wps:portletBack>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399 6.5.15 <wps:portletConfigure> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 6.5.16 <wps:portletEdit> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 6.5.17 <wps:portletHelp> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.5.18 <wps:portletID> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.5.19 <wps:portletMaximize> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.5.20 <wps:portletMinimize> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.5.21 <wps:portletRender>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 6.5.22 <wps:portletRestore> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 6.5.23 <wps:portletTitle> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 6.5.24 <wps:problem> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 402 6.5.25 <wps:screenRender/> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 6.5.26 <wps:text>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 6.5.27 <wps:textParam> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 6.5.28 <wps:time> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 6.5.29 <wps:unless> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404 6.5.30 <wps:url>. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 6.5.31 <wps:urlBase> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 6.5.32 <wps:urlFind> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 6.5.33 <wps:urlFindInSkin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 6.5.34 <wps:urlFindInTheme> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 6.5.35 <wps:urlParent> . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 Contents vii 6.5.36 6.5.37 6.5.38 6.5.39 6.5.40 <wps:user> . . . . . . . . . . . . . . . <wps:width> . . . . . . . . . . . . . . <extend:find> . . . . . . . . . . . . . <extend:pageGroupId> . . . . . . <extend:userObjectId> . . . . . . ....... ....... ....... ....... ....... ...... ...... ...... ...... ...... ....... ....... ....... ....... ....... ...... ...... ...... ...... ...... . . . . . 408 408 408 409 409 Chapter 7. Web Clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 7.1 Web Clipping overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412 7.2 Web Clipping example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413 7.3 HTML clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419 7.4 Text clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424 7.5 Web Clipper settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 7.5.1 Basic settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427 7.5.2 Clipping types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 430 7.5.3 Firewall options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433 7.5.4 Authentication options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 435 7.5.5 URL rewriting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 440 7.5.6 Security options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 7.6 HTML Clipping limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 447 7.7 Future implementation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448 Chapter 8. Search capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 449 8.1 Search in WebSphere Portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 450 8.2 Integrated search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 452 8.3 Extended Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458 8.3.1 Lotus Extended Search architecture . . . . . . . . . . . . . . . . . . . . . . . . 459 8.3.2 Setting up Lotus Extended Search . . . . . . . . . . . . . . . . . . . . . . . . . 463 8.3.3 Creating search sources for Portal . . . . . . . . . . . . . . . . . . . . . . . . . 464 8.3.4 Writing Web client applications for Extended Search . . . . . . . . . . . 472 8.3.5 Portlets using Lotus Extended Search . . . . . . . . . . . . . . . . . . . . . . 472 Chapter 9. Remote portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 475 9.1 Portals in the on-demand era . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 9.2 Web services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476 9.3 Portals and Web services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479 9.4 Using remote portlets with WebSphere Portal . . . . . . . . . . . . . . . . . . . . 484 9.4.1 UDDI registry. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 9.4.2 Preparing the IBM Test Registry . . . . . . . . . . . . . . . . . . . . . . . . . . . 485 9.4.3 Configuring the connection to the UDDI Registry . . . . . . . . . . . . . . 489 9.4.4 Publish a portlet to the UDDI registry . . . . . . . . . . . . . . . . . . . . . . . 492 9.4.5 Accessing a remote portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496 Chapter 10. Personalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501 10.1 Introduction to personalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 viii IBM WebSphere Portal V4 Developer’s Handbook 10.1.1 What is personalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502 10.1.2 Planning a personalization solution. . . . . . . . . . . . . . . . . . . . . . . . 503 10.1.3 Matching types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 10.1.4 Implementing a personalization solution . . . . . . . . . . . . . . . . . . . . 506 10.2 WebSphere Personalization V4.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506 10.2.1 Personalization V4.1 key features. . . . . . . . . . . . . . . . . . . . . . . . . 510 10.2.2 Integration with WebSphere Portal Server . . . . . . . . . . . . . . . . . . 511 10.2.3 Integration with WebSphere Content Publisher . . . . . . . . . . . . . . 512 10.2.4 Runtime rule processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512 10.3 Personalization API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 10.3.1 Resource interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 514 10.3.2 IMVResource interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515 10.3.3 MultiValueUtils interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 10.3.4 ResourceDomain2 interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516 10.3.5 ResourceManager2 interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 10.3.6 AuthIDTranslator interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 10.3.7 BaseResource class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518 10.3.8 Generic query framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 10.3.9 ResourceContext class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521 10.3.10 RuleTrigger class . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522 10.4 Using WebSphere Personalization components . . . . . . . . . . . . . . . . . . 523 10.4.1 Personalization Runtime . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523 10.4.2 Resource Console. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527 10.4.3 Personalization Workspace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541 10.4.4 Plugins for WebSphere Studio Application Developer (Wizards) . 566 10.5 Implementing personalization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581 10.5.1 Authorization considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581 10.5.2 Logging options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 582 10.5.3 Applying Personalization to the YourCo sample . . . . . . . . . . . . . . 586 10.6 Migration of Personalization V3.5.x solutions . . . . . . . . . . . . . . . . . . . . 633 Chapter 11. Content management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 11.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638 11.1.1 Support for content management in WebSphere Portal Server . . 638 11.2 Software Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 11.2.1 Web Content Publisher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 639 11.2.2 Portal Content Organizer (PCO) . . . . . . . . . . . . . . . . . . . . . . . . . . 641 11.3 Web Content Publisher . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641 11.3.1 Features of Web Content Publisher . . . . . . . . . . . . . . . . . . . . . . . 641 11.3.2 A brief tour of WebSphere Content Publisher . . . . . . . . . . . . . . . . 643 11.3.3 Web Content Publisher architecture . . . . . . . . . . . . . . . . . . . . . . . 647 11.3.4 Step-by-step guide to content publishing . . . . . . . . . . . . . . . . . . . 649 11.3.5 Create channel contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712 Contents ix 11.3.6 Resource to resource transformation . . . . . . . . . . . . . . . . . . . . . . 723 11.3.7 Publishing contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 11.3.8 Serving content in the portal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 11.3.9 Workflow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758 11.4 Known problems and workarounds . . . . . . . . . . . . . . . . . . . . . . . . . . . . 770 11.5 Portal Content Publisher (PCO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771 11.5.1 Accessing PCO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772 11.5.2 PCO Administration. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 774 11.5.3 PCO user interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 779 11.6 Third-party content management collaboration . . . . . . . . . . . . . . . . . . . 783 Chapter 12. Host Integration portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785 12.1 Host On-Demand portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 786 12.2 Host Publisher portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 797 Chapter 13. Transcoding. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 811 13.1 Document clipping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812 13.1.1 Under the cover. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 812 13.1.2 Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 814 13.2 Request Viewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817 13.3 XML configuration tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 820 13.4 Fragmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 823 13.4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 824 13.4.2 How does it work? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 825 13.4.3 Fragmentable elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 827 13.4.4 Common problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828 13.4.5 Example 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 828 13.4.6 Example 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 830 13.4.7 Fragmentation and intermediate proxies. . . . . . . . . . . . . . . . . . . . 836 13.4.8 Scenario 1: using a WAP reverse proxy . . . . . . . . . . . . . . . . . . . . 836 13.4.9 Scenario 2: using a forward proxy. . . . . . . . . . . . . . . . . . . . . . . . . 842 13.4.10 Scenario 3: using a forward proxy and reverse proxy . . . . . . . . . 843 Related publications . . . . . . . . . . . . . . . . . . . . . . IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . Other resources . . . . . . . . . . . . . . . . . . . . . . . . Referenced Web sites . . . . . . . . . . . . . . . . . . . . . . How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . IBM Redbooks collections . . . . . . . . . . . . . . . . . ...... ...... ...... ...... ...... ...... ....... ....... ....... ....... ....... ....... ...... ...... ...... ...... ...... ...... . . . . . . 845 845 845 845 847 847 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 849 x IBM WebSphere Portal V4 Developer’s Handbook Notices This information was developed for products and services offered in the U.S.A. IBM may not offer the products, services, or features discussed in this document in other countries. Consult your local IBM representative for information on the products and services currently available in your area. Any reference to an IBM product, program, or service is not intended to state or imply that only that IBM product, program, or service may be used. Any functionally equivalent product, program, or service that does not infringe any IBM intellectual property right may be used instead. However, it is the user's responsibility to evaluate and verify the operation of any non-IBM product, program, or service. IBM may have patents or pending patent applications covering subject matter described in this document. The furnishing of this document does not give you any license to these patents. You can send license inquiries, in writing, to: IBM Director of Licensing, IBM Corporation, North Castle Drive Armonk, NY 10504-1785 U.S.A. The following paragraph does not apply to the United Kingdom or any other country where such provisions are inconsistent with local law: INTERNATIONAL BUSINESS MACHINES CORPORATION PROVIDES THIS PUBLICATION "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Some states do not allow disclaimer of express or implied warranties in certain transactions, therefore, this statement may not apply to you. This information could include technical inaccuracies or typographical errors. Changes are periodically made to the information herein; these changes will be incorporated in new editions of the publication. IBM may make improvements and/or changes in the product(s) and/or the program(s) described in this publication at any time without notice. Any references in this information to non-IBM Web sites are provided for convenience only and do not in any manner serve as an endorsement of those Web sites. The materials at those Web sites are not part of the materials for this IBM product and use of those Web sites is at your own risk. IBM may use or distribute any of the information you supply in any way it believes appropriate without incurring any obligation to you. Information concerning non-IBM products was obtained from the suppliers of those products, their published announcements or other publicly available sources. IBM has not tested those products and cannot confirm the accuracy of performance, compatibility or any other claims related to non-IBM products. Questions on the capabilities of non-IBM products should be addressed to the suppliers of those products. This information contains examples of data and reports used in daily business operations. To illustrate them as completely as possible, the examples include the names of individuals, companies, brands, and products. All of these names are fictitious and any similarity to the names and addresses used by an actual business enterprise is entirely coincidental. COPYRIGHT LICENSE: This information contains sample application programs in source language, which illustrates programming techniques on various operating platforms. You may copy, modify, and distribute these sample programs in any form without payment to IBM, for the purposes of developing, using, marketing or distributing application programs conforming to the application programming interface for the operating platform for which the sample programs are written. These examples have not been thoroughly tested under all conditions. IBM, therefore, cannot guarantee or imply reliability, serviceability, or function of these programs. You may copy, modify, and distribute these sample programs in any form without payment to IBM for the purposes of developing, using, marketing, or distributing application programs conforming to IBM's application programming interfaces. © Copyright IBM Corp. 2003. All rights reserved. xi Trademarks The following terms are trademarks of the International Business Machines Corporation in the United States, other countries, or both: Redbooks (logo)™ eServer™ iSeries™ AIX 5L™ AIX® AS/400® CICS® CT™ Domino™ Domino.Doc® DB2 Universal Database™ DB2® Everyplace™ IBM® IMS™ Lotus Discovery Server™ Lotus Notes® Lotus Workflow™ Lotus® Monday™ NavCode™ Notes® OS/400® QBIC® Redbooks™ Sametime® SecureWay® Tivoli® VisualAge® Wave® WebSphere® The following terms are trademarks of other companies: ActionMedia, LANDesk, MMX, Pentium and ProShare are trademarks of Intel Corporation in the United States, other countries, or both. Microsoft, Windows, Windows NT, and the Windows logo are 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. C-bus is a trademark of Corollary, Inc. in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. SET, SET Secure Electronic Transaction, and the SET Logo are trademarks owned by SET Secure Electronic Transaction LLC. Other company, product, and service names may be trademarks or service marks of others. xii IBM WebSphere Portal V4 Developer’s Handbook Preface This IBM Redbook helps you plan and develop portlet applications using the IBM® WebSphere® Portal Enable and Extend offerings. The information provided in this redbook targets Business-to-Employee (B2E) enterprise applications, but most of the scenarios presented apply to Business-to-Consumer (B2C) applications as well. In this redbook, you will find step-by-step examples and scenarios showing ways to integrate your enterprise applications into an IBM WebSphere Portal environment using the WebSphere Portal APIs provided by the Portal Toolkit to develop portlets; we also discuss extending your portlet capabilities to use other advanced functions such as themes and skins, personalization, search capabilities, content management, national language support, transcoding, Web clipping, etc. Elements of the portlet API are described and sample code is provided. The scenarios included in this redbook can be used to learn about portlet programming and as a basis to develop your own portlet applications. You will also find numerous scenarios describing recommended ways to develop portlets and portlet applications using the APIs provided by the IBM WebSphere Portal Toolkit. A basic knowledge of Java technologies such as servlets, JavaBeans, EJBs, JavaServer Pages (JSPs), as well as XML applications and the terminology used in Web publishing, is assumed. The team that wrote this redbook This redbook was produced by a team of specialists from around the world working at the International Technical Support Organization, Raleigh Center. Juan R. Rodriguez is a Consulting IT professional at the IBM ITSO Center, Raleigh. He received his Master of Science degree in Computer Science from Iowa State University. He writes extensively and teaches IBM classes worldwide on such topics as networking, Web technologies, and information security. Before joining the IBM ITSO, he worked at the IBM laboratory in the Research Triangle Park (North Carolina, USA) as a designer and developer of networking products. © Copyright IBM Corp. 2003. All rights reserved. xiii Jerome Curlier has eight years of application development experience using diverse technologies from C with Linux to C# with the .net Framework. Jerome started and managed a Web Design Company in France for three years. Jerome is currently working as a Technical Architect for the IBM Pacific Development Centre in Vancouver, Canada. Jerome is also the team lead of the Microsoft.net Special Interest Group at the Centre. Werner Frei is a Senior IT Specialist at the IBM e-business Innovation Center in Zurich, Switzerland. He has more than twenty years of experience in application development. He has worked in projects within IBM, in customer projects, in product support for VisualAge® Smalltalk and for four years as a teacher for object-oriented programming, Java and the WebSphere family of products at IBM Learning Services. Denise Hatzidakis is a managing director and WebSphere Architect with Perficient, Inc. Denise has a BS in Physics and a BS degree in Computer Science, as well as an MS in Electrical and Computer Engineering. She joined IBM and spent ten years as a lead developer for VisualAge and WebSphere in various capacities. She has recently joined Perficient, Inc., where she makes extensive use of her skills as a consultant in WebSphere and J2EE technologies. Juergen Moetzel is an IT Specialist at IBM Global Services, BIS e-business Solution Delivery, Munich, Germany. He has five years of experience in Web application development and is currently working in the custom enterprise application development area, focusing on Java technologies and the WebSphere family of products. Nancy Ting is a Senior Consultant in Deloitte Consulting (soon to be Braxton). She focuses on designing and developing business solutions through the application of electronic commerce as well as enabling business through multiple channels (Internet, wireless and voice recognition). Nancy is a certified Java programmer and a DB2® solutions specialist, and has been the lead developer and co-architect in many large-scale e-business application implementations. She also has extensive experience in speech recognition and has won an award for building a speech application for a major telecommunications infrastructure provider. xiv IBM WebSphere Portal V4 Developer’s Handbook Shawn VanRaay has been working with WebSphere Portal, WebSphere Studio and Portal Toolkit since the early days of these products. He is a consultant with Perficient, Inc., specializing in Technical Writing, Education and Consulting in the Java and WebSphere arena. Shawn has over five years of experience with Java technologies and the related WebSphere family of products. Thanks to the following people for their contributions to this project: Margaret Ticknor International Technical Support Organization, Raleigh Center Sarah Hall, David Kennedy, Julie Strong, David Lection, Philip Kregor IBM Research Triangle Park, North Carolina, USA Rogerio Venancio IBM Brazil Become a published author Join us for a two- to six-week residency program! Help write an IBM Redbook dealing with specific products or solutions, while getting hands-on experience with leading-edge technologies. You'll team with IBM technical professionals, Business Partners and/or customers. Your efforts will help increase product acceptance and customer satisfaction. As a bonus, you'll develop a network of contacts in IBM development labs, and increase your productivity and marketability. Find out more about the residency program, browse the residency index, and apply online at: ibm.com/redbooks/residencies.html Preface xv Comments welcome Your comments are important to us! We want our Redbooks™ to be as helpful as possible. Send us your comments about this or other Redbooks in one of the following ways: Use the online Contact us review redbook form found at: ibm.com/redbooks Send your comments in an Internet note to: [email protected] Mail your comments to: IBM Corporation, International Technical Support Organization Dept. HZ8 Building 662 P.O. Box 12195 Research Triangle Park, NC 27709-2195 xvi IBM WebSphere Portal V4 Developer’s Handbook 1 Chapter 1. Overview Web developers are facing increasing challenges as more complexity is introduced into Web Applications. At the core of this complexity is the task of integrating all kinds of user interfaces. Portal server technology provides a framework for designing and building these more complex Web-based interfaces. This chapter provides an overview of the WebSphere Portal technology, IBM’s portal tooling, and its use in developing integrated portal applications. A high level overview of the WebSphere Portal concepts integral to development is presented here. In this chapter we explore: The evolution of portals Fundamental Portal concepts and definitions Portal development patterns © Copyright IBM Corp. 2003. All rights reserved. 1 1.1 Portal evolution As J2EE technology has evolved, much emphasis has been placed on the challenges of building enterprise applications and bringing those applications to the Web. At the core of the challenges currently being faced by Web developers is the integration of desperate user content into a seamless Web application and well designed user interface. Portal technology provides a framework to build such applications for the Web. If we take a step back in time to the original PC days when each application took up the entire screen and used all the computer’s resources, the advent of Windows from Microsoft revolutionized the way we interacted with our desktop. A user no longer had to close one application to interact with another. Each application’s content is aggregated to the desktop. This same evolution is taking place on the Web with portal technology. Taking a shorter step back in time to the advent of the Web, initially interaction with the Web involved entering a single URL to access a single Web site much like the single application model of the early PCs. As the Web quickly evolved, so did the associated browser technology such as applets and browser plug-ins for technologies like Java. Unfortunately, these technologies never standardized and made the job of the Web developer very difficult when trying to provide cross- browser implementations. In parallel with these technologies, the desire grew for dynamic content on the Web drove the development of Web servers into application servers that could serve dynamic content and technologies such as JSPs. Support for portals evolved from this application server evolution along with the need to render multiple streams of dynamic content. The early portals fall in the category of roll your own. These are proprietary and specific to each implementation. As these portals grew, so did tooling and frameworks to support the building of new Portals. The main job of a portal is to aggregate content and functionality. Portal servers provide: A server to aggregate content A scalable infrastructure A framework to build portal components and extensions. Additionally, most portals require personalization and customization. Personalization enables the portal to deliver user specific information targeting a user based on their unique information. Customization allows the user to organize the look and feel of the portal to suit their individual needs and tastes. 2 IBM WebSphere Portal V4 Developer’s Handbook WebSphere Portal provides a framework for addressing all these issues along with an open flexible infrastructure for creating many types or portals accessible from a wide variety of devices. 1.1.1 The three generations of portal technology Portals have gone through an evolution process of their own. First generation portals The first portals, known as first generation portals, were focused on providing static Web content, Web documents and live feeds. Examples of first generation Portals are Yahoo!, Lycos and Excite. In a corporate environment, they had a similar objective providing a single interface to corporate information distributed throughout the enterprise. They typically contained information such as company news, employee contact information, company policy documents and other key Web links. Second generation portals Second generation portals focus on specific information and applications. They incorporate the notion of providing services along with the first generation idea of providing content. Another key feature of second generation portals is collaboration. Collaboration portals provide the ability for teams to work in a virtual office. They provide content management services, the mining and organization of related information, along with collaborative services that allow users to chat, e-mail, share calendars and define user communities. Collaborative portals are typically internal corporate portal installations. Third generation portals Third generation portals are intended to address full-function eBusiness. They take portals beyond the corporate boundaries for use by employees, suppliers and customers. A significant addition to this generation of portals is the integration of application servers. This means they provide a single point of integration for content and applications as well as collaborative services. They also provide access from multiple types of devices to address the diverse user communities in need of services. They offer the richest set of content and application choice via a single user interface to a diverse community including browsers and pervasive devices.They also provide automated personalization via rules engines. The key to their further evolution is their open framework for common services. WebSphere Portal is a third generation portal providing organizations with a portal framework that connects a wide range of enterprise content and Chapter 1. Overview 3 applications. It provides a high degree of integration technologies based on the J2EE platform. Its extensible architecture provides a scalable framework allowing adaptation to the changing needs of business. 1.2 Overview By definition, a portal provides access to content, data and services located throughout the enterprise. The key building block to the Portal technology is a portlet. Portlets are an encapsulation of content and functionality. They are reusable components that combine Web-based content, application functionality and access to resources. Portlets are assembled onto portal pages which, in turn, make up a portal implementation. Portlets are similar to Windows applications in that they present their contents in a window-like display on a portal page. Like a Windows application, the portlet window has a title bar that contains controls, allowing the users to expand (maximize) and shrink (minimize) the application. Portlets function within the Portal Framework where Windows applications function in the Windows framework. From the portal user’s perspective, a portlet is a window on a portal site that provides access to a specific service or resource. A portal also provides the runtime environment for the portlets that make up the portal implementation. This runtime environment is the portlet container.The portlet container, in the J2EE sense of a container, is responsible for instantiating, invoking and destroying portlets. The portlet container provides the lifecycle infrastructure for the portlets. Portlets rely on their container to provide the necessary infrastructure to support a portal environment. The portal infrastructure provides the core sets of services required by the portlets including: Access to user profile information A framework for portlets to participate in events A framework to communicate with other portlets Access to remote content Access to credentials A framework for storing persistent data. WebSphere Portal provides these services through an extensible framework for integrating enterprise application, content, people and processes. WebSphere Portal provides services for single sign-on, security, Web content publishing, search, personalization, collaboration, enterprise application integration, support for mobile devices and site analytics. Self-service features provided by WebSphere Portal allow users to interact with each other through collaboration, 4 IBM WebSphere Portal V4 Developer’s Handbook publishing and sharing documents. Users are also provided interfaces for personalizing their own content through managing their own view of the portal, managing their own profiles and choosing their look and feel. 1.2.1 WebSphere Portal architecture The WebSphere Portal platform is positioned to enhance the WebSphere family of products, providing tooling for aggregating and personalizing Web-based content and making that content available via multiple devices. WebSphere Portal takes advantage of the strong platform provided by WebSphere Applications Server. WebSphere Portal finds its roots in Apache Jetspeed. Jetspeed is an Open Source implementation of an Enterprise Information Portal, using Java and XML. Jetspeed was created to deliver an Open Source Portal that individuals or companies could use and contribute to in an Open (Source) manner. Soon after creation, it became apparent that Jetspeed was going to become an “engine” for Web applications. That, however, was far beyond the scope of the original project. Around that time, there were many discussions on the mailing list that spawned the Turbine project based on technology donated by Jon Stevens/Clear Ink. Turbine is now the Web Application framework that Jetspeed shares with many other Web applications. Building on the Jetspeed implementation, WebSphere Portal provides an architecture for building and running portal applications. The overall WebSphere Portal Architecture can be seen in Figure 1-1. WebSphere Portal provides services for Authentication and Authorization through the WebSphere Member Services. The core of WebSphere Portal architecture is composed of the Presentation Services, the portal infrastructure, and the portal services. Chapter 1. Overview 5 Portlet Data Search Content Access Credential Vault Translation Transcoding Page Aggregation J2EE APIs Web Services Portlet Container Portlet API JMS EJB JDBC Administration Collaboration Authorization Organizer Remote Portlet Requedst Web Clipper Tag Libraries Portlet Proxy Themes and Skins Local Portlet Authentication JCA Internet or Intranet Content Enterprise Data and Applications WebSphere Member Services WebSphere Portal Database UDDI Directory Figure 1-1 WebSphere Portal Architecture Presentation services WebSphere Portal presentation services provide customized and personalized pages for users though aggregation. Page content is aggregated from a variety of sources via content and applications. The portal presentation framework simplifies the development and maintenance of the portal by defining the page structure independent of the portlet definition. Portlets can be changed without impact to the overall portal page structure. The Portal engine WebSphere Portal provides a pure Java engine whose main responsibility is to aggregate content from different sources and serve the aggregated content to multiple devices. The Portal engine also provides a framework that allows the presentation layer of the portal to be decoupled from the portlet implementation details. This allows the portlets to be maintained as discrete components. Figure 1-2 shows the WebSphere Portal Engine Components. 6 IBM WebSphere Portal V4 Developer’s Handbook Portal Engine Full Page View Portal Servlet Aggregation Modules User Bean Portal Registry portlets Authentication Server ser vices Trust Association interceptor LDAP Directory Access Control Relational Database Management System Figure 1-2 WebSphere Portal Engine The Authentication Server is a third party authentication proxy server that sits in front of the Portal engine. Access to portlets is controlled by checking access rights during page aggregation, page customization, and other access points. The Portal Servlet is the main component of the portal engine. The portal servlet handles the requests made to the portal. The portal requests are handled in two phases. The first phase allows portals to send event messages between themselves. In the second phase, the appropriate Aggregation Module for the requesting device renders the overall portal page by collecting information from all the portlets on the page and adding standard decorations such as title bars, edit buttons, etc. Portlet container Portal Services are components WebSphere Portal uses to extend the portal functionality. Key functionality is provided with WebSphere Portal for personalization, search, content management, site analysis, enterprise application integration collaboration and Web services. Portlets can access these services via their container. Portal infrastructure The WebSphere Portal infrastructure is the framework that provides the internal features of the portal. Functionality such as user and group management via self registration, as well as portal administration, are provided by the Portal infrastructure. Chapter 1. Overview 7 User and Group Management The WebSphere Portal infrastructure provides facilities to allow user self management along with enterprise integration with user directories such as LDAP or database structures. Security services As WebSphere Portal runs within the WebSphere Application Server platform, it makes use of the standard Java Security APIs to provide authentication. The WebSphere Portal is configured so that incoming requests pass through an authentication component such as WebSphere Application Server, WebSEAL (a component of SecureWay®) or other proxy servers. A user’s authorization for a particular resource such as page or a portlet is handled by the portal engine. User Beans are provided to allow programmatic access to the User information for use within portlets. Page transformation WebSphere Transcoding Technology is integrated with WebSphere Portal to transform the portal markup produced by WebSphere Portal to markup for additional devices such as mobile phones and PDAs. Portal services Portal services are built-in features the WebSphere Portal provides to extend and enhance the full portal solution. These services are provided via the Portlet container as seen in Figure 1-1 on page 6. Among the services are: Personalization The IBM WebSphere Personalization functionality enables advanced personalization capabilities. Base customization, such as choosing which portlets are desired on a page, is accomplished by the user via administration functionality. Advanced personalization via rules engines, user preferences and profiles is accomplished by the provided personalization services. Content Management WebSphere Portal provides services to facilitate connections to content management sources. Built-in support is provided for several common content types such a as Rich Site Summary (RSS), News Markup Language (NewsML) and Open Content Syndication (OCS) along with most XML and Web browser markup. Search WebSphere Portal offers a simple search service. The Portal Search capability enables search across distributed html and text data sources. The search can crawl a Web site and is configured so as to force it to follow several layers in a site or to extend beyond several links in a site. 8 IBM WebSphere Portal V4 Developer’s Handbook Furthermore, IBM Extended Search and Enterprise Information Portal can be fully incorporated into the portal environment. These search engines are industrial-strength tools that provide federated searches across numerous data sources. Site Analysis You can take advantage of the underlying WebSphere Application Server technology and Site Analyzer to provide information about Web site visitor trends, usage and content. This detailed information can then be used to improve the overall effectiveness of the site. Collaboration Collaboration services are provided by WebSphere Portal through a set of pre-defined portlets. These portlets allow for team-room function, chat, e-mail, calendering and many other collaborative technologies. Web Services WebSphere Portal provides services for exposing and integrating portlets as remote portlets hosted on another portal platform via Web Services technology. The entire process of packaging and responding to a SOAP request is hidden from the developer and the administrator. 1.2.2 WebSphere Portal tooling WebSphere Portal and WebSphere Portal Toolkit, along with their prerequisite products, provide the basic tooling for developing and deploying portals and their associated portlets. WebSphere Portal WebSphere Portal contains built-in support for portlet deployment, configuration, administration and communication between portlets. WebSphere Portal provides the framework for building and deploying portals and the portal components, portlets. Portlet content is aggregated by the WebSphere Portal to provide the desired portal implementation. WebSphere Portal makes use of the WebSphere Application Server technology to provide a portal platform. WebSphere Portal Toolkit The WebSphere Portal Toolkit is provided with WebSphere Portal and provides an environment for developing portal using WebSphere Portal. The WebSphere Portal Toolkit is a plug-in for WebSphere Studio Application Developer (WSAD) Chapter 1. Overview 9 or WebSphere Studio Site Developer (WSSD) which adds the portal development environment. The WebSphere Portal Toolkit provides the ability to quickly create complete, MVC-compliant portlet applications. It also provides intuitive editors for working with the deployment descriptors required by your portlet applications. Furthermore, it allows you to dynamically debug your portlet applications. The WebSphere Portal Toolkit is explored in detail in Chapter 3, “Using the Portal Toolkit” on page 119. 1.3 WebSphere Portal WebSphere Portal takes advantage of the WebSphere Application Server base, making use of its J2EE services. WebSphere Portal itself installs as an Enterprise application in WebSphere Application Server. 1.3.1 Portal concepts Portlet A portlet is an application that displays page content. Portlet application Portlet applications are collections of related portlets and resources that are packaged together. All portlets packaged together share the same context which contains all resources such as images, properties files and classes. Important also is the fact that portlets within a portlet application can exchange messages. Page A portal page displays content. A page can contain one or more portlets. For example, a World Market page might contain two portlets that displays stock tickers for popular stock exchanges and a third portlet that displays the current exchange rates for world currencies. To view a page in the portal, you select its place from the place selector and then click the page within the place. Place or page group A place is a collection of portal pages. The portal administrator can create places, determine which portal pages are in the each place, and give the appropriate users authority to access the place and pages. 10 IBM WebSphere Portal V4 Developer’s Handbook Layout The page layout defines the number of content areas within the page and the portlets displayed within each content area. In many cases, the portal administrator defines the page layout. The administrator can permit specified users or user groups to change the page layout to reflect individual preferences. If you have authority to change a page, use the Layout page in the Work with Pages place to alter the page layout. Permissions Each portal page is subdivided into one or more content areas. Each content area can contain one or more portlets. The portal administrator or a user who has authority to manage a page can control whether others who have authority to edit the page can move, edit or delete the content areas and the portlets on the page. Permissions is the term for controlling those settings. If you have authority to make changes to a portal page, use the Permissions page in Work with Pages place to set the permissions for the page. Themes Themes represent the overall look and feel of the portal, including colors, images and fonts. There are several default themes provided with the standard installation of WebSphere Portal. Each place in the portal may have a different theme associated with it, thereby creating the appearance of virtual portals. Skins The term skin refers to the visual appearance of the area surrounding an individual portlet. Each portlet can have its own skin. The skins that are available for use with a portlet are defined by the portal theme that is associated with the place. The portal administrator or the designer determines the theme for places and the available skins for the theme. The administrator can permit specified users to change the skins to reflect individual preferences. If you have authority to make changes to a portal page, use the Skins page in Work with Pages to set the skins for portlets. 1.3.2 Portlets The base building blocks of a Portal are the portlets. Portlets are complete applications following the Model-View-Controller design pattern. Portlets are developed, deployed, managed and displayed independent of all other portlets. Portlets may have multiple states and view modes along with event and messaging capabilities. Based on the J2EE container model, portlets run inside the Portlet Container of WebSphere Portal analogous to the way servlets run inside the Servlet Container of WebSphere Application Server. Portlets are a Chapter 1. Overview 11 special subclass of HTTPServlet that includes properties and functionality that allows them to run inside the Portlet Container. Though portlets actually run as servlets under the WebSphere Application Server, they cannot send redirects or errors to the browser directly, forward requests or write arbitrary markup to the output stream. All communication back to the end user from a portlet is done via the aggregation modules. To understand the portlet model used by WebSphere Portal, let us take a step back and examine the Flyweight pattern. This pattern is used by WebSphere Portal as the design pattern for the portlet model. The Flyweight pattern The Flyweight pattern was originally presented by the GofF or Gang of Four (Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides) in E.Gamma, et al., Elements of Reusable Object-Oriented Software, Addison Wesley, 1995. Flyweight is a structural pattern used to support a large number of small objects efficiently. Several instances of an object may share some properties. Flyweight factors these common properties into a single object, thus saving considerable space and time otherwise consumed by the creation and maintenance of duplicate instances. Key to the Flyweight Design Pattern is the fact that the objects share some information. It is then possible to greatly reduce the overhead problem and make the presence of so many objects possible. The flyweight object is a shared object that can be used in multiple contexts at the same time; the object functions independently in each context. The state shared by the objects falls into two categories, intrinsic and extrinsic. Intrinsic state State stored in the object and independent of object’s context. Thus the information is sharable across the objects. The more stateless and intrinsic information shared between objects in the flyweight, the better. This allows for greater savings in memory, since less context information needs to be passed around. Extrinsic state State that depends on a single request varies with the objects context and therefore cannot be shared. This information must be stateless and determined by context, having no stored values, but values that can be calculated on the spot. Client Objects are responsible for passing the extrinsic state to the object when the object needs it. This separation into extrinsic and intrinsic information allows great numbers of similar objects to exist, differing only in the context in which they exist. 12 IBM WebSphere Portal V4 Developer’s Handbook The different components involved in the Flyweight Pattern are the Flyweight, the ConcreteFlyweight, the UnsharedConcreteFlyweight, the FlyweightFactory and the Client. The Flyweight: the shared object with intrinsic state. The flyweight declares an interface through which flyweights can receive and act on intrinsic data. ConcreteFlyweight: implements the Flyweight interface and adds storage for the intrinsic state. UnsharedConcreteFlyweight: the flyweight interface enables sharing but does not enforce it. Not all flyweights are shared. It is common for UnsharedConcreteFlyweight objects to have ConcreteFlyweight objects as children at some level in the hierarchy. FlyweightFactory: serves to dispense particular flyweights that are requested. When a Flyweight with certain properties is requested, it checks to see if one already exists, and if so, returns that flyweight. If the requested flyweight does not exist, it creates the requisite flyweight, stores and returns it. Client: when creating an object, a client must assign a flyweight to it, so it asks the FlyweightFactory for a particular flyweight, receives that flyweight, and creates a reference to it in the object it is creating. The parameterization of portlets is based on the flyweight pattern, the Portlet Container being the Flyweight Factory. Portlets Portlets are invoked by the portlet container. Every portlet has to inherit from the abstract org.apache.jetspeed.portlet.Portlet class, either by deriving directly from it, or by using one of the abstract portlet implementations. A portlet is a small Java program that runs within a portlet container. Portlets receive and respond to requests from the portlet container. There is ever only one portlet object instance per portlet configuration in the Web deployment descriptor. There may be many PortletSettings objects parameterizing the same portlet object according to the Flyweight pattern, provided on a per-request basis. When the portal administrator deploys a new portlet or copies an existing one, PortletSettings are created. A Portlet parameterized by its PortletSettings is referred to as a concrete portlet. The settings of concrete portlets may change at runtime since administrators modify the portlet settings by using the configuration mode of the portlet. The PortletSettings initially contain the elements defined in the deployment descriptor and are changeable by the portlet administrator. Chapter 1. Overview 13 Portlet Deployed Portlet Settings PortletData Portlet Placed on a page Persistent Data PortletSession Portlet Accessed by a user Transient Data Figure 1-3 Portlet Parameterization objects Additionally, users can have personal views of concrete portlets. Therefore, the transient PortletSession and persistent concrete PortletData carries vital information for the portlet to create a personalized user experience. When a portlet is added to a page, PortletData is created to parameterize the portlet. The PortletData can only be accessed by the portlet itself, for example when changing a list of desired stocks to watch in a stock portlet. A concrete portlet in conjunction with portlet data creates a Concrete Portlet Instance. PortletData scope depends on the scope of the page. If the administrator places the portlet on a page, the portlet data contains data stored for the group of users associated with the page. If a user puts the portlet on the page, the portlet data contains data for that user. For more information on the portlet data object, refer to Chapter 2, “Portlets” on page 31. Finally, when the user initially accesses a portlet, a PortletSession is created. The portlet session stores transient data associated with an individual use of the portlet. The concrete portlet instance parameterized by the PortletSession is referred to as the User Portlet Instance. 14 IBM WebSphere Portal V4 Developer’s Handbook Portlet Portlet Settings Portlet Portlet Portlet Settings Portlet Settings Concrete Portlet PortletData Portlet Portlet Portlet Settings Portlet Settings PortletData PortletData Concrete Portlet Instance PortletSession Portlet Portlet Portlet Settings Portlet Settings PortletData PortletData PortletSession PortletSession User Portlet Instance Figure 1-4 The Portlet Parameterization 1.3.3 Portlet Modes Portlet Modes are a facet of the Portal display model. Modes allow the portlet to display a different “face” depending on its usage. There are four modes: View Initial face of the portlet when created. The portlet normally functions with this face. Help If the portlet supports the help mode, a help page will be displayed for the user. Edit This mode allows the user to configure the portlet for their personal use, for example, specifying a city for a localized weather forecast. Configure If provided, this mode displays a face that allows the portal administrator to configure the portlet for a group of users or a single user. Chapter 1. Overview 15 1.3.4 Portlet states Portlet states determine how the portlet is displayed in the portal. The state of the portlet is stored in the PortletWindow.State object and can be queried for optimizing processing based on state. The three states of a portlet are: Normal Portlet is displayed in its initial state as defined when it was installed. Maximized The portlet view is maximized and takes over the entire body of the portal replacing all the other portal views. Minimized Only the portlet title bar is visible inside the portlet page. 1.3.5 Portlets and the Model-View-Controller (MVC) design pattern Because portlets must be capable of supporting multiple views for multiple devices, the key design pattern used for portlets is the model-view-controller (MVC) design pattern. This design pattern contains three entities: The model, the data source to be retrieved for the portlet Model data for a portlet is typically retrieved from an external data source and loaded into Java display beans, or arrives formatted in an XML document. The view or views, the output mechanism used to display the data of the portlet Display views are typically implemented as either JSPs, more typically used when the data model is implemented in Java beans, or XSLT style sheets when the incoming data is formatted in an XML document. The controller, which joins the selected view to the data and conducts the operation of the portlet. The controller selects the view for display based on the target device or browser, and then passes the data model to the view. The view extracts the specific display data, formats the data for the browser and renders its output to the browser as part of the portal aggregation of portlet outputs. For portlet development, the MVC pattern has the following characteristics: The portlet is only responsible for calling the right controller, depending on the markup supported by the client. Connectors are responsible for accessing content sources. Typically, there is one connector per content source type, for example, one connector for POP3 access and one for file-based cache. 16 IBM WebSphere Portal V4 Developer’s Handbook Models represent the content as retrieved through the connector. A model is independent of the presentation. Controllers can be used to provide markup-specific content (HTML, cHTML, or WML). In the MVC structure, there is a distinct separation of data from presentation along with a controller component for managing the interaction between the data (model) and the presentation or view. The controller knows the environment in which the application is invoked, gathers information from the data object to be displayed, and then applies the appropriate view to render the data using the markup language appropriate for the current device. A comprehensive discussion of the MVC pattern and how it is applied to portlets is provided in Chapter 2, “Portlets” on page 31. See Section 2.3, “MVC architecture” on page 33 for details. 1.3.6 WebSphere Portal Runtime: the Portlet Container WebSphere Portal is a J2EE application based on the servlet technology. In fact, portlets inherit from HTTP Servlet in the Java hierarchy, providing the servlet functionality. The WebSphere Portal portlet container is not, however, a standalone container as is the servlet container. The portlet container is a thin layer implemented on top of the servlet container designed to reuse the functionality provided by the servlet container. The Portlet API provides the standard interfaces for accessing the services provided by the portlet container. The Portlet API is explored in detail in Chapter 2, “Portlets” on page 31. As previously mentioned, the Portlet Container is implemented on top of the servlet container and thus the Portal API is very similar to the servlet API. 1.3.7 Portlet lifecycle Much like the Servlet Container, the Portlet Container manages the portlet lifecycle along with providing services to the portlets running in the container. The portlet container loads and instantiates the portlet class. This can happen during startup of the portal server or later, but no later than when the first request to the portlet has to be serviced. Also, if a portlet is taken out of service temporarily, for example while administrating it, the portlet container may finish the lifecycle before taking the portlet out of service. When the administration is done, the portlet will be newly initialized. Chapter 1. Overview 17 During the portlet lifecycle, the portlet container invokes the following methods on the Portlet class (subclass of a the Portlet Adapter class) on behalf of user requests as seen in Figure 1-5. init() initConcrete() login() service() – doView() – doEdit() – doHelp() – doConfigure() logout() destroyConcrete() destroy() User page request Portal page returned User logout Portal terminated Portlet init() ; initConcrete() Portlet login() PortletPageListener beginPage(); Portlet service();endService(); PortletPageListener endPage() Portlet markup returned Portlet User login Portal Portlet Container Portlet Initailized Portlet logout() Portlet destroy(); destroyConcrete() Figure 1-5 Portlet Lifecycle The portlet container calls the following methods of the abstract portlet during the portlet's life cycle: init() The portlet is constructed after portal initialization and initialized with the init() method. The portal always instantiates only a single instance of the portlet, and this instance is shared among all users, exactly the same way a servlet is shared among all users of an application server. 18 IBM WebSphere Portal V4 Developer’s Handbook initConcrete() After constructing the portlet and before the portlet is accessed for the first time, the portlet is initialized with the PortletSettings. This is known as the concrete portlet. service() The portal calls the service() method when the portlet is required to render its content. During the lifecycle of the portlet, the service() method is typically called many times. For each portlet on the page, the service() method is not called in a guaranteed order and may even be called in a different order for each request. destroyConcrete() The concrete portlet is taken out of service with the destroyConcrete() method. This can happen when an administrator deletes a concrete portlet during runtime on the portal server. destroy() When the portal is terminating, portlets are taken out of service, then destroyed with the destroy() method. Finally, the portlet is garbage collected and finalized. 1.3.8 Portlet events and messaging Many portals today display static content in independent windows. The ability for portlets to interact within a portal is key to giving a portal a “live” feeling. In “live” portals, quite often the user is presented with one portlet on a page that presents a choice of data, a list of stocks for example, and choosing from the list causes another portlet to be updated with the details of the choice. This type of list-detail processing via multiple portlets is done with portlet events and messaging. This same type of process could be accomplished using a single portlet but consider the example of a stock list, stock details and news associated with the stock. Giving the user this function via three portlets allows the user to customize the portal experience by choosing which information about the chosen stock is displayed by simply adding the associated portlet to the page. In portlet messaging, one portlet typically detects a condition and formats a message as a result of that condition, then sends the message to the receiver. The receiving portlet receives the message from the event handler and processes the message as you would expect. Portlets can both send and receive messages. Portlets communicate using portlet actions and portlet messages. For example, an account portlet creates a portlet action and encodes it into the URL that is rendered for displaying transactions. When the link is clicked, the action listener Chapter 1. Overview 19 is called, which then sends a portlet message to send the necessary data to the transaction detail portlet. There are some basic rules to portlet messaging: Portlets in different applications can only communicate through default portlet message objects. Default portlet message objects can only carry strings. In order for portlets to communicate through custom messages, they must be part of the same portlet application. WebSphere Portal uses a unique class loader for each portlet application to provide security between applications. The message is typically a custom Java object unique to the application. Since messaging portlets must share this message object, they must share the same class loader and therefore they must be part of the same portlet application. For performance reasons, portlets that communicate through messaging must reside on the same page. Since only one page is displayed at a time, there is little need to send messages to portlets not currently displayed. Portlet events contain information about an event to which a portlet might need to respond. For example, when a user clicks a link or button, this generates an action event. To receive notification of the event, the portlet must have the appropriate event listener implemented within the portlet class. Action events: generated when an HTTP request is received by the portlet container that is associated with an action, such as when the user clicks a link. Message events: generated when another portlet within the portlet application sends a message. Window events: generated when the user changes the state of the portlet window. The portlet container delivers all events to the respective event listeners (and therefore the portlets) before generating any content to be returned to the portal page. Should a listener, while processing the event, find that another event needs to be generated, that event will be queued by the portlet container and delivered at a time point determined by the portlet container. It is only guaranteed that it will be delivered and that this will happen before the content generation phase. There is no guarantee for event ordering. Once the content generation phase has started, no further events will be delivered. For example, messages cannot be sent from within the service, doView or other content generation methods. Attempts to send a message during the content generation phase will result in an org.apache.jetspeed. portlet.AccessDeniedException. 20 IBM WebSphere Portal V4 Developer’s Handbook The event listener is implemented directly in the portlet class. The listener can access the PortletRequest. It is important to understand the underlying event handling and message processing to ensure delivery of all send messages. The portal event handling and message processing sees four steps executed in the following order. 1. Processing all action events The user makes a request of the portal, the portal receives the request and decodes the action URI sent by the client and propagates an action event to the appropriate portlet. The receiving portlet’s action listener is called to process an action event. An appropriate time to send messages to other portlets is during the processing of the action event. 2. Processing all message events If a message is sent to a portlet, the portlet’s message listener is called to process the message. Since portlets can send multiple messages and send messages as a result of receiving a message, this process continues until there are no more messaging events pending. Cyclical messaging is prevented by the WebSphere Portal architecture. 3. Processing all window events Sizing operations such as maximize, minimize and restore, along with the portlet’s ability to request a specific size, causes multiple window events to be sent to all portlets affected by the sizing activity. This processing of window events continues until there are no more window events pending. 4. Portlet rendering process Upon completing the event processing in the order specified above, the portal aggregator begins calling each container on the page being displayed, causing its contents to be rendered. The rendering process is explored in detail in “Page aggregation” on page 22. When aggregation is complete, the page is returned to the user. Important: It is important to note that events are not processed in the last step of the process, page rendering. If a message is sent by a portlet during rendering, the message will not be delivered or processed. This is a result of the fact that the event queue is held in the portlet request and at the time of rendering, the portlet request is no longer available. Therefore, if portlet interaction is desired, portlet messages must be sent during the first three steps of the event and aggregation process. Chapter 1. Overview 21 1.3.9 Page aggregation Portals allow users to choose sets of portlets they would like to work with and provide a framework for displaying those portlets in a consistent fashion. A defined set of applications, which should be presented in a common environment, is referred to as a page. Page aggregation is the process that collects information about the user’s choices, the device being used and the selected portlets, then takes that information and combines it to create a display that is appropriate for the device. The aggregation process involves three basic steps: Collecting user information Selecting the active applications Aggregating the output Once the active page is determined, the layout of this page is used to aggregate the content of the defined applications, arrange the output and integrate everything into a complete page. Basic Portal Page Layout can be seen in Figure 1-6. Rendering of page components is done using JSPs, images, style sheets, and other resources. These resources are located in the file system in a path-naming convention that the portal server uses to locate the correct resources for the client. For a complete discussion of portal layout and customization, see Chapter 6, “Portal customization” on page 261. WebSphere Portal provides dynamic aggregation of pages from page descriptors held in the portal database. Collecting user information During the collection of user information, the following information is collected: 22 User The user is authenticated at login and the user identification is available throughout the session. Client The user’s device is determined by information contained in the request header. Once determined, this information is also stored in the session. Markup The markup is associated with the device category. There are currently three markups defined, HTML, cHTML and WML. New markup scan be added via the Markup Manager Portlet. IBM WebSphere Portal V4 Developer’s Handbook Markup version The version for the supported markup. For example, ie5 for the Internet Explorer family of browsers, ns for the Netscape family of browsers. Language The portal determines the language to be displayed via the following algorithm. If the user is logged in, the portal user interface is displayed in the preferred language of the user. If no preferred language is set, the portal UI is displayed in the language set by the client browser if available. If no browser language is available, the portal UI is displayed in the default language set for the portal. Portlets not supporting any of the above scenarios display their UI in the portlet’s default language. Page/page groups The access control list determines which pages and page groups a user has access to. Theme The name of the active theme is taken from the currently active page group. Screen Depending on the interactions of the user with the portal, different screens are presented. The screen holds the output of the portlets on a page. Selecting the active applications During this phase of aggregation, the portal determines the active applications or portlets to be displayed. When the portal receives a request, it determines the active place and the active page for the current user. Aggregation then continues with the rendering of the page. Aggregating the output Once the active page is determined, the portal uses the layout of the page to aggregate the content of the defined applications, to place the output and build the complete page. A page contains components such as row or column containers that contain other components or portlets. Figure 1-6 shows the layout of a portal page. Chapter 1. Overview 23 Banner @ My Portal Server Home Page 1 Page 2 Screen Components RowContainer ColumnContainer ColumnContainer Control Control Figure 1-6 Portal Page Layout A portal page is made up of the following elements. 24 The portal window The content inside the displayed window. It is made up of the banner and the portal page. The banner The top area of the window that holds the company information, the greeting, a page selection box, tabs to select the current page in the page group being displayed and some additional controls for interacting with the portal such as logging in, logging out and help. The screen Hold the output of the portlets on the currently selected page. The layout is determined by its row and column containers. A row A container inside a page that allows portlets to be arranged in a horizontal format. IBM WebSphere Portal V4 Developer’s Handbook A column A container inside a page that allows portlets to be arranged in a vertical format. A control The frame around the portlet is constructed by the frame. It builds the bar above the portlet output including buttons to control the state and view of the portlet. Themes and skins Window and component layouts can be controlled by themes and skins. Themes refer to the window templates. Themes represent the look and feel of the portal, including fonts and colors, and is also used to render to portal banner. Skins refer to the component templates. Skins use the theme name to select the graphics that match the theme colors. Templates Aggregation uses the concept of templates to perform window, screen and component layout. When a corresponding part needs to be rendered, a template loader will load the requested template. If the requested template can’t be found, the default template will be used. A template consists of the template class that controls the rendering, the localization and the launch of the template JSP. The template JSP performs the actual rendering. There are three types of templates: Window templates The Window template is responsible for the layout of the parts of the banner area and the placement of the screen. You can change, for example, the navigation tab location via the window template. Screen templates The Screen template is responsible for the layout and the content of the screen, the portion of the portal page containing the output of the portlets. Component templates Component templates are responsible for rendering the component itself and for starting the rendering of its children components. The children of container components (row and column) may be other containers or controls. The child of a control will always be a single portlet. Page aggregation processing The rendering process is a domino process starting with the root container. The root container triggers the rendering of all the child components in the page hierarchy as seen in Figure 1-7. Rendering the screen triggers the aggregation of a page and its portlets. The pageRender tag in the screen starts the rendering process. If no portlet is maximized, then the pageRender tag calls the RootContainer. Chapter 1. Overview 25 The Root Container holds all the containers and controls for this page. The pageRender tag tells the Root Container to invoke the rendering of all its children. Since the Root Container is used only as a starting point for the aggregation, it does not render itself and therefore is not visible on the screen. Each child of the Root Container invokes its template which is responsible for rendering all the content of its child. If the child contains further child components the componentLoop and componentRender tags execute the rendering of all these components one at a time. Each component invokes its own template which in turn invokes more components until the leaf of each branch is reached. Thus, control moves between component classes and their respective JSPs. Each component writes its content to the servlet output stream. When a control is reached, it invokes the rendering of the portlet, which adds its output to the output stream via its rendering. When the entire tree has been traversed, the output stream is closed and the output is sent back to the requesting client. Page Descriptor Column Container <Page Render Tag/> Root Control Portlet Control Portlet Control Portlet Control Portlet Row Container Column Container Portlet Rendering RowContainer.jsp ColumnContainer.jsp Customizable Aggregation Objects Figure 1-7 Page Aggregation 26 IBM WebSphere Portal V4 Developer’s Handbook Control.jsp 1.4 Portlet solution patterns Enterprise Resource Planning (ERP) and Customer Relationship Management (CRM) systems are excellent candidates for portlets because efficient, personalized access to these functions provide measurable returns on your portal investment. WebSphere Portal includes portlets that help you access a variety of ERP and CRM systems. At the time this book is written the portlet catalog on the IBM Portal Web site contains 55 portlets in the ERP section alone. Enterprise Applications running on a backend or host system are another group of candidates for portlets, especially when the portal addresses the business-to-employee pattern and you want to provide a common working environment to your users, whatever application and system they may need for their work. There are many ways to perform application integration in a Web environment. Not all of them are based on portlets and amongst the portlet-based solutions, several different architectural approaches can be applied. Depending on technical circumstances, the given time frame and the goals of the integration, typically different approaches may be combined in one portal solution. We try to list some of the patterns you might think of. One way we can differentiate is along the line of shrink-wrapped versus roll-your-own. Customizable portlets from a vendor In this pattern, a portlet is provided that can be installed in Portlet Server and, after a configuration effort, the system or application in question can be accessed through the portal. Often, such a portlet is delivered by the vendor of the system that should be accessed. Both the Host On-Demand portlet and the Host Publisher portlet we use in the following examples are of this type. Custom developed portlets This pattern comes into play when either no vendor offers a portlet for the requested application, or the requested level of functionality, usability, accessibility or security is not met by the existing portlets. Another reason might be that you want to combine information or functionality of multiple applications seamlessly into one portlet. Most probably, this integration will include using the Java Connector Architecture (JCA). JCA is a standard architecture for integrating J2EE applications with Enterprise Information Systems that are not relational databases. Each of these systems provides native APIs for identifying a function to call, specifying its input Chapter 1. Overview 27 data, and processing its output data. The goal of the JCA is to achieve an independent API for coding these functions. JCA also defines a standard Service Provider Interface (SPI) for integrating the transaction, security and connection management facilities of an application server with those of a transactional resource manager. Thus, JCA is a standards-based approach to managing connections, transactions, and secure access to enterprise application systems. IBM’s JCA connectors provide access to systems such as SAP, People Soft, CICS®, and IMS™. Leveraging its CrossWorlds acquisition, IBM will also develop and integrate JCA connectors to many other systems. Another way to look at portlets for application integration is from a topology point of view. Client to remote application In this pattern, used by IBM Host On-Demand (see Chapter 12, “Host Integration portlets” on page 785), the portlet is just a bootstrap to allow the client to get in touch with the requested system or application, and Portal Server is the framework for the user interface. This implies that normally, an applet is involved which makes a direct network connection to a remote system. Figure 1-8 Portal Solutions - client to remote application 28 IBM WebSphere Portal V4 Developer’s Handbook Portlet to remote application This is the topology most likely used if you write your own application integration portlet. Access to the requested application or information is gained through standardized interfaces such as JCA connectors, JDBC and JMS, or by using a proprietary API provided by the application that is to be integrated (for example SAP Business Connector). Figure 1-9 Portal Solutions - portlet to remote application Portlet to Web application In this pattern, most of the work is done in a Web application. A sample of this pattern is IBM Host Publisher; see Chapter 12, “Host Integration portlets” on page 785 for details. Also, if you write a Web application using the JCA or EJB and create a portlet interface to it, you follow this pattern. Chapter 1. Overview 29 Figure 1-10 Portal Solutions - Portlet to Web Application 30 IBM WebSphere Portal V4 Developer’s Handbook 2 Chapter 2. Portlets This chapter provides details on the Portlet lifecycle, Portlet API and deployment concerns.The goal of this chapter is to provide you with the ability to not only design and build dynamic portlet applications, but also recognize opportunities to portalize existing applications and services. At the end of this chapter, you should be able to work with the Portlet API to design and build new portlet applications. You will have the requisite skills to deploy new applications as well as existing portalized applications. The WebSphere Studio Application Developer environment is covered in Chapter 3, “Using the Portal Toolkit” on page 119 and as such will not be discussed here. In this chapter, all development and deployment information will be development environment independent. This chapter discusses the following topics: MVC Model 2 Architecture Servlets vs. Portlets Portlet Deployment Portlet Lifecycle Portlet Hierarchy and API Event Handling Portlet Messaging Portlet Services Portlet JSP API © Copyright IBM Corp. 2003. All rights reserved. 31 2.1 What is a portlet? A portlet is a server side application that runs in the context of the WebSphere Portal Server. It inherits from the javax.servlet.http.HttpServlet class and as such is treated as a servlet by the application server. The portlet is executed inside a Web container managed by the application server. In the Portlet API, this container is referred to as the Portlet container. Note: It is not possible to directly execute the portlet functionality by addressing the portlet via http. Though a portlet may provide dual functionality as both a servlet and a portlet, it is certainly a best practice to keep these Controller functions separate. A portlet is visible on a portal page as a single small window, of which each portal page may have many. The portlet is the content inside the window, not the window itself. The window is defined by the selected skin. For more information on skins, refer to Chapter 6, “Portal customization” on page 261. 2.2 Basic portlet terms In order to fully understand some of the introductory topics, it is necessary to define a few of the most basic terms used when discussing portlets. Portlet window This is the window that surrounds the portlet, including the title bar and any border images. State This is the current state of the portlet window. Valid states are Normal, Minimized and Maximized. Mode This defines the current condition of the portlet. The modes that are available for any particular user depend on the permissions for that user, the device they are using to access the portlet and the configuration and implementation of the portlet. Note: All portlets support the default mode, view. 32 IBM WebSphere Portal V4 Developer’s Handbook The following portlet modes are supported: View. When a user is simply viewing the portlet, likely with other portlets on the page, it is in view mode. Edit. When the user selects the Edit button to change some configuration information, the portlet is in edit mode. Users only have access to the edit mode if they have been granted edit access by the administrator. Configure. Configure mode is conceptually similar to edit mode in that it is used to adjust the configuration of the portlet. However, only users with manage permissions on a portlet have access to the Configure mode. In practice, the average user may have edit permissions on a portlet to change certain personal settings such as user IDs and passwords. Typically, only administrators would have manage permissions on a portlet so they could adjust non-user specific settings such as server names, etc. The actual implementation of the edit and configure modes, however, is entirely up to the portlet developer. Help. The Help mode is used to present help information. 2.3 MVC architecture To help you understand the role of a portlet and to help prepare you for effective and well-designed portlet development, a review of the Model View Control (MVC) architecture is necessary. This section will review in brevity the MVC Model 2 architecture. In the simplest of forms, the MVC model 2 architecture is illustrated in Figure 2-1. Chapter 2. Portlets 33 Control Servlet Bean Client JSP Model View Figure 2-1 Simple MVC architecture 2.3.1 Standard MVC architecture The Model View Control architecture is concerned with separation of responsibilities. The objective, no matter how it is applied or to what type of application, is to segregate a system into components. Each component should be small, identifiable, self-contained and reusable. These components are identified by the role they play in the system. Each role in that system may have several classes working in conjunction to achieve the goal of that role. This section will cover the three roles of MVC: Model, View and Control. Though the MVC architecture was originally applied to Swing applications, it has gained popularity and widespread acceptance throughout the servlet community. This section is technology-independent, but will use the servlet technology to demonstrate the application of MVC. Model This component is responsible for encapsulating all the business logic required by the system. It must be independent of the other components in the system. To achieve this objective, it must be able to retrieve the data required to complete the business rules data by itself or accept very generic parameters. Furthermore, it must be able to return the results in a generic form that any potential view component could use. In a typical servlet environment, the model is represented by one or more Java beans, EJBs or other Java classes. 34 IBM WebSphere Portal V4 Developer’s Handbook View This component is responsible for creating a presentation resource for the results of the Model component. Like all MVC components, the view must be independent of the other components in the system. Its success or failure must not depend on the success or failure of the model component. In practice, several different view components may be developed in order to create a dynamic, complete and possibly multi-purpose application. In a typical servlet environment, the view is created using Java Server Pages. Control At the heart of the MVC architecture is the Controller component. Each client request of the system is routed through the Controller class. Its responsibility is threefold. First, it should evaluate the validity of the request, including the user’s state and any parameter information passed as part of the request. The Controller then decides which model component has the requisite functionality to satisfy the business requirements of the request. Once the Model component has completed its work, the Controller is then responsible for deciding which appropriate view component to use to present the results back to the client. If either the Model or View components fails, the Controller is responsible for either attempting to satisfy the request in another fashion or deciding on an appropriate View component capable of presenting an error message. In a typical servlet environment, the servlet itself plays the role of Controller. 2.3.2 Portlet MVC architecture The MVC architecture can be applied as a design pattern to any system needing to achieve separation of responsibilities. In fact, you will see as you read through this redbook that the Portal Server itself is architected in this way. Furthermore, several of the benefits of the portlet architecture are available to you only if you employ a good MVC design. Model The Model in a portlet application is not necessarily unique from the model in any other Java server side application.The Model represents business logic and should not be concerned with the Controller or the View. The Controller could be a servlet, portlet, or simple Java class. The View could be a JSP or even simple HTML. In theory then, provided that existing applications employ solid MVC practices, porting the functionality to WebSphere Portal should not require any changes to the logic. However, in practice, there are always applications that lack this foresight. The rich API covered later in this chapter will arm you with the tools to tackle this situation. Implementing a rigid commitment to the MVC architecture now will conserve an enormous amount of effort in later migrations or maintenance duties. Chapter 2. Portlets 35 View Like the servlet MVC implementation, the View is traditionally implemented using JSPs or simple HTML. However, because the HTML the View returns will be aggregated, it must not contain page-level tags and must be very aware of the environment in which it is executing. Furthermore, the Portlet API provides tag libraries that aid in creating dynamic view resources for the portlet environment. Control The Controller is responsible for determining the requested mode, executing an appropriate model and selecting the correct view. The portlet class itself acts as the Controller. Instead of determining the request method as in servlets, portlets need to determine the mode the user has requested. In a normal presentation, where a page is built with several portlets on it, the mode is View. The user, with appropriate permissions, may click the Edit button in order to perform some edit functionality. In this case, the mode is Edit. WebSphere Portal also supports Help and Configure modes. 2.3.3 Portlet MVC sample In the simplest of portlet applications, the MVC architecture would be applied as in Figure 2-2. Note that Figure 2-2 does not reflect the architecture of the Portal Server, simply the portlets executed by the server in any given single request. t es qu e r WebSphere Portal Portlet Portlet Bean Client re sp on se JSP Aggregated JSP Figure 2-2 Simple portlet MVC architecture 36 IBM WebSphere Portal V4 Developer’s Handbook Portlet Bean JSP Bean JSP 2.4 Servlets versus portlets Those with a servlet background will find many similarities when first working with portlets. This section will address some of the more important conceptual differences between servlets and portlets. When designing your portlet applications, the most important factor to initially consider is the fact that unlike servlets, portlets are only a small piece of a large presentation. Servlets have the luxury of knowing they will be the only presentation resource returned to the client at any given time. Portlets, on the other hand, must understand that the presentation resource they return will be aggregated into a larger resource returned to the client. As a result, they are forced to consider constraints such as screen real estate, portlet interactivity, and events, as well as overall performance. Real estate Portlets can access a variety of information through the API to help it understand its current condition in the portal. The PortletState informs the portlet if the user has requested that the portlet be minimized, maximized or restored (normal). A portlet should attempt to tailor the content it returns in accordance with the requested state. For example, if the user has maximized the portlet window, the content returned should adequately fill the portal page. However, if the user has requested that the portlet be minimized, there is no need to return any content. It is important to remember that the portlet is simply deciding not to return content; it is still executed and any business logic encapsulated in the model will still be performed. It is not possible to dynamically change the state of the portlet except during event-handling. Page aggregation Though a servlet may be a single piece of a much larger Web application, at any given point in time, only a single servlet is fulfilling a user’s request. This provides a great deal of predictability: as the master Controller, it can guarantee what is executed and returned to the client. This is not true of portlets. Each portal page is potentially the aggregation of several portlets. Furthermore, when a servlet executes and returns content to the user, it can be sure that the content it returns will not be affected by any other servlet in the system. This is not true of portlets. A portlet has the ability to write markup to the top of the page even though its normal content is placed inside a cell in a table. This provides a mechanism to include JavaScript functionality the portlet may need. Be aware, however, that as one portlet has that ability, so do all. As such, you must properly encode variable names and functions. Chapter 2. Portlets 37 This functionality must be used with care since there is no inherent mechanism for one portlet to control the presence or absence of another portlet on a page, and as such it cannot reasonably predict what other page-level code may be present. Inter-portlet communication Servlets have the ability to share data through a variety of scopes but since they are executed serially by the client, they cannot interact with each other during a single request. Because portlets are pieces of a larger portal, they have the ability to communicate with other portlets and to be affected by other portlets in a single request. This inter-portlet communication provides a way to create a dynamic portlet application crossing multiple portlets on the same page. For example, one portlet can inform other portlets in the same portlet application or the same page that a user has performed some action. The listening portlets can then alter their presentation, perform alternative logic or otherwise change their behavior. Event handling In the servlet architecture, events are represented via HTTP methods. For example, when a user submits a form, the doPost method is called. The portlet event model, however, closely mirrors the traditional Java event model in that portlets implement appropriate interfaces and are notified by the Portal Server when these events are fired. For example, when a user clicks a button, an action event is generated and sent to the registered listener. The Portlet API also provides WindowEvents and MessageEvents. Security Servlets execute in a neutral environment and are inherently responsible for validating the user’s authenticity and/or authority to make a specific request. This is traditionally a function of the Controller role. A portlet, on the other hand, operates only in the context of the portal server and cannot be called directly. The Portal Server is responsible for authentication and for authorizing all user access. Therefore, portlets can be reasonably assured that authentication and authorization have been performed prior to their execution. They may, however, perform some authorization in order to tailor content to a specific user or role. With servlets, authentication is a daily concern of developers; it is an option for portlet developers. 38 IBM WebSphere Portal V4 Developer’s Handbook 2.5 What is a portlet application? A portlet application is a group of logically associated portlets. At a minimum, a portlet application defines a single portlet, such as in weather portlet application. In practice, the application may contain several portlets such as the exchange2000 portlet application, which contains five portlets as illustrated in Figure 2-3. Portlets defined in the same application may share configuration parameters set in the deployment descriptor or by the administrator at runtime. They also have the ability to communicate with each other with custom messages. Portlet Applications are defined in the deployment descriptors at development time and cannot be created dynamically by the administrator. From an administrative perspective, portlet applications allow repetitive administrative tasks to be completed on a group of portlets instead of on individual portlets. From a development perspective, portlet applications allow developers to provide for deployment all the portlets needed to achieve a business requirement and to ensure at a minimum that all these components are installed into the Portal Server. Figure 2-3 A portlet application with multiple portlets Chapter 2. Portlets 39 2.6 Portlet deployment When a portlet is installed into the portal server, the deployment information is contained in two deployment descriptors. The web.xml deployment descriptor is used by the WebSphere Application server to register the portlets being deployed. The application server is not aware of the portlet hierarchy and is simply installing a Web application containing servlets. The portlet.xml deployment descriptor is used by the portal server to retrieve parameters and to set the initial configuration. When the portlet application is deployed, it is deployed as a Web archive (war), not an enterprise application (ear). When the war file is deployed, the portal server actually creates an associated ear folder in the WebSphere\AppServer\installedApps directory. The new ear folder will contain the original name of the war file with _WPS_PA_191.ear appended to the end of the name of the war file. The last number indicates the order in which the portlet application was installed. The war file that was deployed is placed into the ear file with a META-INF folder. This folder contains the application.xml deployment descriptor, the ibm-application-ext.xmi and the Manifest.MF files. All these files are generated by the portal server when the application is installed. Abstract and concrete portlet applications The portlet.xml deployment descriptor is used by the portal server to identify the abstract and concrete portlet applications you wish to deploy. An abstract portlet application contains one or more abstract portlets. A concrete portlet application contains one or more concrete portlets. The abstract application is used as a foundation for concrete applications. The combination of an abstract application and configuration parameters creates a concrete application. Each portlet.xml may only define a single abstract portlet application. However, any number of concrete applications may be defined based on the single abstract application. The concrete applications are the applications presented in the portal server administration. They are the actual applications available to the users. This allows the same application to be deployed repeatedly with different parameterization, effectively creating multiple applications. 40 IBM WebSphere Portal V4 Developer’s Handbook abstract portlet application abstract portlet 1 abstract portlet 2 concrete portlet application 1 concrete portlet 1 concrete portlet 2 concrete portlet application 2 concrete portlet 2 concrete portlet 3 abstract portlet 3 Figure 2-4 Abstract and concrete relationship in a single portlet.xml Certain configuration parameters are set at the abstract level while others are set at the concrete level. As expected, parameters set at the abstract level affect each concrete application. The parameters and configuration information unique to each concrete application are represented in a PortletApplicationSettings object. Parameter and configuration information unique to each portlet is represented in the PortletSettings object. When the portlet is actually placed on a page, it is parameterized by a PortletData object. When a user logs on and accesses a portlet, it is associated with a session object. This sequence is represented in Figure 2-5. Chapter 2. Portlets 41 PortletSettings portlet PortletSettings concrete portlet concrete portlet ta Da let t r Po concrete portlet instance PortletData concrete portlet instance n essio letS t r o P Port letS essio n user portlet instance user portlet instance Figure 2-5 Portlet parameterization 2.6.1 web.xml The web.xml defines the Web application being deployed. This section will detail the required elements of the web.xml when deploying a portlet application. For details on all of the elements of the web.xml deployment descriptor, refer to http://java.sun.com/j2ee/tutorial. Example 2-1 provides an example web.xml document. To keep this section simple, the deployment descriptors will define only a single portlet in the application. Example 2-1 Simplest web.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app id="WebApp"> <display-name>HelloWorld</display-name> <context-param> <param-name>webmaster</param-name> <param-value>the webmaster</param-value> </context-param> <servlet id="Servlet_1"> <servlet-name>HelloWorldPortlet</servlet-name> <servlet-class> com.ibm.itso.ral.portlets.HelloWorldPortlet 42 IBM WebSphere Portal V4 Developer’s Handbook </servlet-class> <init-param> <param-name> init_param1 </param-name> <param-value> An initialization parameter </param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>HelloWorldPortlet</servlet-name> <url-pattern>/HelloWorldPortlet/*</url-pattern> </servlet-mapping> </web-app> DOCTYPE required This will be the same for each and every web.xml deployed. This tag defines the DTD that is to be used when this document is parsed. Only one is allowed. web-app required This is the top-level tag wrapping the entity of the web.xml. Only one is allowed. – id required This attribute identifies the web-app in the application server but is not seen in the portal environment. display-name required Though this name is never seen in the portal environment, it will be seen in the WebSphere Administrator’s console Event Message screen when the Web module is loaded. Only one is allowed. context-param optional This element provides an opportunity to set context parameters that will be shared by all portlets deployed via this Web application. Every portlet subsequently based on this web.xml will share access to the context parameters via the PortletContext object. There is no limit on the number of context parameters that may be set. These parameters cannot be changed at runtime by the administrator. For more information on parameters, see “Parameter summary” on page 54. param-name required Indicates the name of the parameter. This name is used in code to retrieve the parameter value. For a summary of the various parameters set in the deployment descriptors see “Parameter summary” on page 54. Chapter 2. Portlets 43 param-value required The String value held by the parameter. servlet required This tag wraps the definition of the servlet class. There must be one or more of these tags. – id required This provides an identifier for the defined servlet. This ID will be used in the portlet.xml to refer to the defined class. The ID must be unique within the Web application only. servlet-name required This name is not used by the portlet environment. servlet-class required The full class name must be provided. This class must be accessible either in the deployed war, via the application server library or through the classpath. init-param optional This element provides an opportunity to set parameters that will be shared by all portlets based on this servlet. These parameters are available in code through the PortletConfig object. There is no limit on the number of init parameters that may be set. These parameters cannot be changed at runtime by the administrator. For a summary on the various parameters set in the deployment descriptors, see “Parameter summary” on page 54. param-name required Indicates the name of the parameter. This name is used in code to retrieve the parameter value. param-value required The value held by the parameter. servlet-mapping required Though this element is not used by the portal environment, it is a required element of the web-app element and therefore must be included. servlet-name required This is required and must be the same as the servlet name defined in the servlet element. 44 IBM WebSphere Portal V4 Developer’s Handbook url-pattern required This tag is required and may not be empty. The URL pattern is not used in the portal environment. There are numerous other elements in traditional web.xml, though they are not required in the portal environment. 2.6.2 portlet.xml The portlet.xml elements are defined by the portlet_1.1.dtd which can be found in the WebSphere\PortalServer\app\wps.ear\wps.war\dtd directory. Figure 2-2 displays a simple portlet.xml. Example 2-2 portlet.xml deployment descriptor <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE portlet-app-def PUBLIC "-//IBM//DTD Portlet Application 1.1//EN" "portlet_1.1.dtd"> <portlet-app-def> <portlet-app uid="DCE:d798f9c6c:1" major-version="2" minor-version="1"> <portlet-app-name>HelloWorld application</portlet-app-name> <portlet id="HWPortlet_1" href="WEB-INF/web.xml#Servlet_1" major-version="3" minor-version="2"> <portlet-name>HelloWorld portlet</portlet-name> <cache> <expires>30</expires> <shared>yes</shared> </cache> <allows> <maximized/> <minimized/> </allows> <supports> <markup name="html"> <view output="fragment"/> <configure/> <edit/> <help output="document"/> </markup> <markup name="wml"> <view/> </markup> </supports> </portlet> </portlet-app> <concrete-portlet-app uid="DCE:d798f9c6c:1.1"> <portlet-app-name>HelloWorld application</portlet-app-name> <context-param> Chapter 2. Portlets 45 <param-name>context_param1</param-name> <param-value>A context parameter</param-value> </context-param> <concrete-portlet href="#HWPortlet_1"> <portlet-name>HelloWorld portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>HelloWorld</title> <title-short>Hello</title-short> <description>A simple hello world portlet.</description> <keywords>Hello World simple</keywords> </language> <language locale="it"> <title>ciao mondo</title> <title-short>ciao</title-short> <description>Un portlet semplice del mondo di ciao. </description> <keywords>Ciao mondo semplice.</keywords> </language> <language locale="es"> <title>hola mundo</title> </language> <config-param> <param-name>config_param1</param-name> <param-value>A configuration parameter</param-value> </config-param> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> DOCTYPE required This will be the same for each and every portlet.xml deployed. This tag defines the DTD that is to be used when this document is parsed. Only one is allowed. portlet-app-def required This is the top-level tag which encapsulates all abstract and concrete portlet application definitions. It is required and not more than one is allowed. portlet-app required This tag is used to define the abstract portlet application. This abstract application will be used as a basis for the concrete portlet applications defined later in the descriptor. Only one portlet-app tag is allowed per portlet.xml and only one portlet.xml is allowed per war file. Therefore, each war file may only deploy a single abstract portlet application. 46 IBM WebSphere Portal V4 Developer’s Handbook – uid required This ID uniquely identifies this abstract application in the portal server. This ID must be unique throughout the entire portal environment. For guidelines on ensuring the ID is unique, refer to “UID guidelines” on page 55. This ID will be used if the portlet application is updated. Once the ID is determined, it should not be changed between iterations. Doing so will cause updates to fail. The ID may contain any combination of letters and characters to a maximum length of 255. – major-version optional An optional tag only used by administrators to track releases and not used in the portal. Must be a number; only one is allowed. If this attribute is not supplied, the major-version will always be 0. If this attribute is supplied, the minor-version must also be included or the default value of 0 will be assumed. – minor-version optional An optional tag only used by the administrators to track releases and not used in the portal. Must be a number; only one is allowed. If this attribute is not supplied, the minor version will be 0. If this attribute is supplied, the major-version must also be included or the default value of 0 will be assumed. portlet-app-name required Only one is allowed. Since only concrete portlet applications are visible in the portal, this name is visible in the portal environment when the full information for the portal application is requested on the Manage Portlet Applications portlet. This name need not be unique. portlet required One or more of these tags is required. This tag defines the abstract portlets contained in the abstract portlet application. Each portlet tag maps to a single servlet defined in the web.xml. There is a one-to-one relationship between the servlets defined in the web.xml and the abstract portlets defined in the portlet.xml. You may not map two abstract portlets to the same servlet. Therefore, if there are two servlets defined in the web.xml, there will be two abstract portlets defined in the portlet.xml – id required This ID must be unique within the abstract portlet application only. This ID will be used by the concrete portlets to create a link to the abstract definition. It may be any combination of letters and numbers to a maximum of 64 characters. Chapter 2. Portlets 47 – href required This tag creates the link between the abstract portlet and the servlet defined in the web.xml. The link is formatted as in Example 2-3 where Servlet_1 is the id defined in the <servlet id> tag of the web.xml. Example 2-3 href syntax href="WEB-INF/web.xml#Servlet_1" – major-version optional An optional tag only used by the administrators to track releases. Not used in the portal. Must be a number and only one is allowed.If this attribute is supplied, the minor-version must also be included or the default value of 0 will be assumed. – minor-version optional An optional tag only used by the administrators to track releases. Not used in the portal. Must be a number and only one is allowed. If this attribute is supplied, the major-version must also be included or the default value of 0 will be assumed. portlet-name required Defines the name of the abstract portlet. This name will only be seen in the Show Info screen of the Manage Portlet Application portlet, not during normal portlet administration or execution. Must be unique within the abstract portlet application only. cache optional This tag indicates the type and level of caching this portlet will perform. If this tag is included, it must contain the expires and shared elements. If the cache element is not included, the default values for expires and shared are 0 and no, respectively. expires required Indicates in seconds when the cached content should be considered expired. – 0 indicates the content immediately expires and should always be refreshed – -1 indicates the content does not expire.The content will not be refreshed once the portlet is initialized. – Any other value measures the cache in seconds. 48 IBM WebSphere Portal V4 Developer’s Handbook shared required Indicates if the content is to shared among all users or if a cache must be maintained for each user. Use the no option carefully as a large cache will result. Valid values are yes or no. allows required This tag indicates the portlet states that are supported by this portlet. The normal state is assumed and may not be unsupported. The other valid values are: – maximized optional When selected, the portlet will take ownership of the portal screen and other portlets will not be able to return content for inclusion in the portal page. Each portlet on the page will have the opportunity to execute any listeners it implements, such as PortletPageListener. However, the service method, and by extension doView, of the other portlets will not be executed. – minimized optional When selected, the portlet will be displayed as a title bar only. Any listeners implemented by the portlet will be executed but the portlet’s service (and by extension doView) method will not. – detached, moving, resizing, closed optional Though these are valid values according to the DTD, they have no corresponding support in the portal server. As such, including or omitting them will have no effect at this point. supports required This element indicate which markup languages this portlet can render its content. It is required and at least one markup may be supported. markup required This tag provides a definition for a single markup that this portlet will support. Each markup that is to be supported is defined in a markup element – name required This attribute identifies the name of the markup defined in this element. Valid strings are html, wml, chtml. If custom markups have been defined, they too will be valid. view required Indicates that at a minimum, this portlet supports the view mode. This is required for all markup types. Chapter 2. Portlets 49 – output optional This attribute indicates the type of output the portal server should expect from this portlet. Valid values are document and fragment. • Document : not used in V 4.1.2 • Fragment: all HTML portlets should use this value. configure optional Indicates this portlet supports configure mode. As with the view mode, it may specify as output fragment or document. This tag has no effect on non-HTML markup types. The developer is required to implement configure support by including a doConfigure method in the portlet. This tag simply instructs the portal server to include the appropriate link on the portlet title bar. edit optional Indicates this portlet supports edit mode. As with view mode, it may specify as output fragment or document. This tag has no effect on non-HTML markup types. The developer is required to implement edit support by including a doEdit method in the portlet. This tag simply instructs the portal server to include the appropriate link on the portlet title bar. help optional Indicates this portlet supports the help mode. As with view mode, it may specify as output fragment or document. This tag has no effect on non-html markup types. The developer is required to implement help support by including a doHelp method in the portlet. This tag simply instructs the portal server to include the appropriate link on the portlet title bar. concrete-portlet-app required This element defines the concrete portlet application to be deployed into the portal server. One or more of these elements is required. This concrete application is based upon the abstract portlet application defined earlier in the portlet.xml. A concrete portlet application is not required to contain all of the portlets defined in the abstract application. However, it may not define more portlets than the abstract application. Each concrete portlet contained in the concrete application maps to one and only one abstract portlet. An abstract portlet may not be mapped twice in the same concrete application. – uid required This UID must be unique throughout the entire portal environment. Refer to “UID guidelines” on page 55 for more information on ensuring that UIDs are unique. This UID will be used by the portal server when the portlet is updated or deleted. If the ID changes between iterations, the original concrete application will not be updated. Instead, a new concrete 50 IBM WebSphere Portal V4 Developer’s Handbook application will be installed, resulting in multiple concrete applications. Generally, once the ID has been determined, it should not be changed. The ID may contain any combination of letters and characters to a maximum length of 255. portlet-app-name required This is the application name that will be used in the portal server. When the war file is deployed, each of the concrete applications will be listed. This is the name that will appear in that list. This name need not be unique in the portlet.xml or the portal server. However, deploying more than one concrete portlet application with the same name may cause some administrative confusion. If two or more applications are deployed with the exact same name, only one will be initially active. The other application must be manually activated. In practice, when there is a one-to-one relationship between the abstract and concrete portlet applications, the application names are often the same. This name may contain any combination of letters and numbers to a maximum length of 255 and only one is allowed per concrete application. context-param optional This element provides an opportunity to set parameters that will be shared by all concrete portlets defined in the concrete portlet application. These parameters are available in code through the PortletApplicationSettings object. There is no limit on the number of context parameters that may be set. Be aware that these parameters may be changed at runtime by the administrator via the Manage Portlet Applications portlet. For a summary on the various parameters set in the deployment descriptors, see “Parameter summary” on page 54. param-name required Indicates the name of the parameter. This name will be seen by the administrator if they decide to work with these parameters at runtime. This is also the name used in code to retrieve the parameter value. The name has a maximum length of 255. param-value required The value intended to be held by the parameter. This value can be changed at runtime by the administrator. The maximum length of the parameter value is 1048576. concrete-portlet required This element wraps the definition of the concrete portlet being deployed in this concrete application. Any number of concrete portlets may be deployed Chapter 2. Portlets 51 up to the number of abstract portlets defined in the abstract portlet application. – href required This attribute creates a link between the concrete portlet and the abstract portlet. The syntax dictates that the portlet ID defined in the abstract application be prefixed with a # symbol as illustrated in Example 2-4. Example 2-4 Concrete portlet href <concrete-portlet href="#HWPortlet_1"> portlet-name required This tag indicates the administrative name of the portlet. This name is not the title of the portlet and will not be seen by the average end user. This name need not be unique in the portlet.xml or the portal server. However, take care to properly name your portlets to prevent confusion. If two or more portlets are deployed in the same portlet.xml with the exact same name, only one will be initially active. The name may be any combination of characters to a maximum length of 255. default-locale required This element indicates which language is the default language for this concrete portlet alone. This setting will not override the user’s preferred locale or locale settings provided by the client browser. If the client’s locale cannot be determined, this value is used. Also, if the portlet does not support the locale requested by the user, this default locale is used instead. The value must be a recognized country code including (if appropriate) any variants. This value cannot be changed at runtime by the administrator. language required At least one language block must be included. Though not required, it is a best practice to ensure that at a minimum, the default locale is implemented in a language block. In practice, a language block should be provided for each language this portlet intends to support. ideally this includes all ten group 1 languages. Only the languages defined in the portlet.xml will be available. Though the strings can be changed, there is no mechanism to add new languages at runtime. – locale required This attribute indicates the locale being defined by this language block. The value must a recognized country code, including any applicable variants. 52 IBM WebSphere Portal V4 Developer’s Handbook title required This tag specifies the language specific title of this portlet. This title will be seen in the title bar of the portlet at runtime.This value may be changed at runtime by the administrator. The maximum length of the title is 255 characters. title-short optional This tag specifies the language specific short title of the portlet. The maximum length of the short title is 128. description optional This description is used in several places in the portal. For example, in the Edit Layout and Content portlet, hovering over the portlet will display the description in a hover box. The maximum length for the description is 1024 characters. keywords optional This tag specifies the language specific keywords of the portlet. The maximum length of the keywords is 1024 characters. config-param optional This element allows parameters to be passed to the concrete portlet. Unlike context and servlet-config parameters, these parameters are not shared between portlets. Any number of portlet-config parameters may be supplied. The values can be changed at runtime by the administrator via the Manage Portlets portlet. These parameters are accessed in code via the PortletSettings object. For a summary on the various parameters set in the deployment descriptors, see “Parameter summary” on page 54. param-name required Indicates the name of the parameter. This name will be seen by the administrator if they decide to work with these parameters. This is also the name used in code to retrieve the parameter value. The name has a maximum length of 255. param-value required The value intended to be held by the parameter. This value can be changed at runtime by the administrator. The maximum length of the parameter value is 1048576. Chapter 2. Portlets 53 2.6.3 Parameter summary There are four types of parameters that can be specified in the deployment descriptors Parameter Name Location Visibility Programmatic Access Run Time Accessibility ContextParam web.xml - web app definition Every portlet deployed in the .war PortletContext.get InitParameter() Read-only Init-Param web.xml servlet definition Each portlet based on the particular servlet PortletConfig.getI nitParameter() Portlet.getInitPara meter() Read-only ContextParam portlet.xml concrete app definition All portlets defined in a single concrete app PortletApplication Settings. getAttribute() Read/Write ConfigParam portlet-xml concrete portlet definition Individual Concrete portlets PortletSettings.get Attribute() Read/Write 2.6.4 Web.xml and Portlet.xml relationship The relationship between servlets, abstract portlets and concrete portlets can be best described in Figure 2-6 on page 55. Note that some required elements have been omitted for clarity. 54 IBM WebSphere Portal V4 Developer’s Handbook <web-app id="WebApp"> <display-name>SimplePortlet</display-name> <servlet id="Servlet_1"> <servlet-name>Portlet</servlet-name> <servlet-class>com.yourco.portlets.Portlet</servlet-class> </servlet> <servlet id="Servlet_2"> <servlet-name>AnotherPortlet</servlet-name> <servlet-class>com.yourco.portlets.AnotherPortlet</servlet-class> </servlet> <servlet-mapping> ... </servlet-mapping> <servlet-mapping> ... </servlet-mapping> </web-app> <portlet-app-def> <portlet-app uid="DCE:4604:1"> <portlet-app-name>SimplePortlet application</portlet-app-name> <portlet id="Simple_Portlet_1" href="WEB-INF/web.xml#Servlet_1"> <portlet-name>SimplePortlet portlet</portlet-name> </portlet> <portlet id="Another_Portlet_1" href="WEB-INF/web.xml#Servlet_2"> <portlet-name>New Portlet</portlet-name> </portlet-app> <concrete-portlet-app uid="DCE:4604:1.1"> <portlet-app-name>Simple Portlet application</portlet-app-name> <concrete-portlet href="#Simple_Portlet_1"> <portlet-name>SimplePortlet portlet</portlet-name> </concrete-portlet> </concrete-portlet-app> <concrete-portlet-app uid="DCE:4604:1.2"> <portlet-app-name>Second Simple Portlet Application</portlet-app-name> <concrete-portlet href="#Another_Portlet_1"> <portlet-name>Another Simple portlet</portlet-name> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> Figure 2-6 web.xml and portlet.xml relationship 2.6.5 UID guidelines When determining the UID for either concrete or abstract portlet applications, there are several steps to ensure the ID is guaranteed to be unique throughout the entire portal environment. It is recommended that your organization develop style guidelines to ensure uniqueness in your environment. Chapter 2. Portlets 55 Include the portlet's namespace in the UID, using the same format that is used for Java packages Add some portlet application specific description Add some arbitrary characters to guarantee uniqueness within the namespace, for example: com.ibm.wps.samplet.mail.4969 Add postfixes for the corresponding concrete portlet applications, for example: com.ibm.wps.samplet.mail.4969 2.6.6 Building a war file All the elements of the portlet need to be deployed in a Web archive (.war) file. This file can be created with any zip creation tool, the jar command line utility or the export utility of the WSAD tool. The WSAD environment will be covered in detail in Chapter 3, “Using the Portal Toolkit” on page 119. Each war file should contain elements listed in Figure 2-7. Figure 2-7 Basic WAR contents The source folder is optional and you may choose what source to include for distribution. The webApplication folder is optional and may be used to contain the WEB-INF folder. Alternatively, the WEB-INF folder can placed directly under the root without modification. Generally, it will also contain a JSP folder to hold all JSPs used throughout the entire portlet application. The JSP folder will organize the contained JSPs in folders representing the markup and languages they are intended to support. For example, if a portlet supported HTML, WML and cHTML and provided limited National Language support for HTML requests, the JSP folder would be organized as in Figure 2-8. 56 IBM WebSphere Portal V4 Developer’s Handbook Figure 2-8 WAR structure for a portlet with NLS and Multi-Device support The WEB-INF folder must contain at a minimum the two required deployment descriptors. The web.xml and portlet.xml files must be placed directly under the WEB-INF folder. The classes that make up the portlet application must be stored in one of two locations. Those classes that have been packaged into jar files should be stored in the lib directory. Classes that are not packaged in a jar file are stored in the classes folder with the complete package structure. Both approaches are illustrated in Figure 2-9. Figure 2-9 Storing classes in the WEB-INF folder Once the contents have been organized correctly, you can use the jar command line utility to create the war file. There is no compression requirement for the war file, so you may choose to compress the file or not without affecting deployment. For a complete discussion regarding the jar utility, refer to: http://java.sun.com/docs/books/tutorial/jar/basics/index.html. Chapter 2. Portlets 57 2.6.7 Creating a development environment Though much of your portlet development will be performed in WebSphere Studio Application Developer, this section will guide you through the process of setting up your system for portlet development in a command-line environment. If you will not be compiling classes from the command line, this section may be ignored. In order for your portlets to compile, the following jar files must be added to your classpath. %WAS_HOME%\lib\j2ee.jar; %WAS_HOME%\lib\websphere.jar %WAS_HOME%\lib\app\wpsportlets.jar; %WAS_HOME%\lib\app\wps.jar; %WAS_HOME%\lib\app\portlet-api.jar; If WebSphere is not installed on your system, you must copy the above jar files to your system and set the classpath accordingly. 2.7 Portlet lifecycle This section will explain the portlet lifecycle and when certain objects become available. For a complete discussion on the portlet object, refer to “Portlet” on page 62. The basic lifecycle of each portlet is displayed in Figure 2-10. Though the login and logout methods are part of SessionListener interface, they are covered here as they are usually included in normal portlet implementations. Other listeners are covered in “Listeners” on page 74. 58 IBM WebSphere Portal V4 Developer’s Handbook init initConcrete login* service logout* destroyConcrete destroy Figure 2-10 Basic Portlet lifecyle init(PortletConfig config) This method is called by the portlet container on the abstract portlet when the portlet is first loaded. As with servlets, portlets are loaded when they are first requested. Any subsequent calls to the portlet will not execute this method. Generally, initialization that is applicable to every concrete portlet based on this abstract portlet is placed in this method. If you choose to override this method, at a minimum it should make a call to its parent via super.init(portletConfig). At this point in the portlet lifecycle, no portlet-specific storage objects are available. This includes PortletSession, PortletData, PortletApplicationSettings and PortletSettings. initConcrete(PortletSettings settings) This method is called by the portlet container on the concrete portlet. The initialization code performed in this method is not shared by other concrete portlets even though they may be based upon the same abstract portlet. It is in this method that the PortletSettings object is first available. The PortletSettings encapsulates the concrete portlet configuration parameter information. From the PortletSettings object, the PortletApplicationSettings object is available. The PortletApplicationSettings object encapsulates concrete portlet application context parameters. In this method, no user-specific objects are yet available. Chapter 2. Portlets 59 login(PortletRequest request) If the concrete portlet has been placed on page that requires authorization, the login method is called by the portlet container to associate a user with the portlet. It is at this point that the PortletData object is first available. The PortletSession is created by the container for the registered user at this point and is available in this method via the request object. If the request for the portlet is made by an anonymous user, this method is not called. If this method is not called, a default session object can still be created with no user association, though it may be of little practical use. This method is actually defined in the PortletSessionListener interface which is implemented by the abstract class Portlet. Since your custom portlets will extend from Portlet, it is included in this discussion even though other often used listeners are not. service(PortletRequest request, PortletResponse response) This method is called on each and every request of the portlet. After the portlet has been added to a page and initially accessed by a user, this is the only method that will be called by the portlet container on subsequent requests. Generally, this method will delegate the request to the appropriate do method to render content. At this point, all portlet and, if applicable, user-specific objects are available. logout(PortletSession session) Only when a user specifically selects the Logoff button on the portal is this method called. This method provides you with the opportunity to manage any user-specific information once the user has logged out, and to clean up user-related resources. If the user removes the portlet from their page, the logout method is not called until the user actually logs out of the portal, even though they no longer are accessing the portlet. When the portlet is taken out of service by the Portal server or the administrator, this method will not be called. The PortletSettings object is still available in this method, though the PortletRequest is not. This method is actually defined in the PortletSessionListener interface which is implemented by the abstract class Portlet. Since your custom portlets will extend from Portlet, it is included in this discussion even though other often used listeners are not. destroyConcrete(PortletSettings settings) This method is called when the concrete portlet is taken out of service either through the portal server stopping or the application being uninstalled from the portal server. The portlet container will call each running concrete portlet in the application individually when the application is deleted. In this method, the PortletSettings object is passed in as a parameter and cannot be retrieved from the normal getPortletSettings method. 60 IBM WebSphere Portal V4 Developer’s Handbook destroy(PortletConfig config) The portlet container executes this method on the abstract portlet when the portlet is taken out of service. Since it is executed on the abstract portlet and not the concrete portlets, it is executed only once. This method provides an opportunity to execute cleanup code on each and every concrete portlet in the application derived from this abstract portlet. 2.8 Portlet API Portlets are descendents of HttpServlets and, as such, inherit much of the basic functionality from that class. However, as illustrated in “Servlets versus portlets” on page 37 there are some key differences. This section will introduce many of the key objects in the portlet API. This section is not intended to replace the javadoc, and therefore will discuss the primary function of certain objects and some of their key methods. The complete javadoc for the portlet API can be found in the \WebSphere\PortalServer\app\wps.ear\wps.war\doc\Javadoc\WPS directory. For the most up-to-date API information, refer to: www7b.software.ibm.com/wsdd/zones/portal/ 2.8.1 Hierarchy The abstract class Portlet descends from the HttpServlet interface, as illustrated in Figure 2-11. Note that the package structure indicates the portlet belongs to the org.apache.jetspeed.portlet package. It is important to understand that the WebSphere Portal API and the Jetspeed API are not the same, or even compatible at this time. Figure 2-11 Portlet Hierarchy Chapter 2. Portlets 61 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 lifecycle 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 classes 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 the 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 use 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 62 IBM WebSphere Portal V4 Developer’s Handbook 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 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 V 4.1.2 this method always returns null. Look for updates to this functionality in future releases. Chapter 2. Portlets 63 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 the 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. 64 IBM WebSphere Portal V4 Developer’s Handbook createURI/createReturnURI These methods will create URI object that contains a URL pointing the portlet in particular mode. For more information, see “PortletURI” on page 73. 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 shows the result of most of the methods of the client object when requested via Internet Explorer and a Nokia WAP emulator. Chapter 2. Portlets 65 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. Figure 2-12 Client information displayed on various clients 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 66 IBM WebSphere Portal V4 Developer’s Handbook 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 “PortletContext object” on page 67. 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 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 Portlet Context PortletContext context = getPortletConfig().getContext(); String webmaster = context.getInitParameter("webmaster"); Chapter 2. Portlets 67 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 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 5, “National Language Support” on page 245. 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 the 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 68 IBM WebSphere Portal V4 Developer’s Handbook 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. 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 portlet.xml. getPortletApplicationSettings This method will return the PortletApplicationSettings object discussed in “PortletApplicationSettings object” on page 69. 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. Chapter 2. Portlets 69 getAttribute/setAttribute/removeAttribute are methods that provide access to attributes of the concrete portlet application. 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 user’s 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 places 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 the values into the PortletData object. For example, the HelloWorld portlet uses PortletData to persist the greeting string and the moniker by which the user wishes to be addressed. 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 in to the portal page and opens the Welcome page, he sees the name admin and the greeting hellothere. 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 choose 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"); 70 IBM WebSphere Portal V4 Developer’s Handbook //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 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. Example 2-17 Accessing the PortletLog in PortletAdapter PortletLog log = getPortletLog(); Chapter 2. Portlets 71 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 now 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 illustrates this approach. Minimized, Normal and Maximized are defined as constants in the PortletWindow.State class. 72 IBM WebSphere Portal V4 Developer’s Handbook 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 Chapter 2. Portlets 73 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 78. 2.10 Listeners The event model of the Portal API is very similar to the traditional Java event model. However, there are two main points of distinction. First, there is no need to register listeners. When a portlet is installed, the Portal Server determines the listeners it implements and registers them on behalf of the portlet. Secondly, since the registration is taken care of by the Portal Server, it is not possible to specify which portlets a particular portlet wishes to register for. Therefore, portlets implementing listeners need to carefully plan for receiving unsolicited and unexpected events. There are several listeners defined in the Portal API. The ActionListener is covered in 2.11, “Action event handling” on page 77 and the MessageListener is covered in 2.14, “Portlet messaging” on page 88. 2.10.1 PortletTitleListener This listener allows you to dynamically set the title of the portlet. This listener requires the single method as shown in Example 2-20. This interface is particularly useful when tailoring the title for certain modes or devices. To return a title, simply use a PrintWriter object or include a JSP using the PortletContext object. While the second approach allows you to create a more dynamic title, including images and so forth, you must remain mindful of the limited space in the title bar. Example 2-20 PortletTitlelistener example public void doTitle(PortletRequest request, PortletResponse response) throws PortletException, IOException { PrintWriter out = response.getWriter(); String title = getPortletSettings().getTitle( request.getLocale(), request.getClient()); out.print(title + "(" + request.getMode() + ")"); } 2.10.2 PortletPageListener This interface provides the opportunity to add content to the top and bottom of the aggregated page. Example 2-21 illustrates a simple implementation of the 74 IBM WebSphere Portal V4 Developer’s Handbook PortletPageListener interface. It is important to note that content returned from the beginPage method is not placed at the top of the page but rather at the top of the aggregated content as displayed in Figure 2-13. Example 2-21 PortletPageListener Implementation public class PortletPageListenerExample extends PortletAdapter implements PortletPageListener{ public void beginPage(PortletRequest request, PortletResponse response) throws PortletException, IOException { PrintWriter out = response.getWriter(); out.println("This page contains the PortletPageListener example"); } public void endPage(PortletRequest request, PortletResponse response) throws PortletException, IOException { PrintWriter out = response.getWriter(); out.println("Portions of this page are copyright."); } } Figure 2-13 beginPage and endPage placements The beginPage is a convenient method when you need to include JavaScript functions needed by your portlet. However, be very aware of any content you decide to display in the beginPage method since it may adversely affect the overall aggregation of the page. Furthermore, because the page is aggregated, be sure that any functions or global variables you declare have properly encoded the namespace of the portlet to ensure there are no naming collisions. Use the response.encodeNamespace to do this. Chapter 2. Portlets 75 Restriction: The Home.jsp can choose to cancel calls to the PortletPageListener via the <wps:pageRender includeBeginPage="no" includeEndPage="no"> tag. In this case, your beginPage and endPage methods will not be called. See Chapter 6, “Portal customization” on page 261 for more information. 2.10.3 PortletSessionListener This interface requests that the Portal Server notify the portlet if an authenticated user has accessed the portlet. This interface is already implemented by the PortletAdapter class that is traditionally the parent of most custom portlets. This interface defines the two methods shown in Example 2-22. Figure 2-10 on page 59 illustrates where in the lifecycle of the portlet these methods are called. The functionality of the login and logout methods is detailed in “Portlet lifecycle” on page 58. Example 2-22 PortletSessionListener methods public void login(PortletRequest request) throws PortletException{ ... } public void logout(PortletSession session) throws PortletException{ ... } 2.10.4 WindowListener This interface will notify the portlet that the user has changed the window state. Presently, there are only three supported window states, despite the javadoc. NORMAL, MAXIMIZED and MINIMIZED states are supported. The portlet is notified of these three states through windowMaximized, windowMinimized, and windowRestored, respectively. Though only three states are currently supported, the WindowListener defines methods for windowClosing, windowOpening, windowDetached and windowClosed. This methods are never called by the Portal Server in 4.1.2. However, in order to implement this interface, all seven methods must be implemented even though several will contain empty bodies. Note: You will need to make sure you implement the interface org.apache.jetspeed.portlet.event.WindowListener and not the AWT counterpart since some development environments will offer both. Example 2-23 Implementing the WindowListener public void windowMaximized(WindowEvent arg0) throws PortletException { // Some action can be performed } public void windowMinimized(WindowEvent arg0) throws PortletException { 76 IBM WebSphere Portal V4 Developer’s Handbook // Some action can be performed } public void windowRestored(WindowEvent arg0) throws PortletException { // Some action can be performed } public void windowClosing(WindowEvent arg0) throws PortletException { } public void windowClosed(WindowEvent arg0) throws PortletException { } public void windowDetached(WindowEvent arg0) throws PortletException { } 2.10.5 PortletSettingsAttributesListener The PortletSettings object encapsulates the concrete portlet defined in the portlet.xml. Part of that definition includes configuration parameters that may be declared at deployment time. These parameters can be altered and new one can be added at runtime. The PortletSettingsAttributeListener provides your portlet with a notification if the configuration parameters are changed at runtime. 2.10.6 PortletApplicationSettingsAttributesListener Similar to the PortletSettingsAttributeListener, this listener provides notification when the context parameters of the concrete application have changed, been added or removed. 2.11 Action event handling The event model in WebSphere Portal is very similar to the traditional Java event model. When a portlet wishes to be notified that a user has performed an action, it simply implements the ActionListener correctly and the portal server will take care of calling the appropriate method when the event is generated. Unlike the traditional Java event model, only the portlet generating the event may listen for that event. There will always only be a single listener for any particular ActionEvent. In order to notify other portlets of an event, the listening portlet may choose to send messages. For more information on sending messages, see 2.14, “Portlet messaging” on page 88. When the Portal server services a request, it acts in two distinct phases. The first phase is the event processing phase. All events, including WindowEvents, ActionEvents and MessageEvents are generated, delivered and processed in this phase. Once this phase is complete, the content generation phase begins. Once content generation has begun, no events can be generated. Attempting to generate events during the content generation phase, for example doView, doEdit, etc., will cause an exception. Chapter 2. Portlets 77 2.12 Core event objects This section will cover the objects you will need to work with when managing event handling in action events. 2.12.1 ActionListener The org.apache.jetspeed.portlet.event.ActionListener interface defines a single method to be implemented as illustrated in Example 2-24. Example 2-24 ActionListener Interface org.apache.jetspeed.portlet.event.ActionListener public void actionPerformed(org.apache.jetspeed.portlet.event.ActionEvent event) throws PortletException; 2.12.2 ActionEvent An implementation of the org.apache.jetspeed.portlet.event.ActionEvent interface is passed to the actionPerformed method by the PortalServer when a PortletURI with an PortletAction is executed. The ActionEvent object provides access to the PortletRequest and PortletAction objects as illustrated in Example 2-25. Example 2-25 Working with the ActionEvent public void actionPerformed(ActionEvent event) throws PortletException { PortletRequest request = event.getRequest(); PortletAction action = event.getAction(); } 2.12.3 PortletURI The porletURI represents a URL that can be used to create navigation between modes. The PortletURI can be used to navigate to a previous mode, such as from Edit to View, or to navigate back to the same mode, such as a multi-part form in View or Edit. There is no ability to create a PortletURI object pointing to a mode not yet visited by the user. PortletRequest.createURI returns a portletURI object pointing to the portlet in its current mode. For example, if the portletURI is created in the doView mode, the URL points to the portlet in View. The createReturnURI method returns a PortletURI object pointing to the last mode the portlet was in. This mode is commonly used in the doEdit method when the URI needs to point back to the 78 IBM WebSphere Portal V4 Developer’s Handbook view mode. The edit.jsp would use the PortletURI to bring the user back to the view mode when the edit or configure process has been completed. In order for a portlet to be notified of an event, such as the user clicking a button, the portletURI must contain an associated PortletAction. Typical PortletURI construction and usage is shown in Example 2-26. Example 2-26 Working with PortletURI PortletURI uri = response.createReturnURI(); PortletAction action = new DefaultPortletAction("save"); uri.addAction(action); request.setAttribute("uri", uri.toString()); It is possible to add parameters to the PortletURI object. Parameters added to the PortletURI via code or through a form are accessed in the same way via the portlet request object. This provides a mechanism to pass default values or to pass parameters not displayed in the form. Example 2-27 displays the code for adding a parameter. Be aware that parameters set via the PortletURI are not passed in the traditional HTML syntax. Figure 2-14 shows how parameters are added to the URI. Example 2-27 Adding a parameter to the PortletURi public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { PortletURI viewURI = response.createReturnURI(); PortletAction action = new DefaultPortletAction("save"); viewURI.addAction(action); viewURI.addParameter("Param1", "Param1Value"); request.setAttribute("viewURI", viewURI.toString()); getPortletConfig().getContext().include("/jsp/View.jsp", request, response); } With Parameters /wps/myportal/.cmd/ActionDispatcher/_pagr/104/_pa.104/113/.aref/585309493/.m d/-/.piid/181/.ciid/211/.reqid/-1/PC_181_Param1/Param1Value#211 Without Parameters /wps/myportal/.cmd/ActionDispatcher/_pagr/104/_pa.104/113/.aref/585309493/.m d/-/.piid/181/.ciid/211/.reqid/-1#211 Figure 2-14 PortletURI with and without parameters Chapter 2. Portlets 79 2.12.4 PortletAction and DefaultPortletAction The PortletAction interface is a flag interface in that it defines no methods to be implemented. Therefore, it is not possible to create custom PortletActions. However, the API provides an implementation of the interface in the DefaultPortletAction class. This class implements the PortletAction interface and defines the constructor and three methods listed in Example 2-28. Example 2-28 DefaultPortletAction DefaultPortletAction(java.lang.String name) void addParameter(java.lang.String name, java.lang.Object value) java.lang.String getName() java.util.Map getParameters() In future releases of the Portlet API, the process of adding actions to PortletURI objects will change. The addAction(PortletAction) method will be deprecated and replaced with addAction(String). Since the vast majority of work with PortletActions involves no more than setting a name, this new implementation will be much more convenient. 2.12.5 ModeModifier When a PortletURI is created, it points to a portlet in a particular mode. When that PortletURI is executed and if it contains a PortletAction, it will notify the appropriate listener. If, in the actionPerformed method, you need to redirect the user to a mode other than the one specified, the request.setModeModifier method can be used to redirect the user to another mode. The ModeModifier can only be set during event processing. Calling this method in doView or doEdit will have no effect. There are three possible modes the user can be redirected to. REQUESTED: this ModeModifier will navigate the user to whatever mode was originally set by the PortletURI. Essentially, this is the default. If the ModeModified is changed, it cannot be changed back to REQUESTED. CURRENT: this ModeModifier will keep the user in the current mode. For example, if the user tries to save some information and the actionPerformed determines it is incorrect, setting ModeModifer to CURRENT will return the user to the edit screen. PREVIOUS: this ModeModifier will return the user to the mode the user was in prior to CURRENT regardless of previous ModeModification. Therefore, setting ModeModifer to CURRENT in one event process will not make that mode PREVIOUS in the next event process. The ModeModifer is illustrated in Figure 2-34 on page 87. 80 IBM WebSphere Portal V4 Developer’s Handbook 2.13 Event examples To demonstrate event handling, two examples are presented. The first example is a portlet containing a multi-part form. The second example demonstrates implementing edit or configure functionality in a portlet. 2.13.1 Multi-part form event handling This example illustrates a portlet with a multi-part form that needs to be completed by the user. As the user navigates through the form, the data entered by the user is retrieved, evaluated and stored. If the data is incomplete, the user is presented with an error page. Figure 2-15 on page 84 illustrates the four parts of the form. Throughout the form, the user has the ability to navigate backwards and forwards and to cancel the entire process. This example is intended to display event handling only and as such, persisting the new employee is not included. The form is broken into four JSPs through which the user needs to navigate. Example 2-29 on page 81 shows that there are two important methods in this portlet. Example 2-30 on page 83 displays the EmployeeManager class used to create and populate the Employee bean. doView: the doView method has two main responsibilities. First, it determines which JSP to use next based on a state variable held in the portlet session. Secondly, it creates the necessary PortletURI objects and stores them in the request object to be used by the JSP. The doView creates three different PortletURI objects since some JSPs will have three potential actions generated by the user (Next, Back and Cancel). Each button on the JSPs will have a unique PortletURI and associated action attached to its form. The actionPerformed method will evaluate the action to determine what type of business logic needs to be performed and to determine the next state the user should move to. actionPerformed: the actionPerfomed method has several responsibilities. Initially, it must determine the action that generated the event. If the user has selected Next, the EmployeeManager class is called to strip off the parameters and store an Employee bean in the session object. If any of the parameters is empty, an exception is thrown and the state is set to state0, indicating the error page should be displayed. If the user has selected Back, the actionPerformed determines which state the user should be moved to. Finally, if the user has selected Cancel, the employee object stored in the portletsession is reset and the user is moved to the initial state. Example 2-29 Portlet with a multi-part form public class NewEmployees extends PortletAdapter implements ActionListener{ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { Chapter 2. Portlets 81 String includeFile = "NewUser1.jsp"; String state = (String) request.getPortletSession().getAttribute("state"); if (state == null) { state = "state1"; request.getPortletSession().setAttribute("state", state); } if (state.equals("state0")) { includeFile = "NewEmployeeError.jsp"; } else if (state.equals("state1")){ includeFile = "NewEmployee1.jsp"; } else if (state.equals("state2")){ includeFile = "NewEmployee2.jsp"; } else if (state.equals("state3")){ includeFile = "NewEmployee3.jsp"; } else if (state.equals("state4")){ includeFile = "NewEmployeeSummary.jsp";} request.setAttribute("nextURI", generateURI(response, "next", "next").toString()); request.setAttribute("backURI", generateURI(response, "back", "back").toString()); request.setAttribute("cancelURI", generateURI(response, "cancel", "cancel").toString()); getPortletConfig().getContext().include("/jsp/" + includeFile, request, response); } public void actionPerformed(ActionEvent event) { DefaultPortletAction portletAction = (DefaultPortletAction) event.getAction(); String action = portletAction.getName(); PortletRequest request = event.getRequest(); PortletSession session = request.getSession(); String state = (String) session.getAttribute("state"); if (action.equals("next")) { EmployeeManager.updateEmployee(request); } else if ( action.equals("back")) { if (state == null) state = "state1"; if (state.equals("state0")) state = (String)session.getAttribute("previousState"); else if (state.equals("state2")) state = "state1"; else if (state.equals("state3")) state = "state2"; else if (state.equals("state4")) state = "state3"; session.setAttribute("state", state); } else if ( action.equals("cancel")) { state = "state1"; session.setAttribute("state", state); session.setAttribute("employee", new Employee()); } } public PortletURI generateURI(PortletResponse response, String target, String action) { PortletURI tempURI = response.createURI(); PortletAction tempAction = new DefaultPortletAction(action); tempURI.addAction(tempAction); return tempURI; } 82 IBM WebSphere Portal V4 Developer’s Handbook } Example 2-30 The EmployeeManager class public class EmployeeManager { public static void updateEmployee(PortletRequest request) { String state = (String) request.getPortletSession().getAttribute("state"); if (state == null) state = "state0"; Employee emp = (Employee) request.getPortletSession().getAttribute("employee"); if (emp == null) emp = new Employee(); try { if (state.equals("state1")){ emp.setFname(request.getParameter("fname")); emp.setLname(request.getParameter("lname")); emp.setUid(request.getParameter("uid")); state = "state2"; } else if (state.equals("state2")){ emp.setAddress1(request.getParameter("address1")); emp.setAddress2(request.getParameter("address2")); emp.setCity(request.getParameter("city")); emp.setState(request.getParameter("state")); emp.setZip(request.getParameter("zip")); state = "state3"; } else if (state.equals("state3")){ emp.setSalary(request.getParameter("salary")); emp.setManager(request.getParameter("manager")); emp.setProject(request.getParameter("project")); state = "state4"; } else if (state.equals("state4")){ //submit employee information to admiinstrator -- Not included here emp = new Employee(); state = "state1"; } } catch (Exception e) { request.getPortletSession().setAttribute("error", e.getMessage()); request.getPortletSession().setAttribute("previousState", state); state = "state0"; } request.getPortletSession().setAttribute("state", state); request.getPortletSession().setAttribute("employee", emp); } } Chapter 2. Portlets 83 Figure 2-15 Multi-part form in a single portlet 84 IBM WebSphere Portal V4 Developer’s Handbook NewEmployee1.jsp: this JSP has a simple form; the action is displayed in Example 2-31. Example 2-31 NewEmployee1.jsp <FORM action='<%= request.getAttribute("nextURI") %>' method="POST"> ... fields <INPUT type="submit" name="Next" value="Next"/> </FORM> NewEmployee2.jsp: this JSP makes use of two forms in order to pass an event with a specific action. Example 2-32 illustrates this. Example 2-32 New Employee2.jsp <FORM action='<%= request.getAttribute("nextURI") %>' method="POST"> ... fields <INPUT type="submit" name="Next" value="Next"/> </FORM> <FORM method="POST" action='<%= request.getAttribute("cancelURI") %>'> <INPUT type="submit" name="Cancel" value="Cancel"> </FORM> NewEmployee3.jsp: this JSP makes use of three forms, each utilizing a different PortletURI object. In fact, all three PortletURI objects point to the same URL but have different actions associated with them. Example 2-33 NewEmployee3.jsp <FORM action='<%= request.getAttribute("nextURI") %>' method="POST"> ... fields <INPUT type="submit" name="Next" value="Next"/> </FORM> <FORM method="POST" action='<%= request.getAttribute("backURI") %>'> <INPUT type="submit" name="Back" value="Back"> </FORM> <FORM method="POST" action='<%= request.getAttribute("cancelURI") %>'> <INPUT type="submit" name="Cancel" value="Cancel"> </FORM> 2.13.2 Multi-mode event handling This example will show implementing edit functionality via an InternetMail portlet. The approach presented here can easily be applied to the Configure mode as Chapter 2. Portlets 85 well. If the user has not entered their server information, the View mode will display an informative message telling the user to edit the portlet. Once the user selects the Edit button, the doEdit method creates a PortletURI pointing back to the previous mode, in this case View, using the request.createReturnURI method. This URI is used in the Action attribute of the FORM tag on the edit.jsp page. When the user clicks Save, the actionPerformed is called and the parameters are stored in the portletdata object. If the serverName parameter is empty, the ModeModifier is set to return the user to the edit screen. Otherwise, the user is returned to the View mode as specified by the PortletURI. Example 2-16 illustrates the user flow through this portlet. Figure 2-16 Providing Edit functionality in a portlet 86 IBM WebSphere Portal V4 Developer’s Handbook The code for this portlet is rather simple. This example is intended to illustrate the edit functionality, and therefore the implementation of accessing the mail server has been omitted. Example 2-34 lists the code for this portlet. doView: the doView method in this situation simply evaluates whether the PortletData attributes have been set. If so, it calls the appropriate JSP. If not, it presents an informative message using a PrintWriter. doEdit: when the user clicks the Edit button, the doEdit method is executed. Wen the user has completed setting the parameters, we wish to return them to the previous mode. Usually, the previous mode will be View and technically, the URI could be created there and stored in session or some other persistent scope. However, the edit functionality may be accessed from the Work With Pages place on the Edit Content and Layout page. Therefore, we generate the URI while in the Edit mode and not in View so that the user is always returned to the previous state. Figure 2-17 on page 88 illustrates this. Note that when the edit function is accessed from this location, it is presented in a pop-up window and does not take over the screen as it does in the normal Edit mode. actionPerformed: the actionPerformed method in this portlet performs much in the same way as shown in Example 2-29 on page 81. It retrieves the parameters from the form and attempts to store them in a particular scope, in this case, the PortletData. What is different is the error handling. Whereas the multi-part form handled user errors through state management, this portlet makes use of the built-in functionality. If the user does not enter the server name, the ModeModifer is set to CURRENT. Example 2-34 Implementing edit functionality public class InternetMailPortlet extends PortletAdapter implements ActionListener { public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { String serverName = (String) request.getData().getAttribute("serverName"); if (serverName == null || serverName.equals("")) { response.getWriter().print("Please use the edit button to configure this portlet."); return; } request.getPortletSession().setAttribute("error", ""); getPortletConfig().getContext().include("/jsp/View.jsp", request, response); } public void doEdit(PortletRequest request, PortletResponse response)throws PortletException, IOException { PortletURI viewURI = response.createReturnURI(); PortletAction action = new DefaultPortletAction("save"); viewURI.addAction(action); Chapter 2. Portlets 87 request.setAttribute("viewURI", viewURI.toString()); getPortletConfig().getContext().include("/jsp/Edit.jsp", request, response); } public void actionPerformed(ActionEvent event) { try { PortletRequest request = event.getRequest(); PortletData data = request.getData(); String serverName = request.getParameter("serverName"); String userID = request.getParameter("userID"); String password = request.getParameter("password"); if (serverName == null || serverName.equals("")) { request.getPortletSession().setAttribute("error", "Server Name is required"); request.setModeModifier(ModeModifier.CURRENT); return; } data.setAttribute("serverName", serverName); data.setAttribute("userID", userID); data.setAttribute("password", password); data.store(); } catch (Exception e ){ request.getPortletSession().setAttribute("error", e.getMessage()); } } } Figure 2-17 Accessing Edit mode from page administration 2.14 Portlet messaging One of the most significant advantages of the Portlet architecture is the portlets’ ability to communicate with each other to create dynamic, interactive applications. Portlets can use messages to share information, notify each other of a user’s actions or simply help better manage screen real estate. 88 IBM WebSphere Portal V4 Developer’s Handbook Messages can be sent to all portlets on a page, to a specific named portlet or to all portlets in a single portlet application. To send a message to all portlets on a page, you must send an instance of the DefaultPortletMessage. In order to make full use of this potential, you need to adequately architect the entire portlet application, anticipating inter- portlet communication. Attempting to implement effective and meaningful message after significant portlet development will cause some difficulty and may require the entire application to be overhauled. This is true for several reasons. For example, access to certain storage objects, such as PortletData, is limited to certain modes. Therefore, if the initial design of an application makes significant use of the PorltetData object, implementing messaging later to share configuration information would require a considerable effort. Furthermore, in order to reduce or eliminate code, action event and message event functionality can be combined into a common method. However, to achieve this, it is necessary to consider the information passed via the action or message objects. To help you understand where messaging may fit into your applications, it is important to become familiar with some of the common uses of portlet messaging. This section will present two examples demonstrating common usage of portlet messaging. The first example illustrates how one portlet can use messaging to control the navigation of another portlet. The second example will demonstrate how a portlet can notify other portlets when a user has altered their configuration information using the Edit mode. First, however, you must become familiar with the core objects used in the messaging architecture. 2.15 Core messaging objects This section will cover the objects you will need to work with when messaging between portlets. 2.15.1 MessageListener The org.apache.jetspeed.portlet.event.MessageListener interface must be implemented by the portlets you want the portal server to send messages to. The interface defines the single method listed in Example 2-35. Since the portlet may be notified by more than one other portlet and therefore may receive different types of messages, it should validate the type of message received prior to working with the object. This is illustrated in Example 2-35. Chapter 2. Portlets 89 Example 2-35 Implementing the MessageListener interface public void messageReceived(MessageEvent event) throws PortletException { if (event.getMessage() instanceof DefaultPortletMessage) { DefaultPortletMessage msg = (DefaultPortletMessage) event.getMessage(); String message = msg.getMessage(); //Do something based on the message } } Be aware that when a portlet receives a message, it is not in Edit or Configure mode and therefore faces certain restrictions. For instance, portlets do not have write access to the PorletData object when they are not in Edit mode. Also, they cannot adjust the attributes stored in the PortletSettings object unless they are in Configure mode. Attempts to store attributes in these objects when not in the appropriate mode result in an AccessDeniedException. Therefore, when attempting to share configuration or settings information between portlets, you need to choose your scope carefully or decide to persist to an outside resource. 2.15.2 MessageEvent This object is sent to registered MessageListeners by the portlet container when a portlet executes the send method of the PortletContex object. There are two important methods available in this object. getMessage returns the message object sent with this event. Since this method returns a PortletMessage, the result must be cast to the appropriate type, as illustrated in Example 2-35. getRequest returns the current PortletRequest. The request can be used to access the PortletSession object or to store data to be used in the doView method. 2.15.3 DefaultPortletMessage This object implements the PortletMessage interface and provides the basic functionality needed for sending string messages between portlets. If you broadcast a DefaultPortletMessage to null, it will be sent to all portlets on the page implementing the MessageListener interface. Example 2-36 illustrates sending a simple broadcast message to all portlets on the same page regardless of application affiliation. 90 IBM WebSphere Portal V4 Developer’s Handbook Example 2-36 Broadcasting a message to all portlets on a page PortletMessage msg = new DefaultPortletMessage(“Some Message”); getPortletConfig().getContext().send(null, msg); 2.15.4 PortletMessage This interface defines the message object that will be sent between portlets. Since it is a flag interface, it does not define any methods to be implemented. Therefore, you are free to create message objects that can store a wide variety of information. Example 2-37 illustrates a simple custom message used to carry an employee object. Example 2-37 Creating a custom message import org.apache.jetspeed.portlet.*; import java.net.*; public class EmployeeMessage implements PortletMessage { private Employee emp; public Employee getEmployee() { return emp; } public void setEmployee(Employee employee) { this.emp = employee;} } If you simply need to send a string message between portlets, the DefaultPortletMessage provides this basic functionality. It is not possible to send a broadcast message using custom messages. Setting a custom message to null will only send the message to portlets implementing the MessageListener interface on the same page and deployed as part of the same portlet application. This is illustrated in Example 2-38. Example 2-38 Sending a custom message public void actionPerformed(ActionEvent event) throws PortletException { Employee employee = new Employee(); //Create an employee object with parameters from a form EmployeeMessage msg= new EmployeeMessage(); msg.setEmployee(employee); getPortletConfig().getContext().send(null, msg); } Chapter 2. Portlets 91 2.15.5 ActionListener/WindowListener Though these listeners are not part of the Messaging architecture, they are included here to emphasize that messages can only be sent while handling some other event. This is because the portal server executes in two distinct phases. All events are created, fired and caught in the first phase. Once all event processing is complete, the content rendering phase begins and no further events can be executed. 2.16 Messaging examples To demonstrate inter-portlet messaging, two examples are given. The first example illustrates how one portlet can be used to control the behavior of another. The second example illustrates how portlets can be configured to share configuration information via messaging. 2.16.1 Portlet messaging example 1: navigation control In this example, one portlet displays a Web page using an iframe. Another portlet is used to set the URL the first portlet displays. Figure 2-18 shows the interface of this example. Essentially, the user enters a URL in the sender portlet and that URL is sent via messaging to the viewer portlet. The URL is then used as the SRC attribute in the IFRAME tag. 92 IBM WebSphere Portal V4 Developer’s Handbook Figure 2-18 Portlet Message Example 1 There are three classes used in this example: URLSender: this portlet displays the text field for the user to enter the URL they wish to see. The doView method simply creates a PortletURI with a PortletAction and passes it to the SenderView.jsp. This class implements the ActionListener so it is notified when the user clicks the button. The actionPerformed method simply extracts the string the user entered and uses it to create a new URLMessage object. It then broadcasts the messages. The class is shown in Example 2-39. Example 2-39 URLSender Portlet public class URLSender extends PortletAdapter implements ActionListener{ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { PortletURI uri = response.createURI(); PortletAction go = new DefaultPortletAction("go"); uri.addAction(go); request.setAttribute("uri", uri.toString()); getPortletConfig().getContext().include("/jsp/SenderView.jsp", request, response); } public void actionPerformed(ActionEvent event) throws PortletException { String url = event.getRequest().getParameter("url"); URLMessage msg = new URLMessage(); Chapter 2. Portlets 93 msg.setUrl(url); getPortletConfig().getContext().send(null, msg); } } URLMessage: this simple class implements the PortletMessage interface. It defines two methods, setURL and getURL. This message will be used to pass the URL between the sender and the viewer. This class is shown in Example 2-40. Example 2-40 URLMessage class import org.apache.jetspeed.portlet.PortletMessage; public class URLMessage implements PortletMessage { private String url; public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } } URLViewer: this portlet implements the MessageListener interface. The simple doView method does no more than include the ViewerView.jsp. The messageReceived method accepts the message event and if the event is of type URLMessage, casts it to the correct type. It then retrieves the URL string out of the message and stores it on the session .Example 2-41 displays the code for this class. Example 2-41 URLViewer Portlet public class URLViewer extends PortletAdapter implements MessageListener{ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { getPortletConfig().getContext().include("/jsp/ViewerView.jsp", request, response); } public void messageReceived(MessageEvent event) throws PortletException { if (event.getMessage() instanceof URLMessage) { URLMessage msg = (URLMessage)event.getMessage(); 94 IBM WebSphere Portal V4 Developer’s Handbook event.getRequest().setAttribute("test", msg.getUrl()); PortletSession sess = event.getRequest().getPortletSession(); sess.setAttribute("url", "http://" + msg.getUrl()); } } } There are two JSPs used in this application. SenderView.jsp: this JSP contains a simple form containing a text field. The action behind the form is retrieved from the request object. The uri attribute was created and set in the doView method of the Sender portlet. Example 2-42 displays the code for this JSP. Example 2-42 SenderView.jsp <FORM method="POST" action='<%= request.getAttribute("uri") %>'> Enter the URL: <INPUT size="20" type="text" name="url"> <INPUT type="submit" name="go" value="go"> </FORM> ViewerView.jsp: this JSP retrieves the URL from the session object and passes it to the IFRAME tag. Example 2-43 ViewerView.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> <IFRAME src='<%= portletRequest.getPortletSession().getAttribute("url") %>' width="100%" height="400" scrolling="AUTO" frameborder="0"> You’re browser does not support frames </IFRAME> 2.16.2 Portlet messaging example 2: sharing configuration information This example will demonstrate how a portlet can share configuration information with other portlets. In this example, an InternetMail portlet requires the user to edit the portlet to set their access information. The user is required to enter the server name, their user ID and password. This same information is also used by the InternetToDo portlet which simply retrieves a personal ToDo list from an Internet service. To make the portlets easy to use, whenever the user sets the values in one of the portlets, the other will automatically be updated as well. This Chapter 2. Portlets 95 example is presented to demonstrate information sharing and as such, will not include the database or Internet access code. Figure 2-19 displays the two portlets that have common configuration information. Figure 2-19 Two portlets with common configuration information There are several classes used in this example. ServerInfo: this is a simple Java bean used to temporarily hold the server name, user ID and password strings. Example 2-44 The ServerInfo bean public class ServerInfo { private String serverName; private String userID; private String password; public String getServerName() {return serverName;} public void setServerName(String sName) {this.serverName = sName; } public String getUserID() {return userID;} 96 IBM WebSphere Portal V4 Developer’s Handbook public void setUserID(String userID) {this.userID = userID;} public String getPassword() {return password;} public void setPassword(String password) {this.password = password;} } ServerDBAccess: this class provides two static methods encapsulating the database persistence of the ServerInfo object. ServerInfoMessage: this class implements the PortletMessage interface and is used to send ServerInfo objects to other portlets during messaging. Example 2-45 ServerInfoMessage portlet message public class ServerInfoMessage implements PortletMessage, Serializable { private ServerInfo info; public ServerInfo getInfo() {return info;} public void setInfo(ServerInfo info) {this.info = info; } ServerInfoMessage(ServerInfo info) {this.info = info; } } InternetMailPortlet: this portlet implements the ActionListener and PortletListener interfaces. In doView mode, it simply forwards to the appropriate JSP. In doEdit, it creates a PortletURI that points back to the previous mode. In most cases, the previous mode will be View. An action is added to the URI to notify the actionPerformed method when the user clicks the button. The actionPerformed method completes several tasks. It retrieves the parameters and attempts to build a ServerInfo object. If the serverName parameter is empty, it resets the next mode to redirect the user back to the edit screen. It then passes the ServerInfo object to the ServerDBAcess class to have the data persisted. Once that is successful, it sends the ServerInfo object to other portlets via the ServerInfoMessage. This portlet also listens for messages from other portlets and, if it receives a ServerInfoMessage, it retrieves the ServerInfo object and uses the ServerDBAcess class to persist the information. Example 2-46 InternetMailPortlet import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlet.Portlet.*; import org.apache.jetspeed.portlet.event.*; public class InternetMailPortlet extends PortletAdapter implements ActionListener, MessageListener { public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { Chapter 2. Portlets 97 request.setAttribute("info", ServerDBAccess.getServerInfo(request)); getPortletConfig().getContext().include("/jsp/MailView.jsp", request, response); } public void doEdit(PortletRequest request, PortletResponse response)throws PortletException, IOException { PortletURI viewURI = response.createReturnURI(); PortletAction action = new DefaultPortletAction("save"); viewURI.addAction(action); request.setAttribute("viewURI", viewURI.toString()); getPortletConfig().getContext().include("/jsp/Edit.jsp", request, response); } public void actionPerformed(ActionEvent event) { try { PortletRequest request = event.getRequest(); String serverName = request.getParameter("serverName"); String userID = request.getParameter("userID"); String password = request.getParameter("password"); if (serverName == null || serverName.equals("")) { request.getPortletSession().setAttribute("error", "Server Name is required"); request.setModeModifier(ModeModifier.CURRENT); return; } ServerInfo info = new ServerInfo(); info.setServerName(serverName); info.setUserID(userID); info.setPassword(password); ServerDBAccess.storeServerInfo(info, request); ServerInfoMessage msg = new ServerInfoMessage(info); getPortletConfig().getContext().send(null, msg); } catch (Exception e ){ getPortletConfig().getContext().getLog().warn("Exception in actionPerformed: " + e.getMessage()); } } public void messageReceived(MessageEvent event) throws PortletException { if ( event.getMessage() instanceof ServerInfoMessage) { ServerInfoMessage msg = (ServerInfoMessage) event.getMessage(); ServerDBAccess.storeServerInfo(msg.getInfo(), event.getRequest()); } } } 98 IBM WebSphere Portal V4 Developer’s Handbook InternetToDoPortlet: this portlet’s functionality is largely identical to that of the InternetMailPortlet. However, it uses its own JSP to retrieve and present a ToDo list. Example 2-47 InternetToDo Portlet import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlet.Portlet.*; import org.apache.jetspeed.portlet.event.*; public class InternetToDoPortlet extends PortletAdapter implements ActionListener, MessageListener{ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { request.setAttribute("info", ServerDBAccess.getServerInfo(request)); getPortletConfig().getContext().include("/jsp/ToDoView.jsp", request, response); } public void doEdit(PortletRequest request, PortletResponse response) throws PortletException, IOException { PortletURI viewURI = response.createReturnURI(); PortletAction action = new DefaultPortletAction("save"); viewURI.addAction(action); request.setAttribute("viewURI", viewURI.toString()); getPortletConfig().getContext().include("/jsp/Edit.jsp", request, response); } public void actionPerformed(ActionEvent event) { try { PortletRequest request = event.getRequest(); PortletData data = request.getData(); String serverName = request.getParameter("serverName"); String userID = request.getParameter("userID"); String password = request.getParameter("password"); if (serverName == null || serverName.equals("")) { request.getPortletSession().setAttribute("error", "Server Name is required"); request.setModeModifier(ModeModifier.CURRENT); return; } ServerInfo info = new ServerInfo(); info.setServerName(serverName); info.setUserID(userID); info.setPassword(password); ServerDBAccess.storeServerInfo(info, request); ServerInfoMessage msg = new ServerInfoMessage(info); Chapter 2. Portlets 99 getPortletConfig().getContext().send(null, msg); } catch (Exception e ){ getPortletConfig().getContext().getLog().warn("Exception in actionPerformed: " + e.getMessage()); } } public void messageReceived(MessageEvent event) throws PortletException { if ( event.getMessage() instanceof ServerInfoMessage) { ServerInfoMessage msg = (ServerInfoMessage) event.getMessage(); ServerDBAccess.storeServerInfo(msg.getInfo(), event.getRequest()); } } } 2.17 Attribute storage summary There are many objects in the portal environment for storing attributes. In order to help you choose the right object for the right situation, we refer you to the following chart. Object Scope Attribute Type Programmatic Access Best Practice PortletRequest Limited to request between the portal server and the portlet object getAttribute() setAttribute() removeAttribute() Use a short term bucket for communication between portlet and JSP (for example: Portlet URI) PortletSession Limited to subsequent requests by the same user on the same concrete portlet instance object getAttribute() setAttribute() removeAttribute() Use as an open line of communication between requests. (for example Shopping cart) PortletSettings Shared by all instances of the concrete portlet. Editable only in Configure mode. String getAttribute() setAttribute() removeAttribute() Use only for configuration information that is applicable to all instances (for example user ID) 100 IBM WebSphere Portal V4 Developer’s Handbook Object Scope Attribute Type Programmatic Access Best Practice PortletApplication Settings Shared by all concrete portlet instances deployed in the same concrete application. Editable only in Configure mode. String getAttribute() setAttribute() removeAttribute() Use only for configuration information that is applicable to all concrete portlet instances in the same application (for example server name). PortletData Persistently available to a single concrete portlet instance. object (serializa ble) getAttribute() setAttribute() removeAttribute() Use for information that needs life beyond a session (for example portlet preferences). PortletURI One request through to the actionPerformed method. String addParameter() Use to provide default parameter values in case the user does not enter a value in a form. PortletMessage Only available to registered message listeners in the event processing phase. Object Since each custom portlet message can be implemented uniquely, access is not pre-defined Use to adequately capture all the information necessary to complete the message. There is no predictability regarding order of execution for listeners so do depend on this. PortletConfig Same config object is available to every concrete portlet instance derived from the same abstract portlet String getInitParameter() This vale can only be set during development or deployment. Since its scope is very broad, use carefully. DefaultPortlet Action Available as long as the PortletURI it is attached to is available. object setParameter() getParameters() It is not recommended to store objects such as PortletResponse, etc. Use sparingly. PortletAdapter Available to all instances of the concrete portlet. Value is not unique between users. object getVariable() setVariable() Use this object to store attributes that are not unique to any one user, and can be lost if the server shuts down. Chapter 2. Portlets 101 2.18 Portlet services A PortalService is a discoverable extension to the Portal functionality. A portlet can query the container for a specific service and use that service without ever knowing the implementation or concerning itself with its lifecycle management. Their lifecycle is managed by the portal and as such does not have container restrictions placed on portlets. Example 2-26 illustrates accessing a service in a portlet. Example 2-48 Accessing a service ContentAccessService service = (ContentAccessService) getPortletConfig().getContext().getService(ContentAccessService.class); The default installation of WebSphere Portal Server ships with the ContentAccessService. Other services could be implemented by various vendors or by yourself as seen in “Custom services” on page 103. WebSphere Portal Server also supplies the CredentialsVaultService, which is discussed in detail in “Credential Vault” on page 107. 2.18.1 ContentAccessService The contentAccessService provides a convenient mechanism for accessing content outside the Portal Server. Whereas the PortletContext include method is limited to content relative to the Portlet Application, the ContentAccessService has no such limitations. Example 2-49 illustrates simple usage of the ContentAccessService. There are two important methods defined in this service. include(String url, PortletRequest request, PortletResponse response) This method will write the results of the URL to the response unfiltered. There is no opportunity to remove undesirable or malformed HTML. There is no URL rewriting whatsoever so relative links, such as images, will not be displayed properly. Use this method only when the URL can be trusted to return reliable content. getURL(string URL, PortletRequest request, PortletResponse response) This method returns a java.net.URL object. This object can then be used to open a URLConnection, access an inputStream or access the host, port and other important information. This method provides the opportunity to filter the content prior to including it in the response. 102 IBM WebSphere Portal V4 Developer’s Handbook Example 2-49 Using the ContentAccessService public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { ContentAccessService cas = (ContentAccessService) getPortletConfig(). getContext(). getService(ContentAccessService.class); cas.include(“http://www.ibm.com”, request, response); } 2.18.2 Custom services The Portlet API allows you to create your own services that you can install into the portal server. The main benefits of services are twofold. First, they execute outside of the Portlet Containers. Secondly, they are not tied to any given portlet and therefore their lifecycle is not dependent on individual portlets. This means that once the service has been initialized, it is available to all portlets with no further initialization cost. Likewise, the destruction cost is not absorbed by any single portlet. To create your own service, there four steps to follow. Some of these steps are optional. This section will use a custom MailService as an example. This example allows a portlet to locate the MailService, send an e-mail and verify that it was in fact sent. The actual implementation of the JavaMail API is not included for reasons of clarity. 1. Define the service First, you must define an interface that defines the functionality this service will provide. The custom service interface must extend PortletService. The PortletService interface is a flag interface and therefore does not define any methods. Example 2-50 Defining the service interface package com.yourco.services.mailservice; import org.apache.jetspeed.portlet.service.*; public interface MailService extends PortletService { public boolean sendEMail(String address, String subject, String message); } Chapter 2. Portlets 103 2. Implement the service The service interface then needs to be implemented. The implementation class must implement the custom service interface you defined as well as the PortletServiceProvide interface. The PortletServiceProvide defines the init and destroy methods that must be implemented. The init method may be called by the factory when the implementation class is first created. In practice, while your custom factories may choose not to utilize this method, the default factories do. The init method is an appropriate location to load initialization parameters, establish connection pools, etc. Initialization parameters are discussed in Step 4. The destroy method is an appropriate location to release any resources or perform any other common clean-up code. Example 2-51 Implementing the custom service package com.yourco.services.mailservice.impl; import org.apache.jetspeed.portlet.service.*; import org.apache.jetspeed.portlet.service.spi.*; import com.yourco.services.mailservice.MailService; public class MailServiceImpl implements PortletServiceProvider, MailService { private String server_name; public void init(PortletServiceConfig config) throws PortletServiceUnavailableException { //Set Mail Server name based on inititialization parameters server_name = config.getInitParameter(“SERVER_NAME”); } public void destroy() { //No resources to destroy } public boolean sendEMail(String address, String subject, String message) { //Send mail using JavaMail API return true; } } 3. Create the service factory This step is optional when creating custom services. The factory is used by the PortletContext object to retrieve an instance of the service. Two default factories are provided with Portlet API. PortletServiceDefaultFactory will always return a new instance of the service. PortletServiceCacheFactory will 104 IBM WebSphere Portal V4 Developer’s Handbook always return the same instance of the service. Both of these factories call the init method of the service they are instantiating. Generally, either of the two default factories will provide the functionality you need when creating custom services. However, to ensure this example is complete, Example 2-52 illustrates a custom factory for the MailService service. Example 2-52 Creating a custom factory package com.yourco.services.mailservice.factory; import import import import import import java.util.*; javax.servlet.ServletConfig; org.apache.jetspeed.portlet.service.*; org.apache.jetspeed.portlet.service. spi.*; org.apache.jetspeed.portletcontainer.service.*; com.yourco.services.mailservice.impl.MailServiceImpl; public class MailServiceFactory implements PortletServiceFactory{ private PortletServiceProvider psp = null; public PortletService createPortletService(Class service, Properties props, ServletConfig config) throws PortletServiceUnavailableException { if (psp != null) { return psp; } else { psp = new MailServiceImpl(); psp.init(new PortletServiceConfigImpl(service, props, config)); return psp; } } } 4. Register the service Once the service interface has been defined, the implementation class created and the factory decided upon, the classes should be packaged into a jar file. This jar should be placed in the <WAS-ROOT>lib\app directory. If you have decided to use one of the default factories, they are already in this directory in the wps.jar file. Once the files have been deployed, the service must be registered. Open the PortletService.properties file in the <WP-ROOT>\app\wps.ear\ wps.war\WEB-INF\conf directory. It is recommended that you make a back-up of this file prior to modifying it. The service and its factory must be registered as illustrated in Example 2-53. The first mapping indicates that when a service is requested, the specified implementation class should be returned. Chapter 2. Portlets 105 The second mapping indicates which factory should be used to create this service when requested. This mapping should specify your custom factory, org.apache.jetspeed.portletcontainer.service.PortletServiceCacheFactory or org.apache.jetspeed.portletcontainer.service.PortletServiceDefaultFactory. Example 2-53 Registering the service in PortletServices.properties com.yourco.services.mailservice.MailService = com.yourco.services.mailservice.impl.MailServiceImpl com.yourco.services.mailservice.impl.MailServiceImpl.factory = com.yourco.services.mailservice.factory.MailServiceFactory Initialization parameters are also supplied in the PortletService.properties file, as illustrated in Example 2-54. Accessing these parameters is illustrated in Example 2-51 on page 104. Example 2-54 Setting Unit parameters in PortletService.properties com.yourco.services.mailservice.impl.MailServiceImpl.SERVER_NAME = “SERVER_NAME” 5. Test the service In order for the service to become available in the Portal, the portal server must be restarted. Using the WebSphere Administrator’s Console, restart the WebSphere Portal Application Server. Example 2-55 shows a simple portlet making use of the MailService service. Example 2-55 Using the MailService service public void actionPerformed(ActionEvent event) throws PortletException { PortletRequest request = event.getRequest(); String address = request.getParameter("address"); String subject = request.getParameter("subject"); String msg = request.getParameter("msg"); MailService mailService = (MailService) getPortletConfig().getContext().getService(MailService.class); String result = "" + mailService.sendEMail(address, subject, msg); request.getPortletSession().setAttribute("EmailResult", result); } 106 IBM WebSphere Portal V4 Developer’s Handbook 2.19 Credential Vault WebSphere Portal can be configured to exist in a Single Sign-On environment using a number of different approaches. If the various systems participating in the SSO realm all authenticate to Domino™, WebSEAL can provide the SSO functionality. Third party authentication mechanisms such as Tivoli® Access Manager can also be used to create a unified environment for the user. However, on the portlet level, there may be systems outside the current SSO realm or applications that simply require an explicit login. To facilitate the storage, retrieval and usage of the credentials necessary to access these back-end systems, WebSphere Portal provides the Credentials Vault Service. This service is based on the Portlet Service architecture discussed in “Portlet services” on page 102. The CredentialsVaultService allows you to easily and securely persist user IDs and passwords without concerning yourself with database access code. Credential Vault Service Default Vault (DB) Segment A (admin) Segment B (admin) Segment C (user) Slot (System) Slot (Shared) Slot (Private) Credential (Active) Credential (Active) Credential (Active) Slot (Shared) Slot (Private) Credential (Passive) Credential (Active) Slot (Admin) Credential (Passive) Slot (System) Slot (Private) Credential (Passive) Credential (Passive) Figure 2-20 Credential Vault objects 2.20 Core Credential Vault objects There are several key objects used when working with or administering the Credential Vault. Chapter 2. Portlets 107 2.20.1 Vault This is a persistent store where credentials are actually stored. WebSphere Portal provides the default database vault. The Tivoli Access Manager lock box could also be registered and used as a vault. You can create and register your own custom vault implementations that may store credentials in some database, in memory or even in a simple file system. 2.20.2 Segment A vault can be separated into segments to distinguish the access control portlets have when working with the credentials stored in the vault. Portlets can retrieve credentials from any type of segment. A vault can only be segmented by the administrator. Administrator Managed: a segment flagged as Administrator Managed prevents portlets from creating new slots in the segment. User Managed: this type of segment allows a portlet to dynamically create new slots and to place credentials in that slot. Only the default vault provided by WebSphere Portal provides user managed segments. 2.20.3 Slot A slot is a “drawer” in a segment that actually contains the credential. A slot can only contain a single credential. When retrieving credentials, a portlet searches the vault for a slot based on the slot ID. This ID is usually persisted in the PortletData object. The definition and implementation of slots is dependent on the vault containing the slot. The default vault implementation provided by WebSphere Portal provides four types of slots. System slot: the credentials stored in this type of slot are available to all users and portlets. This type may be used when a user ID/password is company-specific and not unique to each employee. Administrative slot: the credentials stored in this type of slot are applicable to individual users but are associated with administrator-defined resources such as Lotus® Notes®. Shared slot: the credentials stored in this type of slot are available to all the portlets of a specific user. This type may be used when several portlets will access the same back-end system on behalf of the same user. Portlet Private slot: the credentials stored in this type of slot are available to the single portlet instance that stored it. The credential is not accessible from any other portlet. This type may be used when the credentials are required only by a single portlet and are not applicable to any other user. 108 IBM WebSphere Portal V4 Developer’s Handbook 2.20.4 Credential This object actually contains the user ID/password pair. There are two basic types of credentials. Passive credential: this type of credential simply persists the user ID/password pair. When a portlet needs to access some back-end system with credentials stored in a passive credential, it is required to retrieve the user ID string and password character array from the credential and manually construct the connection to the back end. Example 2-56 illustrates using a passive credential. Example 2-56 Accessing a passive credential UserPasswordPassiveCredential cred = (UserPasswordPassiveCredential) vault.getCredential( slotID, "UserPasswordPassive", null, request); if (cred != null ){ String pass = cred.getPassword().toString(); String userid = cred.getUserId(); } // Use ID and password to connect to some back end Active credential: this type of credential encapsulates the user ID/password pair as well as all the logic required to access the back-end system. Portlets do not have access to the user ID or password persisted in the credential. However, the credential provides connection methods and utilizes the persisted user ID and password to establish the necessary connection. Example 2-57 illustrates how an active credential never returns the user ID or password but instead provides the requisite connection functionality. Example 2-57 Accessing and using an active credential JavaMailCredential credential = (JavaMailCredential) vault.getCredential( slotID, "JavaMailCredential", config, request); javax.mail.Session mailSession = javax.mail.Session.getDefaultInstance(props, null); if (credential != null ){ Chapter 2. Portlets 109 mailSession = credential.getAuthenticatedSession(mailSession, host); mailSession.getTransport().send(someMsg); } Since an active credential inherently provides more security, it is the preferred type of credential. WebSphere Portal ships with several predefined types of credentials. Active Credentials – HTTPBasicAuthCredential – HTTPFormBasedAuthCredential – JavaMailCredential – LtpaTokenCredential – WebSealTokenCredential – SiteMinderTokenCredential Passive Credentials – SimplePassiveCredential – UserPasswordPassiveCredential – JassSubjectPassiveCredential Example 2-58 illustrates sample code that can be used to store credentials using the Credential Vault Service provided by WebSphere Portal. Example 2-58 Storing credentials PortletContext context = getPortletConfig().getContext(); CredentialVaultService vault = (CredentialVaultService) context.getService(CredentialVaultService.class); ObjectID defaultSegmentId = vault.getDefaultUserVaultSegmentId(); Map descripMap = new HashMap(); descripMap.put("en", "A simple test slot"); CredentialSlotConfig slot = vault.createSlot( "", defaultSegmentId, descripMap, null, CredentialVaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING, false, true, request); request.setAttribute("Test_SlotID", slot.getSlotId()); int passLength = password.length(); char[] passChars = new char[passLength]; 110 IBM WebSphere Portal V4 Developer’s Handbook password.getChars(0, passLength, passChars, 0); vault.setCredentialSecretUserPassword( slot.getSlotId(), userid, passChars, request); CredentialVaultService Methods getCredentialTypes returns an iterator of all credential types that are registered in the Credential Type Registry 2.21 Portlet JSPs When designing your portlet applications, you will generally use the MVC Model 2 architecture discussed in “Portlet MVC architecture” on page 35. To implement the development of dynamic portlet JSPs, a rich tag library is provided with WebSphere Portal Server. There are several custom tag libraries supplied with WebSphere Portal Server, depending on the installation type and what additional components are installed. portlet.tld This tag library contains the tags used in day-to-day JSP development when working with JSPs. engine.tld This tag library is intended to be used in the construction of themes and skins. For information on themes and skins and details on this tag library, refer to Chapter 6, “Portal customization” on page 261. extend.tld This tag library is only supplied if the installation type is extend or experience. These tags are not available with the enable installation. For details on this tag library, refer to Chapter 6, “Portal customization” on page 261. content.tld This tag is used in JSPs working with the PortletContent Organizer. For more information on the Portlet Content Organizer, refer to Chapter 11, “Content management” on page 637. menu.tld This tag library provides access to Collaborative functionality in the themes. person.tld This tag library provides access to Collaborative functionality inside your portlets. Chapter 2. Portlets 111 2.21.1 Portlet Tag Library Like all tag libraries in the WebSphere Portal Server, the portlet.tld is located in the <WP-ROOT>app\wps.ear\wps.war\WEB-INF\tld directory. Example 2-59 illustrates referencing the tag library at the beginning of a JSP. Example 2-59 Referencing a tag library <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> This section will cover the tags available in the portlet.tld tag library and some of their most common uses. init <portletAPI:init /> This tag must be called if you wish to access the PortletRequest, PortletResponse or PortletConfig objects in the JSP. This tag simply initializes three variables for you: portletRequest, portletReponse, and portletConfig. Attempting to access these variables without calling the init tag will cause the page compilation of the JSP to fail. However, you still have full access to the javax.servlet.http.HttpServlet objects via the normal variable names. createReturnURI <portletAPI:ecreateReturnURI /> This tag returns a string pointing to the portlet in the previous mode. The resulting URI could be used to create a Back button or to specify an action on a form. If you wish to add a PortletAction to the URI object in order to notify any applicable listeners, you can include the URIAction tag in the body of the createReturnURI tags. Example 2-60 illustrates this approach. Example 2-60 Adding a PortletAction to the PortletURI <portletAPI:createReturnURI > <portletAPI:URIAction name="submit" /> </portletAPI:createReturnURI> You can also add a parameter to the PortletURI object using a similar approach to that used with the PortletAction. Example 2-61 Adding a Parameter to the PortletURI and the resulting URI <portletAPI:createReturnURI > <portletAPI:URIParameter name="fname" value="john" /> </portletAPI:createReturnURI> 112 IBM WebSphere Portal V4 Developer’s Handbook Result: /wps/myportal/.cmd/ActionDispatcher/_pagr/104/_pa.104/113/.md/-/.piid/188/.ciid /223/.reqid/-1/PC_188_fname/john#223 createURI <portletAPI:createURI /> This tag returns a string pointing to the portlet in the current mode. As with the createReturnURI tag, PortletActions and parameters can be added to the resulting URI. Though the documentation indicates that the state can be controlled by passing a string attribute, this functionality is not implemented. URIAction <portletAPI:URIAction name=”sting”/> This tag is only used when creating PortletURI object. Example 2-60 illustrates the use of this tag. This tag requires that a name attribute be specified. URIParameter <portletAPI:URIParamter name=“string” value=“string”/> This tag is only used when creating a PortletURI object. Example 2-61 illustrates the use of this tag. This tag requires that name and value attributes be specified. dataAttribute <portletAPI:dataAttribute name=“string” /> This tag will retrieve from the PortletData object the attribute specified by the name attribute. If the attribute does not exist in the PorltetData, nothing is returned. When the dataAttribute tag is used in the body of the a dataLoop tag, it does need to specify the name of the attribute. Example 2-62 Retrieving a single PortletData attribute Welcome <portletAPI:dataAttribute name = "pref.nick_name" /> to your page. dataLoop <portletAPI:dataLoop pattern="string"> </portletAPI:dataLoop> This tag provides a loop through all the attributes stored in the PortletData object. Although by default it will iterate through all attributes, it is possible to specify a pattern to limit the attributes it locates. Omitting the pattern attribute will return all attributes. Example 2-63 illustrates the use of this tag. Notice the loop simply iterates through the collection of attributes; it does not retrieve the value. To retrieve a PortletData value, use the dataAttribute tag. Chapter 2. Portlets 113 Example 2-63 Looping through the attributes in the PortletData object <portletAPI:dataLoop pattern="pref.*"> <portletAPI:dataAttribute/><br> </portletAPI:dataLoop> Though using an asterisk in the pattern is helpful for readability and reliability, the pattern attribute in fact does not need to use an asterisk at all. The tag will attempt to find the value specified by the pattern attribute anywhere in the name of the attribute. For example, if an attribute is stored in the PortletData with the name “pref.greeting”, the code in Example 2-64 on page 114 would successfully locate the attribute. However, it is important to note that the pattern is case sensitive. Therefore, the pattern “name” would not locate the attribute “Name”. Example 2-64 Using the Pattern attribute <portletAPI:dataLoop pattern="eet"> settingsAttribute <portletAPI:settingAttribute name=”string” /> This tag provides access to the parameters set in the <config-param> blocks in the portlet.xml’s concrete portlet section. When the dataAttribute tag is used in the body of the a settingsLoop tag, it does need to specify the name of the attribute. Example 2-65 Accessing the PortletSettings attributes For support contact <portletAPI:settingsAttribute name = "author" /> settingsLoop <portletAPI:settingsLoop pattern="string"> </portletAPI:settingsLoop> If several configuration parameters have been set in the portlet.xm, they can all be retrieved with this tag. The pattern tag is optional. Example 2-66 Looping through the PortletSettings attributes <portletAPI:settingsLoop pattern="info."> <portletAPI:settingsAttribute/><BR> </portletAPI:settingsLoop> If you do not include the pattern attribute or enter an empty string, it will return all attributes in the PortletSettings object. As with the dataLoop tag, the settingsLoop tag will attempt to locate the specified pattern anywhere in the 114 IBM WebSphere Portal V4 Developer’s Handbook attribute’s name. For example, if a <config-param> were set in the portlet.xml with a name of “info.author”, the code in Example 2-67 would successfully retrieve the attribute. However, it is important to note that the pattern is case sensitive. Therefore, the pattern “author” would not locate the attribute “Author”. Example 2-67 Using pattern to locate an attribute <portletAPI:settingsLoop pattern="thor"> encodeNameSpace <portletAPI:encodeNamespace value="string" /> When including JavaScript functions or other variables that will be returned to the aggregated portal page, it is important to ensure the values are unique in order to avoid name collisions. This tag prefixes the namespace of the portlet to the string it is passed. This tag should be used when creating the variable as well as when accessing it. Example 2-68 illustrates the use and result of this tag. Example 2-68 Encoding the name space <portletAPI:encodeNamespace value="function1" /> Result: PC_189_function1 encodeURI This tag will prefix the full URL of the portal to the passed path value. For example, if the image yourco.jpg image is in the images folder directly under the root of the deployed portlet application, the code in Example 2-69 would successfully locate the image and create a fully qualified URL. Example 2-69 Creating fully qualified URL <img src= <portletAPI:encodeURI path="/images/yourco.jpg" /> > Result http://ka0kkhc.sg246897.com/wps/WPS_PA_206/images/yourco.jpg if <portletAPI:if attribute= "string"> </portletAPI:if> This tag allows you to test some of the more common conditions a portlet may face. When the attribute evaluates to true, the body of the if tag is executed. There are several attributes you can evaluate. Chapter 2. Portlets 115 – mode – state – locale – mime type – markup – capabilities Though the info center indicates that the previous mode can be evaluated as well, the previousMode attribute is not functional. You may choose to execute several if statements individually, as shown in Example 2-70. Example 2-70 Executing If tags individually <portletAPI:if state = "Normal"> state is normal </portletAPI:if> <portletAPI:if state = "Maximized"> state is maximized </portletAPI:if> <portletAPI:if locale = "en"> Locale is english </portletAPI:if> <portletAPI:if markup = "html"> Markup is html </portletAPI:if>< <portletAPI:if mimetype = "text/html"> mime type is text html </portletAPI:if><BR> <portletAPI:if mode="view"> Mode is View </portletAPI:if ><BR> You can evaluate more than one condition on a single attribute. In this case, if any of the conditions are true, that attribute will evaluate to true. Example 2-71 illustrates this. Example 2-71 Evaluating multiple conditions on a single attribute <portletAPI:if state="Normal, Maximized" > You may also evaluate multiple attributes in the same tag as illustrated in Example 2-72. All conditions must evaluate to true for the if tag to return true. Example 2-72 Evaluating multiple attributes <portletAPI:if state="Normal" mode="view" locale="en"> Displaying the normal English view </portletAPI:if> log <portletAPI:log text="string" level="string"/> This tag will write the value passed to the log file located in the <WP-ROOT>\log directory. The text attribute contains the string you wish to write to the log file. The level attribute indicates which level this message 116 IBM WebSphere Portal V4 Developer’s Handbook should be written under. This tag does not evaluate whether the requested level is enabled before it attempts to write the message.For more information on writing to the log, see “PortletLog object” on page 71. Example 2-73 illustrates the use of this tag. The valid values for the level attribute are error, warn, debug and info. If you omit the level tag, the default level is error. Example 2-73 Using the log tag <portletAPI:log text="There was an error" level="warn"/> text <portletAPI:text key="string" bundle="string"> This tag provides access to key-value pairs in resource bundles. The text tag will attempt to locate the given key in the given resource bundle. Only if it is unsuccessful will it instead return the text between the open and close text tags. There is no need or opportunity to set the locale used to determine the resource bundle. Example 2-74 Retrieving NLS values from a resource bundle <portletAPI:text key="greeting" bundle="nls.WelcomeStrings"> Hello </portletAPI:text> bidi <porteltAPI:bidi locale=”string” dir=”ltr | rtl” /> This tag is used to support text for bidirectional languages. Bidirectional languages are read from right to left or from bottom to top. The attributes are not required. For example, if the request indicates that the client is Hebrew or Arabic, it will execute the tag contents if dir is set to rtl. 2.22 Resources For the most up-to-date information on WebSphere Portal, refer to the Portal zone at http://www7b.boulder.ibm.com/wsdd/zones/portal/. For help using a news group, visit new.software.ibm.com and locate the ibm.software.websphere.portal-server news group. For other Redbooks discussing installation and administration, refer to http://www.redbooks.ibm.com Chapter 2. Portlets 117 118 IBM WebSphere Portal V4 Developer’s Handbook 3 Chapter 3. Using the Portal Toolkit This chapter will introduce you to the WebSphere Studio development environment for creating portlet applications. It is assumed that you have some experience with the WebSphere Studio environment. If you have not used WebSphere Studio, refer to the redbook WebSphere Studio Application Developer Programming Guide, SG24-6585-00 for detailed information on the entire tool. This chapter discusses the following topics: Portal Toolkit installation Portlet Application Wizard Portlet.xml interface Deploying portlets Adding portlets to applications Configuring Studio for portlet development © Copyright IBM Corp. 2003. All rights reserved. 119 3.1 Portal Toolkit installation introduction WebSphere Portal Version 4.1 includes the Portal Toolkit, a powerful set of extensions that plug into WebSphere Studio Application Developer and extend Application Developer for building and debugging portlets. You can create a portlet application project in Application Developer and import these portlets into the project for building and packaging. Application Developer also features a JSP editor, and the Portal Toolkit provides remote portlet debug facilities for portlet applications. Portal Toolkit is a toolkit for developing portlet applications. The toolkit is implemented as a plug-in to WebSphere Studio Application Developer. Portal Toolkit provides: Portlet Projects, in which you can create Abstract portlets, JSP portlets, Servlet Invoker portlets, XML/XSL portlets, and Multi-Device / View portlets. Portlet Server Projects, in which you can publish your portlet application onto your target WebSphere Portal server machine. Your portlet will appear on the debug page of your Portal Server. Portlet application samples for enterprise applications. 3.2 Installing the WebSphere Portal Toolkit Prerequisites In the development environment: WebSphere Studio Application Developer V4.0.3 In the runtime environment: WebSphere Application Server Advanced Single Server Edition Version 4.0.2 WebSphere Portal Version 4.1 (development mode) DB2 Universal Database™ Version 7.2 fix 5 Installation The Portal Toolkit installation procedure is described here in some detail as follows: 1. Download the Toolkit; PortalToolkit4.1.exe is a self extracting executable. Note: Portal Toolkit can be downloaded from the following Web site: http://www7b.software.ibm.com/wsdd/zones/portal/ 120 IBM WebSphere Portal V4 Developer’s Handbook 2. Run PortalToolkit4.1.exe to unpack the contained files to a location of your choice. 3. Change to the location of the extracted files and invoke install.bat. 4. If you already have the WebSphere Portal Toolkit installed, you will be asked if you want to proceed. Answering Yes will overwrite your install. 5. In the Welcome window, click Next. Figure 3-1 Portal Toolkit installation wizard 6. If WebSphere Studio Application Developer is started, you will be asked to stop it. Chapter 3. Using the Portal Toolkit 121 Figure 3-2 Portal Toolkit Install - Stop WebSphere Studio Application Developer 7. Accept the license agreement and click Next. Figure 3-3 Portal Toolkit Install - License Agreement 8. Confirm the WebSphere Studio Application Developer install directory and click Next. 122 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-4 Portal Toolkit - WebSphere Studio Application Developer installation directory 9. Confirm the installation by clicking Next. Figure 3-5 Portal Toolkit Install - Installation Summary 10.Install the file; create the uninstaller (<WSAD Home>Portaltoolkit\uninstaller.exe). Chapter 3. Using the Portal Toolkit 123 Figure 3-6 Portal Toolkit Install - Installation Complete 11.You will be presented with the option to view the readme. If you choose not to read it now, the file can later be found at <WSAD Home>\PortalToolkit\ PortalToolkit_readme.html. Figure 3-7 Portal Toolkit Readme 124 IBM WebSphere Portal V4 Developer’s Handbook 12.Click Finish to close the installer. Figure 3-8 Portal Toolkit Installation - finished 3.3 Portlet Application wizard In order to create Portlet Applications suitable for deployment in WebSphere Studio Application Developer, you need to use the wizard. To manually construct the necessary folder structure and deployment descriptors would be tedious and utterly pointless. To create a new Portlet Application, switch to the Portlet Perspective by selecting Perspective -> Open -> Other -> Portlet. To start the Porlet Application wizard, from the menu bar, select File -> New -> Portlet Application Project. The wizard can also be started by right-clicking the Portlet Perspective and selecting New -> Portlet Application Project from the context menu. Finally, the wizard can also be started from any perspective by selecting File -> New -> Other... -> Portlet development -> Portlet application project. When the wizard has started, you will see the screen in Figure 3-9. Chapter 3. Using the Portal Toolkit 125 Figure 3-9 First screen of the Portlet application project wizard The fields on the first screen are: Project Name This value will determine the name of the project created by this wizard. The value entered here will be used throughout the remainder of the wizard as the default value for other parameters. Use Default Location This checkbox indicates that you would like the entire contents of the application stored in the workspace. If you would like the contents of the application stored somewhere else on the file system, deselect this box. Location If you deselect the Use Default Location check box, this field is enabled and allows you to specify where the application will be saved. Enterprise Application project name Though the Portal Server does not recognize EAR files, the Portlet application in WebSphere Studio must be contained in a Enterprise Application. When using the Portal Server debugging environment, all portlet applications contained in an EAR file are deployed together. You may choose an existing EAR file or enter a new one to be created. Context Root This value will be used in the application.xml and .websettings files. It will not be the context root of the portlet application when deployed. Since the EAR is not used to deploy the portlet application into a full server, this value is only used when the ear is published to debug Portal Server connected to WebSphere Studio Application Developer. 126 IBM WebSphere Portal V4 Developer’s Handbook Create CSS File If the JSPs you will create will make use of a Cascading Style Sheet, the wizard can create a CSS file for you. The generated style sheet will be placed in the theme directory of the Web Application folder and named master.css. If you select Finish in the first screen of the wizard, an empty portlet application will be created. It is very unlikely that you want to do this. By selecting Next, you will have the opportunity to select the type of portlet you would like to create inside the portlet application. The second window is shown in Figure 3-10. Figure 3-10 Second screen of the Portlet application project wizard Presently, there are six options when deciding which kind of portlet you want included in the portlet application. You can only create a single portlet in an application via the wizard. See “Adding portlets to applications” on page 143 to add more portlets the application. The six types of portlets that can be created are as follows. None This is the default option and will not create a portlet in the application. If you choose this option, you will need to manually add portlets to the application as well as the deployment descriptors. Basic portlet This is by far the most common option and will create a simple portlet in the portlet application. The portlet will extend from PortletAdapter and contain meaningful implementations of all four do methods. The implementations will adhere to the MVC approach. A bean will also be created for you to encapsulate your business logic. The resulting folder structure will appear as in Figure 3-13 on page 131. Chapter 3. Using the Portal Toolkit 127 JSP portlet This option assumes the entirety of the application will be contained in a JSP. The application will specify the com.ibm.wps.portlets. JSPPortlet for deployment. This portlet simply forwards calls to a JSP. The JSP that is called is specified in the config-param of the concrete portlet section in the portlet xml. By default, the wizard will specify and create a view.jsp file for you. You can choose a different name for the JSP in the third screen of the wizard. In the source folder, the wizard will place a dummy.java file that contains no code. MVC portlet This choice utilizes the MCVPortlet provided as part of the com.ibm.wps.portlets package. This Portlet relays calls to Controller classes dedicated to servicing a specific markup. As such, if you select this type of portlet, a controller bean will be created for each markup you choose to support. The third screen of the wizard requires that you enter the base name of the controller classes. This name can be any value you like but is defaulted to MyController. This option will also create complete JSP structures for each markup. Servlet invoker portlet This option will deploy the com.ibm.wps.portlets. ServletInvokerPortlet portlet and specify a URL as a parameter to the config-param in the portlet deployment descriptor. If you choose this option, the wizard requires you to provide a URL pointing to the servlet you wish to serve. The ServletInvoker portlet simply uses the ContentAccess Service to return unfiltered HTML. You must specify the URL you wish to serve in the final screen of the wizard. The resulting folder structure will contain a dummy.java file containing no code. XSL portlet This option makes use of the com.ibm.wps.portlets.xslt. WpsXSLTPortlet. This portlet simply accepts an xml file and a style sheet as parameters and uses these to create a presentation via the XSLT transformation. These parameters must be supplied on the final window of the wizard. If you do not yet have the requisite files, the wizard can use default sample xml and xsl files. The parameters can be adjusted in the portlet.xml or at runtime. The vast majority of your portlet development will begin with a Basic Portlet. As such, we will discuss in detail the options in the final window of the wizard as they apply to creating a basic portlet. Figure 3-11 shows the third and final window of the wizard. 128 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-11 Third screen of the Portlet application project wizard There are eight fields required in the final screen. By default, all fields have been completed for you. Most of these fields are used to complete the portlet.xml deployment descriptor. For more information on the portlet.xml, refer to “portlet.xml” on page 45. Portlet application name This name is used in the portlet.xml to specify the abstract application name. This value will never be seen by the administrator of the portlet or the end-user. Generally, there is no need to change this value. Portlet name This value is used to identify the abstract portlet. This name will never been seen by the administrator or the end user. There is typically no need to alter this value. Concrete portlet application name This name is used in the portlet.xml to specify the concrete application. The administrator will see this value in the portal. If you intend to add more concrete applications to this portlet application, you may want to change this value. Otherwise, there is no need to adjust this value. Concrete portlet name This name specifies this concrete portlet to be deployed. The end user will see this value when they add the portlet to a page. Generally, there is no need to adjust this value. Default locale This value adds the default locale and the language block to the portlet.xml. Chapter 3. Using the Portal Toolkit 129 Concrete portlet title This will complete the language block with the title. The description, short-title and keywords elements are included in the language block but left empty. Portlet class name This name will be used as the name of the portlet created for you. You should adjust this value to reflect the package name you would like to use. If you do not enter a package name, the wizard will place the portlet in the default portlet package. Markups These checkboxes indicate which markup languages you intend to support. By selecting a value, a new folder will be created under the JSP folder containing JSPs specifically for the markup. A basic portlet specifying all three markups will result in the folder structure demonstrated in Figure 3-12. Figure 3-12 Toolkit support for 3 markups Select Finish and the wizard will create the necessary folder structure, classes, JSPs and deployment descriptors. 3.4 Developing portlet applications The wizard will create a skeleton you can use as a foundation for your portlet development. Figure 3-13 shows the result of creating a basic portlet application with the wizard. 130 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-13 The folder structure and contents of a basic portlet application 3.4.1 Portlet application contents The generated project contains the following folders and files by default: source This folder contains the Java files that make up the portlet application. By default, the wizard assumes you will follow an MVC approach and creates a simple Java bean for you. Whatever package name was specified in the final screen of the wizard will be created. If a simple class name was specified without a package, the wizard will place the portlet in a package name portlet. webApplication This folder contains everything needed to deploy the application to the portal. Essentially, this folder will become the war file. This folder contains two sub folders: jsp and WEB-INF. jsp This folder will contain all the JSPs used by the application to create the content of the portlet. For each markup you choose to support, a directory will Chapter 3. Using the Portal Toolkit 131 be created containing JSPs for each of the four modes a portlet may support. It will also contain four JSP files for the modes under the root. In the event that the portal is unable to match a client to a markup folder, it will use the default JSPs contained in the root. To keep development simple and clean, you may choose to delete the default JSPs and work only with the HTML JSPs. WEB-INF This folder contains the compiled code and deployment descriptors used by the Portal to install the application. – classes If your compiled portlet class files are not packaged into a jar file, they are included in this directory. The complete package structure is created in this folder – lib This directory contains any jar files that your application makes use of and which are not normally available in the Portal environment via the classpath. Also, if you have packaged your compiled portlets into a jar, the jar file is placed in this directory. – tld This is included to allow JSPs to compile and recognize the custom tags available in the portal environment. This folder and file are not required at deployment time since the tld is installed with Portal. To make maintenance easier and more reliable, you may choose to delete this file upon deployment. – ibm-web-bnd.xmi This file is not used by the portal environment but is included with all Web applications created in WebSphere Studio. – ibm-web-ext.xmi This file is not used by the portal environment but is included with all Web applications created in WebSphere Studio. – portlet.xml This is the deployment descriptor required by the Portal server to install the portlet application. It must be located under the WEB-INF folder or installation will fail. – web.xml This deployment descriptor is required by the application server to install the Web application. It must be located under the WEB-INF folder or installation will fail. .classpath This file is used by WebSphere Studio to locate the jar files containing the Portlet APIs. It is required for your portlets to compile but is not included in deployment. .websetttings This file is required by WebSphere Studio but is not used by the Portal Server. In fact, it is not included when the application is packaged and deployed. images This folder is not created for you by the wizard. However, if the JSPs you create use images, it is a good practice to place them in an images folder under the webApplication directory and access them as demonstrated in Example 3-1. 132 IBM WebSphere Portal V4 Developer’s Handbook Example 3-1 Accessing images in JSPs <IMG src='<portletAPI:encodeURI path='<%= "images/a001ani.gif" %>'/>' /> 3.4.2 Generated classes Selecting Basic portlet in the wizard will generate two classes for you. To alter the default implementation, see “Default files” on page 149. Portlet This is a simple portlet extending from PortletAdapter and implementing the four modes a portlet may support. Each method is very similar to the code in Example 3-2. Of course, each doXXX method will call the appropriate JSP. Example 3-2 Functionality of the doXXX methods // Make a bean PortletOneBean bean = new PortletOneBean(); // Save name in bean bean.setPortletName("PortletOne portlet"); // Save bean in request request.setAttribute("PortletOneBean", bean); // Invoke the JSP to render getPortletConfig().getContext().include("/jsp/View.jsp", request, response); PortletBean This simple bean extends from the object and contains a single property with the appropriate getters and setters. Example 3-3 demonstrates the code in the bean. Example 3-3 Functionality of the PortletBean public class PortletOneBean { private String portletName = ""; public void setPortletName(String s) { portletName = s; } public String getPortletName() { return (portletName); } } Chapter 3. Using the Portal Toolkit 133 View.jsp Several JSPs are created for you by the wizard. They are simple in functionality. They retrieve the bean from the request object and print out the name property. Example 3-4 displays the code. Each of the JSPs have the same functionality, though different text, of course. Of note is the fact that initially, no DOCTYPE or head tags are included. As soon as you make a change and save the JSP, WebSphere Studio Application Developer will insert a DOCTYPE and head tags. See “Configuring Studio for portlet development” on page 148 for details on disabling this feature. Also, notice that the portlet.tld tag library has not been declared. In order to make use of the portlet custom tags, you will need to add the tld declaration. Example 3-4 JSP code <%@ page contentType="text/html"%> <jsp:useBean id="PortletOneBean" class="com.yourco.portlets.PortletOneBean" scope="request" /> <h1>This is <%=PortletOneBean.getPortletName()%></h1> <br> <h2>Operating in View mode</h2> 3.5 Portlet.xml interface To facilitate creating, organizing and updating the portlet.xml deployment descriptor, the Portal Toolkit provides an intuitive interface. This interface is accessed by double-clicking the portlet.xml file. For details on the elements in the portlet.xml deployment descriptor, see “portlet.xml” on page 45. Since the interface is rather intuitive, this section will cover some of the more important fields and points of concern. The interface allows you to select the contained components and work with a screen dedicated to that element. For example, Figure 3-14 demonstrates working with the abstract portlet application. The wizard will create unique IDs for the abstract and concrete applications. These values are large and entirely unmemorable. Feel free to change the value to something more meaningful but still unique. A best practice is to create the application name from your organization name. For example the ID, com.yourco.portlets.PortletOne.1234 follows the guidelines given in “UID guidelines” on page 55. 134 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-14 Working with the abstract portlet application If you want to add more portlets for deployment, select the Add portlet button. The resulting dialog, shown in Figure 3-15, will allow you to add portlets already defined in the associated web.xml. You cannot add portlets already defined in the abstract application. Figure 3-15 Add Portlet Contained in the abstract application are the abstract portlets to be deployed in this application. Figure 3-16 shows the interface for working with the abstract portlets. Chapter 3. Using the Portal Toolkit 135 If you change the ID field, the corresponding concrete portlet’s ID will also change. The Browse button associated with the Servlet field will only show servlets defined in the web.xml. Figure 3-16 Working with abstract portlets The supports section allows you to add or remove predefined markup languages. If you need to add custom markup languages, they must be manually entered into the portlet.xml via the source tab. The configuration parameters will actually enter servlet-init parameter definitions into the corresponding servlet in the web.xml. Each portlet.xml may only define a single abstract portlet application. However, since it may contain any number of concrete applications, you can choose to add new concrete portlet applications based on the abstract application. By selecting the New Concrete Portlet Application button, a new, empty application will be created. Though the ID and so forth will be created for you, you must add portlets. The Concrete Portlet Application interface provides the opportunity to set the context parameters of the application. The Concrete Portlet Applications window is shown in Figure 3-17. You are also free to change the UID if you like but keep in mind that it must be unique throughout the entire portal environment. 136 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-17 Working with Concrete Portlet Applications The final window allows you to work with the actual concrete portlets that will eventually be seen by end users. This screen allows you to set the title that will be seen in the title bar of the portlet. You can choose to set the contents for language blocks by selecting Add, choosing the locale and completing the title field. You may also choose to complete the keywords, description and short-title fields. Figure 3-18 displays the interface for this final window. The configuration parameters can be set for the portlet by settings in the text area. Chapter 3. Using the Portal Toolkit 137 Figure 3-18 Working with Concrete portlets At any time, you can choose to manually edit the source file by selecting the Source tab at the bottom of the interface. When you have completed working with the portlet.xml, use CTRL-S to save the file. Tip: When a file has unsaved changes, an asterisk will appear beside the name in the Title tab. Be sure to check for unsaved changes in other perspectives as well. 3.6 Deploying portlets Once you have created, edited and configured your portlet application, you must deploy the portlet application. You have two options when choosing to deploy, depending on the target server. If you are intending to debug the portlet and have set up a WebSphere Portal installation connection to WebSphere Studio Application Developer, you can choose to Run on Server. If you are deploying to a full Application Server installation and not connected to the WebSphere Studio Application Developer environment you need to export a WAR file. 138 IBM WebSphere Portal V4 Developer’s Handbook 3.6.1 Deploying to an independent WebSphere Application Server To deploy the portlet application, the webApplication directory must be packaged into a WAR file. To create a WAR file for deployment, select the application and right-click it. From the context menu, select Export WAR.... You can also get this option from the menu by clicking File -> Export and selecting WAR File from the list of options. Either approach will result in the window presented in Figure 3-19. Figure 3-19 Exporting the Portlet Application as a WAR You can only choose a valid Web project although you may deploy it to any accessible directory under any name you like. As a matter of good practice, you should choose to deploy to the same location each time. You can choose to export the source with the WAR file by selecting the appropriate box. Bear in that this will not include the source folder. It will simply add the files in the source directory to the WEB-INF\classses directory containing the compiled class files. The source directory itself or other directories placed off the root of the project are never exported. Once the WAR file has been exported, you must open the WebSphere Portal administration window by logging in to the portal and navigating to the Chapter 3. Using the Portal Toolkit 139 administration place. In the administration place, select the Portlets page and select the Install Portlets portlet. This is demonstrated in Figure 3-20. Figure 3-20 Installing a WAR file Using the Browse button, navigate to the directory containing the WAR file you exported. Select the file and click Next. The portal server will parse the portlet.xml and display the application and contained portlets being deployed as demonstrated in Figure 3-21. Figure 3-21 Determining the application and portlets Once the installation is successful, you must add the portlet to a page using the Work with Pages place, in order to test it. Updating the application After you test the portlet, determine whether changes are necessary and alter the code, you need not step through the entire process outlined above. From WebSphere Studio Application Developer, export the updated WAR and return to the Portal administration place and portlet page. Select Manage Portlet Applications and from the list, locate the war file you initially deployed. This is demonstrated in Figure 3-22. Select the Update link, locate the updated WAR 140 IBM WebSphere Portal V4 Developer’s Handbook file and click Next. There is no need to remove and re-add the portlet to the page it was originally on. When you revisit the original page, the update portlet should be available. Figure 3-22 Updating an existing Portlet Application When you choose to update an application, the portal server attempts to match the UIDs set in the portlet.xml. If the UIDs from the original portlet.xml and the updated application do not match, the update will fail. 3.6.2 Deploying to a connected WebSphere Application Server This option assumes you have connected a WebSphere Application Server Single Server Edition to the WebSphere Studio environment to enable debugging. Refer to Chapter 4, “Portlet testing and debugging” on page 153 to set up connection between WebSphere Studio Application Developer and WebSphere Application Server. In order for your portlet to be published to the target server, the EAR containing the WAR must be associated with the Server. Switch to the Server perspective and add the EAR to the server configuration as demonstrated in Figure 3-23. Chapter 3. Using the Portal Toolkit 141 Figure 3-23 Associating a EAR with a server Once the project has been added to the server configuration, you can switch back to the portlet perspective and select the Portlet Application you want to test. Right-click and from the context menu select Run On Server as shown in Figure 3-24. The project will be published to the server and if necessary, the server will be started. This is also demonstrated in Figure 3-24. Figure 3-24 Running a Portlet on server Once the server has been published and started, an internal Web browser is used to call the Portal. Notice that you do not need to install the portlet or place it on a page. This is done for you as shown in Figure 3-25. 142 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-25 Deployed portlet 3.7 Adding portlets to applications The Portlet Application wizard will only create a single portlet in the portlet application. It is very likely that your application will need to contain more than one portlet, however. In addition to actually creating and coding the new portlet, you must add it to the appropriate deployment descriptors. There are a couple of options you have when creating a new portlet. Create a new class While there is no wizard for creating a single portlet, you can easily use the traditional Java class wizard. In the Portlet perspective, select the portlet application and right-click it. From the context menu, select New -> Other. In the resulting dialog, select Java from the list of types on the left. Then select Java Class. In the new class smart guide, enter the information for your new portlet. Be sure to select the appropriate parent class as shown in Figure 3-26. Chapter 3. Using the Portal Toolkit 143 Figure 3-26 Creating a new portlet class Copy the current portlet You can also choose to make a copy of the portlet the wizard created for you. Select the portlet, right-click and select Copy from the context menu. Accept the default location for the copy as demonstrated in Figure 3-27. The copy will have the name of the original portlet with “copy of” prefixed. 144 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-27 Copying a portlet When the copy is complete, you will get an error indicating that the name of the Java class does not match its declaration. Open the Java file and change the class declaration. When done, use CTRL-S to save the file. WebSphere Studio Application Developer will prompt you as to whether you would like to change the compilation unit. Select Yes and, when done, you will notice that the name of the portlet in the navigator has been changed for you. Add the portlet to Web.XML In order for the new portlet to be deployed, it must be defined in the deployment descriptors. Initially, it needs to be added to the web.xml as a servlet. In the portlet perspective, double-click the web.xml contained in the WEB-INF directory of your portlet application. Select the Servlets tab on the bottom and click New as demonstrated in Figure 3-28. Chapter 3. Using the Portal Toolkit 145 Figure 3-28 The Web.xml interface From the resulting dialog, enter the name of the new portlet. This dialog is case sensitive. Click Add once you have located the new portlet. Though not required in the WebSphere Studio Application Developer environment, a URL mapping is required by the Portal Server. In the list of servlets, select the new portlet and click Add in the URL mappings area as shown in Figure 3-29. Enter a mapping and use CTRL-S to save the web.xml. Figure 3-29 Creating a URL mapping for the new portlet 146 IBM WebSphere Portal V4 Developer’s Handbook Add the portlet to Portlet.xml Finally, the portlet must be included in the portlet.xml deployment descriptor. In the portlet application, double-click the portlet.xml file. Select the abstract portlet application and click the New Portlet button as demonstrated in Figure 3-30. Figure 3-30 Adding new portlet to abstract application The resulting dialog is shown in Figure 3-31. You will only be allowed to add portlets that have been defined in the web.xml and are not yet declared in the portlet.xml. If the new portlet you want to deploy is not presented as an option, be sure it has been added to the web.xml and the web.xml has been saved. Select the portlet you wish to deploy and click OK. Figure 3-31 Selecting portlet for deployment Chapter 3. Using the Portal Toolkit 147 Use CTRL-S to save the deployment descriptor. Once the updated application is saved, deploy the application to the target server. Refer to “Deploying portlets” on page 138 for information on updating portlets in a standalone server and an associated server. 3.8 Configuring Studio for portlet development The Portal toolkit is a powerful, comprehensive tool for creating and working with Portlet Applications. However, the very nature of the WebSphere Studio environment allows you to customize the development environment to suit your specific development needs. This section will discuss a few common configuration issues you may want to consider. 3.8.1 JSP heads and metadata Generally, whenever a JSP is created or saved in WebSphere Studio, certain metadata and head tags are added to the JSP. The Portal Toolkit does not add these tags to the generated JSPs. However, if you change and save the JSPs, as you are likely to do, Studio will insert the tags by default. These tags are not required and can potentially cause difficulties when the portlet is aggregated. These tags are demonstrated in Example 3-5. Example 3-5 Generated Page Tags <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <HTML> <HEAD> <META name="GENERATOR" content="IBM WebSphere Studio"> </HEAD> </HTML> To disable this feature, select Window -> Preferences -> Web Tools -> Files and deselect Insert this DOCTYPE and Include GENERATOR. This is shown in Figure 3-32. Now, whenever a Web page is saved, it will not include the generated content. 148 IBM WebSphere Portal V4 Developer’s Handbook Figure 3-32 Disabling the DOCTYPE and GENERATOR 3.8.2 Default files When you create a new portlet application, the default JSPs have the content displayed in Figure 3-33. Figure 3-33 Default JSP Since this is probably not of particular use in your environment, you can alter the template that the JSP files are based on to create something more meaningful. The same approach applies to the Java files generated by the wizard. It is strongly recommended that you create backups of the templates prior to altering Chapter 3. Using the Portal Toolkit 149 their content. The templates used to create the files for a Basic Portlet are located in Program Files\IBM\ Application Developer\plugins\com.ibm.pvctools.portlettools\ templates\AbstractPortlet. This directory contains the following templates: chtmlPage.jsp Used for all JSPs file contained in a chtml folder. defaultPage.jsp Used for all JSPs not contained in a markup specific directory. htmlPage.jsp Used for all JSPs generated in the html directory. JavaBean.jsp Used to create the framework for the model of your portlet application. You may choose to add common or required class structures unique to your organization. Portlet.java Used to generate the Portlet class. If you have created a parent portlet from which you wish all new portlets to extend, you can alter the class definition here. Also, if you find you rarely implement a particular do method, you may choose to make it a skeleton or to delete it all together. Example 3-6 demonstrates an example where the developer normally implements only the doView and doEdit and always requires a PortletAction in the edit mode. vxmlPage.jsp Used to create all JSPs in a vxml directory if your portlet chose to support this markup. wmlPage.jsp Used to create all JSPs in a wml directory if your portlet chose to support this markup. Example 3-6 Altering the Portlet.java template import java.io.*; import org.apache.jetspeed.portlet.*; public class %CLASSNAME% extends PortletAdapter { public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { getPortletConfig().getContext().include("/jsp/View.jsp", request, response); } public void doEdit(PortletRequest request, PortletResponse response) throws PortletException, IOException { PortletURI uri = response.createReturnURI(); PortletAction go = new DefaultPortletAction("go"); uri.addAction(go); request.setAttribute("uri", uri); getPortletConfig().getContext().include("/jsp/Edit.jsp", request, response); } } 150 IBM WebSphere Portal V4 Developer’s Handbook The Program Files\IBM\ Application Developer\plugins\com.ibm.pvctools. portlettools\ templates\ directory also contains folders for the other types of Portlet Applications that can be created by the wizard. 3.8.3 Macros There may be a significant amount of JSP code you find yourself writing over and over again in various situations. For example, retrieving a uri object and using it to create a basic form is a simple, repetitive task that requires little customization or thought. This task can be fully automated through macros. A macro allows you to insert a block of code with a short-name. To create a new macro, select from the menu Window -> Preferences -> Web Tools -> Source -> Macros. Select Add and enter the name of the new macro. In the text area, enter the code for your new macro. The interface is shown in Figure 3-34. Figure 3-34 Creating a new macro Chapter 3. Using the Portal Toolkit 151 To execute the macro, in the Source tab of the JSP editor, use CTRL-spacebar and from the list, select the macro you have created as demonstrated in Figure 3-35. In the WebSphere Studio Application Developer V 4.0.3, there is no ability to create macros for your Java development. Figure 3-35 Executing a macro 152 IBM WebSphere Portal V4 Developer’s Handbook 4 Chapter 4. Portlet testing and debugging This chapter is designed to walk you through the process of setting up the development environment for developing, testing and debugging WebSphere Portal applications. In this chapter, we will examine the software that needs to be installed and the steps for configuring it. In this chapter we will: Install the prerequisite software Configure the environment Write and debug a portlet (both code and JSP) © Copyright IBM Corp. 2003. All rights reserved. 153 4.1 Overview This chapter contains an overview of what components are needed to create an environment to developing, testing and debugging portlets using the WebSphere tooling. 4.1.1 Development There are two alternatives for developing portlets and portal applications. One alternative is to simply use a plain text editor and the Java JAR utility to create portlet application WAR files to be deployed in an application server. A more attractive alternative is to use the Portal Toolkit plugin for WebSphere Studio Application Developer to develop portlets and portlet applications. This is the development strategy that will be discussed in this chapter. 4.1.2 Testing WebSphere Studio Application Developer contains and runs a copy of WebSphere Application Server Developer’s Edition (WebSphere Application Server Advanced Edition Single Server with the licensing restriction of a “developer only” license). Unfortunately, during the writing of this book we were not able to install WebSphere Portal on the WebSphere Studio Application Developer internal Application Server. Thus we have a couple of options for the testing portion of our portal development environment. The first option is developing in WebSphere Studio Application Developer with the Portal Toolkit plugin and exporting portlet WAR files. The portlet WAR files are then deployed on WebSphere Application Server Advanced Edition or a single server running WebSphere Portal. This solution is not ideal because you lose a substantial amount of the powerful debugging capabilities provided by WebSphere Studio Application Developer, but it is often necessary because WebSphere Application Server Single Server does not provide the entire infrastructure necessary for all portlet development; only enable functionality is supported. Alternatively, WebSphere Studio Application Developer has the ability to test against a remote server, but this is restricted to WebSphere Advanced Edition Single Server remote servers. Therefore, we must install WebSphere Application Server AEs and configure WebSphere Studio Application Developer to test with an external WebSphere Application Server AEs as a remote server. This allows the use of the WebSphere Studio Application Developer debugging capabilities. 154 IBM WebSphere Portal V4 Developer’s Handbook Limitations Using WebSphere Application Server AEs instead of WebSphere Application Server AE poses some limitations. The current version of WebSphere Portal only supports the installation of WebSphere Portal Enable on WebSphere Application Server Single Server as it installs out of the box. Therefore, testing collaboration portal components poses a challenge. Using WebSphere Application Server AEs also poses a limitation with respect to testing security other than the main login page since WebSphere Application Server AEs does not allow for the use of an LDAP source or a custom registry in its configuration. This, however, does provide a viable testing environment for a majority of portal development scenarios and is the one we will detail in this chapter. A final alternative is to deploy the portal application into a remote server and test the Portlet application as a remote Java application. This allows for the debugging environment of WebSphere Studio Application Developer along with testing against a WebSphere Portal extend install. 4.1.3 Components To configure the portlet development, test and debug environment, you need the following components: WebSphere Studio Application Developer (WSAD) V4.0.3 or later or WebSphere Studio Site Developer (WSSD) V4.0.3 or later Portal Toolkit V4.1 Enable Edition Personalization Toolkit (optional) Note that even if you do not install the Personalization Toolkit for use in developing Personalization solutions, two JAR files are required by WebSphere Portal. WebSphere Application Server Advanced Single Server Edition (WAS AEs) V4.0.2 and Portal Server V4.1.2 or WebSphere Application Server Advanced Single Server Edition (WAS AEs) V4.0.3 and Portal Server V4.1.4 IBM DB2 Universal Database V7.2 with FP 5 or later IBM Agent Controller (optional) – This is necessary for remote debugging against WebSphere Application Server Single Server on a remote server Chapter 4. Portlet testing and debugging 155 DB2 WebSphere Studio Application Developer Personaization Toolkit WebSphere Application Server Advanced Single Server Edition Portal Toolkit Portal Server (optionally) IBM Agent Controller Figure 4-1 Portlet development, test and debug environment You can put all components on one machine as shown in Figure 4-1. This requires a rather well equipped PC (at least 1 GB of memory and a 1GHz processor), especially if your portal is part of a larger Web application. Therefore, you might want to split the components and install them on two machines as depicted in Figure 4-2 on page 157. 156 IBM WebSphere Portal V4 Developer’s Handbook DB2 WebSphere Studio Application Developer WebSphere Application Server Advanced Single Server Edition Personalization Toolkit Portal Toolkit Portal Server Agent Controller Agent Controller Network Figure 4-2 Components in a configuration with two computers Note that in this configuration, IBM Agent Controller has to be installed on both systems. Of course, you could go even further and put DB2 on yet another machine, but we will not cover this option. Next, we give a very brief overview of the components involved and pointers to other chapters in this book or other resources where you will find more information. WebSphere Studio Application Developer (WSAD) IBM WebSphere Studio is an integrated application development environment that provides a "portal-like" integration of best-of-breed tools including the Portal Toolkit. The WebSphere Developer Domain (http://www7b.software.ibm.com/wsdd) is a good starting point. At the time of writing, the toolkit is only available for WebSphere Studio Application Developer and WebSphere Studio Site Builder V4.0.3. Chapter 4. Portlet testing and debugging 157 Portal Toolkit The IBM Portal Toolkit Version 4.1 provides the capabilities to customize and manage the enterprise portal and create, test, debug and deploy individual portlets and Web content. Templates enable developers to quickly and easily create their own portlets. Debugging and deployment tools shorten the development cycle. Sample portlets that demonstrate best programming practices are also provided.The Portal Toolkit plugs into the IBM WebSphere Studio Workbench. For an in-depth discussion of the WebSphere Portal Toolkit and its use in WebSphere Studio Application Developer, see Chapter 3, “Using the Portal Toolkit” on page 119 and the WebSphere Platform - Portal Toolkit. WebSphere Application Server Advanced Single Server Edition (WAS AEs) The Single Server Edition supports all of the J2EE APIs (including support for EJBs) in an entry-level, single server environment. This server is ideal for building stand-alone or departmental applications that are transaction- or message-oriented and do not require failure bypass, workload management, enhanced security, or remote administration. WebSphere Portal 4.1.2 will only install on WebSphere Application Server version 4.0.2. This version level can be achieved by installing WebSphere Application Server version 4.0 and installing FixPak 2. Database DB2 DB2 is IBM's relational database management system for AIX®, Linux, HP-UX, Sun, and Windows. Note that DB2 is not required for WebSphere Application Server Advanced Single Server edition (WAS AEs). WebSphere Application Server AEs manages all its configuration information in XML files. DB2 is, however, required for WebSphere Portal when installing on WebSphere Application Server AEs. This is due to the fact that there is no LDAP involved in WebSphere Application Server AEs. WebSphere Portal must install its configuration information in the database. WebSphere Portal requires DB2 version 7.2 with FixPak 5 installed. IBM Agent Controller Agent Controller is a daemon process that provides the mechanism by which client applications either launch new host processes, or attach to agents that coexist within existing host processes. It is used by the remote testing and 158 IBM WebSphere Portal V4 Developer’s Handbook performance profiling tools in WebSphere Studio Application Developer. It is automatically installed when you install WebSphere Studio Application Developer or can be installed manually from the WebSphere Studio Application Developer install CD. Be sure to use the correct Agent Controller for the version of WebSphere Studio Application Developer you are using. This is normally not an issue since the RAC is installed as part of the default installation of WebSphere Studio Application Developer and as a service it is set to automatic. This may become an issue if you have installed varying versions of WebSphere Studio Application Developer on the same machine, such as 4.0.3 and 5.0. The last version that is installed will be started by the service menu and may be incompatible with the version of WebSphere Studio Application Developer you are working from. 4.2 Installing the components This section details the installation of the components necessary to set up and configure a WebSphere Portal development environment. The instructions provided here are high-level instructions and, where appropriate, you are directed to more detailed installation instructions. 4.2.1 WebSphere Studio Application Developer Developing portlets from WebSphere Portal is best done in WebSphere Studio Application Developer with the Portal Toolkit. Installation steps to install WebSphere Studio Application Developer are as follows. More detailed instructions can be found in the WebSphere Studio Application Developer Programming Guide (SG24-6585). To install WebSphere Studio Application Developer: 1. Start with CD 6-1 of the WebSphere Portal CDs. 2. Run <CD-Drive>\wsad\win\setup.exe. 3. Click Next on the Welcome window. 4. Accept the license agreement and click Next. 5. Accept the default installation folder or change the installation folder and click Next. 6. Choose the default user role. This does not affect the install. It only determines the perspective displayed with WebSphere Studio Application Developer is initially invoked. Click Next. 7. Select the version control interface you will be using and click Next. Chapter 4. Portlet testing and debugging 159 8. Click Install to install WebSphere Studio Application Developer to your machine. 9. Once the installation is complete, click Finish to complete the install. 4.2.2 Portal Toolkit Once WebSphere Studio Application Developer is installed, we install the Portal Toolkit plugin for it. For detailed instructions on installing the Portal Toolkit, see Chapter 3, “Using the Portal Toolkit” on page 119. The installation of the Portal Toolkit places all the necessary files into the WebSphere Studio Application Developer plugin configuration.Following are the steps for installing the WebSphere Portal Toolkit for WebSphere Studio Application Developer. 1. Insert CD 3-3, run <CD Drive>\PortalToolkit\install.bat to start the Portal Toolkit installation. 2. Click Next on the Welcome window. 3. If WebSphere Studio Application Developer is running, stop it and click Next. 4. Accept the license agreement and click Next. 5. Confirm the WebSphere Studio Application Developer installation directory and click Next.. 6. Click Next at the installation summary. 7. Click Next when the installation is complete and the uninstaller has been created. 8. View the readme and click Finish to view the readme and complete the install. To verify that you have successfully installed the Portal Toolkit in WebSphere Studio Application Developer, start WebSphere Studio Application Developer; you should now be able to create a Portlet Application Project as seen in Figure 4-3. 160 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-3 Creating a Portlet Application Project 4.2.3 Personalization Toolkit If you will be doing personalization work , there is a Personalization Toolkit similar to the Portal Toolkit for doing personalization work. The Personalization Toolkit installs as a plugin for WebSphere Studio Application Developer and provides wizards for building personalization into your Web applications. To install the personalization toolkit: 1. Start the Personalization Toolkit install by executing PznStudioDeveloperWizards.exe. 2. On the Welcome window, click Next. 3. Accept the license agreement and click Next. 4. Confirm or change the WebSphere Studio Application Developer installation directory as per your installation and click Next. 5. Review the installation summary and click Next to start the install. 6. When the installation is complete, click Finish. 4.2.4 DB2 Universal Database DB2 Universal Database is needed for WebSphere Portal Server. DB2 Universal Database V7.2 with FixPak 5 is required for running WebSphere Portal V4.1.2 so we install the base V7.2 and FP5. Chapter 4. Portlet testing and debugging 161 Installing DB2 Universal Database V7.2 To install DB2 Universal Database V7.2: 1. Insert CD 2-1 and run <CD Drive>\db2\win\setup.exe 2. Click Install to start the installation. 3. Select DB2 Enterprise Edition and click Next. 4. Select Typical as the installation type and click Next.. 5. Specify the installation directory and click Next. 6. Specify the DB2 administrator’s userid/password and click Next. – If the user does not exist: If prompted, click Yes to create the userid/password. – If the user already exists: You may receive a warning that the current user does not have the necessary privileges to validate the user specified. This will not affect the installation, so click OK. 7. Click Next of the configuration summary to start the install. 8. When prompted to install the OLAP starter kit, choose not to install the OLAP starter kit and click Continue. 9. On the Setup Complete window select No, I will restart my computer later, and click Finish to complete the installation. 10.Click Exit when the DB2 First Steps window appears. 11.Complete the product registration, if necessary. Selecting the JDBC 2.0 drivers Once UDB is installed, we must specify that we want to use the JDBC 2.0 drivers. To do this: 1. Verify that all the DB2 processes are stopped. a. Right-click My Computer, and select Manage. b. Select Services and Applications from the left hand tree. c. Double-click Services in the right hand panel to open the services window. d. Locate all the services that start with DB2 and for all the ones that have a status of Started, then right -lick the service and select Stop. 2. Open a Windows command prompt. 3. Navigate to <DB2 install dir>\SQLLIB\java12. 162 IBM WebSphere Portal V4 Developer’s Handbook 4. Type: usejdbc2. This will execute the usejdbc2.bat file. If you receive violation messages, you most likely have DB2 processes running. Make sure all the DB2 processes are stopped and try again. 5. Test the selection by typing: type inuse. This will dump the contents of the inuse file, which should be displayed as JDBC 2.0 as illustrated in Figure 4-4. Figure 4-4 JDBC 2.0 inuse Installing DB2 Universal Database V7.2 FixPak 5 1. Insert CD 2-10 and run <CD Drive>\db2fp\win\setup.exe. 2. If prompted, click Yes to terminate the running DB2 processes. 3. Verify the installation directory and click Next. 4. Specify the appropriate information for the Data Warehouse Control Database (DWCTRLDB) and click Next. 5. If an informational message is displayed indicating that the currently logged on user doesn’t have the rights to validate the userid and password specified in the previous step, click OK. 6. In the setup confirmation window, click Next to start the install. 7. Once finished, select Yes, I want to restart my computer now to restart the system and click Finish. 4.2.5 WebSphere Application Server Advanced Single Server As noted in “Limitations” on page 155, WebSphere Application Advanced Single Server (WAS AEs) is required for testing Portal applications with WebSphere Studio Application Developer. In this section, we install WebSphere Application Server AEs along with the appropriate FixPak and fixes. Chapter 4. Portlet testing and debugging 163 Installing WebSphere Application Server AEs V4.0 1. Insert CD 3-3, and run <CD Drive>\was\win\setup.exe to start the installation of WebSphere Application Server AEs. 2. Select the language for your installation as seen in Figure 4-5 and click OK. Figure 4-5 WebSphere Application Server AEs installation language choice 3. Click Next on the warning window as seen in Figure 4-6 to start the install. Figure 4-6 WebSphere Application Server AEs installation Welcome window 4. With WebSphere Studio Application Developer, we do not need the IBM HTTP Server. We use the internal HTTP server provided with the application server. Installing the IBM HTTP Server more closely emulates the true runtime environment with such functionalities as the ability to serve static content from the HTTP server. Either option is viable for portlet development. 164 IBM WebSphere Portal V4 Developer’s Handbook Choose Custom Installation (Figure 4-7) and click Next. Figure 4-7 WebSphere Application Server AEs installation Custom Install selection 5. Deselect the IBM HTTP Server and the WebServer Plugin as seen in Figure 4-8 and click Next. Chapter 4. Portlet testing and debugging 165 Figure 4-8 WebSphere Application Server AEs installation choose components 6. Verify the installation directory (Figure 4-9) and click Next. Important: If you already have WebSphere Application Server Advanced Edition (WAS AE) installed on your machine, the default directory for installing WebSphere Application Server Single Server (WAS AEs) is the same as the default for WebSphere Application Server AE. Be sure to specify a different install directory if you want both WebSphere Application Server AE and WebSphere Application Server AEs to remain functional. 166 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-9 WebSphere Application Server AEs installation directory 7. Verify the program folder information as seen in Figure 4-10 and click Next. Figure 4-10 WebSphere Application Server AEs installation program folder 8. Verify the installation summary (Figure 4-11) and click Next to start the installation. Chapter 4. Portlet testing and debugging 167 Figure 4-11 WebSphere Application Server AEs installation summary 9. When the installation is complete, click Finish in the Setup Complete window to complete the installation. Figure 4-12 WebSphere Application Server AEs installation Readme 168 IBM WebSphere Portal V4 Developer’s Handbook Installing WebSphere Application Server AEs V4.0 FixPak 2 We have just installed WebSphere Application Server Advanced Single Server V4.0.1. We must upgrade this to V4.0.2 for use with WebSphere Portal 4.1.2. This section guides you through the upgrade to WebSphere Application Server AEs 4.0.2. 1. Insert CD 3-3, and copy the <CD Drive>\was\win\fixpack2 directory to your hard drive (or somewhere that you have write access). The FixPak 2 installation needs to write some files to complete its install process so it will not run directly from the CD. 2. From the directory where you copied the FixPak 2 files, run install.bat to start the installation process. 3. Press Enter to acknowledge that the Application server is not started. Figure 4-13 WebSphere Application Server AEs 4.0.2 update 4. Enter the installation directory where WebSphere Application Server AEs is installed, as seen in Figure 4-13. 5. The WebSphere Application Server and JDK file are now updated as seen in Figure 4-14. Once complete, press any key to continue. Chapter 4. Portlet testing and debugging 169 Figure 4-14 WebSphere Application Server AEs 4.0.2 update successful 6. When prompted to upgrade the IBM HTTP server, type NO and press Enter, as we will not use the IBM HTTP Server with our WebSphere Application Server AEs install. Installing WebSphere Application Server AEs V4.0.2 fixes Finally, we must install fix PQ56615 to endure that WebSphere Portal V4.1.2 will install and run properly on our WebSphere Application Server AEs installation. To do this: 1. Insert CD 3-3 2. Open a Windows command prompt and navigate to the <CD Drive>\was\eFixes directory. 3. From the command prompt, execute the following command: <WAS Install Dir>\java\bin\java -jar PQ56615_eFix_AEServer_AEsServer.jar 4. When prompted, enter the installation directory for WebSphere Application Server AEs as seen in Figure 4-15. 170 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-15 WebSphere Application Server AEs 4.0.2 fix PQ56615 5. Verify there were no errors, as shown in Figure 4-16. Figure 4-16 WebSphere Application Server AEs 4.0.2 fix PQ56615 installation complete without errors Validating the WebSphere Application Server AEs install We now validate the WebSphere Application Server AEs install before continuing with the WebSphere portal installation. To do this: Chapter 4. Portlet testing and debugging 171 1. Start the WebSphere Application Server Advanced Single server by selecting Start->Programs->IBM WebSphere->Application Server AEs->Start Application Server. Figure 4-17 Starting WebSphere Application Server Single Server Edition 2. WebSphere Application Server AEs does not by default run as a service; it will be started in a command window, as seen in Figure 4-18. Important: Closing the command window will stop the application server, so leave the command window open. Figure 4-18 WebSphere Application Server AEs started 3. Once the Application server is started, verify that it is installed correctly by invoking the Snoop servlet from a browser via the URL: 172 IBM WebSphere Portal V4 Developer’s Handbook http://<your server domain>:9080/servlet/snoop where <your server domain> is your server URL. 4. The snoop servlet will appear in your browser as seen in Figure 4-19. Figure 4-19 Snoop Servlet running on WebSphere Application Server AEs Adding the Stop Server icon The WebSphere Application Server Single Server Edition only installs an icon for starting the application server. You can add an icon for stopping the application server by opening the program folder for IBM WebSphere AEs and creating a stop icon. To do this: 1. Select Open All Users from the menu of the Start icon as seen in Figure 4-20. Chapter 4. Portlet testing and debugging 173 Figure 4-20 Open All Users program menu 2. Select and open the Program folder. 3. Select and open the IBM WebSphere folder. 4. Select and open the Application Server 4.0 AEs folder. 5. Select and copy the Start Application Server icon. Figure 4-21 Copying the Start Application Server Icon 6. Paste the icon back into the same folder and an icon called Copy of Start Application Server will be created. 7. Open the icon’s properties. 8. Change the icon’s name to Stop Application Server as seen in Figure 4-22 174 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-22 Stop Application Server Icon General Properties 9. Change the icon’s shortcut to: <WAS AES Install Root>\bin\stopserver.bat as seen in Figure 4-23. Chapter 4. Portlet testing and debugging 175 Figure 4-23 Stop Application Server Icon Shortcut Properties 10.Close the properties file by clicking OK. 11.You should now have Stop and Start icons as seen Figure 4-24. Figure 4-24 Start and Stop Server icons 4.2.6 Portal server We must now install WebSphere Portal on our installation of WebSphere Application Server AEs. This section guides you through this installation process. 176 IBM WebSphere Portal V4 Developer’s Handbook WebSphere Personalization JARs WebSphere Portal requires two JAR files from the WebSphere Personalization, prCommon.jar and personalization.jar. At the writing of this book, WebSphere Personalization did not install on WebSphere Application Server Advanced Single Server (WAS AEs), so we must copy the two necessary personalization JARs in order to have WebSphere Portal function properly. To do this: 1. Insert CD 3-3. 2. Copy the following files from <CD Drive>\external\personalization to <WAS install dir>\lib\app. – personalization.jar – prCommon.jar Installation configuration This sections guides you through the installation of WebSphere Portal V4.1.2 on WebSphere Application Server Advanced Single Server (WAS AEs). Important: If you have installed WebSphere Application Server Advanced Edition (WAS AE) and WebSphere Application Server Advanced Single Server (WAS AEs) on the same machine, it is important to verify that the %WAS_HOME% environment variable is set properly. To check this, run the command echo %WAS_HOME% from a Windows command prompt and verify that it is pointing to your WebSphere Application Server AEs install. To start the installation: 1. Ensure WebSphere Application Server AEs is started as seen in “Validating the WebSphere Application Server AEs install” on page 171 and Figure 4-18 on page 172. 2. Insert CD 7 into the same machine where WebSphere Application Server AEs is installed. 3. Run <CD Drive>\wps\install.bat program to start the installation. 4. Click Next in the Welcome window seen in Figure 4-25. Chapter 4. Portlet testing and debugging 177 Figure 4-25 WebSphere Portal install Welcome window 5. After the installation program checks to make sure the application server is started, click Next in the Prerequisites window (Figure 4-26). 178 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-26 WebSphere Portal install Prerequisites Accept the licensing agreement as seen in Figure 4-27, and click Next. Chapter 4. Portlet testing and debugging 179 Figure 4-27 WebSphere Portal license agreement Note: When installing WebSphere Portal on WebSphere Application Server AEs, you are not asked for the type of Portal install you desire. This is because the only choice you have is a development install. The installation process is smart enough to know that you are installing on WebSphere Application Server AEs instead of WebSphere Application Server AE and automatically installs a development install of WebSphere Portal. 6. Enter the Node name of your machine as seen in Figure 4-29. – This value should already be entered for you. You can accept the value. – You can find this information by entering the command hostname from a Windows command prompt. This is typically your computer name specified in the Network identification tab of MyComputer->Properties. – To verify the node name for your WebSphere Application Server AEs install, open the <WAS Install Dir>\config\server-cfg.xml file and search for the string Node_1 as seen in Figure 4-28. 180 IBM WebSphere Portal V4 Developer’s Handbook <nodes xmi:id=”Node_1” name=“mars”> Figure 4-28 Server-cfg.xml node name specification Figure 4-29 WebSphere Portal installation Application Server none name 7. Enter the complete hostname of the machine including the port number 9080, along with the base URI for the portal as seen in Figure 4-30, and click Next. – The hostname is what WebSphere Portal will use to dynamically generate the URLs that access the portal. – WebSphere Application Server uses port 9080 for its internal HTTP server. Since we did not install an internal HTTP server, it is important that we specify port 9080 in the URL. Otherwise, WebSphere portal will default to look at the standard HTTP Port (80) and it will not be found because there is no HTTP server running on port 80. If you chose to install the HTTP server with AEs using the default, port 80 will work fine. Important: The host name must be able to be resolved remotely if WebSphere Studio Application Developer resides on a separate machine. It does not have to be a fully qualified domain name, however, you must be able to access WebSphere Application Server AEs from a browser (as we did in “Validating the WebSphere Application Server AEs install” on page 171) from both the remote and local machine. Chapter 4. Portlet testing and debugging 181 Figure 4-30 WebSphere Portal URL Important: Remember this URL because it is the one you need for the WebSphere Portal toolkit configuration in WebSphere Studio Application Developer. If these values don’t match, the function will not work properly when debugging from WebSphere Studio Application Developer. 8. Specify the URI for the home page and customized page (Figure 4-31) and click Next. Accepting the default values is fine. Figure 4-31 WebSphere Portal Base URI 182 IBM WebSphere Portal V4 Developer’s Handbook 9. Enter the proxy server information in the window seen in Figure 4-32. The only reason you would need a proxy server here is if your portlets access URLs that are outside your firewall. Figure 4-32 WebSphere Portal Proxy specification 10.Choose Deploy base Portlets into Portal Server (Figure 4-33) and click Next. The base portlets are not necessary for testing your portal applications, but this process also updates the default portlet skins information which is required for the portlet you are debugging to be displayed on the page. The base portlets do, however, provide the administration capabilities in WebSphere Portal and in most development scenarios you will quickly have the need to do this, so installing them now is recommended. This can be done manually but it is much more simple to select this option. Figure 4-33 WebSphere Portal Base portlet installation 11.Select the IBM DB2 database type as seen in Figure 4-34 and click Next. Chapter 4. Portlet testing and debugging 183 Figure 4-34 WebSphere Portal database selection 12.Select Create and Initialize an existing database (Figure 4-35)and click Next. It is best to create a new database to be used with the Portal Toolkit to avoid conflicting configuration data from a full WebSphere Portal install. Figure 4-35 WebSphere Portal database creation 13.Enter the WebSphere Portal database configuration information as seen in Figure 4-36 and click Next. – Specify the userid and password you used when installing DB2 in “DB2 Universal Database” on page 161. – Make sure the database name is correct and not in use before continuing. 184 IBM WebSphere Portal V4 Developer’s Handbook Important: The database name you use will be dropped and rebuilt by the installation program, so if you have an existing WebSphere Portal install using the default name of WebSphere Portal 4.1, it is best to specify another name as seen in Figure 4-36. Figure 4-36 WebSphere Portal database configuration 1. Specify the DB2 JDBC drivers as seen in Figure 4-37 and click Next. – The JDBC drivers are typically located where you installed DB2. Important: If this file cannot be located, the install program will ask you for the location again but will not continue the install. – Make sure that your DB2 installation is using JDBC 2.0 drivers (see “Selecting the JDBC 2.0 drivers” on page 162), otherwise WebSphere Portal will fail to install properly. Chapter 4. Portlet testing and debugging 185 Figure 4-37 WebSphere Portal database JDBC configuration 2. Select Create and Initialize an existing database (Figure 4-35)and click Next. It is best to create a new database to be used with the Portal Toolkit to avoid conflicting configuration data from a full WebSphere Portal install. Figure 4-38 WebSphere Portal Member services database creation 3. Enter the WebSphere Member Services database configuration information as seen in Figure 4-36 and click Next. 186 IBM WebSphere Portal V4 Developer’s Handbook – Specify the userid and password you used when installing DB2 in “DB2 Universal Database” on page 161. – Make sure the database name is correct and not in use before continuing. Important: The database name you use will be dropped and rebuilt by the installation program, so if you have and existing WebSphere Portal install using the default name of WMS, it is best to specify another name as seen in Figure 4-39. Figure 4-39 WebSphere Portal Member Services database configuration 4. Click Next to accept the default JDBC URL prefix (Figure 4-40). Figure 4-40 WebSphere Portal Member Services JDBC configuration Chapter 4. Portlet testing and debugging 187 5. Enter the installation directory for WebSphere Portal Server (Figure 4-41) and click Next. Important: If you already have WebSphere Portal installed on your machine with WebSphere Application Server AE, the default directory for installing Portal on WebSphere Application Server AEs is the same as the default for WebSphere Application Server AE. Be sure to specify a different install directory if you want both WebSphere Application Server AE and WebSphere Application Server AEs to remain functional. For further information on installing WebSphere Application Server AE and WebSphere Application Server AEs on the same machine, see Running Co-Existing installation of WebSphere Application Server. Figure 4-41 WebSphere Portal installation directory 6. Click Next to start the installation process (Figure 4-42). 188 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-42 WebSphere Portal ready to install Installation The second phase of the process to install WebSphere Portal on WebSphere Application Server Advanced Single Server (WAS AEs) builds the database and configures the serer for WebSphere Portal. 1. After clicking Next in Figure 4-42, the installation process starts copying the necessary files. You should see the message Installing WebSphere Portal and a progress bar. 2. When complete, the install process creates the WebSphere Portal database as seen in Figure 4-43. Click Next. Figure 4-43 WebSphere Portal database creation Chapter 4. Portlet testing and debugging 189 3. The WebSphere Portal database will be initialized as seen in Figure 4-44. Click Next. Figure 4-44 WebSphere Portal database initialization 4. Next, the WebSphere Member Services database is created and initialized as seen in Figure 4-45 and Figure 4-46. Click Next when prompted. Figure 4-45 WebSphere Portal Member services database created 190 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-46 WebSphere Portal member Services database initialized 5. A final update is done to the WebSphere Portal database based on the information created in the Member Services database as seen in Figure 4-47. Click Next. Figure 4-47 WebSphere Portal Database update 6. Additional updates are also made to the WebSphere Member Services database as seen in Figure 4-48; this completes the database creation and initialization for WebSphere Portal. Click Next to continue. Chapter 4. Portlet testing and debugging 191 Figure 4-48 WebSphere Portal Member Services database initialized 7. The application server is now configured as seen in Figure 4-49. Three portal enterprise applications are installed so this may take a few minutes, depending on your machine configuration. Figure 4-49 WebSphere Server configuration 192 IBM WebSphere Portal V4 Developer’s Handbook 8. A series of backups are performed before completing the configuration. Click Next when the backups are complete, as seen in Figure 4-50. Figure 4-50 WebSphere Portal install backing up WebSphere Application Server AEs config files The application server is now restarted with the new configuration, as seen in Figure 4-51. Click Next once the server is restarted. The application server is restarted with the new configuration so that the base portlets can be installed and configuration modifications can be made. It is a good idea to make sure the base portal environment has been success fully installed. This can be done in the following manner. a. From a browser, open the URL http://<your.domain.com>:9080/wps/portal. b. After a few seconds, you should see the main portal window with a message indicating that there are no page groups. c. If you do not see this page, there was a problem installing the base portal enterprise applications and the install should be reattempted. Chapter 4. Portlet testing and debugging 193 Figure 4-51 WebSphere Portal installation WebSphere Application Server AEs configuration 9. Once the application server has been successfully restarted, click Next to install the base portlets. 10.The install process will check to make sure the Application server is started, as seen in Figure 4-52. Once this is verified, click Next to continue. Figure 4-52 WebSphere Portal Application Server started 11.The installation process will now install the base portlets. There are approximately 229 base portlets to be installed, which include all the associated configuration changes. This will take several minutes to complete. 194 IBM WebSphere Portal V4 Developer’s Handbook 12.Once complete, as seen in Figure 4-53, click Next to continue. Figure 4-53 WebSphere Portal install Portlets installed successfully 13.The application server will again be stopped and restarted as seen in Figure 4-54 and Figure 4-55, respectively. Click Next when prompted through this process. Chapter 4. Portlet testing and debugging 195 Figure 4-54 WebSphere Portal install stopping WebSphere Application Server AEs 196 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-55 WebSphere Portal restart Portal Server application 14.You are now prompted with some final installation instructions. Read the instructions seen in Figure 4-56 and click Next to continue. Chapter 4. Portlet testing and debugging 197 Figure 4-56 WebSphere Portal final installation instructions 15.Finally, click Finish to complete the installation process. Figure 4-57 WebSphere Portal installation complete Validating the WebSphere Portal install At this point, it is a good idea to validate the WebSphere portal install before continuing on to configure WebSphere Studio Application Developer. Starting WebSphere Portal on WebSphere Application Server AEs Make sure Portal is running. If it is not, open a command window on the server system and make the <was_root>\bin directory the current directory. From there, 198 IBM WebSphere Portal V4 Developer’s Handbook issue the start command for WebSphere Application Server using the configuration file to run Portal: startServer.bat -configFile ..\config\WebSpherePortal-cfg.xml Tip: It is often useful to create icons for stopping and starting the Portal server as we did in “Adding the Stop Server icon” on page 173. Name the icons appropriately, WPS Start Server and WPS Stop Server, for example. Then set their shortcuts respectively to: startServer.bat -configFile ..\config\WebSpherePortal-cfg.xml and stopServer.bat -configFile ..\config\WebSpherePortal-cfg.xml Accessing the portal on WebSphere Application Server AEs You should be able to access Portal from a browser on your development system by entering the URL: http://<serverHostName>:9080/wps/portal <serverHostName> must be able to be resolved from the browser. If you are unsure, run the command ping <serverHostName> from the command line to see if an IP address is resolved. Important: If the URL is not recognized, make sure you started the server with the WebSpherePortal-cfg.xml file. The default start server starts the application server with the default server and not the WebSphere portal server. The config file must be explicitly specified to start WebSphere Portal. Chapter 4. Portlet testing and debugging 199 Figure 4-58 WebSphere Portal successful installation Validate that you can log in with your wpsadmin user ID and password. 4.3 Configuring the environment Now that you have set up the individual components, we will configure them in order to work together. We will set up a configuration on two different machines as shown in Figure 4-59. If you choose to put all components on a single machine, you will find remarks throughout this chapter where your configuration is different. 200 IBM WebSphere Portal V4 Developer’s Handbook 4 1 DB2 WebSphere Studio Application Developer 5 3 Personalization Toolkit 2 7 WebSphere Application Server Advanced Single Server Edition 6 Portal Toolkit 8 Agent Controller Portal Server Agent Controller Network Figure 4-59 Portlet development, test and debug configuration 4.3.1 Preparation Debug ID in Portal Server For testing and debugging, the tool will need a user defined in Portal. This will allow the Portal Toolkit to generate a page, deploy and run the portlets without the need to use Portal’s administrative tools to add portlets to a page. Your are free to choose any ID. This ID will be used by WebSphere Studio Application Developer to log in to the portal for you. We use the default set in Portal Toolkit so we do not have to change the settings there. These values are: User ID: wpsdebug Password: wpsdebug First Name: Wps Last Name: Debug Chapter 4. Portlet testing and debugging 201 Access to Application Server directory If you are running all components on a single machine, there is nothing you have to do to enable automatic deployment of your portlet applications. But as we use two systems, we will have to deploy our portlets from WebSphere Studio Application Developer to WebSphere Application Server running on a different system. To make this happen, we need access from the development machine to the <was_root> directory on the server machine, where <was_root> stands for the directory WebSphere Application Server is installed. The default value for this is C:\WebSphere\AppServer. You can do this either by running an FTP server on the server system or by sharing a directory and mapping it on the client. We did the latter and shared the WebSphere directory which happens to be on drive D: in our environment. Then we mapped the shared directory as drive J: on the client machine so we could to access web_root by specifying J:\AppServer. Creating a deployment directory for debugging It is highly recommended that you create a dedicated directory for testing and debugging. The main reason is that when you deploy your portlet application, this will change the configuration files on your server, too. Using a debug directory makes sure that your base configuration remains unchanged and whatever happens during testing, you will be able to restart your server. We created a folder <was_root>\Debug for this purpose. Installing Agent Controller and checking the configuration Installing is not an issue if you run the configuration on a single machine. When WebSphere Studio Application Developer is installed, Agent Controller is installed and configured automatically. On the server system, howeve, an Agent Controller has to be installed as well. It is found on the WebSphere Studio Application Developer install CD. Search for RAC (Remote Agent Controller). During the installation of the RAC, you may be asked for the location of your JRE. Be sure to point to the WebSphere\AppServer\java directory. After successful installation Agent Controller should be running as a service called IBM Agent Controller. Stopping Application Server As we are starting and stopping Application Server from within WebSphere Studio Application Developer, WebSphere Application Server must be stopped. Open a command window on the server system and make the <was_root>\bin 202 IBM WebSphere Portal V4 Developer’s Handbook directory the current directory. From there, issue the start command for WebSphere Application Server using the configuration file to run Portal: stopServer.bat -configFile ..\config\WebSpherePortal-cfg.xml Alternatively, use the icons if you created them in “Starting WebSphere Portal on WebSphere Application Server AEs” on page 198. 4.3.2 Defining the Server in WebSphere Studio Application Developer Now we turn to the development machine and define the server within WebSphere Studio Application Developer using the Portal Toolkit. 1. Start WebSphere Studio Application Developer and select File -> New -> Other.... 2. In the resulting window (see Figure 4-60 on page 204) select PortalServer -> Portal server instance and configuration and click Next. If these options are not available, Portal Toolkit has not been installed properly. Chapter 4. Portlet testing and debugging 203 Figure 4-60 New Portal server window 3. The wizard then displays the Portal Server settings page (see “Portal Server settings” on page 205) with the following elements: – Location of the WebSpherePortal-cfg.xml file This is the file created by the WebSphere Portal installation. It is located in the <was_root>\config directory. If this is a remote configuration, you will need to map a drive letter to a drive or directory that is shared on the remote machine that has access to the WebSphere Application Server directory. The Portal Toolkit will not recognize the file if there is not a drive letter associated with the location, so you cannot use the UNC (Universal Naming Convention) of the server share (for example, \\server\share is not 204 IBM WebSphere Portal V4 Developer’s Handbook acceptable). If this file is invalid or does not contain the Portal configurations, then you will not be able to proceed. Browse the mapped drive created in “Access to Application Server directory” on page 202 and navigate to the configuration file. In a single system environment, you enter the local configuration file. Alternatively, you may simply copy the config file to the local machine. This file is also needed for migrating the server configuration as discussed in “Adding portal server portlets” on page 233. Figure 4-61 Portal Server settings Chapter 4. Portlet testing and debugging 205 – WebSphere Portal Server administrator This is the wpsadmin account that was automatically created during the WebSphere Portal installation. It is required for the Portal Toolkit to update the page group and page information for displaying your portlet. If you changed the user ID and/or the password, you have to enter the changed ones here. – WebSphere Portal Server debug user This account is the user ID that you created in “Debug ID in Portal Server” on page 201. It is used to log in to WebSphere Portal and will contain your portlets on a page called Debug configured by the Portal Toolkit during the server startup. If you choose a different user ID and/or password, you have to enter the actual values here. – Base URI of home portal page This is the URI for the initial portal home page. It was configured during the WebSphere Portal installation. If you made changes to this URI during the WebSphere Portal installation, you will need to modify it here. When you are done, click Next to proceed. 4. The Create a new server instance and configuration page (see “Server properties” on page 207) is displayed. These are the properties on this page: – Server name This is the name by which the server is known within WebSphere Application Server. You are free to enter any name; we use RemotePortal in this scenario. – Folder: This is not only a folder name but also the name of the server project within WebSphere Application Server in which all information and files related to this server and configuration will be stored. You can have one server project for all of your server instances and configurations or create multiple projects. Therefore, you can either enter the name of an existing server project or a new name. We enter PortalServer which is a new name and the wizard prompts us as shown in “New project prompt” on page 208. 206 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-62 Server properties – Server instance type: Expand WebSphere Servers, and select WebSphere V4.0 Remote Server. This is the only configuration type supported by the Portal Toolkit. This setting tells the Portal Toolkit that files will need to be copied to the remote location and deployed remotely; it is not running on the internal WebSphere V4.0 Test Environment located in the plugins directory of Application Developer. – Server Template: and Server configuration type - Template: Select None because no templates are required. When you are done, click Next to proceed. Chapter 4. Portlet testing and debugging 207 5. Click Yes to create a new server project if you entered a new project name in the folder field of the previous window. Figure 4-63 New project prompt 6. The WebSphere Remote Server Instance Settings page is displayed (see “Remote server settings” on page 209) with the following properties to be set: – Host address: This is the fully qualified domain name specified during the WebSphere Portal installation and the same name used in the browser for testing without the port appended. It is important that you use the exact same name specified when you installed WebSphere Portal. If this name is different, an error will occur when you use the automatic login feature of the Portal Toolkit, and you will be required to log in each time you debug your portlet. If you tested the Portal installation (see “Debug ID in Portal Server” on page 201), then this should not be a problem. 208 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-64 Remote server settings – WebSphere Installation Directory: This is the directory in which WebSphere Application Server is installed. If WebSphere Application Server is on a remote system as is our case, then you will need to specify the actual local drive letter as you would specify on the remote machine; do not specify a mapped network drive. In our scenario, this has to be D:\WebSphere\Appserver. – WebSphere deployment directory: As shown in Figure 4-65, the default for this setting is to use the default WebSphere deployment directory. Chapter 4. Portlet testing and debugging 209 Figure 4-65 Deployment settings We strongly recommend that you deselct the checkbox and enter the dedicated debug directory we created in “Creating a deployment directory for debugging” on page 202. Again, if WebSphere Application Server is on a remote system as it is in our environment, then you will need to specify the actual local drive letter as you would specify on the remote machine; do not specify a mapped network drive. In our scenario this has to be: D:/WebSphere/Appserver/Debug If you select Use default WebSphere deployment directory, then the configuration that is used will be in the <was_root>\config directory, and will overwrite the default server-cfg.xml used by WebSphere Application Server. It will also use the <was_root>\InstalledApps directory to deploy your portlet. You can use this option if you are not going to be using the default server-cfg.xml file to run the default configuration for WebSphere Application Server itself and if you are sure to be able to recreate a running configuration if worst comes to the worst. In our scenario, the server-cfg.xml file and the deployed portlet application will be placed in a separate directory in order to keep the portal application and configuration apart from the original WebSphere Application Server and WebSphere Portal configuration. – Platform of remote machine: This information is needed for deployment. We have a Windows platform and therefore leave the selection as it is. When you are done, click Next to proceed. 7. The Create or Select a Remote File Transfer Instance panel is displayed. In this and in the following window, you define the deployment settings which are aggregated in a file transfer instance object. As we have no existing file transfer instance for our server, we choose the Create a new remote file transfer instance selection. Even if your server is not remote but on the same machine, you must choose this option. 210 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-66 Select file transfer instance The next selection depends on the decision we explained and made in “Access to Application Server directory” on page 202. We have no FTP server but have mapped a drive. So we choose Copy file transfer mechanism. Click Next to proceed. 8. Depending on the selection of the previous panel, the settings of the file transfer instance have to be completed. As “File transfer properties” on page 212 shows, we have three properties: – Project folder: This is the server project inside WebSphere Studio Application Developer where the configuration will be stored. You can use the same folder name specified throughout the configuration to keep everything in the same place (in our example: PortalServer). Chapter 4. Portlet testing and debugging 211 Figure 4-67 File transfer properties – Remote file transfer name: This name will be the file name displayed under the folder you specify. We are free to choose any name as long as it does not already exist; we use wtpclt File Transfer using the target host name to identify the instance. – Remote target directory: This parameter is used to copy the files to the remote machine (or local machine, depending on your configuration). The portlet application files and server configuration will be copied to the location specified here. This must be the same location that was specified previously in the WebSphere Remote Server Instance window for the WebSphere Deployment Directory. If WebSphere Application Server is on the same machine, then the fields will be identical. As we are using a remote configuration with a mapped drive, the path will not be identical, but the paths must ultimately point to the same location. In our configuration, we have mapped an R:\ drive to the D:\WebSphere on the remote machine (“Access to Application Server directory” on page 202). As the directory specified for the WebSphere Deployment Directory was 212 IBM WebSphere Portal V4 Developer’s Handbook D:\WebSphere\AppServer\Debug, we now need to specify R:\AppServer\Debug for this parameter. Click Next to proceed. Note: If you are using FTP instead of drive mapping, the corresponding window is shown below. Be aware which parameters reflect the view from the development environment and which are seen from the perspective of the server. Figure 4-68 Remote File Transfer using FTP 9. In the last panel, you can change the port number for HTTP access to the test server. We can accept the default value of 9080. If you have a different setup, set the port number accordingly. Important: The user login and password specified here must have write access to the remote target directory. Chapter 4. Portlet testing and debugging 213 10.Finally, click Finish to let the wizard generate all necessary files and configurations. When you now open the Server Perspective (Perspective -> Open -> Server or Perspective -> Open -> Other -> Server depending on your settings), you can see the result in the Navigator, Sever Configuration and Servers pane as illustrated in“WebSphere Studio Application Developer Server Perspective” on page 214 (in the Servers pane, you might need to click the Servers tab to se the new server). Figure 4-69 WebSphere Studio Application Developer Server Perspective 4.3.3 Testing the server Now we can verify if the server configuration we just set up really works. Please reconfirm that the server is currently stopped (“Stopping Application Server” on page 202). In the Servers pane of WebSphere Studio Application Developer, select the server instance you just created and open the context menu (Figure 4-70 on page 215). You have three active options. 214 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-70 Server menu Publish copies the server configuration and all necessary resources to the target directory. Figure 4-72 on page 217 shows the content of the Debug folder on the server system after publishing. Start not only starts the server but also publishes whether WebSphere Application Server has detected any changes that affect the server. Debug also publishes, if necessary, and starts the server in debug mode. This means processing will be halted at defined and active debug points. Running in debug mode is a very resource intensive process. We suggest that you use this option only if your really want to debug and breakpoints have been set. Click Publish to first test the settings of your remote file transfer. A window titled Publishing opens. When in this window, the message Publishing was successful appears, click Details. The window should now look similar to the one in Figure 4-71 on page 216. Chapter 4. Portlet testing and debugging 215 Figure 4-71 Publishing details Click OK to close the window when you have checked the details. The Server state of your server should now have changed to Server is synchronized while the status is still stopped. If you go to the server, you see the result in your target directory as shown in Figure 4-72 on page 217. If you experienced any problems, please revisit the remote transfer instance settings by opening it (wtcplt File Transfer.rft in our scenario) from the Navigator in WebSphere Studio Application Developer and check “Hints and tips” on page 242. 216 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-72 Debug folder after Initial publish After you have successfully published the configuration, click Start from your servers context menu. This will take some time, but eventually the Console tab will appear in the server pane of the WebSphere Studio Application Developer workbench. You can maximize it by double-clicking the title bar if you want. Otherwise, just wait until the message Server WebSphere Portal open for e-business appears in the console window as shown in Figure 4-73 on page 217. Figure 4-73 Console of started server If your server does not start successfully, search the console for meaningful messages or Java exceptions and check with “Hints and tips” on page 242. Once the server is started, you can also browse the Portal Server either with your browser or the built-in browser of WebSphere Studio Application Developer by clicking the Open Web Browser icon as seen in Figure 4-74 on page 218. Chapter 4. Portlet testing and debugging 217 Figure 4-74 WebSphere Studio Application Developer Web browser Use the same URL http://<serverHostName>:9080/wps/portal that worked when you first tested the portal installation (see “Debug ID in Portal Server” on page 201). You will most probably not like what you see (Figure 4-75):. Figure 4-75 First portal test 218 IBM WebSphere Portal V4 Developer’s Handbook Only the skeleton of the portal is displayed and instead of the portlets and their content, there are Error 404 messages all over the window. The reason is that the Portlet Toolkit keeps Portal as lean as possible and does not deploy any of the portlets delivered with Portal Server. In “Adding portal server portlets” on page 233, we will add some of them to the test environment. This is the best we can get for the time being. 4.4 Testing and debugging As said before, we assume that you are familiar with WebSphere Studio Application Developer and we concentrate on the specifics of portlet development, Portal Server configuration and the Portal Toolkit. 4.4.1 Debugging the first portlet We walk you through the process of deploying a portlet application, setting a breakpoint and executing the portal in debug mode. First, we let the Portal Toolkit generate a very simple portlet project to test. If you have already created a portlet project and you prefer to test with that, then you can skip “Create a portlet project” on page 219 if you like. Also, you can use different names than we use in this scenario if you are already familiar with the environment. The Portal Toolkit and the options in the wizard we are using is explained in Chapter 3, “Using the Portal Toolkit” on page 119. Create a portlet project 1. Click File -> New -> Other, then select Portlet development and Portlet application project and finally click Next to start the wizard to create a new portlet project. 2. On the next page (see Figure 4-76 on page 220), enter TestPortlet as the project name and PortletEAR as name of the enterprise application project. Chapter 4. Portlet testing and debugging 219 Figure 4-76 Portlet project settings 3. Click Next. 4. Select MVC portlet from the list in the next window (Figure 4-77 on page 221). 220 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-77 Portlet selection 5. Click Next 6. Accept all values on the next page (Figure 4-78 on page 222) and click Finish. Chapter 4. Portlet testing and debugging 221 Figure 4-78 Portlet parameters 222 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-79 New portlet project Portlet Toolkit generates project and folders, Java classes, configuration files, HTML files and JSPs that are needed and displays the new portlet project in the portlet perspective. Setting a breakpoint, deploying and debugging the application 1. If the server is still running, stop it from the server perspective. 2. Open the TestPortlet project. 3. Navigate through the project and check the content. 4. Open the MyController.java source file; now your WebSphere Studio Application Developer workbench should look similar to Figure 4-80 on page 224.You can change the code if you like and are familiar with the environment and portlet API. Chapter 4. Portlet testing and debugging 223 Figure 4-80 Portlet source 5. Set a breakpoint right at the beginning of the doView() method. Right-click the grey border close to the statement at which you want processing to stop (see Figure 4-81 on page 225) to display the context menu. Then click Add Breakpoint. 224 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-81 Add Breakpoint A blue bullet marks the point where processing will be halted. Figure 4-82 Breakpoint 6. Navigate to the server perspective. 7. In the Server Configuration pane, expand Server Configurations and open the context menu of RemotePortalServer (or the name you chose for the server). 8. Click AddProject -> PortalEAR (or the enterprise application project your portlets are in). See Figure 4-83 on page 226. Chapter 4. Portlet testing and debugging 225 Figure 4-83 Add enterprise application project to server 9. Now start the server in debug mode as you see in Figure 4-84 on page 226. Figure 4-84 Start server in debug mode 10.Wait until the server has started and the message Open for e-business is displayed in the console window. Depending on your hardware, this can take up to ten or fifteen minutes. 226 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-85 Run the portlet 11.Then start the portlet by selecting Run on Server from the portlet projects context menu as shown in Figure 4-85. After a while, the windows on your WebSphere Studio Application Developer workbench change and display the Java source of MyControlHTML.java right where the breakpoint has been set, as well as trace information (see Figure 4-86 on page 228). Chapter 4. Portlet testing and debugging 227 Figure 4-86 Debug panes in server perspective 12.Open the debug perspective: (Perspective -> Open -> Debug from the menu or Perspective -> Open -> Other), then select Debug, depending on your setup. In this perspective, you can investigate the content of all assessable variables, inspect referenced objects, step through the code or even into methods invoked from where the processing is currently stopped, and much more. Please refer to the WebSphere Studio Application Developer resources if you are not familiar with WebSphere Studio Application Developer debugging features. 228 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-87 Debug perspective 13.Click the Resume icon or select Debug -> Resume from the menu when you have finished exploring the debugging capabilities. Eventually, the browser window appears and you can see the portlet (Figure 4-88 on page 230). Note that the user ID created for debugging purposes (wpsdebug) is logged in and a page named Debug has been created and used to display the portlet. Chapter 4. Portlet testing and debugging 229 Figure 4-88 Portal with debug page 4.4.2 Debugging portlet JSPs The WebSphere Studio Application Developer portlet development environment allows you to debug not only the portlet Java code you have constructed, but also the JSPs that are used to display content. Since all portlet applications are executed on a remote server instance, you must indicate in the server instance that you want debugging information included when the JSPs are compiled. To do this, open the server configuration file in the server perspective as demonstrated in Figure 4-89. 230 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-89 Opening the server instance In the resulting editor, enable the option box Generate debug information when compiling JSPs (debug mode only). Note that you will need to restart the application server for this setting to take effect. Furthermore, if the JSPs you intend to debug have not changed, you will need to clear out the JSP cache on the application server. It is much simpler to simply mark the JSPs for re-compilation by “touching” them. To do this, open the JSP and add an insignificant space. Save the file and make sure it is republished to the server. Note that adding a breakpoint to a JSP file does not mark it for page compilation. Adding a breakpoint to a JSP follows the same process as adding a breakpoint to a traditional Java file. Simply right-click the gray column next to the code where you wish to stop on and select Add Breakpoint as demonstrated in Figure 4-90. Figure 4-90 Adding a breakpoint to a JSP WebSphere Studio Application Developer will only allow you to place breakpoints in logical locations since only certain elements in a JSP can be debugged: In-line Java code such as that contained in scriptlets, declarations or expressions JSP action tags such as usebean Chapter 4. Portlet testing and debugging 231 JSP custom tags such as those provided by the portal itself via Portlet.tld or Engine.tld There are several key elements that cannot be debugged: All HTML tags are ineligible for debugging Simple text has no execution behavior and therefore cannot be debugged JavaScript is client-side code, not executed by the application server and therefore not available for debugging Figure 4-91 demonstrates that breakpoints cannot be added to non-Java locations. Figure 4-91 Breakpoints cannot be added to JavaScript Execute the JSP by running the portlet application. The normal debugging options available in Java file are also available in JSP debugging, as demonstrated in Figure 4-92. 232 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-92 Debugging a JSP file 4.4.3 Adding portal server portlets We are now able to test and debug a servlet, but we are still limited. Look what happens if we try to enhance our debug portlet page. Figure 4-93 on page 234 shows the result of an attempt to reorganize the page by selecting the Work with Pages place. The reason for all the 404 errors we get is the same as before (see Figure 4-75 on page 218 in “Testing the server” on page 214): the configuration used in WebSphere Studio Application Developer does not include all the portlets delivered with Portal Server. Since Portal Server uses portlets, its own technology, to customize the portal, these portlets are missing as well. Note that the portlets are available if you start WebSphere Application Server AEs using: startServer.bat -configFile ..\config\WebSpherePortal-cfg.xml instead of starting from WebSphere Studio Application Developer. Chapter 4. Portlet testing and debugging 233 Figure 4-93 Work with Pages is broken Which portlets are available is defined in the portal configuration file you made available to the server configuration in WebSphere Studio Application Developer; this is the file named WebSpherePortal-cfg.xml located in the <was_root>\config directory. Example 4-1 on page 234 is an excerpt of that file showing how the portlets are defined as installedApps. Example 4-1 Excerpt from WebSpherePortal-cfg.xml <installedApps xmi:id="ApplicationRef_6" name="WCM Pzn Publish" archiveURL="D:\WebSphere\PortalServer\app\WCMPznPublish.ear"> <modules xmi:type="applicationserver:WebModuleRef" xmi:id="WebModuleRef_9" uri="WCMPznPublish.war"/> </installedApps> <installedApps xmi:id="ApplicationRef_7" name="WebSphere Member Service" archiveURL="D:\WebSphere\PortalServer\app\wms.ear"> ... </installedApps> <installedApps xmi:id="ApplicationRef_8" name="WS Proxy" archiveURL="D:\WebSphere\PortalServer\app\wsproxy.ear"> <modules xmi:type="applicationserver:WebModuleRef" xmi:id="WebModuleRef_10" uri="wsproxy.war"/> </installedApps> <installedApps xmi:id="ApplicationRef_9" name="PortletInstaller_WPS_PA_101" archiveURL="${APP_INSTALL_ROOT}\PortletInstaller.ear"> <modules xmi:type="applicationserver:WebModuleRef" xmi:id="WebModuleRef_11" uri="PortletInstaller.war"/> </installedApps> <installedApps xmi:id="ApplicationRef_10" name="CustomizerPortlets_WPS_PA_103" archiveURL="${APP_INSTALL_ROOT}\CustomizerPortlets.ear"> 234 IBM WebSphere Portal V4 Developer’s Handbook <modules xmi:type="applicationserver:WebModuleRef" xmi:id="WebModuleRef_12" uri="CustomizerPortlets.war"/> </installedApps> <installedApps xmi:id="ApplicationRef_11" name="SelectorPortlet_WPS_PA_105" archiveURL="${APP_INSTALL_ROOT}\SelectorPortlet.ear"> <modules xmi:type="applicationserver:WebModuleRef" xmi:id="WebModuleRef_13" uri="SelectorPortlet.war"/> </installedApps> Which of those portlets are really available when you start Portal Server from within WebSphere Studio Application Developer is defined in a file called plugin.xml which is located in <WSAD_root>\plugins\com.ibm.pvctools.wpsdebug where <WSAD_root> is the directory where WebSphere Studio Application Developer is installed. Example 4-2 on page 235 shows the final part of this file. Example 4-2 plugin.xml <extension point="com.ibm.etools.websphere.tools.bypassAppName"> <bypassAppName name="WPS Enterprise Application" earName="wps" /> <bypassAppName name="WCM Pzn Publish" earName="WCMPznPublish" /> <bypassAppName name="WebSphere Member Service" earName="wms" /> <bypassAppName name="WS Proxy" earName="wsproxy" /> </extension> <extension point="com.ibm.etools.websphere.tools.wpsConfigurator"> <configurator class="com.ibm.pvctools.wpsdebug.configurator.WpsConfigurator" /> </extension> <extension point="org.eclipse.help.contexts"> <contexts name="HelpContexts.xml" /> </extension> </plugin> For each portlet that you want to be available a bypassAppName tag is necessary, where the name of the <installedApps> in the portal server configuration file matches the name of the <bypassAppName>, and the file name of the archiveURL of the <installedApps> matches the earName of the <bypassAppName>. If you want to use, for example, PortletInstallerPortlet for the portlet debug session, you need to add the following statement in the plugin.xml file: <bypassAppName name="PortletInstallerPortlet" earName="PortletInstaller" /> Chapter 4. Portlet testing and debugging 235 The complete list of bypassAppName elements for a default Portal startup that includes all the base portlets installed during a typical installation would include all the bypassAppName elements listed in Example 4-3. Note that while the generated names for your Enterprise applications are likely the same if they were deployed as part of the installation process, it is important to verify the accuracy of these values compared to those on your system. Example 4-3 Base Portlets defined in plugin.xml <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName <bypassAppName name="PortletInstaller_WPS_PA_101" earName="PortletInstaller" /> name="CustomizerPortlets_WPS_PA_103" earName="CustomizerPortlets" /> name="SelectorPortlet_WPS_PA_105" earName="SelectorPortlet" /> name="CredentialAdministration_WPS_PA_107" earName="CredentialAdministration" /> name="WebServicesAdministration_WPS_PA_109" earName="WebServicesAdministration" /> name="Settings_WPS_PA_111" earName="Settings" /> name="MarkupsManager_WPS_PA_113" earName="MarkupsManager" /> name="UsersManager_WPS_PA_115" earName="UsersManager" /> name="PortletManagementPortlets_WPS_PA_117" earName="PortletManagementPortlets" /> name="Tracing_WPS_PA_119" earName="Tracing" /> name="GroupsManager_WPS_PA_121" earName="GroupsManager" /> name="SearchPortlets_WPS_PA_123" earName="SearchPortlets" /> name="ClippingPortlets_WPS_PA_125" earName="ClippingPortlets" /> name="ClientsManager_WPS_PA_127" earName="ClientsManager" /> name="AccessControl_WPS_PA_129" earName="AccessControl" /> name="WelcomePortlet_WPS_PA_131" earName="WelcomePortlet" /> name="WebServicesManager_WPS_PA_133" earName="WebServicesManager" /> name="QuickLinks_WPS_PA_135" earName="QuickLinks" /> name="worldclock_WPS_PA_137" earName="worldclock" /> name="reminder_WPS_PA_139" earName="reminder" /> name="PortalContentPortlets_WPS_PA_141" earName="PortalContentPortlets" /> name="ContentOrganizer_WPS_PA_143" earName="ContentOrganizer" /> Only updating the plugin.xml file does not yet resolve our problem. The plugin file is only read once when creating the server configuration. 236 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-94 Migrate server configuration We have to regenerate the configuration by selecting Migrate Server Config from the context menu of the existing server-cfg.xml. We are prompted again for the portal configuration file, then WebSphere Studio Application Developer does the work. You must have access to the Portal config file through a mapped drive or you must copy it to a drive you can access. After publishing and restarting the server, we are able to work with the portlets used in Work with Pages and the error messages have disappeared. Chapter 4. Portlet testing and debugging 237 Figure 4-95 The full portal 4.4.4 Adding the sample YourCo portlets Most of the examples in this redbook are based on the YourCo sample application. YourCo comes in two flavors: as a WebSphere Application Server sample application and as a portlet version with Portlet Toolkit. The portlet version contains a subset of the WebSphere Application Server webapp and has its own database. We show you in this chapter how you can add the YourCo portlets to our test and debug environment. First, we prepare the system WebSphere Application Server with Portal Server running. 1. Create the database: a. Copy the PortletSample_setup folder from the Portal Toolkit installation CD to somewhere on the computer where Portal Server and DB2 run. b. Open a DB2 command window and make the PortletSample_setup folder your current directory. c. Execute the following command: yourco_setupdb.bat <username> <password> 238 IBM WebSphere Portal V4 Developer’s Handbook where <username> and <password> are the DB2 administrator's name and password. 2. Load the portlet projects: We now turn to the system where WebSphere Studio Application Developer is running. a. From the WebSphere Studio Application Developer menu, click File -> New -> Other. b. Expand Examples on the left hand side of the window that appears (see Example 4-96). Figure 4-96 Portal Toolkit Yourco Samples c. Select Portlet applications. d. On the right-hand side, select one of the YourCo samples and click Next.. e. In the next window, accept the project name but set the enterprise application project name to YourCoEAR and click Finish. Chapter 4. Portlet testing and debugging 239 f. Repeat the preceding steps for all YourCo sample portlets. Note that you must use a different project name (just accept the wizard’s suggestion) for each sample, but you can put them all into the same EAR (YourCoEAR). 3. Deploy, run and customize YourCo portal: a. In the server perspective, add the YourCoEAR project to your server configuration in the Server Configurations pane as we did previously (see Figure 4-83 on page 226 if necessary). b. Publish and start the server. c. Select one of the portlet sample projects (for instance, WhitePages) and click Run on Server in the context menu. The YourCo portlets will show up on the Debug page. Figure 4-97 YourCo Portlet before setup d. To complete the setup, edit the portlets that need database access (click the pencil icon in the title bar). e. The portlet displays in Edit state (see Figure 4-98 on page 241). Enter the values for your environment. If you have a similar setup to the one we described in this chapter, you only have to add a user ID and password (use those of either the user that created the database or the DB2 administrator). 240 IBM WebSphere Portal V4 Developer’s Handbook Figure 4-98 Setting up the connection to the yourCo database f. Click Save and the portlet will display properly. Figure 4-99 The yourCo portal after setup Chapter 4. Portlet testing and debugging 241 g. You can now use the administrative portlets to create a YourCo page as you wish and combine the YourCo portlets with others, as depicted in Figure 4-100 on page 242 Figure 4-100 YourCo page 4.4.5 Hints and tips We try to give you some hints and tips to avoid problems; if the problems are not avoidable, we show you how to identify and resolve them. Agent Controller If WebSphere Studio Application Developer freezes when working with a server or if a ClassNotFound exception is thrown when you try to start the server, it can indicate a problem with Agent Controller. 242 IBM WebSphere Portal V4 Developer’s Handbook Where is it installed? We refer in the following paragraphs to <agent_controller_home> which is the directory where Agent Controller is installed. On machines where WebSphere Studio Application Developer runs, this is by default in <WSAD_home>\IBM Agent Controller; on other systems, it is whatever has been chosen during installation. Is the service running? Open a Services window in the system where WebSphere Studio Application Developer runs and check whether the service named IBM Agent Controller is running. If not, start it. Do the same on the system where Portal is running. If the service is not available, the installation has failed and you must reinstall it. Is the configuration correct? The configuration can be found in <agent_controller_home>\config\serviceconfig.xml. The sequence of installation for the components influences the configuration file. We experienced two problems here: If you find entries of %WAS_HOME% in your config file, they might not be interpreted properly. Replace them with the correct name of the directory WebSphere Application Server is installed in (D:\WebSphere\Appserver in our installation). This is the Application tag from the configuration file that rules the WebSphere Application Server startup: <Application executable="wteRemote.exe" path="d:\WebSphere\AppServer\java\bin\java.exe" location="d:\"> <Variable name="CLASSPATH" value="D:\IBMAgentController\lib\wasTools.jar; D:\IBMAgentController\lib\wteServers.jar; D:\IBMAgentController\lib\logutil.jar; d:\WebSphere\AppServer\properties; d:\WebSphere\AppServer\lib\bootstrap.jar" position="replace"/> <Variable name="PATH" value="d:\WebSphere\AppServer\bin" position="append"/> </Application> Make sure that bootstrap.jar is part of the CLASSPATH variable. Where to find Agent controller messages? Besides the serviceconfig.xml, the file servicelog.xml is also in the configuration directory(<agent_controller_home>\config\). This file contains all messages, the logging level and what details are displayed is defined in serviceconfig.xml. Chapter 4. Portlet testing and debugging 243 Remote directory In the file transfer instance, you have defined where to publish your portlets and resources. Is it defined properly? If publishing fails or your changes are not available on the server then check the definitions in the rft-entries in the server project. If this directory is not configured properly, WebSphere Application Server will be started using the configuration specified in the previous Remote Server Instance pane, which might cause WebSphere Application Server to fail since it cannot locate the proper files to debug. Also, if the file transfer instance points to an existing directory which is not your current deployment directory, publishing will claim to be successful but the published components will never show up on the server. Is it still there? If publishing worked previously but suddenly does not any more, consider this: if you mapped a drive, it may not have been restored after a reboot of your system or somebody may have changed the drive letter. Unexpected behavior We experienced some unexpected behavior even when the configuration was consistent and, most of the time, running properly. Resources not added, replaced or removed Sometimes publishing would claim to be successful, but not add the new resources, nor replace the changed elements or remove deleted elements. Sometimes, stopping and restarting the server would help, and sometimes we needed to remove the contents of the deployment folder and republish the project. Server does not start Sometimes the server does not start and in the console you see a message about unavailable ports. This is caused most of the time by the server not shutting down properly. The first workaround is to issue the stopserver command in a command prompt of the server system: <was_home>\bin>stopserver.bat -configFile ..\config\WebspherePortal-cfg.xml If the server seems to be shut down and the error still appears, either reboot the server or open the Windows Task Manager, then click the Processes tab and look for processes named java or javaw; end these processes. 244 IBM WebSphere Portal V4 Developer’s Handbook 5 Chapter 5. National Language Support In order to make a portal accessible and attractive to a wider audience, it is necessary to provide the portal and its components in multiple languages. At a minimum, you should consider supporting the group 1 languages listed on Table 5-1 on page 247. The WebSphere Portal architecture makes it easy and efficient to provide an NLS enabled portal. The enablement can be performed during development, deployment or runtime with the proper design decisions up front. This chapter will guide you through several approaches to NLS enablement. Using resource bundles Translating whole resources NLS administration Working with Characters NLS best practices © Copyright IBM Corp. 2003. All rights reserved. 245 5.1 Resource bundles A resource bundle is a simple text file that contains key-value pairs. The key is used by a Java class to retrieve a locale-specific value. To provide support for a new locale, you need only create a new resource bundle with the same key names and translated values. Example 5-1 demonstrates a base resource bundle. Example 5-2 demonstrates the resource bundle translated for Spanish. Notice the key names do not change, only the value is translated. Example 5-1 NLSExample.properties resource bundle welcome = hello goodbye = goodbye message = This is the NLSExample portlet Example 5-2 NLSExample_es.properties resource bundle welcome = hola goodbye = adiós message = éste es el portlet NLSExample The file name of the resource bundle is very important. The file must of type properties. All translated copies of the default resource bundle must include the locale in their title. This is illustrated in Figure 5-1. Figure 5-1 Translated resource bundles 246 IBM WebSphere Portal V4 Developer’s Handbook The name is important because the Portal will locate the appropriate bundle for you based on the locale you provide. You need only provide the base name of the bundle and it will append the appropriate locale. The Group 1 locales are listed in Table 5-1. Locale Code Language en English it Italian fr French de German es Spanish pt_BR Brazilian Portuguese ja Japanese ko Korean zh Chinese - Simplified zh_TW Chinese - Traditional Table 5-1 Group 1 languages 5.1.1 Creating resource bundles in WebSphere Studio The resource bundles need to be created in the WEB-INF\classes directory as illustrated in Figure 5-1 on page 246. Though not required, as a matter of good practice, you should place the files in a dedicated directory such as nls. To create a new resource bundle in WebSphere Studio, open the navigator view in the portlet perspective. Locate the WEB-INF\classes directory of the portlet you are enabling and right-click. From the context menu, select New -> Folder. Enter the name of the new folder, typically nls as shown in Figure 5-2. Chapter 5. National Language Support 247 Figure 5-2 Creating the nls folder in WSAD In the nls folder, you need to create the default properties files. Select the nls folder and right-click. From the context menu, select New -> Other -> Simple -> File. Be sure the correct directory is selected and enter the name of the default properties file as illustrated in Figure 5-3. Do not include any language codes in the name, nor should there be any spaces in the name of the resource bundle. When you are done, double-click the properties file in the navigator to open the simple text editor. Using the text editor, define your keys and the default values, such as those shown in Figure 5-1. Use CTRL-S to save the file. 248 IBM WebSphere Portal V4 Developer’s Handbook Figure 5-3 Creating the default properties bundle 5.1.2 Translating resource bundles Once you have defined your default resource bundle with all the keys that will be used by the portlets and JSPs in your application, you must provide translations. It is possible to use the copy functionality in WebSphere Studio. However, there are several reasons you may choose not to. It is a cumbersome process in that simple CTRL-C commands are not recognized when copying whole files. Also, renaming requires a selection from the context menu. While these may seem trivial issues, when creating dozens of resources bundles, they can be frustrating. Instead, you may find it easier to work directly with the source files on the file system. Locate the directory containing the current workspace. You can obtain this path by right-clicking the portlet application and selecting Properties from the context menu. The info option will display the file system location of the application. This is illustrated in Figure 5-4. Chapter 5. National Language Support 249 Figure 5-4 Locating the application on the file system Open the directory containing the application and use the normal system copy/paste and rename functionality to create the new resource bundles. Each new bundle should have a unique locale appended. In practice, you may at development time only have the default and English properties files. This same approach can later be used to import translated files received from an outside source. Once you have created the bundles you want, you need to make them available in the WebSphere Studio environment. To do this, simply select the nls folder, right-click and select Refresh from Local as shown in Figure 5-5. Figure 5-5 Loading resource bundles into WSAD When you are done, the folder should appear as in Example 5-1 on page 246, depending of course on the number of languages you choose to support. 250 IBM WebSphere Portal V4 Developer’s Handbook 5.1.3 Accessing resource bundles in portlets If you are printing out content directly from the portlet, you can use the portlet API to access the resource bundles quite easily. Most of your development will adhere to a good MVC approach; you can use this approach for setting the title, predefining parameters in a PortletURI or if you are providing some content via the beginPage or endPage methods. The resource bundle is accessed via the PortletContext object’s getText method as displayed in Example 5-3. Example 5-3 getText API PortletContext.getText("Bundle Base Name", "Key", Locale) Bundle Base Name The first parameter indicates the base name of the resource bundle. The name includes the path relative to the classes directory as shown in Example 5-4. The name does not specify the locale suffix or the properties file type. If the base file name cannot be found, or the key is not present in the properties file, a PortletException will be thrown. Key This parameter maps to a key value in the properties file. If the key is not found, a PortletException is thrown. Locale This is used by the Portal to create the complete resource bundle name. You are free to use any locale you like but to ensure the user’s locale is returned, the code in Example 5-4 works well. The getLocale 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. Example 5-4 Accessing resource bundles via the API getPortletConfig().getContext().getText("nls.NLSExample", "welcome", request.getLocale()); 5.1.4 Accessing resource bundles in JSPs When you employ a well designed MVC approach to your portlet development, the vast majority of NLS enablement work will need to take place in the view space. This section will guide you through providing locale-specific strings in a JSP. “Translating whole resources” on page 252 will guide you through providing a unique JSP for each locale you choose to support. Chapter 5. National Language Support 251 Your JSP files can access resource bundles in a way similar to the code used in portlets. The code for accessing resource bundle values is shown in Example 5-5. Example 5-5 Accessing resource bundles in a portlet JSP <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:text key="message" bundle="nls.NLSExample"> This is the default text. </portletAPI:text> As with specifying bundles in portlet code, the bundle name here must include the package name relative to the classes directory. There are two main points of distinction from accessing a resource bundle in portlet code. First, the portlet custom tags do not provide you with the opportunity to set the locale. The locale is determined in the tag for you. Secondly, the body of the text tag will be used if the bundle or the key cannot be located. This inherent error handling assures the user will never see a blank string or an error message. 5.2 Translating whole resources If the entirety of your JSP requires translation, you may find programmatically accessing resource bundles impractical. In practice, you will find that help JSPs, for example, contain little or no code and as such can be completely translated without incurring the runtime expense of NLS enablement. WebSphere Portal facilitates this approach by allowing you to organize translated files in a predictable directory structure. Portal will then take responsibility for locating the correct file at runtime. This facility is also available for multiple markup support. Your directory structure should reflect Figure 5-6. 252 IBM WebSphere Portal V4 Developer’s Handbook Figure 5-6 NLS directory structure Each locale you support must have its own folder and contain whatever fully translated resources you want the portal to serve. If the portal cannot find the requested resource in the appropriate directory, it will attempt to locate the default by searching one level higher. If no default resource is located up the directory tree, an exception is thrown. To retrieve the translated resource, simply use the include method of the PortletContext object. Do not specify the NLS directory structure. This code is illustrated in Example 5-6. You should notice that there is in fact nothing unique about calling a translated JSP and calling the simple JSPs. All the work is done by the portal. Example 5-6 Including translated JSP files getPortletConfig().getContext().include("/jsp/View.jsp", request, response); Chapter 5. National Language Support 253 5.3 NLS administration Certain aspects of NLS enablement can be configured via the administration place in WebSphere Portal. While this section will guide you through these features, bear in mind that the administration does not replace the developer’s responsibility for designing and incorporating NLS enablement. 5.3.1 Portlet NLS administration The Manage Portlets page allows you to set locale-specific titles for portlets. You cannot add support for new locales. Only locales specified by the portlet.xml deployment descriptor can be adjusted. Furthermore, you cannot change the default locale specified by the portlet.xml. To access the titles, log in as the administrator and navigate to the Manage Portlets page in the Administration place as illustrated in Figure 5-7. Figure 5-7 Working with portlets Locate the portlet you want to work with and select the Modify parameters link. By default, the resulting window, shown in Figure 5-8, will only display the Group 1 languages indicated for support by the portlet.xml. To add new locales for support in the administration space, see Chapter 6, “Portal customization” on page 261. 254 IBM WebSphere Portal V4 Developer’s Handbook Figure 5-8 Supported languages of the selected portlet To change the title specified by the portlet.xml, select the portlet’s associated radio button and select the Set title for selected locale link as shown in Figure 5-8. Enter the new title in the resulting window shown in Figure 5-9. Figure 5-9 Setting the locale-specific title Chapter 5. National Language Support 255 You may have noticed that only the title can be adjusted via the administration. The description, keywords and short-title values are not configurable via the administration place in Portal V 4.1.2. Again, it is important to stress that by default, the administrator will only be able to set the title for Group 1 locales explicitly specified in the portlet.xml. To add support for a locale in the portlet.xml in WebSphere Studio, open the portlet.xml editor and select the concrete portlet you wish to work with. This is illustrated in Figure 5-10. Figure 5-10 Adding locale support to a concrete portlet To add a new locale, select the Add button in the locale section as shown in Figure 5-10. In the resulting dialog, you can select the locale from the drop-down list or enter the country code if you know it. This is illustrated in Figure 5-11. If the locale you choose is already defined in the portlet.xml, you will be prevented from adding it again. Figure 5-11 Specifying a new locale 256 IBM WebSphere Portal V4 Developer’s Handbook 5.3.2 Portal NLS administration While it is the developer’s responsibility to carefully consider the NLS support portlet applications will support, the administrator is responsible for ensuring the Portal itself properly supports multiple languages. Some of the basic settings for NLS enablement include setting place, page, theme and skin names properly, configuring or maintaining property files and incorporating support for new languages. See Chapter 6, “Portal customization” on page 261 for adding new language support to the portal. 5.3.3 Setting NLS titles To set locale-specific titles for a place, navigate to the Work with Pages place and select Manage Places and Pages. In the list Places you can manage, select the place you want to work with and select Manage place properties as illustrated in Example 5-12. Figure 5-12 Editing Place properties In the resulting window, select the Set locale-specific titles link. In the next window, select the language for which you want to change the title and select the Set title for selected locale link. Enter the new title and select OK. If you need to enter characters that you cannot generate with your keyboard, such as Japanese, you will need to discover the unicode values and enter them using entity references as illustrated in Figure 5-13. The four character unicode values can be found at http://www.unicode.org/charts. The entity reference syntax is � where 0000 represents the unicode character you want to Chapter 5. National Language Support 257 display. If you have access to the interpreted unicode character, you can copy and paste it in the text field as well. Figure 5-13 Setting titles with unicode values. The same basic procedure applies when setting the locale-specific titles for individual pages. Navigate to the Work with Pages place and select Manage Places and Pages. Select the place that contains the page you want to adjust. Select the Manage Pages link. In the resulting window, select the page you want to work with and click the Manage Page Properties link. In the resulting window, select the Set locale-specific titles link. In the next window, select the language you want to change the title for and select the Set title for selected locale link. Enter the new title and select OK. 5.3.4 Adjusting Portal resource bundles There are several resource bundles that are used by the portal server to present locale-specific messages. Be aware that changes to a property file are not recognized until the portal is restarted. All the properties files listed below can be found in <WAS_HOME>\lib\app\nls. button.properties problem.properties field.properties engine.properties CSRes.properties (not available in Enable) titlebar.properties registration.properties LocaleNames.properties 258 IBM WebSphere Portal V4 Developer’s Handbook 5.4 Working with characters Typically, it will not be the developer’s responsibility to provide the translations necessary to provide NLS enablement. Once your base resource bundles and/or static files have been created, the translation process should be completed by a language expert. However, during development, you may need to include some characters that cannot be created by the typical English keyboard. To include these characters, make use of the unicode mappings. Refer to http://www.unicode.org for the current character mappings. Example 5-14 demonstrates unicode values entered in a resource bundle and the result when displayed on a capable device. Figure 5-14 Using Unicode values to display characters 5.5 NLS best practices Make the decision to use the API or translated resources early. This decision will play a large role in the design and development of your View components. Do not commit entirely to one approach. For example, it may make sense to translate your view JSPs at runtime and have your help JSPs fully translated since they are simple text. Plan for NLS enablement from the beginning. Though you may not have access to the translated values during development, building the default resource bundle as you iterate through the development will make future NLS enablement much easier and virtually painless. Be conscious of character-locale ratios. If you are developing in English, be aware that translations into other languages such as German or Spanish may require more screen real estate. A number of API facilities are available for you to determine the current locale. Chapter 5. National Language Support 259 Do not rely on an administration implementation of NLS. The NLS enablement facility for portlets is limited and there is no guarantee or check system. To implement dynamic NLS titles, consider implementing the PortletTitleListener interface and generating the title content via JSP or HTML files. Leave translations to language experts. With proper design, planning and construction of your portlet applications, there should be little to no effort involved in incorporating support for new languages. 260 IBM WebSphere Portal V4 Developer’s Handbook 6 Chapter 6. Portal customization WebSphere Portal includes a versatile and comprehensive out-of-the-box portal. In 6.2, “Guided tour of the portal” on page 267, we provide an overview of this portal and show how its look and feel is defined though the concepts of theme and skin. Companies will typically use this portal as a starting point for their custom portal solution. In 6.3, “Portal customization” on page 299, we describe the components of the portal and show how to easily customize them for an organization’s specific needs. Some companies will already have an existing Web application and might want to portalize it to simplify the application development and maintenance. In 6.4, “Building a virtual portal: the YourCo portal” on page 347, we show how to build a custom portal by portalizing the YourCo application provided with WebSphere Application Server. In 6.5, “JSP tags reference” on page 386, we provide a reference for the two main Java Server Pages tag libraries provided by WebSphere Portal for use in the Java Server Pages resources for the portal layout and customization. © Copyright IBM Corp. 2003. All rights reserved. 261 6.1 Overview WebSphere Portal comes with a portal application (hereafter called the portal) that is available for use immediately after the product is installed and started. This versatile portal is accessible through desktop browsers and mobile devices and supports many languages, such as English, Hebrew, and Chinese. This portal allows end-users to customize their portal experience by switching to other predefined visual elements and changing the layout of each page. In addition, WebSphere Portal provides an easy way of modifying the look and feel of the portal through the concepts of themes and skins. Themes define the visual appearance of pages and skins define the visual appearance surrounding each portlet. When accessing the portal for the first time, users see the portal Welcome page illustrated in Figure 6-1. Figure 6-1 Portal Welcome page The theme applied to this page defines the logo, the banner, the navigation elements, the portal controls, and the overall layout of the page, while the skin defines the portlets title bar, controls, and border. 262 IBM WebSphere Portal V4 Developer’s Handbook A theme determines the global appearance of all pages in a place. Themes define the visual elements of the overall portal such as banners and the navigation structure. Themes also define the overall layout of the overall page. For example, the default theme defines a banner at the top of the Welcome page, navigation elements under this banner including a drop-down list for places and tabs for pages, and icons for the portal controls (login, register and help), and leaves the remaining space of the page for displaying the portlets. The following themes are provided by WebSphere Portal: Admin Corporate Engineering Finance Science WebSphere Portal also includes a default theme that provides all the necessary resources to be used if a required resource isn’t defined by a custom theme. For example, Default.jsp is a required resource, being the entry Java Server Page for the portal. As the Admin theme doesn’t define this resource, the default theme Default.jsp is used. Tip: You can preview all the available themes and skins by using the portal (Work with my Pages) or by displaying the preview.gif image files from the \themes or \skins subdirectories (PortalServer\app\wps.war\themes and PortalServer\app\wps.war\skins, respectively). Each place has a theme associated with it. A theme applies to all of the pages in a place. By using a different theme for each place, a single WebSphere Portal installation can give the appearance of supporting many virtual portals. A theme consists of a set of resources, such as Java Server Pages (JSP) files, Cascading Style Sheets (CSS), JavaScript files (JS) and images. These resources are located in the theme directory or subdirectories. The following are examples of resources for the default theme for the HTML markup: PortalServer\app\wps.ear\wps.war\themes\html\Default.jsp PortalServer\app\wps.ear\wps.war\themes\html\en\Styles.css PortalServer\app\wps.ear\wps.war\themes\html\ie\en\HelpStyles.css Chapter 6. Portal customization 263 The term skin refers to the visual appearance of the area surrounding an individual portlet, including the title bar and the portlet controls such as minimize, maximize, edit and help. Each portlet can have its own skin. Skins are installed independently from themes, however, the skins that are available for use with a portlet are defined by the portal theme that is associated with the place. In addition, skins can use resources from the theme to match the theme look and feel. The portal administrator or the designer determines the theme for places and the available skins for the theme. The administrator can permit specified users to change the skins to reflect individual preferences. The following skins are provided by WebSphere Portal: Album Clear Diamonds Fade Hint NoBorder NoSkin Outline Pinstripe Shadow Wave® Note: For a sample portlet using the outline pre-defined skin, see Figure 6-18. WebSphere Portal includes a special skin called NoSkin. This skin renders portlets without a title bar and border and is intended for administrative pages where the Selector portlet is used. WebSphere Portal also includes a default skin that provides all the necessary resources to be used if a required resource isn’t defined by a custom skin. A skin typically consists of a set of JSP files located in the skin directory. The following are examples of resource for the default skin for the HTML markup: PortalServer\app\wps.ear\wps.war\skins\html\Control.jsp PortalServer\app\wps.ear\wps.war\skins\html\RowContainer.jsp PortalServer\app\wps.ear\wps.war\skins\html\ns4\Control.jsp 264 IBM WebSphere Portal V4 Developer’s Handbook Themes and skins consist of a set of files using standard file formats: JSP, JS, CSS, GIF, and JPG. These standards are widely used and provide an easy means to customize the portal look and feel. WebSphere Portal uses a path-naming convention to locate the skin and theme resources in the file system. Understanding the order in which WebSphere Portal searches for resources allows you to create your own themes, skins, and even set up support for new markup languages. When processing a request, WebSphere Portal gathers information about the user, the client device or desktop browser, and searches for themes and skins starting with the most specific subdirectory and moving up to the more generic, higher-level directory. The following table list the order of the search for theme and skin resources. Location in the /themes directory Location in the /skins directory /locale_country /locale_country /locale /locale /client /client /theme_name /skin_name /markup /markup For example, when a user requests a page from a client using Internet Explorer Version 5 with the locale set to en_US and the user's skins set to Shadow, WebSphere Portal will search for the skin resource file Control.jsp in the following order. 1. /skins/html/Shadow/ie5/en_US/Control.jsp 2. /skins/html/Shadow/ie5/en/Control.jsp 3. /skins/html/Shadow/ie5/Control.jsp 4. /skins/html/Shadow/en_US/Control.jsp 5. /skins/html/Shadow/en/Control.jsp 6. /skins/html/Shadow/Control.jsp 7. /skins/html/ie5/en_US/Control.jsp 8. /skins/html/ie5/en/Control.jsp 9. /skins/html/ie5/Control.jsp 10./skins/html/en_US/Control.jsp Chapter 6. Portal customization 265 11./skins/html/en/Control.jsp 12./skins/html/Control.jsp 13./skins/Control.jsp In this example, if the file is not found in the ../ie5/en_US directory, WebSphere Portal looks for the file in the ../ie5/en directory and keeps moving through this hierarchy until this file is found. If the file is a required resource, it will at least exist in the default skin directory. The theme and skin folders contain most of the files needed to define a skin or theme. Portal designers can copy these folders and modify their contents to create a custom look and feel. In 6.2, “Guided tour of the portal” on page 267, we provide an overview of the portal provided by WebSphere Portal. We also show how the theme and skin used by the portal define its appearance and layout. Companies will typically use the predefined portal as a starting point for their custom portal solution and customize the portal to meet specific needs. They will certainly change the look and feel and the layout to reflect their branding. In 6.3.1, “Basic customization” on page 299, we show how to customize the layout and appearance of the portal. Companies may want to change other components as well. For example, they might want to add a new client, such as the latest version of Netscape, and provide specific markup that take advantage of the new capabilities available for this new browser. They might want to customize the Enrollment page by using different fields, or remove the Enrollment page completely, so users cannot enroll themselves. They might want to change the help provided by default with the portal to be more specific to the company and to reflect the company branding. In 6.3.2, “Advanced customization” on page 315, we show how to customize these portal components. Some companies will already have an existing Web application and will want to portalize it to simplify the application development and maintenance. In 6.4, “Building a virtual portal: the YourCo portal” on page 347, we show how to build a custom portal by portalizing the YourCo application provided with WebSphere Application Server. 266 IBM WebSphere Portal V4 Developer’s Handbook In 6.5, “JSP tags reference” on page 386, we provide a reference for the two main Java Server Pages tag libraries provided by WebSphere Portal for use in the Java Server Pages resources for the portal layout and customization. 6.2 Guided tour of the portal WebSphere Portal provides a portal application that is available for use immediately after the product is installed and started (hereafter called the portal). In this section, we provide an overview of the portal and examine how the portal pages are built for it. 6.2.1 Portal overview Content overview The portal provided by WebSphere Portal contains the three following places: Home Work with Pages Portal Administration The Home place displays the end user content of the portal, while Work with Pages and Portal Administration allow users and administrators to customize and configure the portal. The Home place contains only one page by default: the Welcome page. This page contains four portlets: Welcome, World Clock, Quick Links, and Reminder as illustrated in the following figure. Chapter 6. Portal customization 267 Figure 6-2 Welcome page The Work with Pages place enables users to control the visual appearance of their portal experience, select and arrange portlets for their pages, and lock component on their shared pages. The pages in Work with Pages include Edit Layout and Content, Manage Places and Pages, Set Permissions, and Choose Skins. Each page contains only one portlet. Edit Layout and Content allows you to define the layout and content of a portal page. This page allows users to determine how a page looks, which portlets are on a page, and where the portlets display on a page. Users can set column width, arrange portlets, and modify location and number of columns and rows on a page. This page is illustrated in Figure 6-3. 268 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-3 Edit layout and content page Manage Places and Pages allows users to create, edit, activate, order, and delete pages and places. Manage Places and Pages allows you to create new places and pages and work with existing ones. Set Permissions allows page managers to lock containers on a page and the contents of containers on a page. They can also decide which portlets can or cannot be deleted from the page. Choose Skins allows users to change the skin of a portlet on a page. Users can select a skin for each portlet in a place. Note: End users might not have access permissions for Work with Pages. The Portal Administration place allows administrators to install and manage portlet applications on the portal, publish portlets to a Web service, configure the portal, define the users and user groups for the portal and control which portal resources users and user groups can access. Chapter 6. Portal customization 269 Figure 6-4 Install portlet page This place provides Administrators of the portal with the portlets to administer, configure and customize the portal. It contains the following five pages: Portlets, Portal Settings, Users and Groups, Security and Portal Content. These pages contain the following administrative portlets, respectively: 1. Install Portlet, Manage Portlet Applications, Manage Portlets, Web Clipping, Manage, Web Services, Web Services 2. Global Settings, Themes and Skins, Manage Clients, Manage Markups, Manage Search Index, Enable Tracing 3. Users and Groups, Manage User Groups 4. Access Control List, Credential Vault 5. Manage Content Organizer, Content Organizer Portal markups The portal supports three markup languages out-of-the-box: HTML, for desktop computers and some personal digital assistants, cHTML, for mobile devices in the NTT DoCoMo iMode network, and WML for WAP devices, which are typically mobile phones as shown in Figure 6-7. 270 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-5 Welcome page using a mobile device WebSphere Portal recognizes browsers and mobile device user agent signatures and matches the markup with the client. The framework is very easy to extend to support new browsers and devices. The Manage Markups and Manage clients portlets allow you to easily add new markups and clients. Internationalization To reach as many users as possible, the portal supports different languages for different locations. The portal can concurrently serve portal views to large numbers of users, each in the language of the preference of the individual user. The portal has already been translated into the following languages: English, French, German, Italian, Spanish, Czech, Hebrew, Polish, Turkish, Brazilian Portuguese, Japanese, Korean, Simplified Chinese, and Traditional Chinese. The portal is very easy to extend to support new languages as illustrated in “Language” on page 331. 6.2.2 Portal resources WebSphere Portal build the portal page by aggregating a set of resources and components. Places, pages, and portlets define the content of the portal. Themes and skins define the look and feel of this content displayed to the user. In addition, when a user connects to the portal, WebSphere Portal gathers information about the user and the device or desktop browser used (hereafter client). Chapter 6. Portal customization 271 WebSphere Portal builds a list of capabilities for the client and maps the client to a specific markup, so a portal can deliver an appropriate content and look and feel to the user. Each markup has its own theme and skin resources. Places, pages, and portlets are available to a set list of markup. For example, the Administration place is only available to the HTML markup. The portal installation process gives information about the resources and components used by the portal. The portal installation is a two-step process. During the first step, the installation copies all the files necessary for the portal in their respective directories.The following table shows the directories for the resources for the portal. Table 6-1 Predefined portal resources Folder Description PortalServer\app\wps.ear\wps.war\doc HTML Help files for the portal PortalServer\app\wps.ear\wps.war\html HTML files for the portal PortalServer\app\wps.ear\wps.war\images Graphics for the portal PortalServer\app\wps.ear\wps.war\screens Resources for the screens PortalServer\app\wps.ear\wps.war\skins Resources for the skins PortalServer\app\wps.ear\wps.war\themes Resources for the themes PortalServer\install Portlets applications AppServer\lib\app\nls NLS bundles The second step is to use the XMLInterface with SetupPortal.xml to register the resources and configure the portal. SetupPortal.xml is located in WebSphere\PortalServer\install. Tip: SetupPortal.xml can be used to reinstall the portal in its initial state and as such is very useful in cases where the portal configuration is corrupted. SetupPortal.xml configures the content (places, pages, and portlets), the look and feel (themes and skins), and the list of supported clients and markups for the portal. The <markup> nodes in SetupPortal.xml define markups for the portal. By default, the portal supports three markups: HTML, cHTML, and WML. 272 IBM WebSphere Portal V4 Developer’s Handbook For example, the following example defines the HTML in SetupPortal.xml. Example 6-1 HTML markup definition in SetupPortal.xml <markup action="update" active="true" default-charset="UTF-8" handle="html" mimetype="text/html" name="html"> <localedata charset="UTF-8" locale="cs"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="de"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="en"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="es"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="fr"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="it"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="iw"><title>HTML</title></localedata> <localedata charset="Shift_JIS" locale="ja"><title>HTML</title></localedata> <localedata charset="KSC5601" locale="ko"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="pl"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="pt_BR"><title>HTML</title></localedata> <localedata charset="UTF-8" locale="tr"><title>HTML</title></localedata> <localedata charset="GBK" locale="zh"><title>HTML</title></localedata> <localedata charset="Big5" locale="zh_TW"><title>HTML</title></localedata> </markup> The theme, screen, and skin resources for the markup need to be installed on the file system before registering the markup with WebSphere Portal. The markup directories are always direct children of the theme, screen, and skin directory. For example, the directory PortalServer\app\wps.ear\wps.war\themes\wml defines the theme resources for the WML markup. When a client request a page for the portal, WebSphere Portal will map the client signature to one of the markups for the request. SetupPortal.xml defines a list of clients that WebSphere Portal can use to map to a specific markup. The <client> node defines each client and its capabilities. For example, the following defines the markup and the capabilities of the first version of Internet Explorer. Example 6-2 Internet Explorer definition in SetupPortal.xml <client action="update" handle="Internet_Explorer" manufacturer="Microsoft" markup="html" markup-version="ie" name="Internet Explorer" ordinal="330"> <useragent-pattern>.*MSIE.*</useragent-pattern> <client-capability update="set">HTML_TABLE</client-capability> <client-capability update="set">HTML_2_0</client-capability> <client-capability update="set">FRAGMENT_IDENTIFIER</client-capability> </client> Chapter 6. Portal customization 273 The value of the <useragent-pattern> defines the pattern that WebSphere Portal uses to recognize the client. The clients are ordered by their ordinal value defined by the attribute ordinal so that WebSphere Portal can use specific patterns to match devices and then move to a more generic pattern to match other devices. SetupPortal.xml registers a set of skin. The <skin> nodes define the skins for the portal. For example, the following defines the Shadow skin. Example 6-3 Shadow skin definition in SetupPortal.xml <skin action="update" active="true" handle="Shadow" name="Shadow" resourceroot="Shadow"> <localedata locale="cs"><title>StÃ-nový objekt</title></localedata> <localedata locale="de"><title>Schattierung</title></localedata> <localedata locale="en"><title>Shadow</title></localedata> <localedata locale="es"><title>Sombra</title></localedata> <localedata locale="fr"><title>Double</title></localedata> <localedata locale="it"><title>Ombreggiatura</title></localedata> <localedata locale="iw"><title>צללית</title></localedata> <localedata locale="ja"><title>シャドー</title></localedata> <localedata locale="ko"><title>ì″Œì˜</title></localedata> <localedata locale="pl"><title>CieÅ„</title></localedata> <localedata locale="pt_BR"><title>Sombra</title></localedata> <localedata locale="tr"><title>Gölge</title></localedata> <localedata locale="zh"><title>åº•çº </title></localedata> <localedata locale="zh_TW"><title>é™°å½±</title></localedata> <access-right permission="delegate" subjectid="wpsadmin" subjecttype="user" update="set"/> <access-right permission="manage" subjectid="wpsadmin" subjecttype="user" update="set"/> <access-right permission="delegate" subjectid="wpsadmins" subjecttype="user-group" update="set"/> <access-right permission="manage" subjectid="wpsadmins" subjecttype="user-group" update="set"/> <access-right permission="view" subjectid="any" subjecttype="anonymous-user" update="set"/> <access-right permission="view" subjectid="any" subjecttype="user" update="set"/> </skin> The resources for these skins need to be installed on the file system in a subdirectory of one of the markup directories under the skin directory PortalServer\app\wps.ear\wps.war\skins. For example, the resources for the Shadow skin are in the directory PortalServer\app\wps.ear\wps.war\skins\html\Shadow for the HTML markup. 274 IBM WebSphere Portal V4 Developer’s Handbook SetupPortal.xml also registers a set of themes. The <theme> nodes define the themes. For example, the following defines the Admin theme. Example 6-4 Admin theme definition in SetupPortal.xml <theme action="update" active="true" defaultskinref="NoSkin" handle="Admin" name="Admin" resourceroot="Admin"> <localedata locale="cs"><title>Admin</title></localedata> <localedata locale="de"><title>Administrator</title></localedata> <localedata locale="en"><title>Admin</title></localedata> <localedata locale="es"><title>Admin</title></localedata> <localedata locale="fr"><title>Admin</title></localedata> <localedata locale="it"><title>Amministratore</title></localedata> <localedata locale="iw"><title>×ž× ×”×œ×”</title></localedata> <localedata locale="ja"><title>管ç†</title></localedata> <localedata locale="ko"><title>ê´ ë¦¬</title></localedata> <localedata locale="pl"><title>Administrator</title></localedata> <localedata locale="pt_BR"><title>Administração</title></localedata> <localedata locale="tr"><title>Denetim</title></localedata> <localedata locale="zh"><title>管ç†</title></localedata> <localedata locale="zh_TW"><title>管ç†</title></localedata> <access-right permission="delegate" subjectid="wpsadmin" subjecttype="user" update="set"/> <access-right permission="manage" subjectid="wpsadmin" subjecttype="user" update="set"/> <access-right permission="delegate" subjectid="wpsadmins" subjecttype="user-group" update="set"/> <access-right permission="manage" subjectid="wpsadmins" subjecttype="user-group" update="set"/> <access-right permission="view" subjectid="any" subjecttype="anonymous-user" update="set"/> <access-right permission="view" subjectid="any" subjecttype="user" update="set"/> <allowed-skin skin="NoSkin" update="set"/> </theme> The resources for these themes need to be installed on the file system in a subdirectory of one of the markup directories under the theme directory PortalServer\app\wps.ear\wps.war\themes. The portal installs many portlets. The <package> nodes in SetupPortal.xml define the portlet application for the portal. For example, the Welcome portlet is defined as follows. Chapter 6. Portal customization 275 Example 6-5 Portlet application definition in SetupPortal.xml <package action="update" active="true" globalid="com.ibm.wps.portlets.welcome" handle="com.ibm.wps.portlets.welcome" name="Welcome Application" removable="true"> <url>file:///C:\WebSphere\PortalServer/install/WelcomePortlet.war</url> <application action="update" active="true" globalid="com.ibm.wps.portlets.welcome.1" handle="com.ibm.wps.portlets.welcome.1" name="Welcome" removable="true"> The WAR files for the portlet application need to be installed in the directory defined by the <url> node, here, PortalServer/install. The portal creates the places and the pages for the portal. The <page> nodes in SetupPortal.xml define the pages for the portal. For example, the Welcome page is defined as follows. Example 6-6 Page definition in SetupPortal.xml <page action="update" active="true" handle="Welcome" name="Welcome" owner="wpsadmin" system="false"> <supported-markup markup="html" update="set"/> <supported-markup markup="chtml" update="set"/> <supported-markup markup="wml" update="set"/> <localedata locale="de"><title>Willkommen</title></localedata> <localedata locale="en"><title>Welcome</title></localedata> <component action="create" active="true" deletable="undefined" editable="undefined" handle="Welcome.x-1" maxsize="undefined" modifiable="undefined" movable="undefined" name="-1" nestable="undefined" skinref="undefined" type="row" width="undefined" <component action="create" active="true" deletable="undefined" editable="undefined" handle="Welcome.x-1.x100" maxsize="undefined" modifiable="undefined" movable="undefined" name="100" nestable="false" skinref="undefined" type="column" width="undefined"> <component action="create" active="true" deletable="undefined" editable="undefined" handle="Welcome.x-1.x100.x100" maxsize="undefined" modifiable="undefined" movable="undefined" name="100" nestable="undefined" skinref="undefined" type="control" width="undefined"> <portletinstance action="update" handle="Welcome.x-1.x100.x100.portletinstance" portletref="com.ibm.wps.portlets.welcome.1.Welcome_Portlet"/> </component> </component> </component> </page> 276 IBM WebSphere Portal V4 Developer’s Handbook SetupPortal.xml defines the markup available for the page by using the <supported-markup> node, the portlets residing on the page by using the <portletinstance> node, and the layout of the page by using nested <component> nodes. The <pagegroup> node in SetupPortal.xml defines the places for the portal. For example, the Home place is defined as follows. Example 6-7 Place definition in SetupPortal.xml <pagegroup action="update" active="true" default="true" handle="Home" name="Home" ordinal="1000" system="false"> <supported-markup markup="chtml" update="set"/> <supported-markup markup="html" update="set"/> <supported-markup markup="wml" update="set"/> <localedata locale="en"> <title>Home</title> <description>The Home Space</description> </localedata> <pageref ordinal="100" page="Welcome" update="set"/> </pagegroup> SetupPortal.xml defines the markup available for the place by using the <supported-markup> node, and the pages belonging to this place by using the <pageref> node. To summarize, SetupPortal.xml defines the markups, clients, skins, themes, portlet applications, pages, and places for the portal. It also defines the permissions for all these resources. The markups, skins, themes, and portlet applications require resources to be copied on the file system prior to running this configuration file. Each markup requires a markup subdirectory for the skin, screen, and theme directory, respectively. Each skin and theme require a subdirectory in PortalServer\app\wps.ear\wps.war\themes and PortalServer\app\wps.ear\wps.war\skins, respectively. In addition, the portlet application requires a WAR file on the file system to be installed. The portal combines a set of resources to display the content. For example, the portal administration place uses the Admin theme and its default skin as defined by <pagegroup action="update" name="Administration" themeref="Admin">. Some of the resources are registered by SetupPortal.xml, such as the skins and the themes. Others resources can be used directly by the portal. For example, Chapter 6. Portal customization 277 the resource bundles can be used directly by WebSphere Portal immediately after being added to the AppServer\lib\app\nls directory. The following table shows a summary of the main resources from the file system used by the portal after installation. Table 6-2 Portal resources Folder Description PortalServer\app\wps.ear\wps.war\html HTML resources for the portal PortalServer\app\wps.ear\wps.war\images Graphics resources for the portal PortalServer\app\wps.ear\wps.war\screens Resources for the screens PortalServer\app\wps.ear\wps.war\skins Resources for the skins PortalServer\app\wps.ear\wps.war\themes Resources for the themes AppServer\installedApps\Portlet_Name Portlets applications AppServer\lib\app\nls NLS Bundles PortalServer\app\wps.ear\wps.war\menu Menu for collaboration services PortalServer\app\wps.ear\wps.war\ peopleawareness People Awareness The HTML files for the portal include the privacy, the licence, and the help files for the portal. The NLS bundles include the text for the portal for all the languages supported. The collaboration services install the menu and the people awareness directories that come with WebSphere Portal Extend. 6.2.3 Welcome page aggregation In this section, we describe how WebSphere Portal aggregates the resources and the portal configuration to build the Welcome page. The Welcome page is a typical page for the portal and therefore is a very good example of the aggregation happening in most of the pages displayed by the portal. The theme, skin and screen provide most of the resources to build the Welcome page. In this section, we will review the contribution of each to the Welcome page. The following figure illustrates the different components of the page shown in Figure 6-2 . 278 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-6 Welcome page components Theme The entry resource for the Welcome page is the Java Server Page Default.jsp from the theme directory. Default.jsp is located in the PortalServer/app/wps.ear/wps.war/themes/html directory for the default theme. Note: Many of the scenarios and examples provided in this chapter use the default resources for the HTML markup. Versions of the resources specific to a client, locale or theme/skin are located in a subdirectory. For example, the subdirectory is ns4 for the resources specific to Netscape Version 4. Default.jsp defines the overall page layout, the HTML headers, the Cascading Style Sheets for the page, and the banner with the navigation elements. Default.jsp uses nested HTML tables to define the overall layout of the page for the HTML markup. The following example shows fragments of the HTML generated by Default.jsp. Example 6-8 HTML markup generated by Default.jsp <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <!-- HTML Header (from head.jsp include) --> Chapter 6. Portal customization 279 <body marginwidth="0" marginheight="0" <!-- other body attributes --> > <table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%"> <tr> <td width="100%" height="1" valign="top"> <!-- Banner (from banner.jsp include) --> </td> </tr> <tr> <td width="100%" height="100%" valign="top"> <!-- Screen (from<wps:screenRender> JSP Tag) --> </td> </tr> </table> </body> </html> The source code generated by included files and subcomponents has been removed for clarity. These will be reviewed later in this section. Note: All the source code examples provided in this chapter will be simplified and edited for readability and clarity. Default.jsp defines the top level <table> used for the page layout. This table contains two rows: one for the banner with the navigation components and one for the screen components displayed by the <wps:screenRender> JSP tag. The layout obtained is illustrated in Figure 6-7. Banner and navigation Home Screen Figure 6-7 Layout defined by Default.jsp The two cells defined by Default.jsp correspond to the Banner and Home Screen cells in Figure 6-6. It is recommended that you keep Figure 6-6 in mind while 280 IBM WebSphere Portal V4 Developer’s Handbook going through this section since we will review how each component in this figure is defined. Default.jsp uses the JSP include directive for the HTML headers (Head.jsp) and the banner components (Banner.jsp). Both files are located in the theme directory: PortalServer/app/wps.ear/wps.war/themes/html. Note: Using JSP include is a best practice for code development and maintenance. It is not required, as demonstrated in 6.4, “Building a virtual portal: the YourCo portal” on page 347. Head.jsp generates the HTML header section of the HTML document for the page, including links to the Cascading Style Sheet files and to the JavaScript files. The HTML markup generated by Head.jsp is displayed in Example 6-9. Example 6-9 HTML markup generated by Head.jsp <head> <title>IBM WebSphere Portal</title> <link href='/wps/themes/html/Styles.css' rel="styleSheet" type="text/css"> <link href='/wps/themes/html/HelpStyles.css' rel="styleSheet" type="text/css"> <script type="text/javascript" language="Javascript" src="/wps/menu/menu_service.js"></script> <script type="text/javascript" language="Javascript"> menuService_writeApplet("/wps/menu"); </script> </head> Note: The elements in the header section of the HTML document are only defined by the theme. Screens, skins, and portlets cannot define elements in this section. Styles.css is the default Cascading Style Sheet resource for the default theme. Depending on your browser and locale, another Cascading Style Sheet might be used, such as /wps/themes/html/ie/en/Styles.css when the desktop browser is Internet Explorer and the locale is set to English. This Cascading Style Sheet Styles.css defines the styles for the portal-level elements, but also for other elements, such as portlets, as illustrated in the following fragments. Chapter 6. Portal customization 281 Example 6-10 Fragments from Styles.css /***************************************************************************/ /* General styles */ /***************************************************************************/ a { color: #3366CC; } body { font-family: sans-serif; background-color: #FFFFFF; font-size: 12pt; margin: 0; } /***************************************************************************/ /* Styles used in the header or other common sections of the page */ /***************************************************************************/ /* banner at the top of the page */ .wpsPortalBanner { background-color: #514E54; background-repeat: no-repeat; } /* text on banner at the top of the page */ .wpsPortalBannerText { font-family: sans-serif; font-size: 12pt; font-weight: bold; color: #FFFFFF; } /***************************************************************************/ /* Special styles for administration */ /***************************************************************************/ /* enroll screen background */ .wpsEnrollBack { background-color: #FFFFCC; } /* admin portlets: header bar and task manager selected tab*/ .wpsTableAdminHead {background-color: #EBEBEB; color: #666666; font-family: sans-serif; font-size: 12pt;} /***************************************************************************/ /* Styles used in portlets */ /***************************************************************************/ /* standard portlet background */ .wpsPortletBack { background-color: #FFFFFF; } /* edit and configure mode backgrounds */ .wpsEditBack, .wpsConfigureBack { background-color: #FFFFFF; } The style sheet defines fonts and colors for the HTML elements on the page. For example, the generic styles section defines the font sans-serif with a size of 10 points for HTML tags such as A, TABLE, TD. 282 IBM WebSphere Portal V4 Developer’s Handbook This style sheet also defines a set of classes to be used by components of the portal, such as the header section and the portlet section. The style sheets used by WebSphere Portal contain classes that can be used by portlets to ensure visual consistency between portlets on the page. Using these classes ensures that no matter what theme has been selected, the portlet's look and feel matches that of other portlets and the portal page. To find the portlet classes, look for the following comment in the style sheet Styles used in portlets. Note: It is not required that Cascading Style Sheets be used for the theme, however, it is recommended so that a consistent look and feel can be maintained and to define classes that might be used in commercially available portlets. Banner.jsp displays the banner and the navigation elements for the Welcome page. The following shows fragments of the HTML generated by Banner.jsp. Example 6-11 Fragments from the HTML markup generated by Banner.jsp <table border="0" cellspacing="0" cellpadding="0" width="100%"> <!-- Banner --> <tr> <td valign="middle" class="wpsPortalBanner" background='/wps/themes/html/banner.jpg'> <table border="0" cellspacing="0" cellpadding="6" width="100%"> <tr> <td class="wpsPortalBannerText" valign="middle" align="left" height="39" width="90%"> <img align="absmiddle" alt='IBM WebSphere Portal' title='IBM WebSphere Portal' src='/wps/themes/html/logo.gif'> </td> </tr> </table> </td> </tr> <!-- Navigation Elements --> <tr> <td> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tr> <td class="wpsToolbar" align="left" nowrap> Chapter 6. Portal customization 283 <!-- Place Navigation --> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td> <form name="wpsPageGroupSelectionForm" method="POST" style="margin-bottom: 0" action='/wps/portal/.pcmd/changePageGroupJSPCommand'> <select name="changePageGroupJSPCommand" onchange="this.form.submit ()"> <option value="<!-- url -->" selected>Home </select> </form> </td> </tr> </table> </td> <td class="wpsToolbar" dir="ltr" align="right"> <!-- Portal Controls --> <table border="0" cellspacing="0" cellpadding="1" > <tr> <td valign="middle"> <a href='/wps/portal/.scr/ForgotPassword'> <img <!--nav_forgot_password.gif--> > </a> </td> <td valign="middle"> <a href='/wps/portal/.cmd/PrepareEnrollment'> <img <!-- nav_create_account.gif --> > </a> </td> </tr> </table> </td> </tr> </table> </td> </tr> <tr> <td> <table border="0" cellspacing="0" cellpadding="0" width="100%"> 284 IBM WebSphere Portal V4 Developer’s Handbook <tr> <td class="wpsNavbar" align="left" valign="bottom"> <!-- Page Navigation --> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td class="wpsSelectedTab" valign="top" > <img <--tab_angle.gif--> > </td> <td class="wpsSelectedTab" nowrap height="19"> <a href='<!-- url -->' class="wpsSelectedTab"> Welcome </a> </td> </tr> </table> </td> </tr> </table> </td> </tr> </table> Banners.jsp defines an HTML table with three rows. 1. The first row renders the WebSphere Portal banner with the WebSphere Portal logo and the Welcome message when the user is logged in. 2. The second row renders the pull-down menu for place selection and the portal level controls, such as Enroll, Login, and Help. 3. The third and last row renders the tabs for page selection. Banner.jsp uses the <wps.urlFindInTheme> tag to display most images. For example, the <wps:urlFindInTheme file="banner.jpg"/>'> tag is used to retrieve the URL for the banner image. This tag generates a URL pointing to a resource file from the theme. Which resource file is selected depends on the client (such as Internet Explorer) and the locale. See 6.5.34, “<wps:urlFindInTheme>” on page 406 for more information Chapter 6. Portal customization 285 on this specific tag and refer to 6.5, “JSP tags reference” on page 386 for a reference of common JSP tag used in the theme, skins, and screens. The following source code extract displays the Welcome message for logged in users in the first row. Example 6-12 Source code to render the Welcome message <wps:if loggedIn="yes" screen="Home,LoggedIn"> <wps:text key="welcome" bundle="nls.engine"> <wps:textParam><wps:user attribute="fullName"/> </wps:textParam> </wps:text> </wps:if> The page displays the Welcome message only when the user is logged in and the current screen is Home or LoggedIn. For example, the Welcome message would not be displayed for the registration screens. The <wps:if> tag checks both conditions and executes the inner source code when both conditions are met. See 6.5.6, “<wps:if>” on page 390 for more information. The <wps:text> tag retrieve the Welcome message from the engine bundle. The default corresponding file for this bundle is engine.properties in the /AppServer/lib/app/nls directory. The entry for the Welcome key in this bundle is welcome = Welcome {0}! where {0} is replaced by the parameter passed by the <wps:textParam> tag. The bundle used can have a language suffix corresponding to the user locale, for example, engine_en.properties for English. See “Language and resource bundles” on page 311 for more information. The <wps.user> tag returns information about the logged in user. Here it returns the full name of the user to be passed as a parameter. See 6.5.36, “<wps:user>” on page 408 for more information. The Welcome message displayed is Welcome wpsadmin! for wpsadmin. The drop-down selection for places is built by looping through all the places available to the user and listing them as <option> in the HTML <select> tag. The following source code illustrates how this is accomplished. 286 IBM WebSphere Portal V4 Developer’s Handbook Example 6-13 Source code to render the drop-down elements <wps:pageGroupLoop> <option value="<wps:urlParent/>" <wps:if pageGroupSelected="yes">selected</wps:if>> <wps:pageGroup attribute="title"/> </wps:pageGroupLoop> The <wps:pageGroupLoop> loops through all the places available to the user. For each place available, the <wps:pageGroup attribute="title"/> writes the title of the place to be displayed in the drop-down selection, while <wps:urlParent> sets the value of the <option> tag as the URL of the place. See 6.5.35, “<wps:urlParent>” on page 406 and 6.5.8, “<wps:pageGroup>” on page 397 for more information. The <wps:if> tag is used in this context to select the current place by default in the drop-down menu. The tabs for the pages are displayed using similar tags for the pages as illustrated in the following source code: Example 6-14 Source code to render the tabs <wps:pageLoop> <wps:if pageSelected="yes"> <td class="wpsSelectedTab" valign="top" > <img <!--tab_angle.gif--> > </td> <td class="wpsSelectedTab" nowrap height="19"> <a href='<wps:urlParent/>' class="wpsSelectedTab"> <wps:page attribute="title"/> </a> </td> </wps:if> <!-- Source Code for page not selected --> </wps:pageLoop> The <wps:pageLoop> tag loops though all the pages available in the current place. For each page available, <wps:page attribute="title"/> writes the title of the page to be displayed as a tab, while <wps:urlParent> sets the value of the URL for the outer HTML <a> tag. Chapter 6. Portal customization 287 The <wps:pageLoopInit max=”number”> tag sets the maximum number of tabs displayed. The <wps:pageLoop> loop continues until no more pages are available or when the number of pages is at the maximum value allowed. Combining the tags prepares the URL for page loop shifts. See 6.5.11, “<wps:pageLoopInit>” on page 399 and 6.5.12, “<wps:pageLoopShift>” on page 399 for more information. Banner.jsp defines the portal-level controls such as Forgot Password, Enroll, Login, Logout, and Help on the far right of the place drop-down selection. The following source code extract shows the source code to display the Forgot Password control. Example 6-15 Source code to display the forgot password control <wps:if loggedIn="no" notScreen="ForgotPassword"> <td valign="middle"> <a href='<wps:url screen="ForgotPassword" home="public"/>'> <img <!--nav_forgot_password.gif--> '> </a> </td> </wps:if> The Forgot Password control is displayed when the user is not logged in and the current screen is not the Forgot Password screen. The <wps:url screen="ForgotPassword" home="public"/> tag renders the link to access the Forgot Password screen. See 6.5.30, “<wps:url>” on page 405 for more information. To summarize, Default.jsp renders the <html> root element, the header section of the html document, the top level <table> element to start the layout of the page, and finally all the portal level navigation elements by using Banner.jsp. Default.jsp is a required resource for each markup as Default.jsp is the entry JSP page for the portal. Default.jsp displays most of the pages rendered by the portal. Plain.jsp is used for some of the pages. For example, help for the portlets, by default, opens in a pop-up window and therefore Plain.jsp is used. Screen Default.jsp uses the <wps:screenRender/> tag to render the screen component in its second and bottom cell. 288 IBM WebSphere Portal V4 Developer’s Handbook The Welcome page uses the default screen Home to display the screen components, such as row and column containers and portlets, as do most of the pages displayed by the portal. The Home screen uses the JSP Home.jsp located in the PortalServer/app/wps.ear/wps.war/screens/HTML directory. Other predefined screens include: Log-in (Login.jsp) Forget Password (ForgotPassword.jsp) Sign-up related (UserProfileForm.jsp, UserProfileConf.jsp, etc.) Error related (Error.jsp, ErrorNotLoggedOut.jsp, etc.) The HTML generated by Home.jsp is quite trivial, as shown below. Example 6-16 Fragments from the HTML markup generated by Home.jsp <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <!-- <wps:pageRender/> --> </td> </tr> </table> Home.jsp includes the <wps:pageRender> tag, which aggregates the screen components. Other screens are task-specific and display content related to a task, such as a login form for the Login screen, and as such don’t use <wps:pageRender>. Note: WebSphere Portal uses the same screens independently of the selected theme. Therefore, screens should be theme-independent. Skins The layout of the screen components is controlled by row and column containers, which may contain containers as well as controls. A control is a single portlet with its surrounding (border, title bar). The customizer provides a good way to see the components defined for a page. It is available by selecting Work with Pages -> Edit Layout and Content. The Chapter 6. Portal customization 289 Welcome page view provided by the customizer is displayed in the following figure. Figure 6-8 Customizer page for the Welcome page The Welcome page screen layout presents a Row Container, which contains two Column Containers, each containing two portlet containers or controls, with a portlet in each. The aggregation engine calls RowContainer.jsp to render the Row Container. RowContainer.jsp is located in the skin directory PortalServer/app/wps.ear/wps.war/skins/HTML. The following extracts show the source code generated by RowContainer.jsp: Example 6-17 Source code fragments from RowContainer,jsp <table width="100%" cellpadding="0" cellspacing="0" align="center" border="0"> <tr height="100%"> <wps:componentLoop id="component"> <td valign="top" <wps:width/>> <wps:componentRender/> </td> </wps:componentLoop> 290 IBM WebSphere Portal V4 Developer’s Handbook </tr> </table> RowContainer.jsp defines the <table> and <tr> HTML markup for the row and starts rendering the two columns it holds. The rendering of the columns is started by the <wps:componentRender> tag. This tag has to be surrounded by the <wps:componentLoop> tag, which repeats its content for each component. The aggregation engine calls ColumContainer.jsp to render the column containers. ColumnContainer.jsp is located in the skin directory PortalServer/app/wps.ear/wps.war/skins/HTML. The following extracts show the source code generated by ColumnContainer.jsp. Example 6-18 Source code fragments from ColumnContainer.jsp <table width="100%" height="100%" cellpadding="0" cellspacing="0" align="center" border="0"> <wps:componentLoop> <tr> <td width="100%" valign="top"> <wps:componentRender/> </td> </tr> </wps:componentLoop> </table> ColumnContainer.jsp renders a column container and start the rendering of all the controls it contains. The rendering of the controls is started by the <wps:componentRender> tag. The tag has to be surrounded by the <wps:componentLoop> tag, which repeats its content for each component. The following example shows fragments of the HTML generated by Home.jsp and both row and column containers for the Welcome page. Example 6-19 Fragments of HTML generated by Home, Row and Column containers <!--Home Markup Start--> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <!--Row Container Markup Start--> <table width="100%" cellpadding="0" cellspacing="0" Chapter 6. Portal customization 291 align="center" border="0"> <tr height="100%"> <td valign="top" > <!--Column Container Markup Start (Column 1)--> <table width="100%" height="100%" cellpadding="0" cellspacing="0" align="center" border="0"> <tr> <td width="100%" valign="top"> <!--Markup for the welcome control--> </td> </tr> <tr> <td width="100%" valign="top"> <!--Markup for the clock control--> </td> </tr> </table> <!--Column Container Markup End (Column 1)--> </td> <td valign="top" > <!--Markup for the second column and its content--> </td> </tr> </table> <!--Row Container Markup End (Row 1)--> </td> </tr> </table> <!--Home Markup End--> The row and column containers define HTML tables. The row container defines a HTML table with two horizontal cells, while each column container defines a HTML table with two vertical cells as illustrated in the following figure. 292 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-9 Layout defined by the aggregation engine and the containers JSPs Both column containers contain two controls. The column container displays each of the controls by using <wps:componentRender>. WebSphere Portal uses Control.jsp to render the controls. Control.jsp is located in the skin directory PortalServer/app/wps.ear/wps.war/skins/HTML. The following example shows an extract of the source code for Control.jsp. Example 6-20 Source code fragments from Control.jsp <table width="100%" <wps:if portletState="Normal,Maximized">height="100%"</wps:if> border="0" cellpadding="0" cellspacing="5"> <tr> <td> <table width="100%" <wps:if portletState="Normal,Maximized">height="100%"</wps:if> border="0" cellpadding="0" cellspacing="0" class="wpsPortletBody"> <!--top border--> <tr height="1"> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img <--dot.gif-->> </td> <td bgcolor="<%=borderColor%>" height="1"> <img <--dot.gif-->> </td> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img <--dot.gif-->> </td> </tr> <tr height="1"> Chapter 6. Portal customization 293 <!--title bar left border--> <td bgcolor="<%=borderColor%>" width="1"> <img <--dot.gif-->> </td> <!--portlet title bar--> <td> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <!--portlet title--> <td class="wpsPortletTitle" width="100%" nowrap align="<%= bidiAlignLeft %>" valign="middle"> <wps:portletTitle> <wps:problem bundle="nls.problem"/> </wps:portletTitle> </td> <!--portlet controls--> <td class="wpsPortletTitle" nowrap align="right" valign="middle"> <wps:portletHelp newWindow="true"> <a href="javascript: window.open(<!--.0..-->).focus();"> <img<!--title_help.gif-->> </a> </wps:portletHelp> <wps:if loggedIn="yes"> <wps:portletMinimize> <a href='<wps:urlParent/>'> <img<!--title_minimize-->> </a> </wps:portletMinimize> <wps:portletRestore> <a href='<wps:urlParent/>'> <img<!--title_restore-->> </a> </wps:if> </td> </tr> </table> </td> 294 IBM WebSphere Portal V4 Developer’s Handbook <!--title bar right border--> <td bgcolor="<%=borderColor%>" width="1"> <img <--dot.gif-->> </td> </tr> <wps:if portletState="Normal,Maximized"> <tr height="100%"> <!--portlet left border--> <td bgcolor="<%=borderColor%>" width="1"> <img <--dot.gif-->> </td> <!--portlet--> <td width="100%" valign="top"> <table width="100%" border="0" cellpadding="5" cellspacing="0"> <tr> <td> <wps:portletRender> <font COLOR="red"> <wps:problem bundle="nls.problem"/> </font> </wps:portletRender> </td> </tr> </table> </td> <!--portlet right border--> </tr> </wps:if> <!--bottom border--> </table> </td> </tr> </table> Control.jsp defines the surrounding of the portlet, such as its border and its title bar and uses the <wps:portletRender> tag to render the portlet content. Chapter 6. Portal customization 295 Control.jsp defines two content rows: one to display the title bar, including the portlet controls, and the second to display the portlet content. The rows are surrounded by a border of one pixel, as illustrated in the following figure. title controls portlet content Figure 6-10 Layout defined by Control.js The <wps:portletTitle> tag displays the portlet title. If a problem occurred while displaying the title, the message inside the tag is displayed. See 6.5.23, “<wps:portletTitle>” on page 402 for more information. Control.jsp displays the portlet controls: Configure, Edit, Help, Minimize, Maximize, and Restore. All the controls, except for Help, are displayed for logged-in users only since their functionalities require user sessions, which are not activated for Anonymous by default for performance reasons. Each portlet control has a corresponding tag that displays its inner content depending on the state of the portlet. For example, <wps:portletMaximize> displays its inner content when the portlet state is not maximized. Control.jsp uses <wps:portletRender> to write the output from the portlet. Here, for example, is the result for the Welcome portlet. Example 6-21 Welcome Portlet output IBM WebSphere Portal Server <br> Version: 4.1.2 <br> Build Level: 412xt_118_20020621 2002-06-22 01:51 <br> <br> Licensed Materials - Property of IBM <br> 5724-B88 <br> (C) Copyright IBM Corp. 2001, 2002 All Rights Reserved. <br> 296 IBM WebSphere Portal V4 Developer’s Handbook Note: The cellspacing for the top level table in Example 6-20, “Source code fragments from Control.jsp” on page 293 is set to 5 to allow spaces between portlets. The cellpadding attribute for the table surrounding the portlet content (<wps:portletRender>) is also set to 5 by default to leave space between the portlet content and the border. To summarize, the following JSP resources are used to construct the Welcome page (excluding the portlet resources). Table 6-3 Welcome page resources Folder Resources PortalServer\app\wps.ear\wps.war\themes Default.jsp Banner.jsp (included) Head.jsp (included) PortalServer\app\wps.ear\wps.war\screens Home.jsp PortalServer\app\wps.ear\wps.war\skins RowContainer.jsp ColumnContainer.jsp Control.jsp Theme Screen Default.jsp Home.jsp Head.jsp Banner.jsp Skin RowContainer.jsp ColumnContainer.jsp Control.jsp Control.jsp ColumnContainer.jsp Control.jsp Control.jsp Figure 6-11 Java Server Page resources used for the Welcome page Chapter 6. Portal customization 297 6.2.4 Extend Services WebSphere Portal Extend includes collaboration services. The following source code combined from Head.jsp and Default.jsp shows the implementation of this services. Example 6-22 Source code for the collaboration services <%@ taglib uri="/WEB-INF/tld/extend.tld" prefix="extend" %> <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="pa" %> <%@ taglib uri="/WEB-INF/tld/menu.tld" prefix="menu" %> <menu:menuinit/> <!-- Lotus Collaborative Services --> <wps:if loggedIn="yes"> <pa:peopleinit/> </wps:if> <wps:if loggedIn="yes"> <pa:peopleend/> </wps:if> <menu:menuinit> initializes the menu service that adds menus to the Collaborative Components applications. The <pa:peopleinit/> tag determines whether Sametime® or Discovery Server, or both, are enabled to work with Portal Server and generates the correct HTML and JavaScript for initializing Sametime or enabling Discovery Server, or both. WebSphere Portal Extend also provides a Bookmark functionality and a Find functionality. Banner.jsp defines their location and appearance. The following source code extracts shows the definition for the Find functionality. Example 6-23 Source code for the Find link <extend:find> <a href="<wps:urlParent/>" style="text-decoration:none" title="<wps:text key='link.find' bundle='nls.engine'/>" target="_blank"> <img align="absmiddle" src="<wps:urlFindInTheme file='task_show_info.gif'/>" border="0"> <span style="text-decoration:underline"><wps:text key="link.find" bundle="nls.engine"/></span></a> </extend:find> See “Bookmarks” on page 341, and “Find” on page 346 for more information on these WebSphere Portal Extend functionalities. 298 IBM WebSphere Portal V4 Developer’s Handbook 6.3 Portal customization The portal includes components such as a banner, a logo, a navigation bar, and portlets as illustrated in Figure 6-2. All of these components, and many more, are based on well-known standards and are fully customizable. In 6.3.1, “Basic customization” on page 299, we describe how to easily and quickly customize the layout and the appearance of the portal by modifying the themes and the skins. In 6.3.2, “Advanced customization” on page 315, we show how to add more advanced functionalities of the portal, such as new clients and new markups. Note: If changes to your portal pages do not appear in testing, you might need to clear the WebSphere Application Server cache located in was_root/temp/default_host/wps. 6.3.1 Basic customization WebSphere Portal provides an easy way of modifying the appearance and the layout of the portal through the concepts of themes and skins. Theme Each theme contains a set of resources, such as Java Server Pages, and images. These resources are located in a subdirectory using the theme name in the PortalServer\app\wps.ear\wps.war\themes\markup\ directory. The following resources are typical of a theme: Java Server Pages For example, Default.jsp, and Banner.jsp are used to provide the layout and the navigation of the overall portal. See “Layout” on page 300 for more information on customizing the layout and “Navigation” on page 303 for more information about the navigation. Style sheets Styles.css is the default style sheet for the portal. For incoming Internet Explorer requests, the ie/Styles.css style sheet is used. You can change the style definition for the tags as well as the classes for the CSS style sheets. See “Style sheets” on page 308 for more information about the style sheet. Chapter 6. Portal customization 299 Images You can modify the images used by the portal or create your own and add them to the JSPs. banner.jpg is the background image used by the portal banner. See “Image” on page 308 for an example of customizing the banner. Layout The portal allows end-users with appropriate privileges to customize their portal experience by changing the layout of each page by selecting Work with Pages -> Edit Layout and Content. End users can customize the layout of the portlets. The portlets are contained in a screen as shown in the following figure. page screen portlets Figure 6-12 Portal page The layout is quite complex for the HTML markup. We will therefore consider this markup as other markups provide a simplified layout. The overall layout of the portal is defined by the theme. The theme sets how the pages look and where the screen component is located. The layout for the HTML markup is defined by using nested tables. To modify the page layout, the Java Server Pages files for the theme used, such as Default.jsp and Banner.jsp, need be modified. Inside the screen, the layout is set by the page manager or the end users using the customizer. The layout of the row and column is defined by the skins. Most companies will use the default row and column resources for the HTML markup since it closely matches the table layout defined by using the customizer. 300 IBM WebSphere Portal V4 Developer’s Handbook The layout surrounding the portlet is also defined by the skin. To modify the control layout, the skin resource Control.jsp needs to be modified. The layout of the portlet content is defined by the portlet developers. Some portlets use Java Server Pages to render the layout of the content. In such a case, the JSP file could be modified to change the layout. Customization example: changing the default page layout A portal designer would like to change the layout of the portal. He would prefer the navigation element to be Explorer as on the right of the portal content. To experiment with the new design, we will create a test theme called Portal. 1. Create the folder Portal in the folder PortalServer\app\wps.ear\wps.war\themes\html. 2. Copy Default.jsp from the folder PortalServer\app\wps.ear\wps.war\themes\html into the new folder. 3. Open Default.jsp. 4. Change <%@ include file="./Head.jsp" %> to <%@ include file="../Head.jsp" %> by adding a period after the quote since Head.jsp is now in the folder one level up with respect to the location of the copied Default.jsp. 5. Replace the top-level table and its content with the following source code. Example 6-24 Source code for layout customization <table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%"> <tr> <td height="100%" valign="top"> <!-- new navigation--> <table border="1" cellpadding="5" cellspacing="0" bgcolor="#efefef"> <tr> <td nowrap> My navigation </td> </tr> <wps:pageGroupLoop> <wps:if pageGroupSelected="yes"> <tr> <td nowrap> <strong><wps:pageGroup attribute="name"/></strong> </td> </tr> Chapter 6. Portal customization 301 <wps:pageLoop> <tr> <td nowrap> > <a href="<wps:urlParent/>"> <wps:page attribute="name"/></a> </td> </tr> </wps:pageLoop> </wps:if> <wps:if pageGroupSelected="no"> <tr> <td nowrap> <a href="<wps:urlParent/>"><wps:pageGroup attribute="name"/></a> </td> </tr> </wps:if> </wps:pageGroupLoop> </table> </td> <!--screen render--> <td width="90%" height="100%" valign="top"> <wps:screenRender/> </td> </tr> </table> 6. Add the new theme to the portal using Portal Administration -> Portal Settings - Themes and Skins. 7. Create a new place and apply the new theme to it using Work with Pages -> Places and pages. 8. Create a new page in the place and add a few portlets to it. 9. Activate the new page. 10.Select the new place in the navigation menu. The following figure shows a new home page with the modified layout. 302 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-13 Customized layout for the Welcome page Navigation Typically, a theme provides users with two level of navigation. The first level allows users to select a place. The second level allows users to select a page in the previously selected place. Selecting a place is done through the following drop-down menu for the portal. Figure 6-14 Place selection in the Admin theme The following source code fragment renders this drop-down menu. Example 6-25 Source code for place menu selection <select name="changePageGroupJSPCommand" onchange="this.form.submit ()"> <wps:pageGroupLoop> <option value="<wps:urlParent/>" <wps:if pageGroupSelected="yes">selected</wps:if>> <wps:pageGroup attribute="title"/> </wps:pageGroupLoop> </select> Chapter 6. Portal customization 303 The <wps:pageGroupLoop> tag is used to loop through all the places available for the user and the <wps:urlParent> tag provides the URL to navigate to each of the places. Refer to 6.5, “JSP tags reference” on page 386 for more information. The selection of a page is done via by horizontal tabs for the default portal. The following figure shows the tabs for the Portal Administration place. Figure 6-15 Page selection in the default theme The following source code fragment renders the tabs for the page selection. Example 6-26 Source code for page selection <%-- special code to tell which tab we are drawing --%> <% boolean firstTab = true; boolean previousTabIsSelected = false; %> <wps:pageLoop> <wps:if pageSelected="yes"> <%-- selected page tab --%> <td class="wpsSelectedTab" valign="top" ><img alt="" width="6" height="6" align="top" border="0" src="<wps:urlFindInTheme file='<%= "tab_angle" + bidiImageRTL + ".gif"%>'/>"></td> <td class="wpsSelectedTab" nowrap height="19"> <a href='<wps:urlParent/>' class="wpsSelectedTab"> <wps:page attribute="title"/> </a> </td> <% previousTabIsSelected = true; %> </wps:if> <wps:if pageSelected="no"> <%-- non-selected page tab --%> <% boolean addSeparator = true; // turn off separator if this is the first tab being drawn 304 IBM WebSphere Portal V4 Developer’s Handbook if (firstTab) { addSeparator = false; firstTab = false; } // turn off separator if the previous tab was selected if (previousTabIsSelected) { addSeparator = false; previousTabIsSelected = false; } if (addSeparator) { %> <td valign="middle"> <img alt="" align="absmiddle" width="9" height="9" border="0" src='<wps:urlFindInTheme file="tab_separator.gif"/>'> </td> <% } %> <td class="wpsTabs" nowrap height="19"> <a href='<wps:urlParent/>' class="wpsTabs"> <wps:page attribute="title"/> </a> </td> </wps:if> </wps:pageLoop> The <wps:pageLoop> tag is used to loop through all the pages available for the user in the current place and the <wps:urlParent> tag provides the URL to navigate to each of the pages. Refer 6.5, “JSP tags reference” on page 386 for more information. The images such as tab_separator.gif and tab_angle.gif are used to build the tabs. These images are resources of the theme. The images could be easily modified. The location of the navigation components could be changed by editing Default.jsp and Banner.jsp. Also, the type of selection, such as menu selection or tabs, could be modified by editing Banner.jsp. Chapter 6. Portal customization 305 In the default theme, only the pages for the current selected places are displayed. Example 6-24, “Source code for layout customization” on page 301 shows how to build a navigation component where all the pages for all the places are displayed. The pages of the Portal Administration place include a third level of navigation. After selecting a place, and then a page, users can select a portlet to be displayed. Tabs provide this third navigation element as illustrated in the following figure for the Portal Settings page. Figure 6-16 Portlet selection for the Portal Settings page The Selector Portlet renders the portlet selection tabs for the pages. To use the Portlet Selector, the following conditions should be met: The Selector Portlet should be the first portlet on the page (otherwise the tabs might be displayed after the selected portlet) All the portlets on the page should use the NoSkin skin The portlets should be placed in a one column container The Selector portlet uses the MVC pattern and therefore build its view using a JSP file. This JSP file could be customized for the application layout and feel. The file is located in the WebSphere Application Server directory AppServer\installedApps\SelectorPortlet_WPS_PA_151.ear\SelectorPortlet.war\ WEB-INF\jsp. Note: It is recommended that you create a new Selector Portlet inheriting from the current one when modifying the Java Server Pages. The portal provides navigation to specific tasks by using controls. For example, at the portal level, the following figure displays some of the controls such as login, logout, enroll, and forgot password. To remove or change the controls provided by the default theme, edit Banner.jsp and modify the following part of the source code. Example 6-27 Source code for profile management controls <%-- forgot password button --%> <wps:if loggedIn="no" notScreen="ForgotPassword"> <td valign="middle"> 306 IBM WebSphere Portal V4 Developer’s Handbook <a href='<wps:url screen="ForgotPassword" home="public"/>'> <img src='<wps:urlFindInTheme file="nav_forgot_password.gif"/>' alt='<wps:text key="link.password" bundle="nls.engine"/>' border="0" align="absmiddle" width="28" height="25" title='<wps:text key="link.password" bundle="nls.engine"/>'> </a> </td> </wps:if> <%-- selfcare button --%> <wps:if loggedIn="yes" notScreen="SelfcareUserForm,SelfcareUserConf"> <td valign="middle"> <a href='<wps:url command="PrepareSelfcare" reqid="no"/>'> <img src='<wps:urlFindInTheme file="nav_profile.gif"/>' alt='<wps:text key="link.selfcare" bundle="nls.engine"/>' border="0" align="absmiddle" width="28" height="25" title='<wps:text key="link.selfcare" bundle="nls.engine"/>'> </a> </td> </wps:if> <%-- enroll button --%> <wps:if loggedIn="no"> <td valign="middle"> <a href='<wps:url command="PrepareEnrollment" home="public" reqid="no"/>'> <img src='<wps:urlFindInTheme file="nav_create_account.gif"/>' alt='<wps:text key="link.enrollment" bundle="nls.engine"/>' border="0" align="absmiddle" width="26" height="25" title='<wps:text key="link.enrollment" bundle="nls.engine"/>'> </a> </td> </wps:if> <%-- login button --%> <wps:if loggedIn="no" notScreen="Login"> <td valign="middle"> <a href='<wps:url home="public" screen="Login"/>'> <img src='<wps:urlFindInTheme file="nav_login.gif"/>' alt='<wps:text key="link.login" bundle="nls.engine"/>' border="0" align="absmiddle" width="25" height="25" title='<wps:text key="link.login" bundle="nls.engine"/>'> </a> </td> </wps:if> <%-- logout button --%> <wps:if loggedIn="yes"> <td valign="middle"> <a href='<wps:url command="LogoutUser"/>'> Chapter 6. Portal customization 307 <img src="<wps:urlFindInTheme file='<%= "nav_logoff" + bidiImageRTL + ".gif" %>'/>" alt='<wps:text key="link.logout" bundle="nls.engine"/>' border="0" align="absmiddle" width="25" height="25" title='<wps:text key="link.logout" bundle="nls.engine"/>'> </a> </td> </wps:if> The controls are placed on the page using the HTML image tag <img> in Banner.jsp. The images used by the control are located in the theme directory structure. The location and the appearance of the controls could easily be modified by editing Banner.jsp. Also, the control could be added to other navigation elements such as the page selection element, as they are links to specific pages of the portal. This is the design chosen for the YourCo portal built in 6.4, “Building a virtual portal: the YourCo portal” on page 347. Style sheets Styles.css is the default style sheet. For Internet Explorer requests, the ie/Styles.css style sheet is used. The style sheets used by WebSphere Portal contain classes that can be used by portlets to ensure visual consistency between portlets on the page. Using these classes ensures that no matter what theme has been selected, the portlet’s look and feel matches that of other portlets and the portal page. You can examine the file Style.css to determine which classes to invoke in your portlet inputs. The file includes comments explaining the use of each class. Cascading Style Sheet provides an easy way to modify the look and feel of a theme. Image When displaying a page using the default theme, a banner is located at the top of the page (see Figure 6-2). This same banner is used for all the pages of the portal after the portal installation. Figure 6-17 Banner for the default theme A banner is a component of the look and feel of the overall portal. Therefore, it is typically defined by the theme. 308 IBM WebSphere Portal V4 Developer’s Handbook The resource files used to define the banner location and appearance for the default theme are Banner.jpg and Banner.jsp. Banner.jpg is the image file for the banner. Banner.jsp creates the HTML tags used to display the banner image. Both files are located in the PortalServer/app/wps.ear/wps.war/skins/markup/theme folder. The banner is placed on the page by using the background attribute with the value <wps:urlFindInTheme file="banner.jpg"/> for a <TD> cell in the file Banner.jsp. Example 6-28 Source code to display the banner (Banner.jsp) <%-- banner --%> <tr> <td valign="middle" class="wpsPortalBanner" background='<wps:urlFindInTheme file="banner.jpg"/>'> Banner.jsp is used by Default.jsp, the entry JSP page for the Portal, by using a JSP include directive for the file. The <wps> tags, such as <wps:urlFindInTheme>, are defined in the tag library engine.tld and are imported using <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> in Default.jsp. The <wps> tags can be used to modify the layout of the portal page. Please see 6.5, “JSP tags reference” on page 386 for more information. The banner can be modified by designing a new banner, saving it in the theme directory and then changing the JSP source code to reflect the new name of the banner image file. The location of the banner on the page can be changed by moving the background attribute to another cell in Banner.jsp or even Default.jsp. The background attribute could also be replaced with an image tag. The overall layout of the page could be changed by modifying the top table and/or the nested tables in both files to meet a desired layout. Customization example: designing a new banner image 1. Open Banner.jpg in the PortalServer\app\wps.ear\wps.war\themes\html directory using your favorite image editor. 2. Modify the image. 3. Save the new banner image under a different name such as mybanner.jpg in the same directory. 4. Open Banner.jsp from PortalServer\app\wps.ear\wps.war\themes\html. 5. Change the name of Banner.jpg to that of the new banner . Chapter 6. Portal customization 309 Example 6-29 Source code to display the new banner <%-- banner --%> <tr> <td valign="middle" class="wpsPortalBanner" background='<wps:urlFindInTheme file="mybanner.jpg"/>'> 6. Open and save Default.jsp to trigger a reload of the include files. The logo displayed by the default theme is located at the top left of the page (see Figure 6-12), technically on the banner image. Visually, it is part of the banner. The logo is placed on the page using the image tag <img [...] src='<wps:urlFindInTheme file="logo.gif"/>'> in Banner.jsp. Other images can be changed using the same techniques. The images are typically in the following two directories (or their subdirectories): PortalServer\app\wps.ear\wps.war\images PortalServer\app\wps.ear\wps.war\themes. Screen Screens are JSPs invoked by the portal server for displaying various content. The Home screen is most often displayed because it is used for the portlet content area. Other screens include the Login and Error screens. These screens can be customized by editing the JSP for each of them. Skin Figure 6-18 World Clock portlet with the Outline skin The surrounding of a portlet can be customized by defining a new skin. A theme has a default skin and this skin will be applied to all the portlets unless specified otherwise. 310 IBM WebSphere Portal V4 Developer’s Handbook Control.jsp defines most of the elements of the skins: portlet title, portlet controls, etc. Customizing the skins involves modifying resources in the skin directory. Language and resource bundles Resource bundles are used to store text for several languages. In Portal Server, resource bundles are located in AppServer\lib\app\nls. The naming convention for resource bundles is [bundle]_[language]_[country]_[variant].properties. The ISO standard ISO-639 is used for the language codes of most languages. For Hebrew, the old language code iw is used. The ISO standard ISO-3166 is used for the country codes. Portal Server supports the use of [variant], although resource bundles supplied with the portal do not use it. The portal uses the following resource bundles: button.properties engine.properties field.properties LocaleNames.properties problem.properties registration.properties titlebar.properties CSRes.properties The file can have a language suffix corresponding to the locale, for example, engine_es.properties for Spanish. WebSphere Portal searches for the resource bundles in the following order: 1. [bundle]_[language]_[country]_[variant].properties 2. [bundle]_[language]_[country].properties 3. [bundle]_[language].properties 4. [bundle].properties In WebSphere Portal, the default bundles [bundle].properties are in English. If WebSphere Portal cannot determine the client locale, the default bundle is used. The theme and skin Java Server Pages use the <wps:text> tag to retrieve the text from the bundle. For example, <wps:text key="title" bundle="nls.engine">Portal Title</wps:text> retrieves the portal title in Chapter 6. Portal customization 311 Banner.jsp from the engine bundle. See 6.5.26, “<wps:text>” on page 403for more information. The text can be changed by editing the properties file and then restarting the application server for WebSphere Portal. Customization example: changing Sign Up to Enroll for the Enroll control 1. Open engine.properties in AppServer\lib\app\nls. 2. Locate the key link.enrollment. 3. Change to link.enrollment = Enroll. 4. Save the file. 5. Repeat for engine_en.properties, and other language bundled if necessary. 6. Restart WebSphere Application Server. Customization example: adding a resource bundle for a language 1. Copy an existing resource bundle and translate it . 2. Name the resource bundle according to the naming convention. 3. Restart WebSphere Application Serve. Tip: Convert to Unicode with the Native-to-ASCII converter native2ascii which comes as part of JDK. For more details on native2ascii, see http://java.sun.com/products/jdk/1.1/docs/tooldocs/solaris/native2ascii.html. The portal supports Czech, English, French, German, Hebrew, Italian, Spanish, Brazilian, Portuguese, Japanese, Korean, Polish, Simplified Chinese, Traditional Chinese, and Turkish. The portal determines the language for rendering the portal content by a search process according to the following sequence at login time. 1. If the user has logged in, the portal displays in the preferred language selected by the user. 2. If no user language can be found, the portal looks for the language defined in the user's browser and displays the content in that language. 3. If no browser language can be found, for example if the browser used does not send a language, the portal resorts to its own default language. 4. If the user has a portlet which does not support any of the three languages above, that portlet is shown in its own default language. 312 IBM WebSphere Portal V4 Developer’s Handbook The sequence listed above describes the language selection process which is applied for each user at logon time. For pages viewed by anonymous users, only the last three steps for determining the language apply. This applies, for example, before login and after logoff. The installation panels for the portal installation use the language determined by the locale of your system, for example the operating system on the server on which the portal is installed. This language is also stored in LocalizerService.properties after the installation as the default language for the portal. Customization example: changing the default language of the portal 1. Set the keys locale.default.language, locale.default.country, and locale.default.variant in LocalizerService.properties to your locale identifier. For instance, to change the default language to American English, specify en and US for the language and country, respectively, for the first two parameters. 2. Restart WebSphere Portal Note: The portal offers an interface to change the portal default language in Portal Administration -> Portal Settings. The portal uses resource bundles for all the languages it supports for portal level text. Each portlet needs to provide its own support. The text currently used for a language can be modified by editing the appropriate resource bundle. The title of the Portal is displayed in the browser caption by using the HTML title tag <title><wps:text key="title" bundle="nls.engine"><Page Title></wps:text></title> in the Header.jsp, which is another JSP include used by Default.jsp. The title is also used in the alt and title attributes for the <IMG> tag for the logo in Banner.jsp. The text displayed is defined in the file engine.properties, in the directory was_root/lib/app/nls. For multilingual sites, the file can have a language suffix corresponding to the locale, for example, engine_es.properties for Spanish. I Tip: In the property file, a short version of the title is also defined: title=IBM WebSphere Portal title.short=IBM WPS Chapter 6. Portal customization 313 The portlet title is given by the portlet configuration or at runtime by the portlet title listener. The location and appearance of the title can be customized by editing the Control.jsp file. The welcome message is displayed on the top right when a user has logged in: <wps:text key="welcome" bundle="nls.engine"> <wps:textParam><wps:user attribute="fullName"/></wps:textParam> </wps:text> The <wps:text> tags accepts parameters as described in 2.5.35, “<wps:text>” on page 70 and in 2.5.36, “<wps:textParam>” on page 70. Tip: The user tag could also be used to obtain the user ID, the user family name as described in 2.5.46, “<wps:user>” on page 75. Other pages Licence agreement The License Agreement file contain information that should be changed to include the relevant content specific to the company portal. The file is located in the PortalServer/html directory. The licence information is displayed when a user click the privacy link from the User Profile screen. Example 6-30 Source code to display the link to the privacy page (UserProfileForm.jsp) <wps:text key="enrollment.privacy" bundle="nls.registration"> <wps:textParam> <A href='<wps:urlFind file="privacy.html" />' target="_new" > <wps:text key="enrollment.privacy.link" bundle="nls.registration"></wps:text> </A> </wps:textParam> </wps:text> The link could be removed or modified by editing the UserProfileForm.jsp from the screen directory. The link could also be added to other screens by editing the themes or screens resources. The layout of the policy screen could be changed by editing the privacy.html file. Privacy policy The Privacy Policy file contains information that should be changed to include the relevant content specific to your company. The file is located in PortalServer/html. The licence information is displayed when a user click the licence link from the User Profile screen. 314 IBM WebSphere Portal V4 Developer’s Handbook Example 6-31 Source code to display the privacy link (UserProfileForm.jsp) <a href='<wps:urlFind file="license.html"/> target="_new" > <wps:text key="enrollment.license.link" bundle="nls.registration"></wps:text> </a> The link could be removed or modified by editing the UserProfileForm.jsp from the screen directory. The link could also be added to other screens by editing the themes or screens resources. The layout of the policy screen could be changed by editing the licence.html file. 6.3.2 Advanced customization Most companies will use the portal provided by WebSphere Portal as a basis for their custom portal solution. Once the look and feel of the portal has been changed to meet the company branding, companies may want to change and update more advanced functionalities. They may want to customize the Enrollment page by using different fields, or remove the enrollment page completely, so users cannot enroll themselves. In “Enrollment” on page 315, we show how to add attributes to the Enrollment page. Companies may want to change the help provided by default with the portal to be more specific to the company and to reflect the company branding. In “Portal and InfoCenter help” on page 322, we show how to update the current help. Companies may want to change other components as well. For example, they may want to add a new client, such as the latest version of Netscape, and provide specific markup that takes advantage of the new capabilities available for this new browser. In “Clients” on page 333 and “Markups” on page 336, we show how to add a new client and a new markup for the portal. Enrollment Immediately after the portal is installed and started, guests can register with the portal by clicking the Enroll control. The Enroll control is displayed as an icon on the Welcome page like the other profile controls. This section discusses the enrollment process and customization. Guests can fill in their profile information, such as user ID, first and last names, to become registered users for the portal. They can optionally select the preferred language from a list of available languages. The portal uses this language for this user and makes this Chapter 6. Portal customization 315 information available to all portlets so that they can adapt their content to the user language preference. Users can also optionally select an interest which is used by the WebSphere Personalization sample portlet to customize content. For details, see Chapter 10, “Personalization” on page 501. The configuration file puma.properties is used by the Registration process of the Registration Servlet. It is located in the WAS_Root\lib\app\config directory. The following example displays extracts from this file. Example 6-32 Extracts of puma.properties puma.userValidator = com.ibm.wps.puma.SimpleUserValidator puma.UID.min = 3 puma.UID.max = 60 puma.GIVEN_NAME.min = 1 puma.GIVEN_NAME.max = 60 puma.requiredUserAttributes = UID,PASSWORD,GIVENNAME,SN puma.userProfileForm = UserProfileForm puma.userProfileConf = UserProfileConf puma.congrats = Congrats puma.registrationError = RegistrationError puma.commonname = {0} {1} The key puma.UserValidator, for example, is used to specify the class that validates the user information. The following JSPs are defined for used by the registration commands during the Registration process: UserProfileForm.jsp is used to enter or reenter user information such as user ID, passwords and interests. UserProfileConf.jsp is used to review user information before registering the user in the portal and saving the user data in LDAP and/or in the portal database. Congrats.jsp is displayed to confirm that the user is registered in the portal. RegistrationError.jsp is displayed if an error occurs. The files are located in the PortalServer\app\wps.ear\wps.war\screens\html directory for the HTML markup. 316 IBM WebSphere Portal V4 Developer’s Handbook Note: The screens defined for each command are theme-independent in the sense that the same JSPs can be used by different themes. See “Screen” on page 310 for more information. The Registration JSPs can be expanded by adding new input fields. When adding an attribute to the JSPs, a name such as wps.Name should be used, where Name represents the name you specify. If the attribute Name already exists in the user schema in the LDAP directory, as mapped by the attributeMap.xml (PortalServer\wms\xml), the value the user enters will be written to the LDAP directory. Otherwise, the attribute name and value will be stored in the WebSphere Portal or Member Service database, where the following limitations apply: the name cannot be longer than 64 characters and the value cannot be longer than 255 characters. Customization example: creating new attributes for the self care JSPs In this example, we will add four attributes to the registration process: phone number, gender, job title and job function. Phone number is available in LDAP (homePhone), Gender is available in the WebSphere Membership Service database (table:USERDEMO, field:GENDER). Job Function is available in the attribute table for WMS (table: MBRATTRVAL). Job Title will not be defined in these datasources and therefore will be saved in the WebSphere Portal USER_DESC_DD table. Note: This customization sample assumes an installation with LDAP for member services, and not a custom registry or database only installation. 1. Open UserProfileForm.jsp (PortalServer\app\wps.ear\wps.war\screens\html). 2. Copy the source code for the mail field, as seen in the following example. Example 6-33 Source code to add the new fields to UserProfileForm.jsp <tr> <td align="<%= bidiAlignRight %>"> <%= reqAttributes.contains("MAIL")?"*":" " %> </td> <td align="<%= bidiAlignLeft %>" class="wpsEditText"> <label for="wps.mail"> <wps:text key="person.email" bundle="nls.field" /> </label> Chapter 6. Portal customization 317 </td> </tr> <tr> <td>   </td> <td> <input dir="ltr" class="wpsEditField" type="text" name="wps.mail" value='<%=userWrapper.getAttributeNotNull("mail")%>' > </td> <td class="wpsFieldErrorText"> <wps:text key='<%= errorBean.getState("mail") %>' bundle="nls.registration" /> </td> </tr> For each field, paste the mail source code under the mail section and substitute the values in the following table for the value in bold. Table 6-4 Field name e-mail Home Phone Gender Job Title Job Function MAIL HOMEPHONE GENDER JOBTITLE JOBFUNCTIO N e-mail homePhone gender JobTitle JobFunction mail homePhone gender JobTitle JobFunction 3. Save UserProfileForm.jsp. 4. Open UserProfileConf.jsp. 5. Add the following source code under the mail equivalent source code. Example 6-34 Source code to add the new fields to UserProfileConf.jsp <tr> <td align="<%= bidiAlignRight %>" class="wpsEditText"> <wps:text key="person.homePhone" bundle="nls.field" /> </td> <td> <%= userWrapper.getAttributeNotNull("homePhone") %> </td> </tr> <tr> <td align="<%= bidiAlignRight %>" class="wpsEditText"> <wps:text key="person.gender" bundle="nls.field" /> </td> 318 IBM WebSphere Portal V4 Developer’s Handbook <td> <%= userWrapper.getAttributeNotNull("gender") %> </td> </tr> <tr> <td align="<%= bidiAlignRight %>" class="wpsEditText"> <wps:text key="person.JobTitle" bundle="nls.field" /> </td> <td> <%= userWrapper.getAttributeNotNull("JobTitle") %> </td> </tr> <tr> <td align="<%= bidiAlignRight %>" class="wpsEditText"> <wps:text key="person.JobFunction" bundle="nls.field" /> </td> <td> <%= userWrapper.getAttributeNotNull("JobFunction") %> </td> </tr> 6. Do the same for the following source code under the mail equivalent. Example 6-35 Source code to add the hidden fields to UserProfileConf.jsp <input type="hidden" name="wps.homePhone" value='<%= userWrapper.getAttributeNotNull("homePhone") %>'> <input type="hidden" name="wps.gender" value='<%= userWrapper.getAttributeNotNull("gender") %>'> <input type="hidden" name="wps.JobTitle" value='<%= userWrapper.getAttributeNotNull("JobTitle") %>'> <input type="hidden" name="wps.JobFunction" value='<%= userWrapper.getAttributeNotNull("JobFunction") %>'> 7. Save UserProfileConf.jsp. 8. Add the following code to field.properties and other language bundles as necessary (AppServer\lib\app\nls). Example 6-36 Keys and text to add to the field bundle person.homePhone = Phone: person.gender = Gender: person.JobTitle = Job Title: person.JobFunction = Job Function: 9. Add the following code to registration.properties and other language bundles as necessary (AppServer\lib\app\nls). Chapter 6. Portal customization 319 Example 6-37 Registration.properties changes homePhone = Phone: gender = Gender: JobTitle = Job Title: JobFunction = Job Function: homePhone.isEmpty=Please specify a valid e-mail address homePhone.notValid=Allowed characters are a-z, A-Z, 0-9, '.', '-', '_', '@' homePhone.toShort=Length has to be at least 3 characters homePhone.toLong=Length has to be up to 60 characters gender.isEmpty=Please specify a valid gender gender.notValid=Allowed characters are a-z, A-Z, 0-9, '.', '-', '_', '@' gender.toShort=Length has to be at least 1 characters gender.toLong=Length has to be up to 10 characters JobTitle.isEmpty=Please specify a valid job title JobTitle.notValid=Allowed characters are a-z, A-Z, 0-9, '.', '-', '_', '@' JobTitle.toShort=Length has to be at least 1 characters JobTitle.toLong=Length has to be up to 60 characters JobFunction.isEmpty=Please specify a valid job function JobFunction.notValid=Allowed characters are a-z, A-Z, 0-9, '.', '-', '_', '@' JobFunction.toShort=Length has to be at least 1 characters JobFunction.toLong=Length has to be up to 60 characters 10.Add the following code to puma.properties to set the validation rules for the new fields (AppServer\lib\app\config). Example 6-38 Puma.properies changes puma.HOMEPHONE.min = 3 puma.HOMEPHONE.max = 60 puma.GENDER.min = 1 puma.GENDER.max = 10 puma.JOBTITLE.min = 1 puma.JOBTITLE.max = 60 puma.JOBFUNCTION.min = 1 puma.JOBFUNCTION.max = 60 11.Modify um.properties to add the Member Service fields for user.baseattributes (AppServer\lib\app\config). For example: user.baseattributes=...,homePhone,gender,JobFunction 12.Modify attributeMap.xml to set the LDAP attribute for homePhone (PortalServer\wms\xml). 320 IBM WebSphere Portal V4 Developer’s Handbook Example 6-39 homePhone mapping definition for attributeMap.xml <map> <objectAttribute attrName="homePhone"/> <pluginAttribute name="homePhone" readOnly="false"/> </map> objectAttribute is the name of the attribute used in the Java Server Pages. pluginAttributte is the name of the attribute in LDAP. 13.Restart WebSphere Application Server. The form of the enrollment page should now display more fields, as illustrated in the following figure. Figure 6-19 Customized enrollment form When enrolling a new user, the new field name should be saved in their respective data source as indicated in the following table. Chapter 6. Portal customization 321 Table 6-5 Data source for each field Field name (JSPs) Results wps.homePhone LDAP wps.gender WMS table USERDEMO field GENDER wps.JobTitle WPS table USER_DESC_DD wps.JobFunction WMS table WMSATTRVAL Portal and InfoCenter help WebSphere Portal provides help information for users and administrators of the portal. WebSphere portal provide three sets of help files: Portal help, InfoCenter, and portlet help. The portal help contains the following sections: Accessing your portal This section provides information on logging in and out, editing a profile and navigating. Managing pages and places This section explains how to create, delete and manage places and pages, edit layout, set permissions, and choose skins. Administrating the portal This section provides information on using the administration interface for the portal, such as adding users and enabling tracing. It is intended for administrators of the portal. Design a portal Troubleshooting the portal. The following screen shot shows the portal help screen. 322 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-20 Portal help This information is accessed from the help link in the portal navigation bar. The Help link is defined in Banner.jsp. Example 6-40 Source code to display the help link (Banner.jsp) <%-- help button --%> <td valign="middle"> <a href="<%= wpsDocURL %>/InfoCenter/help_index.html" \ target="PortalHelpWindow" onClick="javascript: window.open('<%= wpsDocURL %>/InfoCenter/help_index.html', 'PortalHelpWindow','resizable=yes,scrollbars=yes, menubar=no,toolbar=yes,status=no,width=800,height=600, screenX=10,screenY=10,top=10,left=10').focus();"> <img src='<wps:urlFindInTheme file="nav_help.gif"/>' alt='<wps:text key="link.help" bundle="nls.engine"/>' border="0" align="absmiddle" width="20" height="25" title='<wps:text key="link.help" bundle="nls.engine"/>'> </a> </td> Chapter 6. Portal customization 323 The help page should be customized to reflect the content of an organization's portal and information about it. For example, to prevent access to administrative information, the link could be changed to access another set of help files, or simply removed. The location of the Help link on the page could be easily changed. The icon is displayed using nav_help.gif in the theme directory and the text is retrieved using the link.key key from the resource engine.property. The portal help is a collection of HTML and image files. The existing help files are located in the PortalServer/app/wps.ear/wps.war/doc/locale/InfoCenter directory. The entry help file help_index.html sets the frames for the banner, navigation, and help content. help_NavBar.html renders the table of contents for the help using a Java applet. The java applet NavBar.class reads the table of content from the file helpnavtext.txt given as a parameter as shown in the following source code fragment. Example 6-41 Source code to display the table of content from help_navBar.html <applet code="NavBar.class" name="NavBar" archive="NavBar.jar" width="500" height="2500" alt="Your browser is not configured to run Java applets or does not support this Java applet. Click the link to the HTML-format table of contents for the Portal Help."> <param name="bkColor" value="969696" /> <param name="fgColor" value="000000" /> <param name="rolloverColor" value="0000ff" /> <param name="selectionColor" value="0000ff" /> <param name="parentTopics" value="yes" /> <param name="indent" value="13" /> <param name="textFile" value="helpnavText.txt" /> <!-- No applet support --> <br> <br> Your browser is not configured to run Java applets or does not support this Java applet. Please refer to the <!-- Link to HTML toc --> <a href="help_htmltoc.html">HTML Table of Contents</a> in order to navigate the help set. </applet> If the browser isn’t configured to display applets, the HTML file help_htmltoc.html is used instead. When adding new help content, the table of contents in the files helpnavText.txt and help_htmltoc.html needs to be updated with links to the new files. 324 IBM WebSphere Portal V4 Developer’s Handbook The original help is available in multiple languages. If the Portal implementation requires support for multiple languages, any new files created will need to be translated and added to each locale supported. WebSphere Portal also comes with the InfoCenter help. This help is available in the PDF format or the HTML format in the same directory: PortalServer/app/wps.ear/wps.war/doc/locale/InfoCenter. The InfoCenter can be started by opening the index.html file in this directory. The following screen shows the InfoCenter help. Figure 6-21 InfoCenter help The InfoCenter help uses the same mechanism for its table of content as the portal help with the files navText.txt and htmltoc.html. Although neither help tool is implemented with JavaHelp, both use the standard JavaHelp search, encapsulated in an applet for use from a Web browser. When performing a search with the portal help, by default, both InfoCenter and the portal help are searched. The search scope and index can be updated by using JavaHelp (see http://java.sun.com/products/javahelp). Chapter 6. Portal customization 325 Tip: When editing the original help files, it is wise to create a backup copy of the original help before making any changes. Customization example: adding a new help page for the bookmark functionality 1. Copy the file accessingPortal.html under the name usingPorta.html in PortalServer\app\wps.ear\wps.war\doc\en\InfoCenter\help. 2. Delete the content inside the <body> tags and insert the following lines. Example 6-42 Body for the new help file (accessingWithDevices.html) <h2> Accessing your portal with devices </h2> <p>The portal supports three markup languages: <ol> <li>HTML, for desktop computers and some personal digital assistants, <li>WML, for WAP devices, which are typically mobile phones, <li>cHTML, for mobile devices in the NTT DoCoMo iMode network. </ol> </p> <p>You can access the portal by using devices supporting these markups by just using the portal URL with your device </p> <p> </p> 3. Save the file under the name accessingWithDevices.html. 4. Open helpnavText.txt. 5. The following example shows how to add a new help page for the bookmark functionality. Example 6-43 Update to the table of content in helpnavtext.txt <2>Browsers<F2><help/accessing_portal.html#browsers> <1>Accessing with devices<F1><help/accessingWithDevices.html> <1>Working with pages<F1><help/customizing.html> 6. Save helpNavText.txt. 7. Open help_htmltoc.html. 8. Inserted the bolded text. Example 6-44 Update to the table of content in helpnavtext.txt <tr> <td WIDTH=11> </td> <td colspan=4> 326 IBM WebSphere Portal V4 Developer’s Handbook <a class="nav" href="help/accessing_portal.html#browsers" target="Main"> Browsers </a> </td> </tr> <tr> <td> <a class="nav" href="help/accessingWithDevices.html" target="Main"> <strong>Accessing with devices</strong> </a> </td> </tr> 9. Save help_htmltoc.html. 10.Stop and restart the IBM HTTP Server. The page has been added to the portal help and is now accessible: Figure 6-22 Accessing with devices new help page Chapter 6. Portal customization 327 The index for the Search functionality on the page includes the InfoCenter and the portal page help. In the following example, we build a new index to include the new page and containing only the help for the portal. Customization example: Creating a new index with the new page and restricted to the portal help pages 1. Install JavaHelp from Sun (http://java.sun.com/products/javahelp). 2. Add the JavaHelp\jh1.1.3\javahelp\bin directory to your path. 3. Copy search.list under the name searchPortal.list. 4. Open and edit searchPortal.list to keep only the portal files. 5. Add the new help page created in the previous customization example. Example 6-45 Content of seachPortal list File File File File File File File File File File File File File File File File File File File File File File File File File File 328 howtosearch.html using.html help/accessing_portal.html help/accessingWithDevices.html help/acl.html help/administering.html help/content_formats.html help/customizing.html help/designing.html help/globalsettings.html help/layout.html help/logfiles.html help/manage_clients.html help/manage_groups.html help/manage_markups.html help/manage_portletapps.html help/manage_portlets.html help/manage_users.html help/manage_webservices.html help/pagegroups.html help/permissions.html help/portletinstall.html help/search.html help/signing_up.html help/skins.html help/themesskins.html IBM WebSphere Portal V4 Developer’s Handbook File help/troubleshooting.html File help/vault.html File help/webservices.html File help/web_clipping.html File help/welcome_help.html StopWordsFile stopwords_en.list 6. Save the file searchPortal.list. 7. Run the DOS command: jhindexer -c searchPortal.list -db wps_portal_search The new folder wps_portal_search should be created in the PortalServer\app\wps.ear\wps.war\doc\en\InfoCenter directory. 8. Open the file help_search.html. 9. Change the searchdbdir parameter for Search applet to : <param name="searchdbdir" value="wps_portal_search" /> 10.Stop and restart the IBM HTTP Server. The following results are now displayed when searching for WML. Figure 6-23 Customized help search Chapter 6. Portal customization 329 Note: If the portal supports many language, the same modifications should be done for each language. Portlet help Most of the Portlets also provides help information. For example, the following figure displays the help for the World Clock portlet. Figure 6-24 World Clock help pop-up The Help page for a portlet will typically be built by a JSP file in the portlet directory. In the World Clock portlet example, the JSP file is located in was_toot\installedApps\worldclock_WPS_PA_183.ear\worldclock.war\WEB-INF\ worldclock\html and could be edited. The skin applied to the portlet will define whether the help link is displayed in the title bar. The skin templates such as Control.jsp could be modified to change the layout, appearance and functionality of the help link for the portlets. The link is currently specified by the following source code. Example 6-46 Source code to display the portlet help link <wps:portletHelp newWindow="true"> <a href="javascript: window.open('<wps:urlParent/>', 'portletHelpWindow','resizable=yes,scrollbars=yes, menubar=no,toolbar=no,status=no,width=450,height=260, screenX=200,screenY=200,top=200,left=200').focus();"> <img border="0" align="absmiddle" width="12" height="16" src='<wps:urlFindInTheme file="title_help.gif"/>' alt='<wps:text key="help" bundle="nls.titlebar"/>' title='<wps:text key="help" bundle="nls.titlebar"/>'> </a> </wps:portletHelp> 330 IBM WebSphere Portal V4 Developer’s Handbook Customization example: opening the portlet help in the same window 1. Open Control.jsp from PortalServer\app\wps.ear\wps.war\skins\html . 2. Update the source code in Example 6-46 to the following version. Example 6-47 Source code to display the portlet help in the same window <wps:portletHelp> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="12" height="16" src='<wps:urlFindInTheme file="title_help.gif"/>' alt='<wps:text key="help" bundle="nls.titlebar"/>' title='<wps:text key="help" bundle="nls.titlebar"/>'> </a> </wps:portletHelp> Clicking the help control should now display the help in the same window as illustrated in the following figure. Figure 6-25 World Clock help in the same window Language To support a new language, the file language.properties needs be edited. The file is located in the directory AppServer\lib\app\config and its content is displayed in the following example. Chapter 6. Portal customization 331 Example 6-48 Content of language.properties # @copyright properties #Sat Jun 22 01:51:12 CEST 2002 language.14=zh_TW language.13=zh language.12=tr language.9=ko language.11=pt_BR language.8=ja language.10=pl language.7=iw max.count=14 language.6=it language.5=fr language.4=es language.3=en language.2=de language.1=cs A new entry for the language should be created by using the language letter acronym. The max.count value also needs to be changed to reflect the number of languages. Then, all the resource bundles need to be translated in the new languages and saved using the two letters for the language, as well as the resources bundles and the source code, where applicable, for the portlets. Customization example: adding French Canadian to the portal 1. Open language.properties in AppServer\lib\app\confi. 2. Add a new language such as language.15=fr_CA. 3. Modify the language count max.count=15. 4. Save the file. 5. Open registration.properties in AppServer\lib\app\nls. 6. Add the key fr_CA=French Canadian next to the other language keys. This should be done for all the registration resources. 7. Save the file. 8. Add a new entry in the LANGUAGE table in the WebSphere Portal database using the following SQK statement: INSERT INTO language(language_id,localename,language,country,encoding,mimecharse t) VALUES ( -25,'fr_CA','fr','FR','ISO8859-1','iso-8859-1') 332 IBM WebSphere Portal V4 Developer’s Handbook Now, a user could select French Canadian for his preferred language. The following source code can be implemented in Default.jsp to test the new setting. Example 6-49 Source code to test adding a language <wps:if locale="fr_CA"> Your locale is set to French Canadian </wps:if> Clients During the operation of the portal site, you may discover that some users have upgraded their browser, and that the new browser has certain HTML requirements. Or, you could get a request to support a new mobile phone that has special WML requirements. In either case, you can add support for the client to the portal site. If the new client requires markup that is not supported by the portal site, then you first define support for the new markup. See “Markups” on page 336 for more information. To add a new client, you first need to find its user agent signature. This is the user agent that is used for the HTTP request. There are several ways to find the user agent for a client. One way is to log the HTTP request with the user agent property with the WebServer. Tip: To log the HTTP request with IBM HTTP Server, open the configuration file http.conf in the IBM HTTP Server conf directory, comment the line CustomLog logs/access.log common, uncomment the line #CustomLog Logs/access.log common, and restart HTTP Server. For Netscape 7.0, selecting About Netscape provides the Netscape user agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.0.1) Gecko/20020823 Netscape/7.0. WebSphere Portal uses the list of clients installed by default with SetupPortal.xml to match the user agent with a pattern from this list. See 6.2.2, “Portal resources” on page 271 for more information. .*Mozilla/5..* is the first pattern matching Netscape 7.0 in the list of clients installed. Therefore, Netscape 7.0 is considered to be equivalent to Netscape 6.0. Netscape 6.0 is defined as follows. Chapter 6. Portal customization 333 Example 6-50 Netscape 6.0 definition in SetupPortal.xml <client action="update" handle="Navigator.3" manufacturer="Netscape" markup="html" markup-version="ns6" name="Navigator" ordinal="300" version="6.x"> <useragent-pattern>.*Mozilla/5..*</useragent-pattern> <client-capability update="set">HTML_4_0</client-capability> <client-capability update="set">HTML_IFRAME</client-capability> <client-capability update="set">HTML_FRAME</client-capability> <client-capability update="set">HTML_NESTED_TABLE</client-capability> <client-capability update="set">HTML_2_0</client-capability> <client-capability update="set">HTML_JAVASCRIPT</client-capability> <client-capability update="set">HTML_3_2</client-capability> <client-capability update="set">HTML_3_0</client-capability> <client-capability update="set">HTML_JAVA</client-capability> <client-capability update="set">HTML_CSS</client-capability> <client-capability update="set">HTML_TABLE</client-capability> <client-capability update="set">FRAGMENT_IDENTIFIER</client-capability> </client> We might want to create a new entry for Netscape 7.0 so we can provide a different resource to Netscape 7.0 compared to previous Netscape browsers. This entry will have a new markup version: ns7. Once defined, we can use this markup version to create a set of resource specific to Netscape 7.0. Customization example: adding a new client (Netscape 7.0) To add a new client, we can use the Administration portal. 1. Log in to the portal with administrative rights. 2. Select Portal Administration -> Portal Settings -> Manage Clients. 3. Select Add new client. 4. Enter the following information for each field: Table 6-6 Netscape 7.0 configuration information 334 Field name Value User agent .*Netscape/7.* Markup html Markup version ns7 Manufacturer Netscape Model Navigator Version 7.x IBM WebSphere Portal V4 Developer’s Handbook Field name Value Capabilities HTML_4_0 HTML_IFRAME HTML_FRAME HTML_NESTED_TABLE HTML_2_0 HTML_JAVASCRIPT HTML_3_2 HTML_3_0 HTML_JAVA HTML_CSS HTML_TABLE FRAGMENT_IDENTIFIER Position after Opera/4.* Now we can create a resource specific to Netscape 7.0 to check the configuration. Customization example: creating a resource for a specific client We will create an banner image specific to Netscape 7.0. Netscape 7.0 was created with the markup version ns7. This name has to be used for the directory for the resources specific to Netscape 7.0. 1. Create the folder ns7 under PortalServer\app\wps.ear\wps.war\themes\html. 2. Copy the file banner.jpg from the folder PortalServer\app\wps.ear\wps.war\themes\html to the ns7 folder. 3. Open the image copied in the ns7 folder with your favorite image editor. 4. Add some text to the banner, for example Netscape 7. 5. Save the file. When connecting with Netscape 7.0, the user can see the new banner. A new client may have a new functionality not available to other clients. We might want to take advantage of this new functionality in our source code. In the following customization example, we will add a new functionality to Netscape 7.0 and modify the source code to display a message when this functionality is available from the client. Customization example: adding and using a client functionality To define a new functionality, we can use the Administration portal. 1. Log in to the portal. 2. Select Administration -> Portal Settings -> Manage Clients. Chapter 6. Portal customization 335 3. Select Netscape 7. 4. Click Edit-> Select Client. 5. Add the NEW_BROWSER_CAPABILITY. 6. Save. 7. Log out of the portal. 8. Open Default.jsp in the theme/html directory. 9. Add the following source code to one of the JSP resource, such as Default.jsp. Example 6-51 Source code to use the new functionality <wps:if capableOf="NEW_BROWSER_CAPABILITY"> Your client is capable for the new functionality </wps:if> 10.Restart WebSphere Portal. Connect to the portal using Netscape 7.0; you should see the following message: Your client is capable for the new functionality’ Markups WebSphere Portal supports HTML, WML, and cHTML markup languages. If you want to define another markup language to support, you must ensure that you have portlets that provide markup for the language. In addition, you need to create a subdirectory for the markup in each of the following locations: PortalServer/wps.ear/wps.war/app/screens PortalServer/wps.ear/wps.war/app/themes PortalServer/wps.ear/wps.war/app/skins Customization example: adding a new markup to the portal An application UIBuilder would like to connect to the portal to retrieve information about the portal places, pages, and portlets. A new markup language is designed by the XML team for the communication between WebSphere Portal and UIBuilder. The Portal Definition Markup Languageis also known as PDML. 1. Create a new folder (pdml) in the theme directory. 2. In this folder, create the resource Default.jsp with the following content: Example 6-52 Default.jsp for the PDML markup <?xml version="1.0"?> <%@ page session="false" buffer="none" %> 336 IBM WebSphere Portal V4 Developer’s Handbook <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <pdml> <navigation> <wps:pageGroupLoop> <place <wps:if pageGroupSelected="yes">selected="yes"</wps:if>> <name><wps:pageGroup attribute="name"/></name> <url><wps:urlParent/></url> <wps:pageLoop> <page <wps:if pageGroupSelected="yes">selected="yes"</wps:if>> <name><wps:page attribute="name"/></name> <url><wps:urlParent/></url> </page> </wps:pageLoop> </place> </wps:pageGroupLoop> </navigation> <screen> <wps:screenRender/> </screen> </pdml> 3. Create a new folder (pdml) in the screen directory. 4. In this folder, create the resource Home.jsp with the following content: Example 6-53 Home.jsp for the PDML markup <%@ page session="false" buffer="none" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <home> <wps:pageRender/> <wps:if pageAvailable="no" pageGroupAvailable="no"> <warning><wps:text key="error.nopagegroup" bundle="nls.engine"/></warning> </wps:if> <wps:if pageAvailable="no" pageGroupAvailable="yes"> <warning><wps:text key="error.nopagegroup" bundle="nls.engine"/></warning> Chapter 6. Portal customization 337 </wps:if> </home> 5. Create a new folder (pdml) in the skin directory. 6. In this folder, create the resource RowContainer.jsp with the following content. Example 6-54 RowContainer.jsp for the PDML markup <%@ page session="false" buffer="none" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <component type="row"> <wps:componentLoop> <wps:componentRender/> </wps:componentLoop> </component> 7. tIn this folder, create the resource ColumContainer.jsp with the following content. Example 6-55 ColumnContainer.jsp for the PDML markup <%@ page session="false" buffer="none" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <component type="column"> <wps:componentLoop> <wps:componentRender/> </wps:componentLoop> </component> 8. In this folder, create the resource Control.jsp with the following content. 338 IBM WebSphere Portal V4 Developer’s Handbook Example 6-56 Control.jsp for the PDML markup <%@ page session="false" buffer="none" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <component type="control"> <portlet> <title><wps:portletTitle/></title> <wps:portletRender/> </portlet> </component> 9. Use the administration place to add the new markup to the portal site. Make sure that the markup name that you add is the same as the subdirectory name that you used for the markup. You can add markup by clicking Portal settings -> Manage Settings and using the following settings. Table 6-7 Settings for the pdml markup Field name Value Markup name pdml MIME Type text/xml Default character set UTF-8 10.Activate the new markup. 11.Restart WebSphere Portal. To test the new markup, we need a client to connect to WebSphere Portal supporting the pdml markup and at least one portlet on a page supporting the markup. 1. To map one of the client to the new markup, for example Netscape 7.0, use Manage Clients; select the desired client and set pdml as the markup for the client. 2. Create a portlet that supports the new pdlm markup. The portlet renders both HTML and PDML markups. The result of the PDML markup is <content>This is Test PDML Portlet sample for pdml.</content>. 3. Install the portlet using the Administration interface. 4. Set the permissions settings for the portlet. Anonymous users should be able to view the portlet application and the portlet. 5. Add a new Place and page by clicking Work with Pages -> Manage Places and Pages. Make the pdml markup available for both. Chapter 6. Portal customization 339 6. Add the portlet to the page. 7. Connect using your PDML client. Example 6-57 illustrates what you would get when invoking the portal from a device supporting PDML. Example 6-57 PDML sample results <?xml version="1.0"?> <pdml> <navigation> <place selected="yes"> <name>Home</name> <url>/wps/portal/.cmd/ChangePageGroup /.pagr/103/_pagr/103/_pa.103/110</url> <page selected="yes"> <name>Welcome</name> <url>/wps/portal/.cmd/ChangePage/.pa/110 /.pagr/103/_pagr/103/_pa.103/110</url> </page> </place> </navigation> <screen> <home> <component type="row"> <component type="column"> <component type="control"> <portlet> <title>Hello pdml Portlet portlet</title> <content>This is Hello pdml sample for pdml.</content> </portlet> </component> </component> </component> </home> </screen> </pdml> 340 IBM WebSphere Portal V4 Developer’s Handbook 6.3.3 WebSphere Portal Extend WebSphere Portal comes with a Bookmark functionality that allows place managers to define a list of bookmarks available for a place. It also comes with a Find functionality that provides a link to a search functionality defined at the WebSphere Portal level. Bookmarks WebSphere Portal Extend provides a Bookmark functionality, allowing users with manage access for a place to define a list of bookmarks for it. A page belonging to such a place will display a bookmark link. A user can click the link to display a pop-up window showing a list of predefined bookmarks. Bookmarks can be internal to WebSphere Portal, such a link to another page, or external, such as a link to a Web site on the Internet. Figure 6-26 Bookmark link and pop-up Note: Some themes do not include the bookmark link, so the link and the pop-up window will not be available in these themes. The bookmark list is defined by using Manage Places and Pages -> Define Bookmark List for a selected place by a place manager. The Bookmark link is located on the right of the menu selection for places in the default theme. The following source code shows the definition of the link in Banner.jsp. Example 6-58 Source code to display the bookmark link (Banner.jsp) <%-- bookmark --%> <a href="#" [...] onClick="w=window.open('<%=wpsBaseURL%>/extend/ bookmarks.jsp?pgiid=<extend:pageGroupId/>&oid=<extend:userObjectId/> Chapter 6. Portal customization 341 &path=<%=java.net.URLEncoder.encode(request.getServletPath())%>', 'Bookmarks','toolbar=no,location=no,directories=no,status=no,menubar=no, scrollbars=yes,resizable=yes,width=400,height=280,top=100,left=100'); w.opener=self;w.focus();"> <img align="absmiddle" src='<wps:urlFindInTheme file="bookmarks.gif"/>' border="0"> <span style="text-decoration:underline"> <wps:text key="bookmarks" bundle="nls.engine"/> </span> </a> The icon is displayed using bookmarks.gif from the theme directory. The text displayed is retrieved from the resource file engine.property using the bookmarks key. See “Language and resource bundles” on page 311 for more information. The location of the Bookmark link on the page could easily be changed by moving the source code to another location in Banner.jsp or Default.jsp. The text and icon could also easily be changed. Customization example: removing the text and moving the icon to the right of the page selection tab 1. Edit Banner.jsp in the PortalServer\app\wps.ear\wps.war\themes\html directory. 2. Cut the following source code from Banner.jsp. Example 6-59 Source code to cut from Banner.jsp <td class="wpsToolbar" align="<%=bidiAlignLeft%>" nowrap> <%-- bookmark --%> <a href="#" style="text-decoration:none" onClick="w=window.open('<%=wpsBaseURL%>/extend/bookmarks.jsp? pgiid=<extend:pageGroupId/>&oid=<extend:userObjectId/> &path=<%=java.net.URLEncoder.encode(request.getServletPath())%>', 'Bookmarks','toolbar=no,location=no,directories=no,status=no, menubar=no,scrollbars=yes,resizable=yes,width=400,height=280, top=100,left=100');w.opener=self;w.focus();"> <img align="absmiddle" src='<wps:urlFindInTheme file="bookmarks.gif"/>' border="0"> <span style="text-decoration:underline"> <wps:text key="bookmarks" bundle="nls.engine"/> </span> </a> </td> <td class="wpsToolbar"> </TD> 342 IBM WebSphere Portal V4 Developer’s Handbook 3. Paste the source code in the cell displaying the tab stripes. 4. Modify the source code to remove the Bookmark text as in the following example. Example 6-60 Source code to display the modified bookmark link <td height="18" background='<wps:urlFindInTheme file="tab_stripes.jpg"/>'> <%-- bookmark --%> <a href="#" style="text-decoration:none" onClick="w=window.open('<%=wpsBaseURL%>/extend/bookmarks.jsp? pgiid=<extend:pageGroupId/>&oid=<extend:userObjectId/> &path=<%=java.net.URLEncoder.encode(request.getServletPath())%>', 'Bookmarks','toolbar=no,location=no,directories=no,status=no, menubar=no,scrollbars=yes,resizable=yes,width=400,height=280, top=100,left=100');w.opener=self;w.focus();" <img align="absmiddle" src='<wps:urlFindInTheme file="bookmarks.gif"/>' border="0"> </a> </td> 5. Open and save Default.jsp to force a reload of the include file Banner.jsp. The bookmark icon should now be displayed to the right of the Welcome page tab as illustrated in the following figure. Figure 6-27 Customized bookmark link The layout of the pop-up window can also be customized by modifying the bookmarks.jsp in PortalServer\app\wps.ear\wps.war\extend. The images used for the pop-up window are part of the WebSphere Portal image resource located in PortalServer/images. Chapter 6. Portal customization 343 Customization example: displaying the internal links first and then the external links This is an alternative to mixing the links and showing a different type of arrow for each of them. 1. Open the Bookmarks.jsp file from PortalServer\app\wps.ear\wps.war\extend. 2. Change the source code to display first the local links and then the external links, as follows. Example 6-61 Source code for the new pop-up <table cellspacing="4" cellpadding="0" border="0" width="100%"> <% boolean hasItems = false; int cnt = 0; Iterator i = folder.getItems().iterator(); boolean hasDisplayedTitle = false; while (i.hasNext()) { hasItems = true; cnt++; Bookmark b = (Bookmark) i.next(); if (b.isLocal()) { if (!hasDisplayedTitle) { hasDisplayedTitle = true; cnt++; %> <tr> <td nowrap style="font-family: sans-serif; background-color: #FFFFFF; font-size: 9pt; margin: 0;"> Local Links </td> </tr> <% } %> <tr> <td nowrap style="font-family: sans-serif; background-color: #FFFFFF; font-size: 9pt; margin: 0;"> <a href="#" style="text-decoration:none" onClick="javascript:top.opener.window.location.href= '<%=bean.getBaseUrl(request)%><%=path%>/_pagr/<%=b.getPageGroup()%> /_pa.<%=b.getPageGroup()%>/<%=b.getPage()%>';top.opener.window.focus();"> <img src="../images/admin/task_right.gif" align="absmiddle" border="0"> <span style="text-decoration:underline"> <%=b.getName()%> 344 IBM WebSphere Portal V4 Developer’s Handbook </span> </a> </td> </tr> <% } } i = folder.getItems().iterator(); hasDisplayedTitle = false; while (i.hasNext()) { hasItems = true; cnt++; Bookmark b = (Bookmark) i.next(); if (!b.isLocal()) { if (!hasDisplayedTitle) { hasDisplayedTitle = true; cnt++; %> <tr> <td nowrap style="font-family: sans-serif; background-color: #FFFFFF; font-size: 9pt; margin: 0;"> External Links </td> </tr> <% } %> <tr> <td nowrap style="font-family: sans-serif; background-color: #FFFFFF; font-size: 9pt; margin: 0;"> <a href="<%=b.getUrl()%>" target="_blank" style="text-decoration:none"> <img src="../images/admin/task_right.gif" align="absmiddle" border="0"> <span style="text-decoration:underline"> <%=b.getName()%> </span> </a> </td> </tr> <% } } if (!hasItems) { ... Chapter 6. Portal customization 345 The bookmark pop-up should now display the local bookmarks first and then the external bookmarks, as in the following figure. Figure 6-28 Customized bookmark pop-up Find WebSphere Portal Extend provides a Find functionality allowing a Portal administrator to define a URL that will be opened when users click the Find link. Portal Administrators can define this URL by using the administration interface (Portal Administration -> Portal Settings) or by editing the config.properties file in AppServer\lib\app\config\services. If no URL is defined, the link will not be displayed. Note: Some themes do not include the Find link, so the link will not be available in these themes. The Find icon and text are located on the right of the Bookmark link for the pages using the default theme (see Figure 6-2). The following source code extract shows how the link is constructed in Banner.jsp. Example 6-62 Source code for Find (Banner.jsp) <%-- find --%> <extend:find> <a href="<wps:urlParent/>" style="text-decoration:none" title="<wps:text key='link.find' bundle='nls.engine'/>" target="_blank"> <img align="absmiddle" src="<wps:urlFindInTheme file='task_show_info.gif'/>" border="0"> 346 IBM WebSphere Portal V4 Developer’s Handbook <span style="text-decoration:underline"> <wps:text key="link.find" bundle="nls.engine"/> </span> </a> </extend:find> The location and appearance of the Find link on the page can easily be changed. The icon is displayed using task_show_info.gif in the theme directory and the text is retrieved using the link.find key from the resource engine.property. See “Bookmarks” on page 341 for a customization example. 6.4 Building a virtual portal: the YourCo portal Some companies will already have an existing Web application and will want to portalize it to simplify the application development and maintenance. We show how to build a custom portal by portalizing the YourCo application provided with WebSphere Application Server. This section is a step-by-step guide to building a custom portal. 6.4.1 YourCo sample overview The YourCo sample is provided by WebSphere Application Server. The following figure shows some of the windows of the application. Chapter 6. Portal customization 347 Figure 6-29 WebSphere Application Server YourCo The YourCo application provides a public view with some applications (White pages, YourCo news) and an Employee view (Employee Center) restricted to employees. Employees can personalize their intranet view, search databases for company jobs and personnel information, schedule meetings in conference rooms, and manage their vacation time. WebSphere Portal Toolkit Portlets Application provides five sample portlets for the YourCo application. WebSphere Studio Application Developer makes these portlets available as example projects. 348 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-30 Sample YourCo portlets provided by WebSphere Portal Toolkit Note: The portlets provided with WebSphere Portal Toolkit use a different database than the YourCo application provided by WebSphere Application Server. 6.4.2 Building the YourCo portal Building the YourCo portal involves building the resources for the portal: theme, screen, skin, bundles. YourCo theme Defining the YourCo theme involves creating a subdirectory in the theme directory where all the theme resources will be created. For now, the YourCo portal will deliver content to HTML aware clients only. Therefore, the YourCo theme will be created in the html markup directory. 1. Create a new theme directory named YourCo in the HTML themes directory: PortalServer/app/wps.ear/wps.war/themes/html/YourCo The new theme directory will include the overall portal Cascading StyleSheet, the Java Server Pages files, and the images used by the theme. The WebSphere Application Server YourCo is using a style sheet to define the font for the Body and TD tag. As the predefined portal defines classes that Chapter 6. Portal customization 349 might be used by commercially available portlets, the default Cascading Style Sheet will be used as the starting point to create the YourCo stylesheet. 2. Copy the stylesheet Styles.css from the default theme directory (PortalServer\app\wps.ear\wps.war\themes\html) to the YourCo theme directory (PortalServer\app\wps.ear\wps.war\themes\html\YourCo). The YourCo sample application uses the stylesheet YourCo.css from the AppServer\installedApps\Samples.ear\theme.war directory. The following example provides the stylesheet definition. Example 6-63 YourCo sample Stylesheet YourCo.css BODY{font-family : Verdana,sans-serif;} TD{font-family : Verdana,sans-serif;} The YourCo.css stylesheet defines the font family for the <body> and <td> tags. 3. Open Styles.css. 4. Change the font size to from 12 pt to 10 pt by replacing font-size: 12pt with font-size: 10pt. 5. Change the font family by replacing font-family: sans-serif with font-family: verdana, sans-serif. 6. Save Styles.css. The YourCo application is using a banner and a background image. These images are part of the look and feel of the YourCo portal, and therefore should be copied to the YourCo theme directory. Others images that will be used later need to be copied also. 7. Copy the following images from the YourCo WebSphere Application Server directory (App_server/InstalledApps/Samples.ear/theme.war) to the YourCo theme directory. – bg.gif – topBanner.gif – button.gif – buttonDWN.gif – horzLine.gif – twistcb.gif The entry Java Server page for the YourCo portal is Default.jsp in the theme directory. This page defines the overall layout of the portal. 8. Create a new file Default.jsp in the YourCo theme directory with the content from the following example. 350 IBM WebSphere Portal V4 Developer’s Handbook Example 6-64 Starting Default.jsp for the YourCo theme <%@ page session="false" buffer="none" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <wps:constants/> <html> <!--headers--> <head> <title> <wps:text key="title" bundle="nls.yourco"/> </title> <link href='<wps:urlFindInTheme file="Styles.css"/>' rel="styleSheet" type="text/css"> </head> <!--body--> <body marginwidth="0" marginheight="0" background="<wps:urlFindInTheme file="bg.gif"/>"> <center> <table width="620 border="0" cellspacing="8" cellpadding="0" height=”100%”> <!--banner--> <tr> <td width="100%" valign="top"> <img src="<wps:urlFindInTheme file="topBanner.gif"/>" border="0" alt="<wps:text key="title" bundle="nls.yourco"/> align="bottom" width="607" height="46"> </td> </tr> <!--screen--> <tr> <td width="100%" height="100%" valign="top"> <wps:screenRender/> </td> </tr> </table> </center> </body> </html> Chapter 6. Portal customization 351 Default.jsp defines the top level <table> used for the page layout. This table contains two rows: one for the banner and one for the screen components displayed by the <wps:screenRender> JSP tag. The layout obtained is illustrated in the following figure. Banner Home Screen Figure 6-31 Layout defined by Default.jsp Note: It is recommended that you reduce white space and use the nontransferable JSP comment format (<%-- --%>) as opposed to the HTML comment format (<!-- -->) in the JSP. In this sample portal, we use space to make the source code easier to understand and HTML comment to provide information on the client in the HTML. 9. Save Default.jsp without closing your editor; we will modify the file in the following steps. Default.jsp uses the engine tag library. See 6.5, “JSP tags reference” on page 386 for more information about the library. Default.jsp uses the <wps:urlFindInTheme> tag to get the URL for the stylesheet and images. It is good practice to use this tag to get the URL of the resources used by the Java Server Pages since it allows you to replace the resource for a specific browser or locale. Default.jsp uses the <wps:text> tag to support multilanguages. Even though the YourCo portal isn’t required to provide content in several languages, it is a good practice not to include the text in the Java Server Page source code and to use a bundle instead. Default.jsp uses <wps:text key="title" bundle="nls.yourco"/> to retrieve the text for the title. Therefore, we need to create a bundle for YourCo. 10.Create the file yourco.properties in the directory AppServer\lib\app\nls by copying the content in the following example. 352 IBM WebSphere Portal V4 Developer’s Handbook Example 6-65 YourCo resource bundle # # RESOURCES FOR THE YOURCO PORTAL # title=YourCo Portal 11.Restart WebSphere Application Server for the changes to be loaded. Now, we need to build the navigation elements for the portal. The portal designer decided to display the page navigation under the banner as in the original YourCo application. 12.Add the following source code to Default.jsp below the closing </tr> for the banner. Example 6-66 Source code for page navigation <!--page navigation--> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <wps:pageLoop> <wps:if pageSelected="yes"> <td valign="middle" align="left" width="25"> <img src="<wps:urlFindInTheme file="buttonDWN.gif"/>" width="20" height="20" border="0"> </td> <td valign="middle" align="left"> <b> <wps:page attribute="title"/> </b> </td> </wps:if> <wps:if pageSelected="no"> <td valign="middle" align="left" width="25"> <img src="<wps:urlFindInTheme file="button.gif"/>" width="20" height="20" border="0"> </td> <td valign="middle" align="left"> <a href="<wps:urlParent/>"> <wps:page attribute="title"/> </a> Chapter 6. Portal customization 353 </td> </wps:if> </wps:pageLoop> </tr> </table> </td> </tr> The portal designer decided to display the place navigation at the bottom of the page like some of the links in the original YourCo application. 13.Add the following source code to Default.jsp above the closing </table>. <!--separation--> <tr> <td> <img src="<wps:urlFindInTheme file="horzLine.gif"/>" border="0"> </td> </tr> <!--place navigation--> <wps:if pageGroupAvailable="yes"> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <wps:pageGroupLoop> <td> <img src="<wps:urlFindInTheme file="twistcb.gif"/>" width="12" border="0"> </td> <td valign="middle" align="left"> <wps:if pageGroupSelected="yes"> <b> <wps:pageGroup attribute="title"/> </b> </wps:if> <wps:if pageGroupSelected="no"> <a href="<wps:urlParent/>"> <wps:pageGroup attribute="title"/> </a> </wps:if> </td> </wps:pageGroupLoop> 354 IBM WebSphere Portal V4 Developer’s Handbook </tr> </table> </td> </tr> </wps:if> 14.Save Default.jsp. Portal configuration We would like to view the current portal with the new theme. We need to create the YourCo place and apply the YourCo theme to it. 1. Log in to the portal with administrative privileges. 2. Add the YourCo theme to the portal by clicking Portal Administration -> PortalSettings -> Themes and Skins as illustrated in the following figure. Figure 6-32 Adding the YourCo theme Note: Make sure the Theme directory name matches exactly the directory created for YourCo in the theme directory. Chapter 6. Portal customization 355 The theme is now available for use by places. We need to create the YourCo place with the YourCo pages. The portal designer decided to initially build four pages for the YourCo portal: Home, White Pages, Let’s Meet, and Help Wanted. Home and White Pages will be available to all users, whereas Let’s Meet and Help Wanted will be only available only to YourCo employees. 3. Create a new place named YourCo by clicking Work with Pages-> Manage Places and Pages. Select the YourCo theme for this new place and the html markup only as illustrated in the following figure. Figure 6-33 Adding the YourCo theme 4. Move the YourCo place before the default Home place by clicking Order all places. 5. Add the four YourCo pages to the YourCo place in the following order: a. Home b. White Pages c. Let’s Meet d. Help Wanted 356 IBM WebSphere Portal V4 Developer’s Handbook The YourCo pages use only one column and initially will be available only for the HTML markup. The following figure illustrates the settings to add the Home page. Figure 6-34 Adding the YourCo Home page The YourCo portlets are provided by the WebSphere Portal toolkit, and they should be installed. The YourCo portlets are now added to the pages. YourCo Expiring HTML and YourCo Survey will be on the Home page. YourCo expiring HTML will be available to all users, whereas YourCo Survey will only be available to authenticated users. The White Pages page will contain both YourCo White Pages portlets. The Let’s Meet page will contain the YourCo Meeting Reservation portlet. The Help Wanted page will contain the YourCo Job Search portlet. 6. Add the portlets to their respective pages as indicated in the following table by clicking Work with Pages -> Edit Layout and Content. Chapter 6. Portal customization 357 Table 6-8 Pages and portlets layout for YourCo Page Portlets Home YourCo Expiring HTML and YourCo Survey White Pages YourCo White Page and YourCo White Pages Results Let’s Meet YourCo Meeting Reservation Help Wanted YourCo Job Search The following figure shows the portal screen after adding the YourCo expiring HTML and YourCo Survey portlets to the Home page. Figure 6-35 Adding the Home page portlets Tip: Make sure to activate the page after adding the portlets. Finally, we need to set the permissions for the place, the pages and the portlet applications. 7. Set the following security settings by clicking Portal Administration -> Security -> Access Control List. 358 IBM WebSphere Portal V4 Developer’s Handbook Anonymous users Table 6-9 Permission setting for Anonymous users Object Type Permission YourCo Place View Home Page View White Pages Page View YourCo Expiring HTML Portlet View YourCo White Page Portlet View YourCo White Pages Results Portlet View Authenticated users Table 6-10 Permission settings for authenticated users Object Type Permission YourCo Place View Home Page View White Pages Page View Let’s Meet Page None Help Wanted Page None YourCo Expiring HTML Portlet View YourCo Survey Portlet View YourCo White Page Portlet View YourCo White Pages Results Portlet View YourCo Meeting Reservation Portlet View YourCo Job Search Portlet View The following figure illustrates the settings for anonymous users for places and pages. Chapter 6. Portal customization 359 Figure 6-36 Permissions settings for Anonymous users 8. Log out. The following figure displays the current YourCo portal available to Anonymous users. 360 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-37 Current YourCo Home page Tip: Click the Home place using the link at the bottom of the page to move back to the Welcome page where the login functionality is available. User login and logout Employees need to be able to log in and log out of the portal. We first need to add a login/logout link to the portal pages. For this purpose, you will need to add a link to the login page if the user isn’t logged in. 1. Open Default.jsp. 2. Add the following source code under the closing tag </wps:pageLoop>. Example 6-67 Source code for the Login and Logout Controls <!--Login link--> <wps:if loggedIn="no" notScreen="Login"> <td valign="middle" align="left" width="25"> <img src="<wps:urlFindInTheme file="button.gif"/>" Chapter 6. Portal customization 361 width="20" height="20" border="0"> </td> <td valign="middle"> <a href='<wps:url home="public" screen="Login"/>'> <wps:text key="login" bundle="nls.yourco"/> </a> </td> </wps:if> <!--Logout link--> <wps:if loggedIn="yes"> <td valign="middle" align="left" width="25"> <img src="<wps:urlFindInTheme file="button.gif"/>" width="20" height="20" border="0"> </td> <td valign="middle"> <a href='<wps:url command="LogoutUser"/>'> <wps:text key="logout" bundle="nls.yourco"/> </a> </td> </wps:if> 3. Save Default.jsp. Default.jsp uses two more resources from the YourCo bundle: login and logout. Therefore, we need to add these resources to the YourCo bundle. 4. Open the file yourco.properties in the directory AppServer\lib\app\nls. 5. Add the new keys to the YourCo bundle. The following example shows the current content of the bundle. Example 6-68 Current YourCo resource bundle # # RESOURCES FOR THE YOURCO PORTAL # title=YourCo Portal login=Login logout=Logout login.title=YourCo Employee Center Login login.description=For sample purposes, use one of the username and password combinations below. Employees and managers have different authority, which affects the options and data shown on some pages. The login.title and login.description will be used later when creating th elogin page for the YourCo portal. 362 IBM WebSphere Portal V4 Developer’s Handbook Although the login.description value displays on several lines here, it should be saved as one line in the property file. 6. Save yourco.properties. 7. Restart WebSphere Application Server for the changes to be loaded. Now, the Home page should include a link to the login page when the user is not authenticated and a link to log out when the user is logged in. YourCo screen The login screen should also be changed to match the look and feel of the YourCo portal.The Home screen can remain the same. Screens are independent of the themes. Modify the Login screen to replace the default login screen for all places and themes. Note: It is recommended that you back up the default Login screen before making the following modifications. 1. Back up the file Login.jsp in the screens directory for the HTML markup (PortalServer\app\wps.ear\wps.war\screens\html). 2. Create a new Login.jsp screen by using the following source code. Example 6-69 YourCo login.jsp <%@ page session="false" buffer="none" %> <%-- @copyright jsp --%> <%@ page import="com.ibm.wps.command.portalsettings.*, com.ibm.wps.command.*, java.util.*, com.ibm.wps.engine.Tracker" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <wps:constants /> <wps:import rundata="rundata"/> <jsp:useBean id="errorBean" class="com.ibm.wps.auth.ErrorBean" scope="request" /> <form method="POST" action='<wps:url command="LoginUser"/>' enctype="application/x-www-form-urlencoded" name="LoginPage"> <!--login title--> <table cellspacing="0" cellpadding="0" border="0" width="100%"> <tr> <td align="center"> <br> <h3> Chapter 6. Portal customization 363 <wps:text key="login.title" bundle="nls.yourco"/> </h3> </td> </tr> </table> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tr> <td align="center" valign="top"> <table border="0" cellspacing="6" cellpadding="0"> <% if (errorBean.getCause() != null) { %> <tr> <td class="wpsEditText" colspan="2"> <div class="wpsFieldErrorText"> <% if ( errorBean.getCause().equals("passwordInvalid") ) { %> <wps:text key="error.pwdinvalid" bundle="nls.engine" /> <% } else if ( errorBean.getCause().equals("userIDInvalid") ) { %> <wps:text key="error.uidinvalid" bundle="nls.engine" /> <% } else if ( errorBean.getCause().equals("loginInvalid") ) { %> <wps:text key="error.logininvalid" bundle="nls.engine" /> <% } %> </div> </td> </tr> <% } %> <tr> <td colspan="2"> <wps:text key="enrollment.main.title" bundle="nls.registration"/> </td> </tr> 364 IBM WebSphere Portal V4 Developer’s Handbook <tr> <td colspan="2"> </td> </tr> <tr> <td rowspan="4"> </td> <td align="left" class="wpsEditText"> <label for="userid"> <wps:text key="userid" bundle="nls.field"/> <label> </td> </tr> <tr> <td> <input class="wpsFieldText" size="16" value='<%= rundata.getParameters(). getString("userid", "") %>' name="userid" type="text"> </td> </tr> <tr> <td align="left" class="wpsEditText"> <label for="password"> <wps:text key="password" bundle="nls.field"/> </label> </td> </tr> <tr> <td> <input class="wpsFieldText" size="16" value="" name="password" type="password"> </td> </tr> <tr> <td colspan="2"> </td> </tr> <tr> <td colspan="2" align="center"> <input type="button" name="Submit" id="<wps:text bundle="nls.button" key="login"/>" value="<wps:text bundle="nls.button" key="login"/>" onClick="document.LoginPage.submit(); return false;"> <input type="button" name="Cancel" id="<wps:text bundle="nls.registration" key="button.cancel" />" value="<wps:text bundle="nls.registration" key="button.cancel" />" onClick="location.href( Chapter 6. Portal customization 365 '<wps:url home='public' reqid='no'/>'); return false;"> </td> </tr> </table> </td> </tr> </table> </form> <script language="JavaScript"> document.LoginPage.elements['userid'].focus(); </script> The Login page should now look like that shown in the following figure. Figure 6-38 YourCo login page The Home screen and the error-related screens, such as Error and ErrorNotLoggedOut, are theme-independent in their construction and therefore don’t require a change to match the YourCo theme. The ForgetPassword and Sign-up related screens, such as UserProfileForm and UserProfileConfig, are not used by the current implementation of the YourCo portal, and therefore won’t be updated to match the YourCo look and feel. 366 IBM WebSphere Portal V4 Developer’s Handbook YourCo skin Defining your own skin involves creating a subdirectory in PortalServer/app/wps.ear/wps.war/skin/markup/ and creating the supporting resources within that directory. The Java Server Pages resources for skins are RowContainer.jsp, ColumnContainer.jsp, and Control.jsp. RowContainer.jsp and ColumnContainer.jsp are fine. However, Control.jsp needs to be updated to reflect the YourCo look and feel. 1. Create a directory for the YourCo skin in PortalServer\app\wps.ear\wps.war\skins\htm. 2. Create the Control.jsp file by using the following source code. Example 6-70 YourCo Control.jsp source code <%@ page session="false" buffer="none" %> <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> <wps:constants/> <% String borderColor="#006699"; %> <!--framing table to allow space--> <table width="100%" <wps:if portletState="Normal,Maximized">height="100%"</wps:if> border="0" cellpadding="0" cellspacing="5"> <tr> <td> <table width="100%" <wps:if portletState="Normal,Maximized">height="100%"</wps:if> border="0" cellpadding="0" cellspacing="0" class="wpsPortletBody"> <!--top border--> <tr height="1"> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> <td bgcolor="<%=borderColor%>" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> </tr> Chapter 6. Portal customization 367 <tr height="1"> <!--title left border--> <td bgcolor="<%=borderColor%>" width="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'> </td> <!--title bar--> <td> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <!--portlet title--> <td class="wpsPortletTitle" width="100%" nowrap align="left" valign="middle"> <wps:portletTitle> <wps:problem bundle="nls.problem"/> </wps:portletTitle> </td> <td class="wpsPortletTitle" nowrap align="right" valign="middle"> <img alt="" border="0" width="1" height="16" src='<wps:urlFindInTheme file="title_minheight.gif"/>'> <!--back control--> <wps:portletBack> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="12" height="16" src="<wps:urlFindInTheme file='title_back.gif'/>" alt='<wps:text key="back" bundle="nls.titlebar"/>' title='<wps:text key="back" bundle="nls.titlebar"/>'> </a> </wps:portletBack> <wps:if loggedIn="yes"> <!--Configure control--> <wps:portletConfigure> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" src='<wps:urlFindInTheme file="title_configure.gif"/>' alt='<wps:text key="configure" bundle="nls.titlebar"/>' title='<wps:text key="configure" bundle="nls.titlebar"/>'> </a> </wps:portletConfigure> 368 IBM WebSphere Portal V4 Developer’s Handbook <!--Edit control--> <wps:portletEdit> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" src='<wps:urlFindInTheme file="title_edit.gif"/>' alt='<wps:text key="edit" bundle="nls.titlebar"/>' title='<wps:text key="edit" bundle="nls.titlebar"/>'> </a> </wps:portletEdit> </wps:if> <!--Help control--> <wps:portletHelp> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="12" height="16" src='<wps:urlFindInTheme file="title_help.gif"/>' alt='<wps:text key="help" bundle="nls.titlebar"/>' title='<wps:text key="help" bundle="nls.titlebar"/>'> </a> </wps:portletHelp> <wps:if loggedIn="yes"> <!--Minimize control--> <wps:portletMinimize> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" src='<wps:urlFindInTheme file="title_minimize.gif"/>' alt='<wps:text key="minimize" bundle="nls.titlebar"/>' title='<wps:text key="minimize" bundle="nls.titlebar"/>'> </a> </wps:portletMinimize> <!--Restore control--> <wps:portletRestore> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" src='<wps:urlFindInTheme file="title_restore.gif"/>' alt='<wps:text key="restore" bundle="nls.titlebar"/>' title='<wps:text key="restore" bundle="nls.titlebar"/>'> </a> </wps:portletRestore> <!--Maximize control--> <wps:portletMaximize> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" Chapter 6. Portal customization 369 src='<wps:urlFindInTheme file="title_maximize.gif"/>' alt='<wps:text key="maximize" bundle="nls.titlebar"/>' title='<wps:text key="maximize" bundle="nls.titlebar"/>'> </a> </wps:portletMaximize> <!--Restore control--> <wps:portletRestore> <a href='<wps:urlParent/>'> <img border="0" align="absmiddle" width="16" height="16" src='<wps:urlFindInTheme file="title_restore.gif"/>' alt='<wps:text key="restore" bundle="nls.titlebar"/>' title='<wps:text key="restore" bundle="nls.titlebar"/>'> </a> </wps:portletRestore> </wps:if> </td> </tr> </table> </td> <!--title right border--> <td bgcolor="<%=borderColor%>" width="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> </tr> <tr height="100%"> <!--portlet left border--> <td bgcolor="<%=borderColor%>" width="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'> </td> <!--portlet content--> <td width="100%" valign="top"> <table width="100%" height="100%" border="0" cellpadding="5" cellspacing="0"> <tr> <td class="wpsPortletBack" valign="top"> <wps:portletRender> <font COLOR="red"> <wps:problem bundle="nls.problem"/> </font> </wps:portletRender> </td> 370 IBM WebSphere Portal V4 Developer’s Handbook </tr> </table> </td> <!--portlet right border--> <td bgcolor="<%=borderColor%>" width="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'> </td> </tr> <!--Bottom border--> <tr height="1"> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> <td bgcolor="<%=borderColor%>" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> <td bgcolor="<%=borderColor%>" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='<wps:urlBase/>/images/dot.gif'></td> </tr> </table> </td> </tr> </table> We will change the classes in the theme Cascading Style Sheet Styles.css to implement the YourCo look and feel for the portlet skin. 3. Open Styles.css from the YourCo theme directory. 4. Modify the style for the wpsPortletTitle and wpsPortletBack as shown in the following example. Example 6-71 Classes modified for the YourCo skin /* portlet title text style */ .wpsPortletTitle { background-color: #006699; color: #FFFFFF; font-weight: bold; font-family: verdana, sans-serif; font-size: 10pt; } /* standard portlet background */ .wpsPortletBack { background-color: #99CCFF; } 5. Save Styles.css. 6. Stop and restart IBM HTTP Server. 7. Log in to the portal with administrative rights. Chapter 6. Portal customization 371 8. Add the skin to WebSphere Portal by clicking Portal Administration -> Portal settings -> Themes and Skins. 9. Apply the new skin to the YourCo theme by editing the YourCo theme and adding the YourCo theme as the default skin for the theme as shown in the following figure. 10.Log out. Figure 6-39 Adding the YourCo theme The following figure displays the current YourCo portal available to Anonymous users with the YourCo theme and the YourCo skin. 372 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-40 YourCo Home page with YourCo theme and skin 6.4.3 Adding features to the YourCo portal Preview Themes and skins use preview images to display the theme and the skin when selecting them while customizing hte portal. Theme preview 1. Capture the page area of your Web browser for the YourCo Home page. 2. Edit the image captured in your favorite image editor. 3. Add a black border around the image. 4. Resize the image to a size of 300x225. 5. Save the image in the YourCo theme directory. Chapter 6. Portal customization 373 Figure 6-41 YourCo theme preview.gif The following figure illustrates the use of the theme preview. Figure 6-42 Use of YourCo theme preview Skin preview 1. Capture the portlet area of your Web browser for the YourCo Home page. 2. Edit the image captured in your favorite image editor. 3. Resize the image to a size of 307x159. 374 IBM WebSphere Portal V4 Developer’s Handbook 4. Remove the portlet content and title. 5. Type <....> at the portlet title location. 6. Resize the image to a size of 307x159. 7. Save the image in the YourCo skin directory. Figure 6-43 YourCo skin preview.gif Internationalization YourCo is expanding in France. The employee portal therefore needs to support French as well as English. We will make the portal available in French. 1. Copy the resource bundle yourco.properties to yourco_fr.properties in the AppServer\lib\app\nls directory. 2. Translate the values for each keys as indicated in the following example. Example 6-72 Content for yourco_fr.properties # # FRENCH RESOURCES FOR THE YOURCO PORTAL # title=YourCo Potail login = Connexion logout = D\u00e9connexion login.title=Connexion pour le personnel login.description=Pour ce prototype, utilisez un ID utilisateur et un mot de passe ci-dessous. L'acc\u00e8s aux fonctionalit\u00e9s du portail est determin\u00e9 par la function de l'utilisateur. We now need to define the locale for the places and pages created as indicated in the following table. Chapter 6. Portal customization 375 Table 6-11 French title for the YourCo place and pages Object French title YourCo YourCo Home Accueil White Pages Pages blanches Let’s meet Rendez-vous Help wanted Offres d’emploi 3. Log in to the portal with administrative rights. 4. Add the locale for places and page by selecting Work with Pages -> Manage Places and Pages -> Select the YourCo place -> Manage Pages. 5. For each page, select the page and click Manage Page Properties -> Set locale specific title. Select French and click Set Title for the selected locale, then enter the locale for French and save. 6. Log out. We also need to change the banner to reflect the French title. 1. Create a new subdirectory named fr in the YourCo theme directory. 2. Copy the Banner file topBanner.gif from the YourCo directory to the fr directory. 3. Open the copied file using your favorite image editor. 4. Change the title in the banner from Your Company to Votre Société. 5. Save the image file. Now, the YourCo portal should support both French and English. To check the result, create a user with the language set to French for its profile. The Home page should display like the following figure. 376 IBM WebSphere Portal V4 Developer’s Handbook Figure 6-44 French version of the YourCo portal As you can notice from the previous picture, the portlets were already supporting French. Collaboration services WebSphere Portal Extend includes collaboration services. To use the collaboration portlets, we need to initialize the people service and the menu service. 1. Open Default.jsp from the theme directory. 2. Add the tag libraries shown in the following example under the reference to the wps tag library (<%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %>). Example 6-73 Source code for the collaboration services tag libraries <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="pa" %> <%@ taglib uri="/WEB-INF/tld/menu.tld" prefix="menu" %> 3. Add the menu and people initialization code shown in the following example under the closing </head> tag. Chapter 6. Portal customization 377 Example 6-74 Source code to initialize the collaboration services <!-- Lotus Collaborative Services --> <wps:if loggedIn="yes"> <pa:peopleinit/> </wps:if> <menu:menuinit/> <menu:menuinit> initializes the menu service that adds menus to the Collaborative Components applications. The <pa:peopleinit/> tag determines whether Sametime or Discovery Server, or both, are enabled to work with Portal Server and generates the correct HTML and JavaScript for initializing Sametime or enabling Discovery Server, or both. 4. Add the people service finalization code shown in the following example before the closing </body> tag. Example 6-75 Source code to finalize the people service <wps:if loggedIn="yes"> <pa:peopleend/> </wps:if> Summary The following files and folders have been created to build the YourCo portal: AppServer\lib\app\nls – yourco.properties – yourco_fr.properties PortalServer\app\wps.ear\wps.war\screens\html – Login.jsp PortalServer\app\wps.ear\wps.war\skins\html\YourCo – Control.jsp – preview.gif PortalServer\app\wps.ear\wps.war\themes\html\YourCo – bg.gif – button.gif – buttonDWN.gif – Default.jsp – horzLine.gif 378 IBM WebSphere Portal V4 Developer’s Handbook – preview.gif – Styles.css – topBanner.gif – twistcb.gif PortalServer\app\wps.ear\wps.war\themes\html\YourCo\fr – topBanner.gif WebSphere Portal generates the following source code when a user connects to the YourCo Home page. Example 6-76 YourCoHome page source code <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <html> <!--headers--> <head> <title>YourCo Portal</title> <link href='/wps/themes/html/YourCo/Styles.css' rel="styleSheet" type="text/css"> <!-- Lotus Collaborative Services --> <script type="text/javascript" language="Javascript" src="/wps/menu/menu_service.js"> </script> <script type="text/javascript" language="Javascript"> menuService_writeApplet("/wps/menu"); </script> </head> <!--body--> <body marginwidth="0" marginheight="0" background="/wps/themes/html/YourCo/bg.gif"> <center> <table width="620 border="0" cellspacing="8" cellpadding="0" height=”100%”> <!--banner--> <tr> <td width="100%" valign="top"> <img src="/wps/themes/html/YourCo/topBanner.gif" border="0" alt="YourCo Portal" align="bottom" width="607" height="46"> Chapter 6. Portal customization 379 </td> </tr> <!--page navigation--> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td valign="middle" align="left" width="25"> <img src="/wps/themes/html/YourCo/buttonDWN.gif" width="20" height="20" border="0"> </td> <td valign="middle" align="left"> <b> Home </b> </td> <td valign="middle" align="left" width="25"> <img src="/wps/themes/html/YourCo/button.gif" width="20" height="20" border="0"> </td> <td valign="middle" align="left"> <a href="/wps/portal/.cmd/ChangePage/.pa/128/ _pagr/108/_pa.108/131"> White Pages </a> </td> <!--Login link--> <td valign="middle" align="left" width="25"> <img src="/wps/themes/html/YourCo/button.gif" width="20" height="20" border="0"> </td> <td valign="middle"> <a href='/wps/portal/.scr/Login'> Login </a> </td> </tr> </table> </td> </tr> <!--screen--> 380 IBM WebSphere Portal V4 Developer’s Handbook <tr> <td width="100%" height="100%" valign="top"> <!--Home begin --> <table width="100%" cellpadding="0" cellspacing="0" border="0"> <tr> <td> <!--Page Render --> <!--Row Container Begin--> <table width="100%" cellpadding="0" cellspacing="0" align="center" border="0"> <tr height="100%"> <td valign="top" > <!--Column Container Begin--> <table width="100%" height="100%" cellpadding="0" cellspacing="0" align="center" border="0"> <tr> <td width="100%" valign="top"> <!--portlet--> <!--framing table to allow space--> <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="5"> <tr> <td> <table width="100%" height="100%" border="0" cellpadding="0" cellspacing="0" class="wpsPortletBody"> <!--top border--> <tr height="1"> <td bgcolor="#006699" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> <td bgcolor="#006699" height="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> <td bgcolor="#006699" width="1" height="1"> <img alt="" border="0" width="1" Chapter 6. Portal customization 381 height="1" src='/wps/images/dot.gif'></td> </tr> <tr height="1"> <!--title left border--> <td bgcolor="#006699" width="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'> </td> <!--title bar--> <td> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr> <!--portlet title--> <td class="wpsPortletTitle" width="100%" nowrap align="left" valign="middle"> YourCo Expiring HTML - Sample portlet </td> <td class="wpsPortletTitle" nowrap align="right" valign="middle"> <img alt="" border="0" width="1" height="16" src='/wps/themes/html /title_minheight.gif'> </td> </tr> </table> </td> <!--title right border--> <td bgcolor="#006699" width="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> </tr> <tr height="100%"> 382 IBM WebSphere Portal V4 Developer’s Handbook <!--portlet left border--> <td bgcolor="#006699" width="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'> </td> <!--portlet content--> <td width="100%" valign="top"> <table width="100%" height="100%" border="0" cellpadding="5" cellspacing="0"> <tr> <td class="wpsPortletBack" valign="top"> <--portlet rendering--> <table height="310"> <tbody> <tr> <td rowspan="2" valign="top" align="left"> <font size="+2" PM edition </font><br> <font size="+1"> YourCo afternoon news </font><br> <br> <font size="-1"> YourCo stock soars. <br> <br> This page is displayed by an ExpiringHTML portlet. The portlet checks the current time and chooses either the morning news or the afternoon news.<br> </font><br> <font size="-1"> To see the Breakfast Edition, you will have to check the news before 12 noon. </font></td> <td rowspan="2" width="20"></td> <td rowspan="2"> <table width="200"> <tbody> <tr> <td valign="top" align="center"> <img src="/wps/WPS_PA_197/images/photo01.jpg" border="0" align="top"> </td> </tr> Chapter 6. Portal customization 383 <tr> <td align="center"><i><font size="-2"> Looking skyward from the YourCo home office - Anywhere, USA. </font></i></td> </tr> </tbody> </table> </td> </tr> </tbody> </table> </td> </tr> </table> </td> <!--portlet right border--> <td bgcolor="#006699" width="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'> </td> </tr> <!--Bottom border--> <tr height="1"> <td bgcolor="#006699" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> <td bgcolor="#006699" height="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> <td bgcolor="#006699" width="1" height="1"> <img alt="" border="0" width="1" height="1" src='/wps/images/dot.gif'></td> </tr> </table> </td> </tr> </table> </td> </tr> 384 IBM WebSphere Portal V4 Developer’s Handbook </table> <!--Column Container End--> </td> </tr> </table> <!--Row Container End--> <!--Page Render End --> </td> </tr> </table> <!--Home end --> </td> </tr> <!--separation--> <tr> <td> <img src="/wps/themes/html/YourCo/horzLine.gif" border="0"> </td> </tr> <!--place navigation--> <tr> <td> <table border="0" cellspacing="0" cellpadding="0"> <tr> <td> <img src="/wps/themes/html/YourCo/twistcb.gif" width="12" border="0"> </td> <td valign="middle" align="left"> <b> YourCo </b> </td> <td> <img src="/wps/themes/html/YourCo/twistcb.gif" width="12" border="0"> </td> Chapter 6. Portal customization 385 <td valign="middle" align="left"> <a href="/wps/portal/.cmd/ChangePageGroup/.pagr/103/.reqid/0"> Home </a> </td> </tr> </table> </td> </tr> </table> </center> <!--finalize people service--> </body> </html> 6.5 JSP tags reference This section describes the most common tags for use in the skin and theme Java Server Pages. These tags can be used to modify the layout of the portal page. To use the tags ib the JSP, the reference to the taglib should be included at the Note: See the product InfoCenter for a complete description of the tags used for Java Server Pages. beginning of the file: <%@ taglib uri="/WEB-INF/tld/engine.tld" prefix="wps" %> The corresponding taglib file is named engine.tld and can be found in the PortalServer/app/wps.ear/wps.war/WEB-INF/tld directory. The prefix used in the JSP file is typically wps for this taglib and therefore will be used in this section. 386 IBM WebSphere Portal V4 Developer’s Handbook Note: When an attribute is required, it will be displayed as attribute="required", when optional, as attribute="optional". This section describes the tags provided by the Extend version of the Portal. The corresponding taglib file is named extend.tld and can be found in the ServerPortalServer/app/wps.ear/wps.war/WEB-INF/tld directory. To use the tags ib the JSP, the reference to the taglib should be included at the beginning of the file: <%@ taglib uri="/WEB-INF/tld/extend.tld" prefix="extend" %> 6.5.1 <wps:bidi> <wps:bidi dir="rtl|ltr" attribute="portlet|page|pagegroup"> Some languages support text from right to left instead of right to left. This tag is used to support text for both directions. The following example shows a typical use of this tag for the portal. Example 6-77 Source code for sample use of <bidi> <wps:bidi dir="rtl"> <% bidiAlignRight = "left"; bidiAlignLeft = "right"; bidiImageRight = "Left"; bidiImageLeft = "Right"; bidiImageRTL = "_rtl"; %> </wps:bidi> // // // // // BIDI BIDI BIDI BIDI BIDI value value value value value for for for for for align="right" attribute align="left" attribute adding "Right" to a graphic name adding "Left" to a graphic name adding _rtl to a graphic When the locale of the user requesting the page is defined to be a BIDI locale, the content of the <bidi> tag will be evaluated. Otherwise, the content of the tag is ignored. The languages that are BIDI locale are defined in the file language.properties from the AppServer\lib\app\config directory. The locale for the user is defined by the user preferences, the browser settings, or the portal default. See “Language and resource bundles” on page 311 for more information. Chapter 6. Portal customization 387 dir=”rtl|ltr” When this is set to rtl, the tag content is evaluated only if the user locale is defined to be a BIDI locale. When this is set to ltr, the tag content is evaluated only if the user locale is not defined to be a BIDI locale. attribute=”portlet|page|pagegroup” When the attribute is set to pagegroup, the content of the <bidi> tag will be evaluated only when the locale used to for the place title is a BIDI locale when it is set to rtl, or isn’t a BIDI locale when it is set to ltr. When used like that, the tag must be called inside a <wps:pageGroupLoop> tag. When the attribute is set to page or portlet, the title considered is the page or the portlet title, respectively. For attribute="page", this tag must be called inside a <wps:pageLoop> tag. For attribute="portlet", this tag must be used in Control.jsp. locale=”value” The tag content is evaluated if the locale is a BIDI locale. Note: The is attribute is deprecated and is replaced by the dir attribute. The locale attribute is also deprecated. 6.5.2 <wps:componentLoop> <wps:componentLoop id="component"> This tag is used by the aggregation components to iterate through all the components defined for a container. The following example shows its use in the default RowContainer.jsp: Example 6-78 Source code illustrating <wps:componentLoop> (RowContainer.jsp) <wps:componentLoop id="component"> <td valign="top" <wps:width/>> <wps:componentRender/> </td> </wps:componentLoop> 388 IBM WebSphere Portal V4 Developer’s Handbook id=”component” The id attribute is optional. It should always be set to component in the current release. This tag is only used in RowContainer.jsp and ColumnContainer.jsp. 6.5.3 <wps:componentRender> The tag renders the component in the context of <wps:componentLoop>. This tag can only be used within a <wps:componentLoop> tag. If the component is a row container, the aggregation engine calls RowContainer.jsp to render the component. If the component is a column container, the aggregation engine calls ColumnContainer.jsp to render the component. If the component is a control, the aggregation engine calls Control.jsp to render the compoment. See Example 6-78 for an example of the use of ComponentRender. 6.5.4 <wps:constants> This tag set three constants to be used on the page: wpsBaseURL, wpsTheme, and wpsDocUrl. It should be used at the beginning of a page for the constants to be used afterwards. wpsBaseURL returns the fully qualified base URL for WebSphere Portal. Banner.jsp uses wpsBaseURL to retrieve the dot.gif image in <img src='<%= wpsBaseURL %>/images/dot.gif' >. wpsTheme returns the theme applied to the current page. wpsDocURL returns the fully qualified URL for the Help documents. For example, <%= wpsDocURL %>/InfoCenter/help_index.html returns the link to the Help entry page in Banner.jsp. The returned link depends on the locale defined for the user. 6.5.5 <wps:date> <wps:date pattern=”value” style=”long|medium|short”> This tag writes the current date depending on the user's locale and the style attribute. The Corporate, Engineering, and Science them provided by WebSphere Portal use <wps:date style="long"/> to display the date. Chapter 6. Portal customization 389 The following table displays a set of examples for the english locale. Table 6-12 <wps:date> examples style value result long August 30, 2002 medium Aug 30, 2002 short 8/30/02 Refer to the description of the SimpleDateFormat class in the JDK API documentation for details at the following link: http://java.sun.com/j2se/1.3/docs/api/java/text/SimpleDateFormat.html 6.5.6 <wps:if> <wps:if capableOf=”value” locale=”value” loggedIn=”yes|no” newWindow=”yes|no” notLocale=”value” notScreen=”value” pageAvailable=”value” pageAvailableNext=”yes|no” pageAvailablePrevious=”yes|no” pageCompletelyActive=”yes|no” pageGroupAvailable=”yes|no” pageGroupSelected=”yes|no” pageSelected=”yes|no” portletMaximized=”yes|no” portletMode=”edit|view|configure|help” portletState=”maximized|minimized|normal” problem=”value” resumeLevel=”value” resumeOption=”value” screen=”value” > Through the attributes of this tag, several conditions can be checked. If all the conditions are true, the content of the tag is written to the page. Otherwise the content is skipped. For example, the tag in the following example displays its content only if the user is logged in and the current page is the Home page. Example 6-79 Source code sample for <wps:if> <wps:if loggedIn="yes" screen="Home,LoggedIn"> <!-- content area --> </wps:if> An attribute can have several values separated by a comma. In such cases, if one of the values is valid, then the condition is met. The following example from Banner.jsp displays the content if the screen screen is one of the three screens and the current place is available: 390 IBM WebSphere Portal V4 Developer’s Handbook Example 6-80 Source code sample for <wps:if> with multivalued attribute <wps:if pageGroupAvailable="yes" screen="Home,LoggedIn,LoggedOut"> <!-- content area --> </wps:if> The following looks at each of the possible attributes: capableOf="capability" This attribute checks whether the client requesting the page supports the specified capability. The capability can be one of the following values. – HTML_2_0 – HTML_3_0 – HTML_3_2 – HTML_4_0 – HTML_CSS – HTML_FRAME – HTML_JAVA – HTML_JAVASCRIPT – HTML_NESTED_TABLE – HTML_TABLE – WML_1_0 – WML_1_2 – WML_TABLE The values can be extented by the client definition as illustrated in “Clients” on page 333. locale="locale" This attribute checks whether the locale of the client is that of the specified locale (or subtype of the specified locale). You can specify a comma separated list, such as en, en_US. Example 6-81 Source code illustrating the locale attribute(UserProfileConf.jsp) <wps:if locale="ja,ko,zh,zh_TW"> <tr> <td align="<%= bidiAlignRight %>" class="wpsEditText"> <wps:text key="person.givenname" bundle="nls.field"/> </td> <td> <%= userWrapper.getAttributeNotNull("givenName") %> Chapter 6. Portal customization 391 </td> </tr> </wps:if> The content of the tag is written only when the locale is one of the specified values (or subtype of the specified locale). loggedIn="yes|no" This attribute checks whether the user is logged in. For example, in Banner.jsp, the following code displays an enrollment icon when the user is not logged in. Example 6-82 Source code sample for loogedIn=”no” <%-- enroll button --%> <wps:if loggedIn="no"> <td valign="middle"> <a href='<wps:url command="PrepareEnrollment" home="public" reqid="no"/>'> <img src='<wps:urlFindInTheme file="nav_create_account.gif"/>' alt='<wps:text key="link.enrollment" bundle="nls.engine"/>' border="0" align="absmiddle" width="26" height="25" title='<wps:text key="link.enrollment" bundle="nls.engine"/>'></a> </td> </wps:if> newWindow="yes|no" This attribute checks whether the current control is rendered in a separate browser window from the portal. notLocale="value" This attribute checks whether the locale of the client is not that of the specified locale (or subtype of the specified locale). You can specify a comma separated list, such as en, en_US. For example, UserProfileConf.jsp uses <wps:if notLocale="ja,ko,zh,zh_TW">. notScreen="value" This attribute checks whether the current screen is not of a certain value. Multiple screen names separated by a comma can be provided. For example, Banner.jsp uses <wps:if notScreen="Home,LoggedIn,LoggedOut">. pageAvailable="yes|no" This attribute checks whether a page is available. For example, this tag is used in Home.jsp to determine if a page is available before starting aggregation. 392 IBM WebSphere Portal V4 Developer’s Handbook Example 6-83 Source code sample fro pageAvailable=”yes” <wps:if pageAvailable="yes"> <wps:pageRender/> </wps:if> pageAvailableNext="yes|no" This attribute checks whether a next page is available. In Banner.jsp, this condition is used to render a scroll icon to provide paging between a set of pages. pageAvailablePrevious="yes|no" This attribute checks whether a previous page is available. The following example from Banner.jsp illustrates the use of pageAvailableNext and pageAvailablePrevious. Example 6-84 Source code sample for paging (Banner.jsp) <wps:pageLoopShift by="-6"> <wps:if pageAvailablePrevious="yes"> <td> <a href='<wps:url type="parent"/>'> <img src='<wps:url type="base"/>images/themes/<wps:theme/>/tab_prev.gif' alt='<wps:text key="link.scrolltableft" bundle="nls.engine"/>' border="0" align="absmiddle" width="14" height="14"></a> </td> </wps:if> <wps:if pageAvailablePrevious="no"> <td> <img src='<wps:url type="base"/>images/themes/<wps:theme/>/tab_prev_dis.gif' alt='<wps:text key="link.scrolltableft" bundle="nls.engine"/>' border="0" align="absmiddle" width="14" height="14"> </td> </wps:if> </wps:pageLoopShift> pageCompletelyActive="yes|no" This attribute checks whether the page and its parents (places) are active. Pages can be deactivated using Work with pages. The following example from Home.jsp displays a message if the page is not active. Example 6-85 Source code sample for pageCompletelyActive (Banner.jsp) <wps:if pageCompletelyActive="no"> <p align="center" class="wpsFieldErrorText"> Chapter 6. Portal customization 393 <b> <br> >>> <wps:text key="info.pagenotcompletelyactive" bundle="nls.engine"/> <<< <br> </b> </p> </wps:if> pageGroupAvailable="yes|no" This attribute checks whether the current place is available. Places can be deactivated using Work with pages. pageGroupSelected="yes|no" This attribute checks whether the currently place is the selected one. This attribute has to be used in the context of a <wps:pageGroupLoop> . See 6.5.9, “<wps:pageGroupLoop>” on page 397 for an example. pageSelected="yes|no" This attribute checks whether a page is selected as the actual page. IThis attribute has to be used in the context of a <wps:pageLoop>. See 6.5.10, “<wps:pageLoop>” on page 398 for an example. portletMaximized="yes|no" This attribute checks whether the portlet is maximized. This attribute is only used in Control.jsp . portletMode="edit|view|configure|help" This attribute checks whether the current portlet supports the requested mode. This attribute is only used in Control.jsp . portletState="maximized|minimized|normal" This attribute checks whether the portlet is in the indicated state. Portlet states are "normal", "maximized", and "minimized". For example, in Control.jsp, the following source code renders the portlet content only when the portlet state is normal or maximized. Example 6-86 Source code sample for portletState (Control.jsp) <wps:if portletState="Normal,Maximized"> <tr> <td width="100%" valign="top" colspan="2"> <table width="100%" border="0" cellpadding="3" cellspacing="0"> <tr> <td width="100%" valign="top"> 394 IBM WebSphere Portal V4 Developer’s Handbook <wps:portletrender> <font color="red"> <wps:error bundle="nls.error"/> </font> </wps:portletrender> </td> </tr> </table> </td> </tr> </wps:if> problem="value" This attribute checks whether the error specified as attribute occured. The predefined errors are: – userid.invalid – password.invalid – portlet.not.active – portlet.not.available – portlet.not.authorized – portlet.title.not.available resumeLevel="value" This attribute checks whether the WebSphere Portal setting for the level on which that persistent session should operate has the provided value. resumeOption="yes|no" This attribute checks whether the WebSphere Portal setting for users to resume the session has the provided value. The following fragment shows the configuration file for the resume level and option. Example 6-87 Sample configuration for resume level and option # Determines the level that persistent session should operate on # # 0 -> do not use persistent window state # 1 -> use persistent window state, but start with the default page # 2 -> use persistent window state and start with the page the user visited before logging out # # Default: 2 Chapter 6. Portal customization 395 persistent.session.level =0 # Determines whether the user get the option to resume the session # # 0 -> the user has no option to resume or not resume as the case may be # 1 -> the user is presented with an option to resume the session at login # # Default: 1 persistent.session.option =0 The file ConfigService.properties located in AppServer\lib\app\config\services sets the configuration for resume option and level. The following illustrates the use of both attributes in Login.jsp. Example 6-88 Source code illustrating use of resumeLevel and resumeOption <wps:if resumeLevel="1,2" resumeOption="no"> <%-- hide and check resume session checkbox - user has no choice --%> <td> <input type="hidden" value="true" name="resumeSession"> </td> </wps:if> <wps:if resumeLevel="1,2" resumeOption="yes"> <%-- user is allowed to resume the prior session at their option --%> <%-- show the checkbox unchecked --%> <td> </td> <td> <input value="true" name="resumeSession" type=checkbox> <label for="resumeSession"> <wps:text key="resume" bundle="nls.field" /> </label> </td> </wps:if> <wps:if resumeLevel="0"> <%-- user is not allowed to resume. Do not generate the checkbox --%> <td> </td> <td> </td> </wps:if> screen="value" This attribute checks whether one of the values provided is the current screen name. For example, in Banner.jsp, this attribute is used to display the Layout tab only when the user is customizing the layout and content of the portal page. See Example 6-79 for details. 396 IBM WebSphere Portal V4 Developer’s Handbook Note: The error attribute is deprecated and has been replaced by the problem attribute. The notCapableOf attribute is deprecated, the <wps:unless> tag should be used instead. 6.5.7 <wps:page> <wps:page attribute="name|id|title"> This tag returns the value for the provided attribute (name, identifier, and title) for the current page. It can only be used inside a <wps:pageLoop> tag. Banner.jsp uses <wps:page attribute="title"/> to write the name of the page for each tab. When getting the page title, the tag will return a value depending on the locale of the client. 6.5.8 <wps:pageGroup> <pageGroup attribute="name|title|id"> This tag returns the value for the provided attribute (name, identifier, and title) for the current place. It can only be used inside a <wps:pageGroupLoop> tag. Banner.jsp uses <wps:pageGroup attribute="title"/> to write the name of the place for each <option> in the pull-down menu. The title returned is locale-dependent. When getting the place title, the tag will return a value depending on the locale of the client. 6.5.9 <wps:pageGroupLoop> <wps:pageGroupLoop screen="value"> The body of this tag is executed for each place available for the user. screen="value" The attribute identifies the name of the screen for which the loop will execute. The following example shows how selectPageGroup.jsp uses the tag. Chapter 6. Portal customization 397 Example 6-89 Source code sample for <wps:pageProupLoop> <wps:pageGroupLoop screen="SelectPage"> <wps:if pageGroupSelected="yes"> <p> <strong><wps:pageGroup attribute="name"/></strong> </p> <wps:pageLoopInit max="99"/> <wps:pageLoop> <p align="center"> <a href="<wps:urlParent/>"> <wps:page attribute="name"/> </a> </p> </wps:pageLoop> </wps:if> <wps:if pageGroupSelected="no"> <p> <strong> <a href="<wps:urlParent/>"> +<wps:pageGroup attribute="name"/> </a> </strong> </p> </wps:if> </wps:pageGroupLoop> 6.5.10 <wps:pageLoop> This loops through all of the user's pages. It is possible to set the maximum number of pages displayed by using the <wps:pageLoopInit> tag. The body of this tag is evaluated until no more pages are available or the value of the max attribute is reached when <wps:pageLoopInit> is used. Example 6-90 Source code sample for <wps:pageLoop> <wps:pageLoop> <wps:if pageSelected="yes"> <%-- selected page tab --%> <!-- Markup to render the selected tab different from other tabs --> </wps:if> <wps:if pageSelected="no"> 398 IBM WebSphere Portal V4 Developer’s Handbook <%-- non-selected page tab --%> <!-- markup for all other tabs --> </wps:if> <TD><IMG alt="" src='<wps:url type="base"/>images/dot.gif' border="0"></TD> </wps:pageLoop> 6.5.11 <wps:pageLoopInit> <wps:pageLoopInit max="value"> This tag sets the maximum number of page <wps:pageLoop> can iterate through. For example, in Banner.jsp, <wps:pageLoopInit max="7"/> sets the maximum number of tabs displayed to 7. If the user has defined more pages, then the portal must provide markup to enable the user to access the tabs for those pages. These are rendered with the use of <wps:pageLoopShift> and pageAvailablePrevious and pageAvailableNext attributes of the <wps:if> tag. 6.5.12 <wps:pageLoopShift> <wps:pageLoopShift by="value"> This tag prepares the URL for page loop shifts. If the navigation is to display only a subset of page tabs, the displayed subset needs to be shifted to the left or right. 6.5.13 <wps:pageRender> <wps:pageRender includeBeginPage="yes|no" includeEndPage="yes|no"> This tag is used in the screen resources to render the screen components. This tag can only be used once on a portal page. The includeBeginPage and includeEndPage attributes indicate whether the portlet container should invoke portlets' beginPage() and endPage() methods. Note: Many commercially available portlets are implementating the beginPage and endPage methods. It is therefore strongly recommended to set the attributes to yes, which is the default. 6.5.14 <wps:portletBack> The content of the tag is rendered when a back mode is available for the portlet in the current request context. This tag can only be used inside Control.jsp. Chapter 6. Portal customization 399 This tag is used in Control.jsp for rendering the Back button in the title bar to allow the user to return to a previous mode. The content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. The link for taking the portlet back is generated depending on the portlet's current window state. Example 6-91 Source code sample for <wps:portletBack> (Control.jsp) <wps:portletBack> <a href='<wps:url type="parent"/>'> <img border="0" align="absmiddle" width="16" height="18" src='<wps:url type="base"/>images/themes/<wps:theme/>/title_back.gif' alt='<wps:text key="link.portlet.back" bundle="nls.engine"/>'> </a> </wps:portletBack> 6.5.15 <wps:portletConfigure> <wps:portletConfigure newWindow="true|false|yes|no"> The content of the tag is rendered when a configure mode is available for the portlet for the current user. This tag can only be used inside Control.jsp. In Control,jsp, the content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. The newWindow attribute indicates that the portlet help should be rendered in a new browser window. The default is "no" or "false". 6.5.16 <wps:portletEdit> <wps:portletEdit newWindow="true|false|yes|no"> The content of the tag is rendered when a configure mode is available for the portlet for the current user. This tag can only be used inside Control.jsp. In Control,jsp, the content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. T The newWindow attribute indicates that, for HTML, the portlet help should be rendered in a new browser window. The default is "no" or "false". 400 IBM WebSphere Portal V4 Developer’s Handbook 6.5.17 <wps:portletHelp> <wps:portletHelp newWindow="true|false|yes|no"> The content of the tag is rendered when a help mode is available for the portlet. This tag can only be used inside Control.jsp. In Control,jsp, the content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. The newWindow attribute indicates that, for HTML, the portlet help should be rendered in a new browser window. The default is "no" or "false". 6.5.18 <wps:portletID> This tag retrieve the instance ID of the current portlet. This tag should only be used in Control.jsp. 6.5.19 <wps:portletMaximize> The content of the tag is rendered when a maximize mode is available for the portlet. This tag can only be used inside Control.jsp. This tag is used in Control.jsp for rendering the maximize button in the title bar to allow the user to maximize the portlet. The content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. 6.5.20 <wps:portletMinimize> The content of the tag is rendered when a minimize mode is available for the portlet. This tag can only be used inside Control.jsp. This tag is used in Control.jsp for rendering the Minimize button in the title bar to allow the user to minimize the portlet. The content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. 6.5.21 <wps:portletRender> This tag render the current portlet by calling the render() method of the corresponding portlet. This tag can only be used inside Control.jsp. If a portlet is not active or deactivated, the body of the tag is executed and a corresponding message can be shown with the problem tag, or other error handling can be implemented. The body of the tag could hold further JSP code. Chapter 6. Portal customization 401 See the <wps:problem> tag for an example of how this tag is used in Control.jsp. 6.5.22 <wps:portletRestore> The content of the tag is rendered when the current mode of the portlet is minimized or maximized. This tag can only be used inside Control.jsp. This tag is used in Control.jsp for rendering the Restore button in the title bar to allow the user to restore the portlet to its original state. The content of this tag includes a link (rendered as <wps:urlParent>) and an icon image. 6.5.23 <wps:portletTitle> <wps:portletTitle id=”value”> This tag writes the title for a portlet. The title returned is locale-dependent. The content of the tag is evaluated only if problems occur during the processing and may be used for error processing. In the follwoing example from Control.jsp, the title is displayed to the left side of each portlet's title bar. Example 6-92 Source code example for <wpd:portletTitlte> <td class="wpsPortletTitle" width="100%" nowrap align="left" valign="middle"> <wps:portletTitle> <wps:error bundle="nls.error"/> </wps:portletTitle> </td> 6.5.24 <wps:problem> <wps:problem bundle="bundle"> This is similar to the <wps:text> tag, where the key for the text in the bundle is taken from the problem indicator. This tag can only be used inside the <wps:portletRender> tag in Control.jsp . 402 IBM WebSphere Portal V4 Developer’s Handbook Example 6-93 Source code sample for <wps:problem> <wps:portletRender> <font color="red"> <wps:problem bundle="nls.problem"/> </font> </wps:portletRender> 6.5.25 <wps:screenRender/> This tag renders the current screen. Screens include Home (default), Login, etc. This tag can only be used once on a portal page. Example 6-94 Source code sample for <wps:screenRender> (Default.jsp) <table border="0" cellpadding="0" cellspacing="0" width="100%" height="100%"> <tr> <td width="100%" height="1" valign="top"> <%@ include file="./Banner.jsp" %> </td> </tr> <tr> <td width="100%" height="100%" valign="top"> <wps:screenRender/> </td> </tr> </table> 6.5.26 <wps:text> <wps:text key="value" bundle="value"> This tag returns the text for a given key in the specified language. The key indicates a resource in the property file, indicated by bundle. Both attributes are required. For example, in Banner.jsp, this tag is used to generate the alt text for the banner image using <img alt='<wps:text key="title" bundle="nls.engine">Portal Title</wps:text>' src='<wps:urlFindInTheme file="logo.gif"/>'>. The value of the title key can be found in the appropriate resource bundle nls.engine. See “Language and resource bundles” on page 311 for more information. Chapter 6. Portal customization 403 6.5.27 <wps:textParam> If the text that is retrieved contains placeholders in the form of "{0}", "{1}", "{2}", etc., the value for these can be set using this tag. The text to be substituted for the placeholders needs to be entered as content for this tag. It can even be an expression. For example, the welcome parameter in a resource bundle is set as follows: welcome = Welcome {0}!. The value of the <wps:textParam> tag in the call to retrieve this key is written in place of the {0}. The following example shows the call to retrive the Welcome message. Example 6-95 Source code sample for <wps:textParam> <wps:text key="welcome" bundle="nls.engine"> <wps:textParam>World</wps:textParam> </wps:text> 6.5.28 <wps:time> <wps:time style=”long|medium|short”> This tag returns the current time depending on the user's locale and the style attribute. The following table displays a set of examples for the english locale. Table 6-13 <wps:time> examples style value result long 2:42:21 PM GMT+2:00 medium 2:42:09 PM short 2:42 PM 6.5.29 <wps:unless> <wps:unless capableOf=”value” locale=”value” loggedIn=”yes|no” newWindow=”yes|no” pageAvailable=”value” pageAvailableNext=”yes|no” pageAvailablePrevious=”yes|no” pageGroupAvailable=”yes|no” pageGroupSelected=”yes|no” pageSelected=”yes|no” portletMaximized=”yes|no” portletMode=”edit|view|configure|help” portletState=”maximized|minimized|normal” problem=”value” screen=”value”> 404 IBM WebSphere Portal V4 Developer’s Handbook This tag operates in contrast to the <wps:if> tag. Through the attributes of this tag, several conditions can be checked. If all the conditions are met, the content of the tag is not written to the page. Otherwise, the content is written. For more information, see the corresponding description for each attribute under the <wps:if> tag. 6.5.30 <wps:url> <wps:url command=”value” commandParam=”value” home=”value” screen=”value” ssl=”value”> This tag retruns a portal URL depending on the attribute provided. Only one of the screen, command, or home attributes can be specified in a single url tag. command="LoginUser|LogoutUser" This creates a URL to log in or log out of the portal These attributes are typically used for the login panel and for the logout button, respectively. This part of a user login form uses the <wps:url> tag to set the action attribute for the form element. Example 6-96 Source code sample for <wps:url command=”value”> <FORM method="POST" action='<wps:url command="LoginUser"/>' enctype="application/x-www-form-urlencoded" name="LoginPage"> commandParam This parameter directs the portal engine to obtain the actual command to execute from an HTTP request parameter instead of on the URL directly. The name of the parameter is the value of the commandParam attribute. home="public|protected" This attribute creates a URL pointing to the public or protected page of the portal. reqid="yes|no|true|false" In the logged-in mode, URLs carry a request ID to allow proper sequencing of the requests. Requests with outdated IDs are not executed any more. To allow out of sequence requests, the value of "no" or "false" turns off sequence checking for this URL. Chapter 6. Portal customization 405 screen="screen_name" This attribute creates a URL pointing to the screen name to be displayed. Note: The type attributes is deprecated for <wps:url>. 6.5.31 <wps:urlBase> This tag creates a URL to the WebSphere Portal installation. It could be used to include resources from a fixed location independent of themes and skins. 6.5.32 <wps:urlFind> <wps:urlFind file=”” path=”value” root=”value”> This tag generates a URL pointing to a resource file. The resource is searched under different paths, depending on the markup and locale supported by the client and the specified attributes of the tag. 6.5.33 <wps:urlFindInSkin <wps:urlFindInSkin file="value" skin=”value”> Similar to <wps:urlFind>, this tag generates a URL pointing to a resource file from the skin. If the skin is provided, the file is searched in the skin directory provided. If the skin attribute isn’t provided, the resource is searched in the current skin for the portlet. This tag can only be used inside Control.jsp. 6.5.34 <wps:urlFindInTheme> <wps:urlFindInTheme file="value" theme=”value”> Similar to <wps:urlFind>, this tag generates a URL pointing to a resource file theme directory. If the theme is provided, the file is searched in the theme directory provided. If the theme attribute isn’t provided, the resource is searched in the current theme. 6.5.35 <wps:urlParent> This tag creates a URL that supports one of the following surrounding tags. 406 IBM WebSphere Portal V4 Developer’s Handbook Surrounded by <wps:pageLoop>, <wps:urlParent> generates a URL used to activate the currently selected page. This is intended to be used for navigation tabs. Surrounded by <wps:pageGroupLoop>, <wps:urlParent> generates a URL used to select the currently processed place. The following example shows how to generate a selection box that loops through the user's defined places, creates an <option> tag for the selection box and makes the current place the selected option. Example 6-97 Source code example for <wps:urlParent> <select name="pagegroups" onchange="this.form.action=this[this.form.pagegroups.selectedIndex].value; this.form.submit ()"> <wps:pageGroupLoop> <option value="<wps:urlParent/>" <wps:if pageGroupSelected="yes">selected</wps:if>> <wps:pageGroup attribute="title"/> </wps:pageGroupLoop> </select> Surrounded by <wps:PageLoopShift>, <wps:urlParent> generates a URL that shifts the set of the currently visible pages by the amount specified in the <wps:pageLoopShift> tag. This is normally used to scroll through page tabs when the user has more pages than can be viewed. Surrounded by <wps:PortletMaximize>, <wps:urlParent> is used in Control.jsp to generate a URL to put the portlet in the maximize state. Surrounded by <wps:PortletMinimize>, <wps:urlParent> is used in Control.jsp to generate a URL to put the portlet in the minimize state. Surrounded by <wps:PortletRestore>, <wps:urlParent> is used in Control.jsp to generate a URL to put the portlet in the normal state. Surrounded by <wps:PortletBack>, <wps:urlParent> is used in Control.jsp to generate a URL to return the portlet in its previous mode. Surrounded by <wps:PortletConfigure>, <wps:urlParent> is used in Control.jsp to generate a URL to return the portlet in its configure mode. Surrounded by <wps:PortletEdit>, <wps:urlParent> is used in Control.jsp to generate a URL to return the portlet in its edit mode. Chapter 6. Portal customization 407 Surrounded by <wps:PortletHelp>, <wps:urlParent> is used in Control.jsp to generate a URL to return the portlet in its help mode. 6.5.36 <wps:user> <wps:user attribute="userID|fullName|familyName"> If the user is logged in, the tag returns one of the specified values of attribute. In Banner.jsp, this tag displays the name of the user after login. Example 6-98 Source code example using <wps:user> (Banner.jsp) <wps:if loggedIn="yes" screen="Home"> <wps:text key="welcome" bundle="nls.engine"> Welcome <wps:textParam><wps:user attribute="fullName"/></wps:textParam>! </wps:text> </wps:if> 6.5.37 <wps:width> This tag return the width of a component. This tag is valid only in the context of a component. RowContainer.jsp uses the tag to set the width of the cell. Example 6-99 Source code example using <wps:width> (RowContainer.jsp) <wps:componentLoop id="component"> <td valign="top" <wps:width/>> <wps:componentRender/> </td> </wps:componentLoop> 6.5.38 <extend:find> The content of the tag is displayed if the functionality is enabled. The tag is used in Banner.jsp to display the Find link. Example 6-100 Source code sample for <extend:find> <%-- find --%> <extend:find> <a href="<wps:urlParent/>" style="text-decoration:none" title="<wps:text key='link.find' bundle='nls.engine'/>" target="_blank"> <img align="absmiddle" src="<wps:urlFindInTheme file='task_show_info.gif'/>" border="0"> 408 IBM WebSphere Portal V4 Developer’s Handbook <span style="text-decoration:underline"> <wps:text key="link.find" bundle="nls.engine"/> </span> </a> </extend:find> 6.5.39 <extend:pageGroupId> This tag returns the pageGroup Id to be used to render the list of bookmarks defined for a place. The following example shows the implementation of the tag in Banner.jsp. Example 6-101 Source code sample for <extend:pageGroupId> <a href="#" style="text-decoration:none" onClick="w=window.open('<%=wpsBaseURL%>/extend/bookmarks.jsp? pgiid=<extend:pageGroupId/>&oid=<extend:userObjectId/> &path=<%=java.net.URLEncoder.encode(request.getServletPath())%>', 'Bookmarks','toolbar=no,location=no,directories=no,status=no, menubar=no,scrollbars=yes,resizable=yes,width=400,height=280, top=100,left=100');w.opener=self;w.focus();"> 6.5.40 <extend:userObjectId> This tag returns the Object Id to be used to render the list of bookmarks defined for a place. The following example shows the implementation of the tag in Banner.jsp. Chapter 6. Portal customization 409 410 IBM WebSphere Portal V4 Developer’s Handbook 7 Chapter 7. Web Clipping This chapter describes Web Clipping technology within WebSphere Portal. Web Clipping allows an enterprise to deploy existing content in portlets without having to create new versions of the existing content. Web Clipping uses the Transcoding technology provided by WebSphere Transcoding Publisher. In this chapter, we describe the administration interface to build Web Clippers (or portlets) using Web Clipping; we also discuss the different types of clipping options and the settings to create or modify a Web Clipper. © Copyright IBM Corp. 2003. All rights reserved. 411 7.1 Web Clipping overview WebSphere Portal comes with Web Clipping technology, a component of WebSphere Transcoding Publisher. Web Clipping allows an enterprise to deploy existing content in portlets within WebSphere Portal without having to create new versions of the existing content. For example, a company might already have a Web reporting application publishing reports as HTML document. The company might want to publish part of this content on their enterprise portal beside other related portlets. Web Clipping allows Web content from the report application to be clipped and displayed within a portlet on a portal page. In this way, you can keep those pieces of information that are important while discarding undesirable information or elements in the document that the client device is incapable of displaying. The Web Clipping portlet application consists of two concrete portlets: a Web Clipping administration portlet and a Web Clipper runtime portlet. The Web Clipping administration portlet provides a end-user interface to create and manage clipping portlets, or Web clippers, by using a wizard-like interface to specify how to obtain the external content and then identifying (clipping) the regions of those pages that should be displayed in the portlet. A Web Clipper is a concrete portlet of the Web Clipper runtime portlet parametrized by a XML configuration stored in com.ibm.wps.portlets.clipper.config-data. Web Clipping provides two approaches to identify section of a document: HTML Clipping HTM Clipping operates on the DOM form of the source document by using nodes delimiters. See 7.2, “Web Clipping example” on page 413, for an example of building a HTML Web Clipper using the Web Clipping administration portlet. In this example, we clip parts of the Home page from the YourCO sample provided with WebSphere Application Server. In 7.3, “HTML clipping” on page 419, we describe how this HTML clipping sample use annotation to clip the desired part of the Welcome page. 412 IBM WebSphere Portal V4 Developer’s Handbook Text Clipping Text Clipping operates on the text form of the document by using string-based delimiters. In 7.4, “Text clipping” on page 424, we will build a Text Clipping portlet and describe how it works. With the ever-increasing emphasis on security, Web Clippers might need to access external content through a proxy. Or the external content might need some form of authentication for the Web Clipper to reach the content. In 7.5, “Web Clipper settings” on page 427, we will review the settings allowing to meet such requirements, as well as other settings. Note: It is recommended that you obtain the latest version of the Web Clipping portlet from the portlet catalog as new features are added to the portlet constantly. The NavCode™ for the Web Clipping portlet application is 1WP10003P. 7.2 Web Clipping example In this section, we will create a Web Clipper that uses HTML clipping to identify and extract several part of the Home page of the WebSphere Application Server YourCo application. We will then publish this Web Clipper on the Home page of the YourCo portal application created in 6.4, “Building a virtual portal: the YourCo portal” on page 347. Note: The scenarios provided in this chapter will be using the YourCo application provided with WebSphere Application Server. The following figure displays the current Home page for the YourCo WebSphere Application Server application and the two portions that we wish to display in our portal application: Chapter 7. Web Clipping 413 Figure 7-1 WebSphere Application Server YourCo Home page for clipping sample To create a simple Web Clipper using the Web Clipping Administration Portlet, follow these steps. 1. Log in as an Administrator to the portal (for example wpsadmin). 2. Select the Web Clipping administration portlet by clicking Portal Administration -> Portlets -> WebClipping. The portal displays the Web Clipping administration portlet as illustrated in the following figure. 414 IBM WebSphere Portal V4 Developer’s Handbook Figure 7-2 Web Clipping administration portlet Note: If instead of displaying the portlet administration, the page shows the error message: The portlet is unavailable. If the problem persists, please contact your portal administrator, please install the latest Web Clipping portlet available from the portlet catalog (NavCode: 1WP10003P) or the latest fix. With this administration portlet, you can perform all the operations that are necessary to manage the Web Clippers. The list on the left show all the Web Clipper within the portal. The list is empty by default. To the right of this list are three buttons labeled Add, Edit, and Delete, from top to bottom. Add allows you to add a new Web Clipper, Edit to change the settings for a existing Web Clipper, and Delete to remove a Web Clipper from the portal. We will now create a new Web Clipping portlet, or Web Clipper. The first step in creating a new Web Clipper is to specify the basic settings for the Web Clipper. To bring up the Basic Settings page, follow these steps. 1. Click Add. 2. Enter the name of the Web clipper in the Name and default locale title field. This value is used both as the name to identify the Web clipper and as the default locale title. For example, this could be YourCo Welcome for our new Web Clipper Chapter 7. Web Clipping 415 3. Enter a description for the Web clipper in the Description field. For example, This is the Welcome Web Clipper using content from the YourCo Web application. 4. Enter the URL of the HTML document that the Web clipper is associated with in the URL to clip field. THe URL needs to be a fully qualified URL. For example, http://ka0kkcf.itso.ral.ibm.com/WebSphereSamples/YourCo/index.jsp where ka0kkcf.itso.ral.ibm.com is the fully qualified name of the WebSphere Application Server Web application. 5. Enter a timeout value in the Connection timeout field. Here, we can keep the default value. To specify titles and descriptions for the Web clipper in other languages, you need to click Set locale-specific titles and descriptions. If you want to modify the default values for the advanced settings for the Web Clipper, such as clipping type, authentication options, URL rewriting rules, or firewall options, click the corresponding link on the basic settings page. 6. Click Next from either the top or the bottom of the Basic Settings page. The next step in creating an HTML Clipper is to clip the content of the document by selecting elements of the page to keep. All other elements will be not be displayed by the Web Clipper. When performing HTML clipping, consider the following: – To select an element, simply move your mouse over the element and click it. The element will be highlighted. – To select more than one element, hold down the Control key when you click additional elements. By default, a single click selects an element, and if any other elements were previously selected, they are deselected. – To deselect an element, simply click it again and the element will be deselected. You might need to experiment on the best place to click to highlight the particular element you are interested in, whether it is the contents of a table cell or the entire table itself. You can also right-click and step up through the element nesting order to whatever level you wish. To ensure that you get the expected content, pay attention to the highlighting. 7. Select the content to keep. Here, we will select the Welcome message and the counter at the bottom right of the page as illustrated in the following figure. 416 IBM WebSphere Portal V4 Developer’s Handbook Figure 7-3 Content selection for YourCo Welcome Web Clipper Selected elements are highlighted in yellow to indicate that they will be kept by the clipping portlet. The Preview button at the top right of the clipping page allows you to open a new window to preview the current Web Clipper selection. The following figure shows the preview window for our selection. Chapter 7. Web Clipping 417 Figure 7-4 Preview for Web Clipper example Note: When selecting different content from the Web Clipping page, the content of the Preview window isn’t updated. You will need to click the Preview button again to bring the Preview window to the front and to update its content. 8. Click Next from either the top or the bottom of the Web Clipping page. The Preview window automatically closes when exiting the clipping page. The new page allows you to see the Web Clipper content based on the current settings for confirmation before finishing. To make other changes, just click the Cancel button to come back to the clipping page. 9. Verify the output and click Done Once the Web Clipper is created, you can administer it as you would any other portlets. For example, you can add this new portlet at the top of the YourCo Home page created in the chapter Portal customization. The Home page now has three portlets as displayed in the following figure. 418 IBM WebSphere Portal V4 Developer’s Handbook Figure 7-5 YourCo Welcome portlet displayed on the Home page The Home page displays the new Web Clipper as it would any other portlet. In the following section, we will look at how this example works. 7.3 HTML clipping Web Clipping recognizes and extracts specific portions of a HTML document by using annotation. Annotation, an XML dialect, contains various instructions which are used by the Transcoding technology to delimit parts of an HTML document, and then choose to either keep them or discard them. For example: column - selects an entire column to be kept or discarded keep - indicates that a node identified by annotation should be retained Chapter 7. Web Clipping 419 insertAttribute - adds a new attribute, or modifies an existing attribute inserthtml - inserts an HTML fragment using HTML insertMarkup - inserts rendered markup in a page remove - indicates that the node identified by annotation should be removed row - selects an entire row to be kept or discarded Web Clipping uses external annotation as the annotation instructions are not located in the clipped document. This approach is appropriate since the developer typically does not have control over the source HTML. The external annotator is stored within the portlet configuration under the parameter com.ibm.wps.portlets.clipper.config-data. To see the annotator for a Web Clipper, select the portlet under Portal Administration -> Portlets -> Manage Portlets and click Modify parameters. The following example shows the Web Clipper configuration for the YourCo Welcome sample. Example 7-1 Web Clipper configuration for YourCo Welcome <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE config-data SYSTEM "clipping-config.dtd"> <config-data version='1.0'> <url> <![CDATA[ http://ka0kkcf.itso.raleigh.ibm.com/WebSphereSamples/YourCo/index.jsp ]]> </url> <clipping type="HTML"> <annotation> <![CDATA[ <?xml version="1.0" encoding="UTF-8"?> <annot version="2.0"> <description take-effect="before" target="/HTML[1]/BODY[1]/*[1]"> <remove/> </description> <description take-effect="before" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/B[1]/FONT[1]"> <keep/> </description> <description take-effect="after" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/B[1]/FONT[1]"> 420 IBM WebSphere Portal V4 Developer’s Handbook <remove/> </description> <description take-effect="before" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/FONT[1]"> <keep/> </description> <description take-effect="after" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/FONT[1]"> <remove/> </description> <description take-effect="before" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/FONT[2]"> <keep/> </description> <description take-effect="after" target="/HTML[1]/BODY[1]/CENTER[2] /TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/FONT[2]"> <remove/> </description> <description take-effect="before" target="/HTML[1]/BODY[1]/CENTER[3] /TABLE[1]/TBODY[1]/TR[2]/TD[1]/FONT[1]"> <keep/> </description> <description take-effect="after" target="/HTML[1]/BODY[1]/CENTER[3] /TABLE[1]/TBODY[1]/TR[2]/TD[1]/FONT[1]"> <remove/> </description> </annot> ]]> </annotation> </clipping> <timeout>5</timeout> <url-rewriting></url-rewriting> </config-data> The Web Clipper configuration is maintained as an XML document. You may recognize some of the settings we used for the Web Clipper. This Web Clipper performed HTML Clipping as indicated by the clipping type. In Appendix 7.4, “Text clipping” on page 424, we will look at Text clipping. Chapter 7. Web Clipping 421 The content of the <annotation> node is the annotator for this Web Clipper. Because the annotator is using XML, the first entry is the XML version statement, represented as <?xml version="1.0" encoding="UTF-8"?>. Below is the root element for the annotation language represented as <annot version="2.0">. Each annotation instruction is represented in a <description> element. The take-effect attribute identifies when annotation is to occur, either before or after the target node. The target attribute identifies the target node (as defined by the XPath to a given element). The actions are children of the <description> element, for example, <remove> and <keep>, as in our example. This annotator is applied to the HTML document defined by the <url> node. The following code displays fragments from the HTML document: Example 7-2 WebSphere Application Server Web Application Home page: fragments <html> <body background="/theme/bg.gif"> <center> </center> <center> <table width="620" height="310"> <tbody> <tr> <td colspan="5" height="20"> <img src="/theme/circleLine.gif"> </td> </tr> <tr> <td colspan="2" valign="top" align="left"></td> <td rowspan="2" width="257" valign="top" align="left"> <p> <b> <font size="+1"> Welcome! </font> </b> <br> <font size="-1"> You are at the Home page for the YourCo sample Web </font> <font size="-1"> site. 422 IBM WebSphere Portal V4 Developer’s Handbook </font> </p> </td> </tr> </tbody> </table> </center> <center> <table width="620" height="50"> <tbody> <!--counter--> <tr> <td align="right"> <font size="-1"> This page has been accessed <b>107</b> times. </font> </td> </tr> </tbody> </table> </center> </body> </html> The second action defined by the annotator is a <keep> action. This action keeps the node located by the XPath expression /HTML[1]/BODY[1]/CENTER[2]/TABLE[1]/TBODY[1]/TR[2]/TD[2]/P[1]/B[1]/FONT [1]. That is the font node in the HTML document with the text Welcome!. When applying the annotator to the HTML document, the following content is generated. Example 7-3 YourCo Welcome content sample <font <font <font <font size="+1">Welcome!</font> size="-1">You are at the Home page for the YourCo sample Web </font> size="-1">site.</font> size="-1">This page has been accessed <b>137</b> times.</font> The Web Clipping administration portlet provides a quick and easy way to create an annotator to apply on an HTML document and render the content in a portlet. Chapter 7. Web Clipping 423 Only a few annotation instructions are used by the Web Clippers created with the Web Clipping portlet interface. By editing the annotator XML document, developers can access a number of additional features. 7.4 Text clipping While HTML clipping operates on the DOM form of the document by using nodes delimiters, text clipping operates on the text form of the document by using string-based delimiters. One of the challenges of operating in the text form can be illustrated by the following example. Suppose you have the following markup in your document: <p> <b>Weather</b> </p> If we search for Weather and extract the text from that point, we will find the following code. Weather</b> </p> The resulting content will have closing </b> and </p> tags. Also, if we choose to search for something like <b>Weather</b>, we are relying on the fact that Weather will always be the exact string in a <B> element. By operating instead on the DOM form of the document, some of this complexity can be alleviated. Although clipping according to the DOM presents some advantages over clipping the text form of a document directly, in some cases, clipping the text form of the document might be a better solution. One obvious example is a document that doesn’t have a DOM representation, such as a text file. In this section, we will create a Web Clipper that uses text clipping to identify and extract the Web counter from the Home page of the WebSphere Application Server YourCo application. We will then publish this Web Clipper on the Home page of the YourCo Portal. The HTML source code for the Home page of the YourCo Web application reveals the following source code for the counter: This page has been accessed <B>141</B> times. 424 IBM WebSphere Portal V4 Developer’s Handbook To make our delimiters unique, we will use This page has been accessed <B> for the starting delimiter and </B> times. for the closing delimiter. To create a new Web Clipper using text clipping, follow these steps. 1. Log in to the portal as an Administrator. 2. Select the Web Clipping administration portlet by clicking Portal Administration -> Portlets -> WebClipping. 3. Click Add. 4. Enter the name of the Web clipper in the Name and default locale title field, for example, YourCo Counter. 5. Enter the URL of the HTML document that the Web clipper is associated with in the URL to clip field. THe URL needs to be a fully qualified URL. For example, http://ka0kkcf.itso.ral.ibm.com/WebSphereSamples/YourCo/index.jsp where ka0kkcf.itso.ral.ibm.com is the fully qualified name of the WebSphere Application Server Web application. 6. Select Modify Clipping Type. 7. Select Text clipping. 8. Enter This page has been accessed <B> for the Start clipping after text field 9. Enter </B> times. for the End clipping before text field Do not select Include start and end text with clipped content since we are only interested in the number. 10.Click Done. 11.Click Next. The content from the given URL is searched for literal occurrences of the start string followed by the end string. The content to clip may contain zero or more pairs of the start and end text. You may choose to include all the text portions between each pair or select individual text portions to include by selecting the checkbox next to the desired text portions. In our case, we have only one occurrence of the clip. 12.Check the only text portion. 13.Click Next. The page shows the content that will appear in the portlet based on the current settings. 14.Verify the output of the Web Clipper and click Done. Once the Web Clipper is created, you can add this new portlet at the top of the YourCo Home page as illustrated here. Chapter 7. Web Clipping 425 Figure 7-6 YourCo Counter portlet displayed on the YourCo Home page The following shows the value of com.ibm.wps.portlets.clipper.config-data. for the YourCo Counter portlet: Example 7-4 Web Clipper configuration for YourCo Counter <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE config-data SYSTEM "clipping-config.dtd"> <config-data version='1.0'> <url> <![CDATA[ http://ka0kkcf.itso.ral.ibm.com/WebSphereSamples/YourCo/index.jsp ]]> </url> <clipping type="COMMENT"> <comment-start> <![CDATA[ This page has been accessed <B> ]]> </comment-start> <comment-end> <![CDATA[ </B> times. ]]> </comment-end> 426 IBM WebSphere Portal V4 Developer’s Handbook <include-tags> false </include-tags> <annotation> <![CDATA[ 0 ]]> </annotation> </clipping> <timeout>5</timeout> <url-rewriting></url-rewriting> </config-data> The YourCo Counter configuration is quite different for the YourCo Welcome clipper configuration. The clipping type is set to COMMENT instead of HTML. There is no definition for the annotator. Instead, the text delimiters are stored, as well as the include flag. 7.5 Web Clipper settings When retrieving content from another Web Application, some specific settings may be needed. For example, we might have to use a proxy to reach a document outside of the intranet where WebSphere Portal could reside. In this section, we will review all the configuration settings for Web Clipper. 7.5.1 Basic settings To create a new clipper, the first step is to enter a set of basic settings. The Web Clipper requires a name and a URL. The description is optional, as well as the locale specific titles and descriptions. The following figure displays the page to set the basic settings. Chapter 7. Web Clipping 427 Figure 7-7 Web Clipper basic setting screen Name and default locale title This is the name for the Web Clipper. This is also the default locale title. Refer to “Set locale-specific titles and descriptions” on page 428 to see how to set locale-specific titles. Description This is a description to provide more detailed information about the Web Clipper. Set locale-specific titles and descriptions This option allows you to specify locale-specific titles and descriptions for the Web clipper. When selecting Set locale-specific titles and descriptions, a list of locales appears. To set specific locales, follow these steps. 428 IBM WebSphere Portal V4 Developer’s Handbook 1. Select a locale. 2. Click Set title for selected locale. A prompt for the title appears. 3. Type in the Web clipper title for the selected locale. 4. Click OK. Repeat this procedure for each locale for which you want a locale-specific title. Click Done when you have finished setting locale values. Note: This option only appears if the portal is configured to support more than one language. URL to clip This is the URL of the document to clip. The URL should be a fully qualified URL. Connection timeout This is the amount of time, in seconds, that you want to keep the connection to the origin server open when idle (maximum time: 100). Web Clipping supports advanced settings such as authentication and firewall settings. The following section will cover these settings. These optional settings are available from the basic settings page: Modify clipping type - Select the clipping choice. See 7.5.2, “Clipping types” on page 430. Modify firewall options- Specify the settings if you use a proxy server to access the content. See 7.5.3, “Firewall options” on page 433. Modify authentication options - Specify the authentication mechanism. See 7.5.4, “Authentication options” on page 435. Modify rules for URL rewriting - Indicates whether URLs in the clipped content need special handling. See 7.5.5, “URL rewriting” on page 440. Modify security options - Specify whether to include or remove JavaScript in the clipped content. See 7.5.6, “Security options” on page 445. The advance settings have a default value, therefore it is not required to enter information in their windows. For example, the clipping type is by default HTML. Chapter 7. Web Clipping 429 7.5.2 Clipping types Web Clipping provides three choices for clipping: HTML Clipping (default setting) Text Clipping Keep all content The following figure displays the page to set the clipping types: Figure 7-8 Web Clipper clipping types window HTML Clipping HTML Clipping operates on the DOM form of the document by using nodes delimiters. You can manually select elements of the HTML document by clicking them with the mouse. Selected elements are highlighted in yellow to indicate that they will be kept after clipping. Section 7.2, “Web Clipping example” on page 413 provides a step-by-step guide for building a Web Clipper using HTML Clipping. HTML Clipping has some limitations about the document being clipped. See 7.6, “HTML Clipping limitations” on page 447 for more information. 430 IBM WebSphere Portal V4 Developer’s Handbook Text clipping Text Clipping operates on the text form of the document by using string-based delimiters You can select the content between specific text strings that are in the document. Content between these strings is kept, and all other content is discarded. Start clipping after text This is the string where clipping starts. The content of the string can be included in the result. End clipping before text This is the string where clipping stops. The content of the string can be included in the result. Include start and end text with clipped content This option is set if both starting and closing text strings are included in the resulting output. Section 7.4, “Text clipping” on page 424 provides a step-by-step guide for building a Web Clipper using Text Clipping. Keep all content This choice brings the entire Web page into your portlet without discarding any content. This method is useful to create a portlet to retrieve and publish some external content within the portal, allowing users to see the content and stay in their portal application. It is also valuable when the external content requires a proxy or an authentication mechanism. To create a new Web Clipper keeping all content from the source document, follow these steps. 1. Log in to the portal as an Administrator. 2. Select the Web Clipping administration portlet by clicking Portal Administration -> Portlets -> WebClipping. 3. Click Add. 4. Enter the name of the Web clipper in the Name and default locale title field, for example, YourCo Home Content. 5. Enter the URL of the HTML document that the Web clipper is associated with in the URL to clip field. THe URL needs to be a fully qualified URL. For example, http://ka0kkcf.itso.ral.ibm.com/WebSphereSamples/YourCo/index.jsp Chapter 7. Web Clipping 431 where ka0kkcf.itso.ral.ibm.com is the fully qualified name of the WebSphere Application Server Web application. 6. Select Modify Clipping Type. 7. Select Keep all content. 8. Click Done. 9. Click Next. The page displays the content that will appear in the portlet based on the current settings. 10.Verify the output of the Web Clipper and click Done. Once the Web Clipper is created, you can add this new portlet at the top of the YourCo Home page as illustrated here. Figure 7-9 YourCo Home Content portlet displayed on the YourCo Home page Note: The HTML content clipped is the inner content of the <body> tag from the source HTML document. 432 IBM WebSphere Portal V4 Developer’s Handbook The following example provides the com.ibm.wps.portlets.clipper.config-data. configuration for the YourCo Home Content portlet. Example 7-5 Web Clipper configuration for YourCo Home content <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE config-data SYSTEM "clipping-config.dtd"> <config-data version='1.0'> <url> <![CDATA[ http://ka0kkcf.itso.raleigh.ibm.com/WebSphereSamples/YourCo/index.jsp ]]> </url> <clipping type="NONE"> </clipping> <timeout> 5 </timeout> <url-rewriting> </url-rewriting> </config-data> The clipping type is set to NONE instead of HTML or COMMENT. There is no definition for the annotator. Also, there is no text delimiters configuration. Only the URL is needed. 7.5.3 Firewall options Many corporation uses a firewall to protect internal content from outsiders. To go though the firewall to retrieve external content may require some additional settings for the Web Clippers. The following Firewall Settings page allows you to configure these settings. Chapter 7. Web Clipping 433 Figure 7-10 Web Clipper firewall options screen Use a proxy server This choice indicates that you require a proxy server to access the HTML document. By default, this is not selected and indicates that you do not require a proxy server to access the HTML document you want to clip. Proxy hostname This is the fully qualified of the proxy server (for example, proxy.company.com). Proxy port This is the port number used to communicate with the proxy server. User ID This is the user ID used to access the proxy server. This is optional. Password This is the password used to access the proxy server. This is optional. The current Web Clipping implementation uses the Java Virtual Machine (JVM) built-in configuration for proxy support. Unfortunately, the scope of the configuration encompasses all threads in the same JVM. If two or more portlets using different proxies reside on the sample page, problems can arise if they are not initialized in sequence. Because of this 434 IBM WebSphere Portal V4 Developer’s Handbook limitation, it is recommended that you use Web Clippers with different proxy settings on a separate page. See “Proxy support” on page 448 for future implementations of Web Clipping. 7.5.4 Authentication options Web Clipping supports two authentication mechanism: HTTP basic authentication and form-based authentication. HTTP basic authentication is a simple mechanism provided by the HTTP protocol to allow a server to request authentication information from a client before delivering the contents of a page. HTTP basic authentication requires a userid, password, and realm. The realm identifies a protected space on the target server that the user wants to access. Form-based authentication is a process whereby a request is redirected to a login page that contains an HTML form in which the user must enter a user ID, password, and, possibly, additional credentials before accessing protected content. Typically, a session is then created so that all subsequent request can use the same credentials. The following Authentication Settings page allows you to configure these settings. Chapter 7. Web Clipping 435 Figure 7-11 Web Clipper authentication options window No authentication required This choice indicates that no authentication is needed to access the HTML document. This is the default setting. Authentication required This choice indicates that an authentication method is required for accessing the HTML document. Both HTTP Basic Authentication and form-based authentication require a user ID and a password. User ID This is the user ID used to access the document. 436 IBM WebSphere Portal V4 Developer’s Handbook Password This is the password used to access the document. Note: The values entered as the user ID and password are used so that the content can be retrieved for editing and previewing. The values must be reentered at runtime. HTTP Basic Authentication This option indicates that HTTP Basic Authentication is used to access the HTML document. Realm The realm to which the document belongs need to be specified. Form-based authentication This option indicates that Form-based Authentication is used to access the HTML document. Log-in URL This is the URL to process the login form. To determine this value, view the login page, right-click View Source, and use the value of the action attribute of the <FORM> tag for the login form. User parameter name This is the name of the user ID field on the form. To determine this value, view the login page, right-click View Source, and use the value of the name attribute of the INPUT tag for the User ID field. Password parameter name This is the name of the password field on the form. To determine this value, view the login page, right-click View Source, and use the value of the name attribute of the INPUT tag for the password field. Additional key value pairs This is where any additional key value pairs corresponding to other parameters required by the form are entered. An ampersand (&) should be used to separate each pair. There are generally extra <INPUT> elements in the form. The following example shows an instance of clipping a document residing behind a form-based authentication. We will use the YourCo employee center from the YourCo samples. Chapter 7. Web Clipping 437 The URL for the form is: http://ka0kkcf/WebSphereSamples/servlet/WebSphereSamples. YourCo.LoginLogout.Login. The relevant information form the source code is given in the following example. Example 7-6 Source code fragments from the YourCo login page <FORM METHOD="post" ACTION="/WebSphereSamples/servlet/WebSphereSamples.YourCo.LoginLogout.Login" TARGET="_top"> <TABLE width="620" border="0"> <TR> <TD colspan="3" align="center"></TD> </TR> <TR> <TD align="right" valign="top"><FONT size="-1"><B>Username:</B></FONT></TD> <TD valign="top" align="left"><INPUT TYPE="text" NAME="username" ID="username" SIZE="20" MAXLENGTH="20"></TD> </TR> <TR> <TD align="right" valign="top"><FONT size="-1"><B>Password:</B></FONT></TD> <TD valign="top" align="left"><INPUT TYPE="password" NAME="passwd" ID="passwd" SIZE="20" MAXLENGTH="20"></td> </TR> </TABLE> <P> <INPUT TYPE="submit" NAME="Submit" ID="Submit" VALUE="Submit"> <INPUT TYPE="reset" NAME="Reset" ID="Reset" VALUE="Reset"> </P> </FORM> 438 IBM WebSphere Portal V4 Developer’s Handbook To create a new Web Clipper, keeping all content from the source document, follow these steps. 1. Log in to the portal as an Administrator (for example wpsadmin). 2. Select the Web Clipping administration portlet by clicking Portal Administration -> Portlets -> WebClipping. 3. Click Add. 4. Enter the name of the Web clipper in the Name and default locale title field. For example, YourCo Employee Center. 5. Enter the URL of the HTML document that the Web clipper is associated with in the URL to clip field. THe URL needs to be a fully qualified URL. For example: http://ka0kkcf.itso.ral.ibm.com/WebSphereSamples/servlet/WebSphereSamples.Y ourCo.Customization.Center where ka0kkcf.itso.ral.ibm.com is the fully qualified name of the WebSphere Application Server Web application. 6. Select Modify Authentication options. 7. Check Authentication required. 8. Enter sean for the user name. 9. Enter employee for the password. 10.Check Form based authentication. 11.Enter http://ka0kkcf/WebSphereSamples/servlet/WebSphereSamples.YourCo.LoginLogout .Login for Log-in URL 12.Enter username for the user parameter name. 13.Enter passwd for the password parameter name. Chapter 7. Web Clipping 439 Figure 7-12 BUG 7.5.5 URL rewriting For any given link within the content clipped by a Web Clipper, there are three ways that the retrieved link can be rendered. Inline Display (default) By default, when a link is followed, the content to which it refers is displayed inline, within the Web Clipper’s display area (portlet window). In this case, the Web Clipper acts like a proxy for the new content. The browser sends a request back to the Web Clipper, asking it to handle the link traversal. The Web Clipper retrieves the content to which the link refers and replaces the current content with the retrieved content. Same Window Display The typical browser behavior when following links is to retrieve the content to which the link refers and display it within the same display space. You can direct 440 IBM WebSphere Portal V4 Developer’s Handbook Web Clippers to do the same. In this case, the browser is asked to handle the link traversal rather than sending a request back asking the portal to follow the link. The advantage of this method is that the content can be displayed in its natural or intended environment, as opposed to being limited to the Web Clipper’s display area. The disadvantage is that for all practical purposes, you will have stepped "out of bounds" of the portal; the only method for returning is the browser's Back button. This may cause problems, depending on the session state of the portal. New Window Display Many browsers provide an alternate behavior for displaying the content that results from link traversal. Instead of displaying the content to which the link refers in the existing window, it opens a new window for the retrieved content. Web Clippers can be directed to do this too. Here, the browser is asked to handle the link traversal and display the resulting content within a new window. This method has the advantage of the same window display, but without the disadvantage. The retrieved content can be displayed in its intended environment while maintaining your portal session. Note: In WebSphere Portal Version 4.1, URL rewriting applies only to those URLs contained within the HREF attributes of ANCHOR (<A>) elements. Web Clipping uses the URL rewriter component to modify the URL from the content source. The URL rewriter can be controlled by two sets of regular expressions called rules. Each expression is referred to as a rule and each set may contain zero or more rules. One set contains the set of rules that determine which URLs should be displayed using the Same Window Display method. This set consists of the expressions entered in the listbox labeled The following URLs will not be modified on the URL Rewriting Settings page. The other set contains the set of rules that determine which URLs should be displayed using the New Window Display method. This set consists of the expressions entered in the listbox labeled The following URLs will not be modified and will be opened in a new window on the URL Rewriting Settings page. The following URL rewriting Settings page allows you to configure these settings. Chapter 7. Web Clipping 441 Figure 7-13 Web Clipper URL rewriting screen The URL rewriting component is called after the Web content has been clipped but before any further transcoding occurs. It attempts to match each URL in the document against a rule in one of the sets. If the URL matches a rule within the Same Window Display set, the URL is rewritten so that when traversed, it displays in the same window. If the URL matches a rule within the New Window Display set, the URL is rewritten so that when traversed it displays in a new window. If a URL matches one or more rules in both sets, the rule in the Same Window Display takes precedence. If a URL does not match any rules, it is rewritten so that when traversed, it displays inline within the portlet's display area, which is the default. 442 IBM WebSphere Portal V4 Developer’s Handbook Use standard URL rewriting This choice ensures that URLs in links within the Web Clipper are modified to point to the portal, rather than the host originally targeted by the link. Use rules to exclude URLs from rewriting This choice enables you to specify rules that are used to identify which URLs will not be altered. These links will not go through the portal. For example, a rule of ".*.gif$" will match any URL that ends in ".gif", while a rule of ".*ibm.com.*" will match any URL containing "ibm.com". See “Regular expressions” on page 444. The following URLs will not be modified This is the rules to identify URLs whose content will be retrieved from the original host. These links are opened in the same window. The following URLs will not be modified and will be opened in a new window This is the rule to identify URLs whose content will be retrieved from the original host and will be displayed in a new window. For example, a rule of ".*ibm.com.*" will match any URL containing "ibm.com". The following example shows an implementation of clipping a document with links. We will use the YourCo Home page that we include in our HTML clipping example and add the links below the Welcome message. Let’s edit the YourCo Welcome example to add the portion of the document with the links: 1. Log in to the portal as an Administrator. 2. Select the Web Clipping administration portlet by clicking Portal Administration -> Portlets -> WebClipping. 3. Select the YourCo Home Content Web Clipper. 4. Click Edit. 5. Select Modify rules for URL rewriting. 6. Check Use rules to exclude URLs from rewriting. 7. Add the rule .*/WebSphereSamples.* for URLs that will not be modified and will be opened in a new browser window. The text entered is a regular expression. The pattern .*/WebSphereSamples.* represents the sets of all text strings that contain /WebSphereSamples. See the section “Regular expressions” on page 444 for more information. 8. Click Done. Chapter 7. Web Clipping 443 9. Click Next. 10.Click Done. Coming back to the display of the YourCo Home page, when clicking a link such as White Pages, we can now open the content in a new window. Regular expressions Web Clipping uses the Xerces library for the regular expression implementation. Web Clipping uses regular expressions only for matching. Regular expressions are generated from strings. The strings are a pattern that will be tested against other strings to see if the tested string contains the regular expression pattern. For example, the regular expression “images” tested on the string "http://server/images/image.html" results in a match. However, if the string tested is "http://server/FUDGEBROWNIES/billy.htm", there would be no match. Regular expressions can also contain all sorts of meta characters (meta characters are `. * ? { [ ( ) | \ ^ $'.) and character classes (such as [0-9], \d, [^a-z]). For example, if you had a regular expression"im[a,b,c]ges", this would match "images", "imbges" and "imcges". It would not match for "imdges". Sample rules: ExcludePatterns – "images" - will match any URL containing the string "images" – "pictures" - will match any URL containing the string "pictures" – ".*.gif$" - will match any URL that ends in ".gif" – ".*.jpg$" - will match any URL that ends in ".jpg" ExcludeNewWindowPatterns – ".*cnn.com.*" - will match any URL containing "cnn.com" – ".*usatoday.com.*" - will match any URL containing "usatoday.com" – ".*weather.com.*" - will match any URL containing "weather.com" – ".*jimmythrasher.com.*" - will match any URL containing "jimmythrasher.com" Please read the Xerces API documentation for a more in-depth discussion of regular expressions as implemented by Xerces at: http://xml.apache.org/xerces-j/api.html 444 IBM WebSphere Portal V4 Developer’s Handbook and specifically: org.apache.xerces.utils.regex.RegularExpression at http://xml.apache.org/xerces-j/apiDocs/org/apache/xerces/utils/regex/Re|gul arExpression.html. 7.5.6 Security options The following Firewall Settings page allows you to configure these settings. Figure 7-14 Web Clipper security window Remove JavaScript from clipped content Most JavaScripts are evaluated and executed on the client, after the clipping process is complete. This means that any content dynamically generated by such scripts cannot be subject to clipping. In general, it is a good idea not to include any JavaScript within a Web clipper unless that JavaScript is self-contained, meaning it does not depend on other variables, methods, structures, or other elements that are defined elsewhere. If you must include JavaScript, be aware of the following restrictions: All <SCRIPT> blocks defined by the HTML <SCRIPT> element and JavaScript within the <HEAD> element of the HTML document being clipped will be removed both during edit-time presentation and at runtime. During editing, all JavaScripts, including all event handlers and embedded JavaScripts, are removed prior to displaying the HTML page being clipped. This means that for those scripts that generate content, the content will not be displayed in the HTML clipping editor and therefore cannot be clipped. Chapter 7. Web Clipping 445 For the same reason, <SCRIPT> blocks that are located within the <BODY> element of the HTML document cannot be individually retained. They may be retained implicitly if an element that contains the <SCRIPT> element within the document hierarchy is selected to be retained. For example, if the <BODY> directly contains a <SCRIPT> element child that generates some content, and the <BODY> element is not selected to be retained, the SCRIPT will be lost. However, if a <TD> element within the document contained a <SCRIPT> element that generated content for the <TD> and the <TD> element were selected to be retained, the <SCRIPT> would be retained as well (barring the Remove JavaScript security constraint switch). JavaScript within HTML implicit event handlers (such as onLoad, onMouseOver, and onKeyDown) will only be retained if the element which defines the attribute is retained. JavaScript embedded within HREF attributes (using the javascript: prefix or &{...} syntax) will only be retained if the element which defines the attribute is retained. At runtime, Web Clippers that contain <SCRIPT> elements, JavaScripts embedded within HREF attributes, or JavaScript within HTML implicit event handlers (due to one of the implicit cases above) will behave in one of two ways: If the Remove JavaScript security option is ON, they will be removed prior to constructing the Web Clipper's content. If the Remove JavaScript security option is OFF, they will be retained and subsequently executed by the browser. Also, in all cases: All references from within JavaScript being retained to variables and functions defined within the document <HEAD>, within another <SCRIPT> block that is not being retained, or within an external JavaScript file referenced from a <SCRIPT> block that is not being retained, will break. All references from within JavaScript being retained that reference or depend on a particular document structure or DOM structuring of the document will break. URLs are not rewritten within any JavaScripts within the document (such as references to resources and links within JavaScripts being retained). Such references will break unless the reference is an absolute and not a relative URL. To summarize, these are the only ways to retain JavaScript within a Web Clipper: For <SCRIPT> blocks, retain an element that is an ancestor of the script block within the document hierarchy and set the Remove JavaScript option to OFF (it is ON by default). 446 IBM WebSphere Portal V4 Developer’s Handbook For scripts within implicit event handlers, retain the element on which the handler is defined. For proper functionality, ensure that the inline script does not contain references to custom-defined functions that have been clipped out. For scripts embedded within HREF attributes, retain the element on which the handler is defined. Again, for proper functionality, ensure that the inline script does not contain references to custom-defined functions that have been clipped out. 7.6 HTML Clipping limitations If the output of your Web clipper is not what you expected, keep the following limitations in mind. <FRAME> elements HTML Clipping cannot be used for pages containing the <FRAME> elements. If you attempt to do so, you will receive a message stating that the page you are trying to clip contains <FRAME> elements. JavaScript Many Web sites use scripting languages such as JavaScript to generate or manipulate portions of their HTML content. The Web Clipper bases its clipping decisions on the hierarchical format of the HTML tag structure. Because relationships between JavaScript functional definitions and function calls cannot be represented in this hierarchy, the clipped output of documents containing JavaScript can sometimes be unpredictable. See “Remove JavaScript from clipped content” on page 445. Browser limitations Netscape Communicator and Navigator 4.7 will occasionally prematurely disconnect from an outstanding request to a Web Clipper, causing an empty document to be returned instead of the appropriate content. Later versions of the Netscape browsers do not exhibit this problem. Internet Explorer 5.0 sometimes causes content from one portlet to "bleed" into the content of another portlet on the same portal page, meaning text from one portlet appears to overlay text from another. Resizing the browser window corrects the problem. Later versions of Internet Explorer do not exhibit this behavior. Chapter 7. Web Clipping 447 Devices support Some portlets can be created in a specific markup language so their content can be changed individually from the other portlets. Web clippers, on the other hand, are created only in HTML and must be transcoded to WML or Compact HTML (C-HTML) on the fly. There is no separate file or portlet that can be edited to modify the WML or C-HTML markup that gets created. When WebSphere Portal is installed with WebSphere Everyplace™ Access, the content of all Web Clippers is automatically available to wireless WML and C-HTML devices. 7.7 Future implementation The future Web Clipping implementation will fix some of the limitations of Web Clipping and implement many exciting new features. Proxy support The current Web Clipping implementation uses the Java Virtual Machine (JVM) built-in configuration for proxy support. If two or more portlets using different proxies reside on the sample page, problems can occur if they are not initialized in sequence. The next version of Web Clipping will remedy this problem. Credential Vault WebSphere Portal supports the use of a credential vault where users and administrators can safely store credentials for authentication. Portlets written to extract the user's credentials from the vault can hide the login challenge from the user. The Credential Vault provides exactly this functionality. Portlets can use it through the Credential Vault Portlet Service. The current implementation stores the credential information without the use of Credential Vault. The next version of Web Clipping will make the Credential Vault available for Web Clipper portlets. Multipage clipping The current implementation of Web Clipping allows you to clip content from one document. The next implementation will make possible to clip portions of several documents and aggregate the results. 448 IBM WebSphere Portal V4 Developer’s Handbook 8 Chapter 8. Search capabilities This chapter first introduces the options WebSphere Portal offers to integrate search functionality into a portal solution. The search options specifically provided by WebSphere Portal Extend, namely the integrated Juru search and Lotus Extended Search, will then be discussed in detail in the remainder of the chapter. At the end of the chapter, you will: Understand the various options for integrating search in WebSphere Portal Use the out-of-the-box Juru search engine to configure and perform searches Understand the architecture of Lotus Extended Search Be able to install Lotus Extended Search and perform basic configuration for searches Understand the various ways to create search interfaces to Lotus Extended Search © Copyright IBM Corp. 2003. All rights reserved. 449 8.1 Search in WebSphere Portal Search capabilities form an integral part of a Web portal. The ability to find relevant documents based on a set of keywords is the life line for an information portal. WebSphere Portal offers various options to be used, depending on the product offering you have installed and the needs your portal has to fulfill. Integrated Search Integrated Search is part of all of the Portal offerings. It provides integrated text search capabilities, including a search portlet, a crawler, and a document indexer. The search service can search the portal’s document repository as well as Internet content. It is also used within Portal for administrative purposes. Integrated Search leverages Java-based search and indexing technologies called Juru developed at the IBM research lab in Haifa (http://www.haifa.il.ibm.com/km/ir/juru/). It is often referred to as basic search or Juru search as well. It is covered in “Integrated search” on page 452. Lotus Extended Search Lotus Extended Search is part of WebSphere Portal Extend and is not available in the Enable offering. Lotus Extended Search provides distributed, heterogeneous searching across Domino servers, databases, and the Internet, without the user having to know the details of these various systems. The result is single-point of access to a variety of data sources without requiring a new, central index. Extended Search can search and retrieve documents from repositories that include Lotus Notes and Domino. Extended Search also searches external sources such as Microsoft Index Server and Site Server, LDAP-compliant directories, eighteen popular Web search sites and News sites, commercial content providers, and relational databases such as IBM DB2, Oracle, Sybase, MS SQL-Server, and other ODBC compliant databases. Results can be ranked by relevancy over multiple data stores. Extended Search is covered in “Extended Search” on page 458. Enterprise Information Portal (EIP) IBM Enterprise Information Portal (EIP) can manage data access across multiple sources such as content management repositories, e-mail systems, relational databases, file systems, Web sites and more. EIP integrates data sources across the enterprise, with a unified set of APIs to simplify programming and provide an interface layer that isolates portal applications from changes to underlying data repositories. 450 IBM WebSphere Portal V4 Developer’s Handbook Documents can be categorized into taxonomies, enabling search by category. APIs are provided for capturing and storing other metadata about documents. EIP provides connectors for a variety of repositories, provided by IBM, Lotus, and other vendors such as Documentum and Filenet. Federated searches can be applied across multiple such repositories, and can exercise searching based on metadata, full text, and other specialized search properties such as Query by Image Content (QBIC®), depending on the search services enabled for each repository. The Text Analysis features of EIP support creating full-text indices, and subsequent searching across all the text portions of the content sources configured for use in the portal. Sources can be accessed for indexing via the Web crawler, or via a metadata search. Portlets for accessing EIP advanced and federated search functions are available from the portlet catalog. Since we concentrate on WebSphere Portal Enable and Extend, we will not cover the EIP any further. Lotus Discovery Server™ Lotus Discovery Server creates expertise and knowledge maps by analyzing and categorizing documents. It creates profiles of users based on their document activity, including their topics of interest and their area of expertise. Discovery Server also examines user activity such as reading documents, responding to documents, timeliness of interactions, or links to specific documents. This way, Discovery Server can determine the relative proficiency of individuals to content categories. These proficiency indicators are called affinities, and they indicate the relative expertise of individuals to particular business areas of the organization. The Discovery Server continually assesses the strength of affinities using metrics, ensuring that individuals with recent and high quality expertise ratings are found and presented to users seeking expertise when browsing the Discovery Server Knowledge Map interface. Lotus Discovery Server is purchased separately and is currently not part of any WebSphere Portal offering, therefore we will not cover it any further. Partner add-on products There are various specialized companies who provide search engines and technologies. The portlet catalog at http://www-3.ibm.com/software/webservers/portal/portlet/catalog/ contains many portlets to access popular search engines as well as portlets Chapter 8. Search capabilities 451 provided by companies who play a role in then search area, such as Autonomy, divine, Factiva, Information Builders, Inktomi, Stellent, Verity, YelloBrix and others. Since we concentrate to WebSphere Portal Enable and Extend, we will not cover the add-on products 8.2 Integrated search WebSphere Portal provides integrated text search capabilities, including a search portlet, a crawler, and a document indexer. The search service can search the portal’s document repository as well as Internet content. The portal server’s built-in search engine is optimized for full-text searching of small and medium-sized collections where precision is essential. It efficiently applies state-of-the-art search algorithms, producing high quality search results. The search engine supports free-text queries, with query assistance and query word completion. Search queries use advanced query operators (+ or -) to indicate keywords that must be in the document or keywords that must not be in the document. The search engine can search documents in any language, and also supports synonyms and stop word lists. Search results include document summarization and search results clustering. To prepare for searching, the search engine builds a full text index in order to search documents that are stored in the local file system. The indexer supports multi-word indexing for disambiguation and high precision. The index can be compressed, and the size can be controlled for situations where the size of the index needs to be limited. Portlets are provided for using the search feature as well as for creating, updating, and managing the indices. The configuration of the integrated search is covered in depth in IBM WebSphere Portal 4.1 Handbook, Redbook, SG24-6883. To give you an idea of this concept, we guide you through the steps needed to build a search index, a search portlet and a page to display it. As a showcase, we use the YourCo Application since it is delivered as a sample application included in WebSphere Application Server. 452 IBM WebSphere Portal V4 Developer’s Handbook Search portlet for the YourCo site 1. Configure the index a. Log on to the portal as an administrator and open Portal Administration. b. Go to Portal Settings -> Manage Search Index. c. Click Configure search index. Figure 8-1 Create index page d. Supply the following information: • Set Location of the index: to C:\wp_index\yourCo • Select the New Index radio button. • Select HTML as Document types to be indexed. • For Index documents by following links starting with URL: fill in http://<YourCoHost>/<YourCoUri> where <YourCoHost> is the hostname of the system WAS is running and <YourCoUri> is the URI for the YourCo sample application. This is WebSphereSamples/YourCo in a standard installation. If this sample application is not available, you can use any other Web site. Chapter 8. Search capabilities 453 • From the Levels of linked documents to index: drop down list select 3 Levels. • Deselect Documents with domain only. • From the Number of linked documents to index: drop down list select 5000. e. Click OK. f. Click Done. 2. Build the index. a. Select Manage search index. Figure 8-2 Manage index page b. Select C:\wp_index\yourCo from the index drop down list. c. Click Begin index update. d. Click Done. e. Wait a few minutes for the index to be created. Select Manage search index. If index creation is complete, the status will be updated, showing the number of documents indexed and the completion time stamp as in Figure 8-2. Repeat Steps d) and e) if necessary until you see the completion time stamp; do not proceed until index creation has finished. 3. Create a Search News Portlet. a. Go to Portlets -> Manage Portlets. b. Select the portlet named Document Search. 454 IBM WebSphere Portal V4 Developer’s Handbook c. Click Copy. Figure 8-3 Copy Document Search d. A prompt window pops up; provide the new portlet name WebSearch:YourCo and click OK (see Figure 8-3). e. Select the new WebSearch:YourCo portlet. f. Click Modify parameters. Figure 8-4 Portlet parameters Chapter 8. Search capabilities 455 g. In the value field of the IndexLocation parameter enter: C:\wp_index\news (see Figure 8-4). h. Click Save. i. Click Set title for selected locale j. Set the title to Search YourCo and click OK. k. Click Save. l. Click Close. m. Click Activate/Deactivate to activate the portal. 4. Create the search page. a. Go to Work with Pages -> Manage Places and Pages. b. Select the page group (for example YourCo in this sample scenario) or create a new group. c. Click Manage pages -> Create page -> Create new. d. Enter Search as the title and click OK -> Done. e. Go to Edit Layout and Contents. f. Select YourCo as place and Search as page. g. Click Get portlets and add WebSearch:YourCo to the list. h. From there, add it to the page and click Activate. i. Navigate to the YourCo portal; Search should now be available as seen in Figure 8-5 on page 457. j. Navigate to the search page and enter a search request. For example, search for news as illustrated in Figure 8-5 and Figure 8-6. 456 IBM WebSphere Portal V4 Developer’s Handbook Figure 8-5 Search option in portal Figure 8-6 YourCo Search portlet Chapter 8. Search capabilities 457 Note: For more details on how to add a new page to a portal place, see Chapter 6, “Portal customization” on page 261. 5. Provide permissions for all authenticated users to access page and portlet. a. Go to Portal Administration -> Security. b. Select Special Groups: and from the drop down list All authenticated users. c. Search for the Search page and grant view permission. d. Search for the WebSearch:YourCo portlet and grant edit permission. 6. Create additional search portlets. You can create additional search portlets by repeating Steps 1 - 4. In Step 1, for example, you could use the URL http://www.cnn.com to configure an index in C:\wp_index\news. Be aware that building the index (Step 2) might take a little longer than in our local example. Finally, you create another copy of the Document Search portlet and name it WebSearch:News. Then add it to the Search page or create a new page and provide the permissions as done in Step 5. Figure 8-7 Search page with two search portlets 8.3 Extended Search Lotus Extended Search is a sophisticated and powerful search engine that comes with WebSphere Portal Extend and Experienced. Not only does it allows text searching of text documents, it also enables distributed searching of Documents from repositories including Lotus Notes, Domino.Doc®, Domino Connectors, and Domino R5 Domain Index. 458 IBM WebSphere Portal V4 Developer’s Handbook Popular Web search sites and news sites using third party software. Databases such as IBM enterprise Information Portal databases, relational databases including DB2 and Oracle, and any databases that comply with Open Database Connectivity (ODBC) standards. File systems, Lightweight Directory Access Protocol (LDAP) directories, and catalogs, indexes, and mail folders created with Microsoft Site Server, Microsoft Index Server, and Microsoft Exchange Server. Once the search on multiple datasources is completed, the results are aggregated and ranked. Links are created to enable the user to view the actual document. Administrator-defined actions such as e-mailing the resulting documents to users can also be created. Extended Search also enhances the searching capabilities by enabling users to create mapped fields, so that similar fields with a different nomenclature can be mapped and manipulated in the same fashion. Additional searching capabilities include enabling the user to define parameters to influence data source behavior and design hitlists. Periodic searching on datasources can also be scheduled according to your enterprise’s needs. A Web crawling capability is included where the Extended Search Web crawler downloads data from Web sites to a file system. Search results can be saved, re-used, shared, and stored. These capabilities are helpful for data mining and knowledge management purposes. Due to the extensive features of Lotus Extended Search, this chapter intends to provide the reader the necessary information for a head start to integrate Lotus Extended Search with WebSphere Portal. For details on administering Lotus Extended Search, refer to the document Extended Search Administration that can be found in <ES_INSTALL_DIR>/docs/<REGION_CODE>/pdf/es_admin.pdf. 8.3.1 Lotus Extended Search architecture Extended Search provides a single point of access for searching numerous data sources and the Internet. To shield the user from the complexity of the various underlying native search languages used for each datasource, Extended Search uses its own internal generalized query language (GQL) as the search language. Extended Search translates the GQL for each query into the native search language of the data source, and uses search and retrieval methods that are native to each data source. No central index is created. This approach obscures the complexity of query language from the end user, and enables multiple and varied data sources to be searched in parallel. Chapter 8. Search capabilities 459 In order to implement this multi-source searching capability, Extended Search uses a multi-tiered client/server approach as shown in Figure 8-8. Figure 8-8 Architectural overview for Lotus Extended Search Client-side components The client-side component of the Extended Search is the interface for users to submit queries to the search engine. There are two types of client interface: the Web client and the Notes client. Web client interface The Web client interface is represented by the Web browser in the top left-hand corner in Figure 8-8. This interface makes use of a set of search templates and Java servlet technologies to expose the Extended Search capabilities to the Web community. The Web client uses HTML or JSP files to create the interfaces for gathering search requests and displaying search results. Search requests gathered on HTML or JSP pages are sent via HTTP to an Extended Search servlet (component C). The programmer can optionally enable the user to specify 460 IBM WebSphere Portal V4 Developer’s Handbook searches on specific data sources and modify search and retrieval options. Once a search request is received by the Extended Search servlet, the request is dispatched to the various server side search components to service the request. When the search request is completed, the results are then returned back to the user via HTTP. The Web designer can customize the look and feel of the query and results page. The programmer can program any further actions to be performed on the search results on the results page by using control tags and Javabeans provided by Extended Search. The Web client interface is the key programming interface for providing search functionalities to the WebSphere Portal solution. Notes client interface (component B) The Notes client interface is not used for interfacing with WebSphere Portal. However, the mechanism of this interface is briefly described below for your information. The Notes client interface enables users to perform searches using Extended Search by utilizing the Lotus Notes client and the Extended Search LotusScript Extensions (LSXs) component. The user interacts with the Lotus Notes client to submit requests, view results and retrieve documents. Lotus Notes synchronizes its local database with the server database. Thus, when any Extended Search related actions on the Notes client database are performed, the LotusScript Extension (LSX), an application program interface that enables Lotus Notes to communicate with other software programs, submits the requests to the Extended Search server. When the search is completed, the results are then returned and stored in the Notes client database. Server-side components The server side consists of three tiers. The first tier is represented by the Extended Search servlet and reflector. They serve as the entry points to the server side. The second tier is the Extended Search engine. It consists of brokers and agents. The third tier is the actual back-end data sources and search engines. Extended Search servlet and reflector (component C) The Extended Search servlet and the reflector (component C) are the points of entry for Extended Search client side requests. The Java servlet handles HTTP requests and is always installed. The reflector is a Common Gateway Interface (CGI) program that handles Notes-based requests. It is only needed if a Notes client or IBM Enterprise Information Portal is used. Both components are installed on the machine that hosts the Web server for Extended Search. Once the servlet or reflector receives client search requests, they forward the requests to the Extended Search engine. Chapter 8. Search capabilities 461 Configuration database (component E) Extended Search uses IBM DB2 Universal database for the configuration database. Extended Search stores the following information in this database configuration database (CDB): Data sources information and how they should be searched Network addresses Saved queries Saved search results Data downloaded by the Web crawler The information in the configuration database can be administered using the Extended Search administration interface. You can access the administration interface by typing http://<ES_WEB_SERVER>/lotuskms from your browser. Brokers (component D) The broker is the initial point of contact of the Extended Search server. It acts as the resource coordinator to respond to client requests that are forwarded from the Extended Search servlet or the reflector. The typical tasks performed by the broker are: Validating the user. Obtaining a list of data sources available to the application and resolving the source addresses by referencing the configuration database. Distributing the queries to agents for parallel searching. Aggregating and optionally sorting search results returned by various agents into a single hitlist. Honoring timeouts and response options. Issuing requests to agents to retrieve source documents. Note that for Web-based searches, the Web browser uses the URL to retrieve the actual document. There is more than one broker for the Extended Search server to provide enhanced performance and scalability. Each broker has its own network address which is stored in the configuration database, so any individual broker can be located. Agents (component G) Agents are the most important component in the Extended Search server. Before defining what an agent is, we will first introduce the Extended Search link. An Extended Search link is the component that carries out the actual search for each data source. Thus, a link needs to be defined for each data source type. 462 IBM WebSphere Portal V4 Developer’s Handbook The link needs to first translate a search request into the native calls of the underlying data source’s programming interface. Then the translated request is executed against the data source. After the results are returned, the link stores the search results in a common hitlist structure which will be returned to the agent. Extended Search includes a list of supported links. However, if the data source that you are using is not included in the list, a custom link can be developed. For information for developing custom links, refer to the Extended Search Programming guide in the <ES_INSTALL_DIR>/docs/<REGION_CODE>/pdf/ directory. Back to the definition of an agent: it is a server component that directs the link activities. An agent can be configured to handle requests for all link types or a discrete set of link types. More than one copy of an agent can be started to handle concurrent search and retrieval requests to achieve load balancing. Monitors (component F) An Extended Search Monitor is included which enables the user to observe the server’s activity. To start the monitor, click Start -> Programs -> IBM Extended Search -> Extended Search Monitor. 8.3.2 Setting up Lotus Extended Search As opposed to the integrated Juru search, which comes with the WebSphere Portal Server install, Lotus Extended Search engine is a separate install. It is strongly recommended that Lotus Extended Search be installed on a separate machine from the WebSphere Portal due to its intensive use of memory. Follow the installation instructions in the Extended Search Installation Guide in the <ES_INSTALL_DIR>/docs/<REGION_CODE>/pdf directory. Here are some tips for a successful Extended Search installation that enables collaboration with WebSphere Portal. Lotus Extended Search can be installed on Domino R5+ Server or WebSphere Application Server. You should install Extended Search on WebSphere Application Server. Be sure to perform the necessary configuration steps on WebSphere Application Server before installing Lotus Extended Search. Chapter 8. Search capabilities 463 You can install Extended Search using Extended Search RMI server or EJB. If you install Extended Search with Extended Search RMI server, you need to install JRE1.2.2. The Extended Search RMI server will not start otherwise. 8.3.3 Creating search sources for Portal The most common search that is performed on a portal is to search the file contents of the Portal. We will first illustrate how this can be done so that you can be more familiar with Extended Search. After this example, other ways of creating Web resource data sources will be discussed. This section serves as a brief introduction to creating resources and demonstrating how a search can be performed on the newly created resources. For information on creating resources, such as datasource resources and LDAP resources, refer to the Extended Search Administration Guide. Step-by-step guide to creating file system resource 1. Open the Extended Search Admin console by typing http://<ES_SERVER>/lotuskms/. You should see a window similar to Figure 8-9. 464 IBM WebSphere Portal V4 Developer’s Handbook Figure 8-9 Extended Search admin console 2. Right-click By Agent and select Discover Data sources. 3. In the Discover Data source window, select File System Sources from the drop-down menu. In the File System Sources panel, select the checkbox of the drive(s) where the file contents that you would like to discover reside. You screen should look similar to Figure 8-10. Chapter 8. Search capabilities 465 Figure 8-10 Discover data sources 4. Click Start Discovery. 5. All the files on the drive selected are displayed in the lower pane. Select the directory where you would like to perform the search and click Add to ES. You should receive a message indicating that data sources are loaded successfully. 6. Repeat Step 5 to add more file resources. Then click Close. 7. On the By Agent view, select the newly added file resource on the right pane. Right-click the resource and select Properties. 8. Select the Mapped Fields tab. Your screen should look similar to Figure 8-11. 466 IBM WebSphere Portal V4 Developer’s Handbook Figure 8-11 Data source properties 9. Click Assign. 10.In the Assign Mapped Field to Data Source window, select the field Title and click OK. 11.Select Title on the Data Source Properties window. Highlight the field DocFileName and click the right arrow. You have now mapped the Title of the file data source to the DocFileName of the native field. Your screen should look similar to Figure 8-12 with the DocFileName under the Title folder. Chapter 8. Search capabilities 467 Figure 8-12 Mapped fields to native fields 12.Select the Parameters tab. Change the SubDirSearch parameter to Yes as shown in Figure 8-13. The sub-directories of your folder will now be searched. Figure 8-13 Data source parameters 468 IBM WebSphere Portal V4 Developer’s Handbook 13.Click Apply. Then click OK. 14.Refresh your domain by right-clicking Search Domain and selecting Refresh Domain. Now we need to verify whether the data source is properly configured for searching. Extended Search provides sample templates which showcase the features of Extended Search. The sample template Demo provides the most comprehensive example for all the features available for Extended Search. 1. In the Extended Search admin console, select Demo under Search Templates. 2. Double-click Demo (JSP 1.1) as shown in Figure 8-14. Figure 8-14 Extended Search sample templates 3. The Extended Search Demo application should be launched in a new browser window. Select the Sources tab. Chapter 8. Search capabilities 469 4. You should see a screen similar to Figure 8-15. Highlight the file resource that you added. Figure 8-15 Source tab for Demo 5. Click the Query tab. 6. Enter a query in the query textbox and click Submit Query. 7. The Results tab should appear showing the links to each searched document. The window should look similar to Figure 8-16. 470 IBM WebSphere Portal V4 Developer’s Handbook Figure 8-16 Search Results Alternatives in creating search resources for Portal contents In many situations, your enterprise might want to enable users to search for information on the intranet sites or other Web sites. In such cases, you need to add Web resources in addition to the preconfigured ones that come with Extended Search. There are three ways to accomplish this. The first approach is to use a toolkit provided by Intelligent Algorithms Enterprises to create a .sbb file. For information on obtaining this kit, refer to the Extended Search Administration Guide. The .sbb file is used to discover and search new Web sources. However, it is required that the target Web sites have a search function. You will then define that search function in the .sbb code. Note that only the URL is returned in the hitList. The second approach is to use Microsoft Index Server, which is included in the Windows Option pack, to index the pages that you would like to search. Then, use Extended Search to set up a search resource on the resulting index. The advantage of this approach is that you can bring back a document Chapter 8. Search capabilities 471 summary from the Index Server along with the URL that would be used to fetch the document. The third approach is to use the Web crawler to crawl Web sites and use a program such as Lotus Discovery Server to index the downloaded data. After the documents are fetched and indexed, you can use Extended Search to search the index. 8.3.4 Writing Web client applications for Extended Search Lotus Extended Search provides a set of fully functional application program interface (API) for creating and configuring searches as well as manipulating the search results. There are mainly two approaches in writing Web client applications: HTML-based or JSP-based. HTML-based Web client applications utilize data beans and a proprietary tag named Java Knowledge Management (JKM) to develop HTML-based Web client applications. A HTML-based version of the Demo application provides an extensive sample of how this approach is used. Refer to page 9 of the Extended Search Programming Guide for a full list of APIs as well as tutorials on this approach. If WebSphere Application Server is used, it is recommended that you use the JSP-based approach. Sample applications are included during the Extended Search install. These applications can be used as a starting point for building customized Extended Search client applications for your enterprise. Extended Search provides collections of Java bean for both JSP 1.0 and JSP 1.1. However, if you are using WebSphere Application Server version 3.5.3 or higher, it is recommended that you use the bean collection for JSP 1.1. Just like the HTML-based Web client application, JSP-based versions of the Demo application provide great samples of how the tags are being used. You can also refer to page 41 of the Extended Search Programming guide for the full list of APIS and tutorials on the JSP-based approach. 8.3.5 Portlets using Lotus Extended Search In most cases, you should install WebSphere Portal on a separate machine from Extended Search. One of the ways to expose the search capabilities is to create a Web service for Extended Search. In fact, you can download the Extended Search portlet from the portlet catalog in the WebSphere Portal Developer Domain at http://www7b.boulder.ibm.com/wsdd/zones/portal which demonstrates this approach. Follow the instructions to install the Web services Web application on the WebSphere Application Server where Extended Search resides and install the sample portlets on your Portal server. Then, configure the portlet so that it points to your Extended Search server. Note that you must install 472 IBM WebSphere Portal V4 Developer’s Handbook Extended Search on WebSphere Application Server in order to use these portlets. The architecture of this approach is depicted in Figure 8-17. Figure 8-17 Extended Search Web services and portlet collaboration 1. The user submits a query via the query page. 2. The portlet receives the query and convert the request into XML. 3. The XML request is transported to the Extended Search Web service on the application server where Extended Search resides. 4. The Extended Search Web service translates the XML/RPC call. 5. The Extended Search Web service makes the appropriate Extended Search API call to the Extended Search engine. 6. The Extended Search engine returns the hitlist back to the Extended Search Web service. 7. The Extended Search Web service converts the response to XML format. 8. The XML response is sent back to the requesting portlet via HTTP. 9. The controller portlet formats the XML data and creates a result page. 10.The results page is presented to the client. Chapter 8. Search capabilities 473 474 IBM WebSphere Portal V4 Developer’s Handbook 9 Chapter 9. Remote portlets This chapter discusses the use of Web Services in a portal environment. After a short overview of Web Services, the concept of remote portlets is introduced. Finally, the use of remote portlets within WebSphere Portal is demonstrated. © Copyright IBM Corp. 2003. All rights reserved. 475 9.1 Portals in the on-demand era A great part of portals deals with integrating existing functionality into an aggregated Web-based interface. Often, similar functions are desired in multiple portals. This can be the case within a company, for example in both the intranet site for employees and in the Internet portal directed toward customers where a product catalog portlet is needed. Portlets such as a news ticker, weather or stock information, etc., are found in many portals. So the same functionality is developed redundantly all over. But even if you use the same existing portlet and deploy it to multiple portals, this might not be the best solution. One issue is maintenance, another the effort of deployment which is still a change in the overall system configuration. Depending on the portlet in question, the fact that the same task is done at different sites may be troublesome as well. The concept of remote portlets, which we introduce in this chapter, allows for one portlet running at a given site to be accessed in multiple remote portals seamlessly and fully transparent to the portal user. Moreover, using some simple administration tasks in WebSphere Portal, a portlet can be made available when it is needed and removed or replaced later on, depending on the needs of the portal operator. In the future, even the user will be able to search and shop for remote portlets. 9.2 Web services The concept of Web services has been developed to allow business applications to communicate and cooperate over the Internet. Web services imply a paradigm shift compared to the way the Internet works today. While traditional applications interacting with services in the Internet need to know those services a-priori and need to be pointed to these peers manually, the Web services concept allows applications to find Web services in a standardized directory structure and bind to these services with minimal human interaction. Web services allow objects to be distributed across Web sites where clients can access them via the Internet. Global service registries are used to promote and discover distributed services. A client that needs a particular kind of service can make a query to the global service registry to find services that suit its needs. The client can select one of the services, bind to that service, and use it for a certain period of time. As service discovery and selection in some cases can be performed without human interaction, services can be switched very quickly. Automated service discovery also allows the establishment of very robust networks of services. If multiple Web services exist that provide identical functions, a client can easily switch to a back-up system if the currently used service fails. 476 IBM WebSphere Portal V4 Developer’s Handbook The most important standards in this area are Universal Description, Discovery, and Integration(UDDI) for registration and discovery of Web services, the Simple Object Access Protocol(SOAP) for communication between Web services, and the associated Web Services Description Language(WSDL) for formal description of Web service interfaces (see also “Web services technologies” on page 478). Roles and operations Service provider Any entity that has a software service and wants to make it available over the Web can become a service provider. It deploys the service(s) to a UDDI registry that makes those services accessible. The functions of a given Web service are described using the Web Services Description Language (WSDL). Publish Publishing and unpublishing involves promoting a service to a registry or removing those entries. When a service is listed in a UDDI registry, it can be discovered and subsequently invoked by the service requestor. Service registry The registry acts as a service broker and helps service providers and service requestors find each other. It provides a UDDI application programming interface to perform the find from a program. There are a number of UDDI registries set up by companies like IBM, Microsoft and HP. Figure 9-1 Roles and operations Chapter 9. Remote portlets 477 Service requestor A service requestor looks for a service it needs by performing a find operation on the registry. When the registry returns results, the service requestor can use these results to bind to a particular service and invoke it. Find The find operation is performed by service requestors and service registry together. The service requestors describe the kinds of services they are looking for, and the registry delivers the results that best match the request. Bind The bind operation takes place between the service requestor and the service provider. After locating a particular service, the requestor can bind to the service using the SOAP protocol. Web services technologies Web services rely on standard transport technologies (such as HTTP) and data encoding techniques (such as XML) to make it easier for applications and devices to share information across the Internet. This interaction uses an XML document to define the interface and describe the service, along with a network protocol (which could be HTTP, SMTP, or JMS). Because neither the service provider nor the service requester knows what platforms or languages the other is using, interoperability is achieved. UDDI (Universal Discovery, Description and Integration) UDDI is a specification for information registries of Web services. UDDI-based registry is where a Web service is discovered. UDDI's approach to discovery is to have a registry of services distributed across the Web. In that distributed registry, businesses and services are described in a common XML format. The structured data in those XML documents is easily searched, analyzed, and manipulated. Currently, there are a number of global registries that allow businesses to find each other across enterprise boundaries. WSDL (Web Services Description Language) WSDL is an XML-based language for describing the interface of Web services. The service requestor can use WSDL to find a compliant service and the service provider uses WSDL to describe the service it is providing. SOAP (Simple Object Access Protocol) SOAP is a joint submission to World Wide Web Consortium (W3C) by IBM and Microsoft, and other industry leaders. It is an XML protocol for exchanging messages and defining how those messages are to be processed. These messages can be sent using standard transport protocols, such as HTTP or HTTPS. 478 IBM WebSphere Portal V4 Developer’s Handbook 9.3 Portals and Web services Web services will become the predominant method for making information and applications programmatically available via the Internet. Portals will exploit this technology. One way to do so is to write portlets which access Web services as any other program can. WebSphere Studio and the Portal Toolkit provide some support for that (1 in Figure 9-2). The other way is known as Remote Portlet where the portlet itself is published as a Web service and can be integrated in a portal through a proxy portlet which uses RPWS as illustrated in Figure 9-2. Web Services Remote Portal Portlet Proxy SOAP/RPWS Inventory Portlet 2 Portlet Proxy Pricing Portlet SOAP/RPWSI Local Portal Search Portlet SOAP/XML 1 1 Pricing Service Search Service SOAP/XML Local Portlet Figure 9-2 Web services in a portal context In the area of remote portlets, standard bodies work to extend the Web services standards to the needs of portals, but on the other hand, WebSphere Portal provides some tooling to put up and use remote portlets based on Web services. Remote portlet standards Web Services for Remote Portals (WSRP) WSRP is a standard for interactive, user-facing Web services that plug and play with portals. WSRP will define: A WSDL interface description for invocation of WSRP services How to publish, find, and bind WSRP services and metadata Markup fragment rules for markup emitted by WSRP services Applicable security mechanisms, billing information and more Chapter 9. Remote portlets 479 Companies involved in WSRP include Bea, Bowstreet, Divine, Epicentric, Factiva, France Telecom, Fujitsu, HP, IBM, Interwoven, Lexis-Nexis, Lotus, Moravia IT, Netegrity, Oracle, Peoplesoft, Plumtree, Silverstream, Stellent, SUN, Sybase, Tibco, WebCollage, SAP Portals and SeeBeyond. See http://www.oasis-open.org/committees/wsrp for details. Web Services for Interactive Applications (WSIA) WSIA states the following goals: Create an XML and Web services centric framework for interactive Web applications that enables businesses to distribute Web applications through multiple revenue channels, and enable new services or applications to be created by leveraging existing applications across the Web. Harmonize WSIA as far as is practical with existing Web application programming models (for example, Portals, Macromedia Flash, etc.), with the work of the W3C (for example, XForms, DOM, XML Events, XPath, XLink, XML Component API task force), emerging Web services standards (for example SOAP, WSDL, WSFL), and with the work of other appropriate business information bodies. Ensure that WSIA applications can be deployed on any tier on the network and remain target device and output markup neutral. Ultimately, to promote WSIA to the status of an international standard for the conduct of XML and Web services-based Web application development, deployment and management. Entities working on WSIA include BEA, Bowstreet, Cisco, Computer Associates, CrossWeave, Cyclone Commerce, Divine, USAF/Dept of Defense, Epicentric, France Telecom, Fujitsu, HP, IBM, Intel, KiNZAN, Macromedia, Nokia, Peregrine Systems, Plumtree, Pointgain Corp, SAP, SeeBeyond, Silverstream, Sterling Commerce, Vitria and WebCollage. See http://www.oasis-open.org/committees/wsia for details. 480 IBM WebSphere Portal V4 Developer’s Handbook (X)HTML WML WSRP Voice XML WSRP/ WSI A Common Base cHTML ... WSIA UDDI WSDL SOAP (Publish,Find&Bind) (Description) (I nvocation) Figure 9-3 Standards overview as seen by the WSRP standards body Besides the WSRP and WSIA which are both independent of programming language, there is also a Java Specification Request (JSP168) on its way through the Java community process (http://www.jcp.org) to define the Java API to WSRP (and similar efforts are undertaken for C++ and .NET). Some of these standards should be out soon, so be aware of the dynamics in this process. Remote portlets in WebSphere Portal Figure 9-4 shows the big picture when portal A publishes a portlet and in portal B this portlet is added to a page and invoked; the subsequent paragraphs provide some details about this process.“Using remote portlets with WebSphere Portal” on page 484 guides you through this process. Chapter 9. Remote portlets 481 Figure 9-4 Remote portlets in WebSphere Portal - The big picture Figure 9-5 Publishing a portlet In this step, administrators make portlets available for use by other portals as remote portlet Web services. Publishing portlets may include two or three steps, depending on whether the portal has already been associated with a business in the UDDI repository. If this is not the case, the administrator has to enter the required business descriptions, publish a business entry to the UDDI directory, and associate the portal with that entry. Once the portal is associated with a business entry in UDDI, publishing portlets only requires two steps: in the first step, the administrator selects the portlet to be published and in the second step, he provides a description for the new UDDI service entry to be created for the portlet. Finding and binding a portlet Finding portlets requires three steps. First, the administrator uses the built-in UDDI browser to find remote portlet Web services and selects one of them. 482 IBM WebSphere Portal V4 Developer’s Handbook Second, he finds the desired portlet provided by the selected business and selects it. Finally, he lets WebSphere Portal Server add the remote portlet to its portlet registry to make it available for portal users. Figure 9-6 Using a portlet Using a remote portlet is as simple as using a locally installed portlet; administrators or users can add the portlet to a page and use it. However, what happens under the cover is a little more complex. Figure 9-7 Remote portlet invocation When a page that references a remote portlet is rendered, the portal uses a portlet proxy to invoke the remote portlet Web service through the WSRP protocol. The portlet invokes the portlet proxy exactly as it would invoke a local portlet, passing PortletRequest and PortletResponse objects. The portlet proxy internally invokes a SOAP proxy to marshal all parameters into a SOAP request and sends it to the remote server hosting the portlet Web service. The SOAP wrapper on the Web service side unmarshals all information in the incoming request and calls on the remote portlet. For the remote portlet, it is transparent whether it is invoked directly by a portal engine or indirectly through the Web service interface. In each case, it processes the input parameters and returns a PortletResponse object. The SOAP wrapper marshals the response into a SOAP response and sends it back as the reply to Chapter 9. Remote portlets 483 the SOAP proxy, which in turn unmarshals the response for the portlet proxy that finally returns a PortletResponse object to the portal engine which initiated the request. 9.4 Using remote portlets with WebSphere Portal In this section, remote portlet architecture in WebSphere Portal is described. 9.4.1 UDDI registry The first step is to decide what registry to use and how to prepare this registry. Public registry There are several public registries available. We give the actual list below; for an up-to-date list, please visit http://www.uddi.org/find.html. Some registries are dedicated to testing usage, you can use them for education, development and testing purposes; the others are reserved for real businesses, publishing or looking for Web Services. Each registry publishes three URLs, one to access the registry using a Web browser and two for programmatical access using an API, one for inquiry and one for publishing. Business UDDI registries Organization Purpose URL IBM Homepage http://uddi.ibm.com Inquiry API http://uddi.ibm.com/ubr/inquiryapi Publish API https://uddi.ibm.com/ubr/publishapi Homepage http://uddi.microsoft.com Inquiry API http://uddi.microsoft.com/inquire Publish API https://uddi.microsoft.com/publish Homepage http://uddi.sap.com Inquiry API http://uddi.sap.com/uddi/api/inquiry Publish API https://uddi.sap.com/uddi/api/publish Homepage http://www.ntt.com/uddi Microsoft SAP NTT Com 484 IBM WebSphere Portal V4 Developer’s Handbook Organization Purpose URL Inquiry API http://www.uddi.ne.jp/ubr/inquiryapi Publish API https://www.uddi.ne.jp/ubr/publishapi Test UDDI registries Organisation Purpose URL IBM Homepage http://uddi.ibm.com/testregistry/registry.html Inquiry API http://uddi.ibm.com/testregistry/inquiryapi Publish API https://uddi.ibm.com/testregistry/publishapi Homepage http://test.uddi.microsoft.com Inquiry API http://test.uddi.microsoft.com/inquire Publish API https://test.uddi.microsoft.com/publish Homepage http://udditest.sap.com Inquiry API http://udditest.sap.com/UDDI/api/inquiry Publish API https://udditest.sap.com/UDDI/api/publish Microsoft SAP Private registry If you make your portlets available only within your organization, you can set up your own private registry. In a development and testing environment, a private registry could be the best choice. The IBM WebSphere UDDI Registry can be downloaded from http://www7b.boulder.ibm.com/wsdd/downloads/UDDIregistry.html. In our scenario, we will use the IBM Test Registry. 9.4.2 Preparing the IBM Test Registry The first time we visit the home page of the registry, we need to register ourselves in order to get a user ID and a password. Once we got these, we can access the registry. We will need two things: 1. A business, since any Web Service has to be associated with a business. a. Log in to the registry using your user ID and password. b. Click Publish -> Add a new Business. c. Enter a name and a description and confirm all your changes. Chapter 9. Remote portlets 485 2. The key of a technical model or tModel for short. The tModel is the UDDI element that contains the technical specifications of a service or, more specifically, a protocol in our case. The protocol used for remote portlets is called RPWS and a registry should contain a tModel with this name. To get this key, find the tModel and display the details (see Figure 9-8 on page 486). a. Click Find in the navigation. b. Select Technical Model from the drop-down list. c. Enter RPWS in the entry field. d. Click the Find button. Figure 9-8 Find RPWS tModel e. Click RPWS in the Technical Model Name column of the result table. If there are multiple results, choose one. In the detail view, you will find the requested tModel key (Figure 9-9 on page 487). 486 IBM WebSphere Portal V4 Developer’s Handbook Figure 9-9 The RPWS tModel key This is a test registry and if you do not want to share your test portlets, you can create your own tModel as described as an alternative solution in the following steps (please do not call it RPWS since this would create confusion; at the time this book was written, there were already two models with this name in the registry). a. Click Add a new Technical Model. b. Enter a name for this model and click Continue. c. Click Add an Overview URL. d. Enter the URL of your Portal and click Continue, then Add. e. Click Save, then continue to get back to your main window, which should look similar to Figure 9-10. Chapter 9. Remote portlets 487 Figure 9-10 UDDI Registry with Business and tModel f. Click the name of your tModel to display the details. 488 IBM WebSphere Portal V4 Developer’s Handbook Figure 9-11 Technical Model Details g. In the Technical Model Details view, you will find the key (marked in Figure 9-11) that will be used in the portal administration. 9.4.3 Configuring the connection to the UDDI Registry 1. To define UDDI registries to WebSphere Portal, select Portal Administration -> Portlets -> Manage Web Services. 2. Click Manage Web Services Portlet and you should see a window as shown in Figure 9-12 on page 490. Your list will still be empty, of course. Chapter 9. Remote portlets 489 Figure 9-12 Manage Web Services Portlet for adding UDDI registry information 3. Click Add. Figure 9-13 Manage Web Services Task The values in this form are all mandatory even though you will not need them all if you just want to use remote portlets from other sources and have no intention of publishing portlets yourself. 490 IBM WebSphere Portal V4 Developer’s Handbook We strongly recommend that you check all values and the spelling. There is no verification by the system and any typographical mistake will later on lead to errors which are very difficult to track down. These are the values for the IBM UDDI Test Registry: – Display name for Registry: IBM UDDI Test Registry – Registry inquiry URL: http://uddi.ibm.com/testregistry/inquiryapi – Registry publish URL: https://uddi.ibm.com/testregistry/publishapi – tModel key:<tModel_key> where <tModel_key> is the key value of the Technical Model in the UDDI registry (see Figure 9-9 on page 487 or Figure 9-11 on page 489, depending on your solution). . Note: If you use a private IBM WebSphere UDDI registry, you will find all the information you need, especially about how to define the tModel key, in the redbook WebSphere Portal V4.1 Handbook, SG24-6883. If you use another registry, please refer to the respective documentation. You can also try to connect to another IBM registry in Austin, Texas. This service runs on an as-is basis, there is no guarantee how long it will be available to the public. Try the following values (including the tModel key below): – Display name for Registry: IBM Austin Test Registry – Registry inquiry URL: http://dwuddi.austin.ibm.com/uddisoap/inquiryapi – Registry publish URL: http://dwuddi.austin.ibm.com/uddisoap/publishapi – tModel key: UUID:30151A70-0D6F-4651-B578-1AE609AA147C 4. Once you furnished the URL information and the key, click OK to register or Cancel to return. 5. If you click OK, you should see IBM UDDI Test Registry added to UDDI Web Services registries in the Manage Web Services portlet. Chapter 9. Remote portlets 491 9.4.4 Publish a portlet to the UDDI registry We will publish the World Clock portlet that comes with WebSphere portal. Later, we will integrate it as a remote portlet into the YourCo portal. 1. Click the Web Services tab. A list of tasks is displayed (Figure 9-14). Figure 9-14 Web Services Tasks 2. Click Provide registry authentication information. Figure 9-15 Authentication selection. 3. Select a registry and click Set authentication. In the next screen, enter the user ID and password your are known by with the registry. Click OK. This step may be not necessary if you use another registry. 4. Back on the Web Services page, click Manage Web Services businesses. 492 IBM WebSphere Portal V4 Developer’s Handbook Figure 9-16 If you see the business you created in the registry, you have managed the first hurdle. Click Done. Tip: The Manage Web Services businesses and the Publish Portlets option automatically connect to the first registry in its registry selection list when the task is opened. To access a different registry, just select it from the drop-down list. The connection is automatically refreshed to the newly selected registry. Even if the correct registry is selected, you may have to reselect it from the drop-down list to force a refresh. 5. Back on the Web Services page, click Publish portlets. Chapter 9. Remote portlets 493 Figure 9-17 Publish a portlet 6. Click the Get portlets link to populate the list of portlets using the well-known administration portlets to publish. Prior to publishing, you can click Edit name and description to modify the corresponding portlet information as it will appear in the registry. 7. Make sure you have selected the correct registry and business. Note: The IBM UDDI Test Registry allows only one business per user, so you have to add the portlet to the existing business. Other registries (for example, the IBM Austin Test Registry) allows you to create a new business along with publishing a portlet from this page. 8. Click Publish. If a message at the bottom says Portlets published successfully (see Figure 9-18), then you have completed the process successfully. 494 IBM WebSphere Portal V4 Developer’s Handbook Figure 9-18 Successful published 9. To remove a portlet from the registry, select the Unpublish portlets task on the Web Services task page. 10.If you now look at the registry in the Web browser, your portlet shows up as a service of your business as shown in Figure 9-19 (click the + sign to expand the list). Chapter 9. Remote portlets 495 Figure 9-19 The published portlet in the registry 9.4.5 Accessing a remote portlet Now we will integrate the published portlet (and another one) into the YourCo portal. 1. Click Integrate a Web Service as a remote portlet from the Web Service page. You should see a window open as shown in Figure 9-20 on page 497. 2. Select the appropriate registry from the drop-down list (IBM UDDI Test Registry in our scenario). 3. Enter the search criterias for the portlets. You have two options when searching for portlets in the selected registry: – Use the List all portlets option if the number of published portlets in the registry is not large. – If there is a large number of published portlets, you should use the List portlets within business option. Before you click the Get businesses 496 IBM WebSphere Portal V4 Developer’s Handbook link, you may want to refine the list of businesses returned by entering a string in the Business name contains field. From the list of businesses returned, select one. In our scenario, we used the Get Businesses command first and selected the List portlets within business option. 4. Click Get portlets to retrieve the list of portlets that match the search criteria. Figure 9-20 Integrate a Web Service as a Remote Portlet 5. Select the portlet(s) you want to integrate in your portal, then click OK. In our scenario, we first added the World Clock portlet we just published, then we added a portlet called YourCo Instructions Portlet that was published by somebody else and happened to work. Be aware that most of the portlets somebody else has published in the test registry will not work for you. Chapter 9. Remote portlets 497 Figure 9-21 Remote portlets to integrate in a page 6. After a remote portlet has been integrated, you can access the portlet in the same ways you would access a locally installed portlet (see Figure 9-21 on page 498), for instance, you can add it to pages, assign access control, choose skins, etc. The name of a remote portlet is prefixed with the string IBM_Proxy. 7. In Figure 9-22, you see the two remote portlets on a YourCo portal page. Figure 9-22 Two remote portlets in the YourCo portal 498 IBM WebSphere Portal V4 Developer’s Handbook You will not find any traces of publishing or integrating remote portals in configuration files; all information is placed in the WebSphere Portal Server database. Figure 9-23 Published and integrated portlet information in the database Chapter 9. Remote portlets 499 500 IBM WebSphere Portal V4 Developer’s Handbook 10 Chapter 10. Personalization This chapter introduces the features of WebSphere Personalization V4.1 and describes its key components. A detailed explanation of the main tools that are used within WebSphere Personalization V4.1 follows as the second part of this chapter. Examples based on the YourCo sample application will show step-by-step how to implement different personalization scenarios in the third part of this chapter. © Copyright IBM Corp. 2003. All rights reserved. 501 10.1 Introduction to personalization If you are not familiar with personalization, this chapter will give you a brief introduction to the concept. Readers who already understand personalization and are focused on the implementation of it may skip the introduction and continue with 10.2, “WebSphere Personalization V4.1” on page 506. 10.1.1 What is personalization Personalization is the individual-directed addressing of a person or group based on well-defined characteristics of that target. As opposed to the personalized approach, general addressing is spread towards a mostly undefined target audience. A simple example clearly demonstrates and differentiates the contrary approaches: An auto maker is sending invitations for a test drive of the newest version of one of his car models as a mailing campaign to customers who bought a car from this toolmaker during the last five years. This would clearly be a personalized action since the individually addressed group was selected based upon one (or more) specific characteristics. If this auto maker showed a commercial on TV to promote the new version of his car model, then this would be general addressing based on the “watering can” principle. Marketing experience proves that personalized campaigns are considerably more effective and efficient than ordinary campaigns. Their main focus is on binding the customer to the company, improve customer satisfaction and enhance customer loyalty, which in the end leads to greater customer value as well as increased return-on-customer for the company. From the above example, the essential key factor for personalization is quite obvious: without an accurate, detailed and up-to-date customer profile, no individual addressing is possible. Another important factor is the communication channel. Personalized communication must be feasible. Classic communication channels supporting personalization are, for example, letters, telephone calls and personal conversation. But the Internet especially, as a modern communication channel with almost unlimited coverage, allows cost-effective and individual communication. In addition, gathering information about customers to build the necessary customer profile is quite easy and can be accomplished at minimum cost and effort. 502 IBM WebSphere Portal V4 Developer’s Handbook Note: The term Internet is used in this context to summarize Internet, Extranet and intranet as to the general approach to personalization; the differences are less important. Transferring the example to a personalized Internet scenario could result in the following: On the Web site of the auto maker, Internet users could register and sign up for a test drive with the new car model. The next time this user comes to the auto maker’s Web site, he will be addressed by his name, get individual information based on the interests he stated when registering as well as on the areas of the Web site he visited so far, combined with special offers for the new car model; he will also be notified if there are promotion events at car dealers in his area. 10.1.2 Planning a personalization solution Let’s look at how personalization of Internet content can be approached in general. Note: When we describe a personalization solution in this chapter, it will refer to Internet-based context only. Personalization of Internet content always follows one basic principle as illustrated in Figure 10-1. Chapter 10. Personalization 503 Figure 10-1 Elements of a personalization system Even though the basic principle is not very complex or difficult in its structure and might seem easy to achieve, you should be aware that a personalization solution which really supports your business will need far more than just some dynamic inserts to your existing Web site. To successfully launch your personalization solution, you should start with a planning phase where you define all the requirements. The most important thing, to begin with, is of course to be clear on the intention and motivation for your solution. The business goals have to be well defined, as well as organizational support processes, other related and required projects and processes. Once you have identified your business requirements and target audience, you need to develop user and content models for your solution. You have to think about the user characteristics you want to use, which content should be personalized and how the presentation of the personalized content should take place. With these steps, you will be able to identify whether you already have the user information and content or if it has to be gathered or created. If the information you need is not available, you should think of how and where to get it. 504 IBM WebSphere Portal V4 Developer’s Handbook For mapping the user to the content, you need to define criteria on which content selection will be accomplished and which matching approach you will invoke. This may enhance your user and content model because you might define additional attributes or metadata (for more on matching types, see 10.1.3, “Matching types” on page 505). Finally, you should reach a decision as to how the presentation should take place. As the Internet offers a wide variety of technologies for presentation of content and interaction with users, this decision will be the basis for the implementation of your solution and will define the technical requirements. After this planning phase, your solution should be well defined and prepared to enter the implementation phase. 10.1.3 Matching types Matching types describe the underlying principle for selecting content for particular (user) attributes or (user triggered) events. There are different approaches to deciding what content to present to the user. User profile-based User profile-based or simple filtering is used to display content based on predefined groups or user profiles. For example, a user registers on the portal and selects which news feeds he is interested in. The displayed content would then be personalized according to these attributes. Rules-based Rules-based personalization is used to display content on predefined business rules. The business rules usually provide segmentation on user characteristics to classify the individual user. For example, if the user has an income of over USD 50 000, he qualifies as a gold customer and gets special discounts or offers. Collaborative filtering Collaborative filtering is used to display information based on a combination of preferences from the specific user and like-minded users. For example, if a user is searching for a particular product on your portal, then you could display a list of related products that other users also looked at when originally searching for the same product. User profile and rules-based personalization are easier to implement and apply to most Web sites. Collaborative filtering is most effective when used by Web sites with a large number of users because when you have established a large user base, you can effectively combine preferences of a individual user and like-minded users to make recommendations. Chapter 10. Personalization 505 Note: In this redbook, user profile-based and rules-based personalization are used. For information on collaborative filtering based personalization, refer to the LikeMinds Recommendation Engine user documentation and the WebSphere Personalization Solutions Guide, SG24-6214. 10.1.4 Implementing a personalization solution Implementing a personalization solution can get quite complex, as you may have to create access to the numerous resources involved, usually located in a wide range of data stores, implement the matching approach, which could consist not only of many different cases and attributes but also of numerous different matching hierarchies and steps, and finally create the dynamic content presentation, which will usually not include just a couple of pages but, indeed, the whole Web site. To implement a personalization solution according to complex requirements and to be able to manage, track and continuously improve the personalization solution, you could use software products like IBM WebSphere Personalization to benefit from the wide variety of features and reduce your development effort. In the following chapters, we will introduce WebSphere Personalization V4.1 and demonstrate how to use the included tools for building individual information on Web sites; we will focus especially on portal Web sites and portlets by implementing some sample scenarios for a personalized version of the YourCo Sample Application. 10.2 WebSphere Personalization V4.1 As part of the WebSphere product family, WebSphere Personalization is designed to fit seamlessly into IBM’s software platform for e-business to provide maximum value for the customers. The WebSphere product family and the placement of WebSphere Personalization as a foundation extension component is shown in Figure 10-2. 506 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-2 WebSphere product family IBM WebSphere Personalization for Multiplatforms, Version 4.1 provides an integrated set of tools to enable you to successfully build and run personalized Web sites. The tools included in WebSphere Personalization can be distinguished between development tools, runtime components and administration tools. For development, the plugin for WebSphere Studio provides the following wizards: Content Wizard You can use the Content Wizard to create content resources from relational databases. User Wizard To create user resources for lightweight directory access protocol (LDAP) directories and relational databases, you can use the User Wizard. Content Spot Wizard You can use the Content Spot Wizard to create the classes for your content spots. To build the class for the content spot, you have to know about the content type which will be returned. Chapter 10. Personalization 507 HRF Editor The HRF Editor allows you to create application objects and define resource collections within WebSphere Studio. The Personalization runtime components reside on the application server and include three engines: Resource engine Enables the personalization system to query databases of profiles and content through Java interfaces at runtime. These interfaces normalize the differences between databases so that the personalization system can locate and retrieve the content. The resource engine also allows content and profiles to be grouped under categories to facilitate the segmentation of site visitors and targeting of content. Rules engine The rules engine provides the execution environment for the business rules. At runtime, the rules engine evaluates the business rules defined for a Web page by retrieving a user’s profile, mapping it against the specified rules, evaluating if the conditions of the business rule are met and retrieving the content defined by the business rule. The content is then returned to the WebSphere Application Server, which assembles the Web page for serving to the site visitor. Recommendation engine WebSphere Personalization’s recommendation engine is a collaborative filtering system that can uses multiple inputs, including individual clickstream data, purchase history and content similarities; the recommendation engine provides content and product suggestions. Trends from the behavior of site visitors are extracted based on sophisticated statistical techniques. You can adapt to changing trends in visitor interest without having to create new business rules. The WebSphere Personalization V4.1 utilizes LikeMinds Personalization Server and Recommendation Engine V5.2.1 collaborative filtering technology. Java-based APIs are provided for database creation, access and applications integration. Figure 10-3 illustrates the Personalization runtime environment. 508 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-3 Personalization Runtime environment Note: In this redbook, rule-based personalization is used. For information on collaborative filtering-based personalization, please refer to the LikeMinds Recommendation Engine user documentation and the WebSphere Personalization Solutions Guide, SG24-6214. Running on the application server, the Personalization administration tools are: Resource console (PersAdmin) – Enable or disable logging of user activity – Delete campaign data – Add security mappings – Add and manage resource collections and hierarchies – Add and manage Web application objects (session objects) that you want your personalization solution to access Personalization Workspace (PersWorkspace) The Personalization workspace is the Web browser-based interface that provides you with integrated access to tasks such as creating, editing and managing rules, campaigns, e-mail campaigns and previewing. Chapter 10. Personalization 509 10.2.1 Personalization V4.1 key features Personalization workspace Business managers can use this browser-based tool to easily control and preview the personalization behavior of a Web site. The control function of the Personalization workspace allows you to work with WebSphere Application Server and your Web browser to design and create personalization rules. You can create rules using conversational language in easy-to-use editors. The interactive preview function enables you to create, edit or change rules on the fly. You can also see how the rules you create affect the various visitors to your Web site. You can also create campaigns for your Web site and include personalized e-mail, defining the recipients and content accordingly by using personalization rules. Campaign management This Personalization workspace component gives business managers the ability to control time-delimited personalized Web site content, and personalize e-mails targeted for specific segments of the audience. Multiple campaigns can be implemented simultaneously. Each campaign can target any or all of the personalized areas of a site. The e-mail campaigns can use business rules to define dynamic lists of e-mail recipients and personalize e-mail content. Rule and campaign effectiveness You can integrate WebSphere Personalization and WebSphere Site Analyzer to more accurately personalize content for your intended audiences. Reports allow you to gauge campaign and rule effectiveness, update user profiles, modify business rules accordingly and help ensure that your personalized site is meeting your business objectives. Implicit profiling You can develop site visitor profiles in real time and personalize content, based on visitor activity, while the visitor views the site. Implicit profiling allows you to log information about the content that a Web site user views. You can use this information in real time to modify the content that is shown, which makes the site more responsive to each visitor’s interests. You can also update the visitor’s profile so that it is current when the visitor returns to your site. Content that is viewed can be tracked at the individual and group levels. Wizards for WebSphere Studio WebSphere Studio is an integral part of WebSphere Personalization, and not just as a tool for creating HTML, JSP pages and servlets. The User and Content resource wizards have been enhanced for Personalization V4.1 features. A new Content Spot wizard marks positions on Web pages where personalized content 510 IBM WebSphere Portal V4 Developer’s Handbook can be defined by the business manager. A new Resource editor allows you to quickly edit your .hrf files. Enhanced and expanded rule functions Exclude content: allows you to filter a subset of a set of selected content. Limit: allows you to specify the maximum number of items to be returned. Browser capability resource: allows you to personalize content based on the browser your Web site visitor is using. Nested properties: allows you greater control and more flexibility regarding your resources. Support for rules to be used within non-HTTP session invoked programs. 10.2.2 Integration with WebSphere Portal Server WebSphere Portal allows users to customize the appearance of their portal pages according to personal preferences. The customization is accomplished partly through administrative setup, which defines the default settings and access rights to portlets. Further customization is accomplished through explicit user actions to change the contents and layout of the portal pages. The WebSphere Personalization goes beyond page customization and adds the capability of providing individual information to specific users. However, WebSphere Portal invokes and manages user profiles to enable customization. These user profiles are shared between Portal and Personalization, facilitating the tight integration of both products. In other words, the User bean class of the WebSphere Portal is already enabled for use in WebSphere Personalization. Portlet JSP views can easily be modified to work with Personalization and use content spots, rules and recommendations to dynamically present individual personalized content. Rules and recommendations can also be used in the layout JSP templates or in the page customizer JSP to provide personalization of the portal far beyond the possibilities of Portal customization. Companies that have already used WebSphere Personalization to create personalized Web pages can take advantage of the JSP portlet to reuse their existing JSP pages. The content model and the user profile are also highly reusable. If there is no existing user profile resource class, the one supplied with Portal is already enabled for use with Personalization and will speed up development. If there is an existing user profile resource class, then using the same LDAP repository for both Personalization and Portal ensures that the user identity information is consistent. Chapter 10. Personalization 511 Since Personalization is highly integrated with WebSphere Portal Server and provides a tremendous business value, all of the WebSphere Portal offerings (Enable, Extend, Experience) include WebSphere Personalization. 10.2.3 Integration with WebSphere Content Publisher Also, WebSphere Personalization is highly integrated with WebSphere Content Publisher (WCP), as WebSphere Content Publisher not only uses the same concept of resources and the same resource engine of Personalization, but also the Personalization Content Wizard for WebSphere Studio to create content resources. For more information on Personalization in WebSphere Content Publisher refer to Chapter 11, “Content management” on page 637. 10.2.4 Runtime rule processing At runtime, a personalization content spot bean located in a JSP or servlet will search for the assigned rule to fill the spot with personalized data. Which rule to use depends on the campaigns that have been set up to execute at the time of the request. The rule mapped to the content spot in the campaign with the highest priority will be executed. Rule processing results in a set of resources or a classification being returned. The returned resources or classification can be used for generating the dynamic, personalized content for the response. Figure 10-4 illustrates how a Personalization rule is processed. 512 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-4 Runtime rule processing in Personalization 1. Step A: The process begins when a user requests a Java Server Page (JSP) or servlet in which a content spot bean has been embedded. When the Web server receives the client request for the JSP or servlet, the request is passed to the WebSphere Application Server, which then invokes its JSP or servlet processor. 2. Step B: When the embedded content spot bean is invoked, the processor passes the HTTPServletRequest object to the content spot bean. The client request is used to initialize the Personalization context. The content spot bean properties are retrieved in the same manner as retrieving properties for any JavaBean.The Personalization context provides access to the resources needed for rule processing and invokes the Personalization resource engine. The Personalization context is in the JVM for the duration of the HTTP request. 3. Step C: The content spot bean invokes the Personalization rules engine to process the rule. The getRuleContent method of the content spot bean determines the appropriate rule to execute based on campaigns having a rule mapped to the spot. The rules engine is an implementation of IBM Business Rule Beans (BRB). BRB provides runtime and development frameworks for applications that externalize business rules. Within WebSphere Personalization V4, there are no APIs for the BRB rules engine (APIs are defined in the full stand alone BRB product.). However, you Chapter 10. Personalization 513 can enable a rule audit function that provides details about the execution paths and results of processing a selected rule. 4. Step D: The rules engine processes the rule to obtain the results of the rules execution. 5. Step E: The rules engine returns the result of the rule execution to the content spot bean. The result can be a list of valid content, a string, a boolean value, or no results. The content spot can only return personalized data of a single type which has to be defined as the content spot class is created. Web developers do not need to know where or how the content is retrieved, only that content of the specific type will be returned containing a set of properties to be displayed. Finally, the Web server forwards the page to the client. 10.3 Personalization API This chapter will provide a description of the most important classes of Personalization API. If you use the wizards for WebSphere Studio Application Developer, you will find the described interfaces implemented in the generated code. For details on programming with other development environments or a better understanding of the generated classes, we have listed the APIs used to access user and content data in customer data stores. For a complete Personalization API listing, please refer to the Personalization API Javadoc, which is available at: http://www.ibm.com/software/webservers/personalization. 10.3.1 Resource interface The interface com.ibm.websphere.personalization.resources.Resource enables the mapping of your user model, content model, or other resource model to data in your customer data store. Table 10-1 Interface com.ibm.websphere.personalization.resources.Resource 514 Method Explanation getId() Returns the primary key or identifier for this resource. The primary key must be a string and unique within the resource collection. get(String name) Returns the value of the specified dynamic property for this resource. IBM WebSphere Portal V4 Developer’s Handbook Method Explanation keys() Returns all (an Enumeration) of the property keys associated with this resource. put(String name, Object value) Sets the specified dynamic property for this resource. remove(String name) Removes the specified dynamic property. In addition to the methods listed in this table, your implementation must contain methods for setting and getting each fixed property in the data model. For example, if your user model includes a fixed property userName, you would define the methods getUserName() and setUserName(). Personalization V4.0 rules support nested method calls. Suppose your Resource interface implementation defines a user object with a fixed property employer for which there is a fixed property name. With WebSphere Personalization V4, it is now possible to use nested method calls like user.employer.name to make properties accessible to rules. Note: The WebSphere Studio Wizard for user and content resources implement the IMVResource interface. The IMVResource interface extends the Resource interface and supports multi-value properties. 10.3.2 IMVResource interface The com.ibm.websphere.personalization.resources.IMVResource interface extends the Resource interface and enables mapping multi-value properties. Table 10-2 Interface com.ibm.websphere.personalization.resources.IMVResource Method Explanation setMultiValueUtils(IMultiValueUtils instance) Saves the reference to the instance of MultiValueUtils. That reference is used when invoking the fillinMultiValueProperties method of the MultiValueUtils class. This method does not return output. addMultiValuePropertyValue(String propertyname, Object propertyvalue) Enables the IMVResource instance to get values for multi-value properties. This method does not return output. Chapter 10. Personalization 515 Note: The WebSphere Studio Wizard for user and content resources implement the IMVResource interface. The IMVResource interface extends the Resource interface and supports multi-value properties. 10.3.3 MultiValueUtils interface The interface com.ibm.websphere.personalization.resources.IMultiValueUtils is a set of utilities for retrieving multi-value properties when those resources are in a database. This class supports mapping multi-value properties to the corresponding database tables. Table 10-3 Interface com.ibm.websphere.personalization.resources.IMultiValueUtils Method Explanation convertSQLtoMultiValue(String query) Converts the SQL query string for ResourceManager classes that need to search on single value and multi-value properties. Returns an enumeration that contains the converted WHERE clause followed by one or more elements that contain the table names that are involved in the query. fillinMultiValueProperties(IMVResource theResource) Retrieves the value for all multi-value properties and calls the addMultiValuePropertyValue method of IMVResource. This method does not return output. fillinMultiValueProperty(IMVResource theResource, String propertyName) Retrieves the value for all single value properties and calls the addMultiValuePropertyValue method of IMVResource. This method does not return output. assignMultiValueProperty(IMVResource theResource, String propertyName, Vector values) Populates the multi-value property into the resource repository. 10.3.4 ResourceDomain2 interface The com.ibm.websphere.personalization.resources.ResourceDomain2 interface enables you to query and select resources based on fixed properties. The access is read only mode. Like the Resource interface, ResourceDomain2 generally applies to resources. 516 IBM WebSphere Portal V4 Developer’s Handbook ResourceContext is an object created by you in your JSPs or servlets and allows you to pass information to your resource classes. The resource engine adds the current user's ID to the ResourceContext with the key of ResourceContext.UserID. Table 10-4 Interface com.ibm.websphere.personalization.resources.ResourceDomain2 Method Explanation findResourcesByProperty(String name, String value, ResourceContext context) Returns the resource whose identifier is specified. When you add a resource to a resource hierarchy, you specify a resource ID that is used internally and as a visible label when the resource is displayed in the Resource Console. You determine the resource ID. The resource ID does not correspond to a property in the resource schema (data model), but mapping to a property of the resource is permitted. findResourcesByProperty(String name, String value, ResourceContext context) Returns all (an Enumeration) of the resources with properties having the specified name and value. findResourcesByQuery(Query query, ResourceContext context) Uses the specified query object to return all (an Enumeration) of the resources. The query is the equivalent of the WHERE clause in a SELECT statement in a rule. Although the syntax matches the SQL where clause, the ResourceDomain2 implementation might need to convert the property names (specified in the input string) to column names used in the database. Conversion is not required if the property names match the column names. Note: The ResourceDomain interface of V3.5.x is deprecated in V4.x and will be removed in the next release. It is replaced by the new ResourceDomain2 interface described here. 10.3.5 ResourceManager2 interface The com.ibm.websphere.personalization.resources.ResourceManager2 interface supports updating, adding and deleting resources (of type Resource) in the customer data store. Chapter 10. Personalization 517 ResourceContext is an object created by you in your JSPs or servlets and allows you to pass information to your resource classes. The resource engine adds the current user's ID to the ResourceContext with the key of ResourceContext.UserID. Table 10-5 Interface com.ibm.websphere.personalization.resources.ResourceManager2 Method Explanation add(Resource resource, ResourceContext context) Adds the specified resource to the customer data store. Throws the AddResourceException and DuplicateResourceException. delete(Resource resource, ResourceContext context) Deletes the specified resource from the customer data store. Throws DeleteResourceException. When getting the resource, Personalization locks the resource until the sync() method is called or time out. getForUpdate(String id, ResourceContext context) Gets the resource with the specified identifier (resource ID). sync(Resource resource, ResourceContext context) Synchronizes the changes. Throws ResourceUpdateException. 10.3.6 AuthIDTranslator interface The interface com.ibm.websphere.personalization.security.AuthIDTranslator is included in the JAR file prCommon.jar and provides translation functionality for the user ID when Personalization is installed on WebSphere Application Server with global security enabled. Table 10-6 Interface com.ibm.websphere.personalization.security.AuthIDTranslator Method Explanation translateAuthID(String id) Receives as input the user ID and returns the corresponding resource ID (string). 10.3.7 BaseResource class The com.ibm.websphere.personalization.resources.BaseResource class enables user applications to access the Personalization database to obtain the dynamic properties that a resource inherited from groups. If your Personalization solution uses resource hierarchies and your customer data store contains dynamic properties for users, content, or other resources, this class enables your 518 IBM WebSphere Portal V4 Developer’s Handbook user applications to access any dynamic properties in the Personalization database. Note: Groups and Dynamic Properties stored by the Personalization database are deprecated in Personalization V4.x and will be removed in the next release. The BaseResource class implements the Resource interface. To make use of the BaseResource class, create a class that implements the Resource interface and extends the BaseResource class. The BaseResource class provides three constructors: BaseResource() supports serialization and the need for a null constructor to support Class.forName. BaseResource(String node, String rh) passes the primary key of the resource and the name of the resource hierarchy with which the resource is associated. BaseResource(String node) passes only the primary key of the resource and sets the resource hierarchy identifier to null. You specify the resource hierarchy elsewhere, for example in the add() method of your ResourceManager implementation. This constructor is useful when you use the same Resource implementation in multiple resource hierarchies and you want to use the same BaseResource instance in both hierarchies. Table 10-7 Class com.ibm.websphere.personalization.resources.BaseResource Method Explanation get(String name) Returns the specified dynamic property associated with the resource. If the dynamic property is not defined explicitly for the resource, this method returns any of the inherited (coalesced) dynamic properties for the resource. getId() Returns the primary key or identifier for this resource. keys() Returns all (an Enumeration) of the dynamic property keys associated with this resource, including inherited properties. getResourceHierarchyId() Returns the unique name of the resource hierarchy with which the resource is associated. Chapter 10. Personalization 519 Method Explanation setResourceHierarchyId(String id) Sets the name of the resource hierarchy with which the resource is associated. Used when the BaseResource class is instantiated with the constructor BaseResource(String node). setPropsInternal(Boolean value) Sets the property that indicates whether dynamic properties set using the Resource Console are stored in the Personalization database or the customer data store for user and content resources. arePropsInternal() Returns a Boolean that indicates whether dynamic properties are stored in the Personalization database or the customer data store for user and content resources: If true, the put and remove methods described below perform an action. If false, you must extend the put and remove methods. You do not call super.BaseResource and you write your own implementations of the put and remove methods. put(String name, Object value) See the explanation of the arePropsInternal() method. remove(String name) See the explanation of the arePropsInternal() method. 10.3.8 Generic query framework The generic query framework enables resource domain developers to convert a property-based query object into a language specific executable query string. It contains query component classes, and builder and callback interfaces. Query component classes, such as Query, Predicate, provide object representation of a query. Builder and callback interfaces together facilitate a query string generation mechanism that delegates operations to domain specific callbacks for property-to-attribute resolution and query string syntax conversion. Using the generic query framework in personalization The resource engine constructs a generic query object and passes it to domain developers via the ResourceDomain2 interface method findResourceByQuery(). 520 IBM WebSphere Portal V4 Developer’s Handbook The developer can take one of the following approaches to convert this query object into a meaningful domain query string. 1. Walk through the query object The com.ibm.websphere.query.base.Query class contains query components that the developer can traverse through to generate domain specific query string. 2. Use a system provided builder callback Personalization ships three builder callbacks: – SQL (com.ibm.websphere.query.callbacks.SqlSelectQueryCallback) – LDAP (com.ibm.websphere.query.callbacks.LdapSelectQueryCallback) – EIP (com.ibm.websphere.query.callbacks.EipSelectQueryCallback) Property resolution and query syntax conversion are handled in the callbacks. The developer can prepare a property mapping hash table and use it with one of the callbacks above to build the executable query string. Here is the sample code for SQL query string generation: String s=q.buildString(new SqlSelectQueryCallback(h)); where q is a query object, and h is a property mapping hash table. 3. Develop and use a domain specific builder callback If the system provided builder callbacks do not satisfy resource domain requirements, a domain specific builder callback can be created and used as long as it implements ISelectQueryCallback. The developer can decide on the mechanisms to interpret properties and derive the proper query syntax in their own callbacks. The code would look like this: String s=q.buildString(new MySelectQueryCallback(myParameter)); where q is a query object, and MySelectQueryCallback is the custom builder callback that takes myParameter as parameter. 10.3.9 ResourceContext class The com.ibm.websphere.personalization.resources.ResourceContext class can be used to pass information from your program to your resource class implementation. For example, you might construct a resource collection that does special processing based on the user ID of the current user. Your JSPs or servlets can set the user ID in the resource context, and then the rules engine will pass this context to your resource classes when they are called. Chapter 10. Personalization 521 Table 10-8 Class com.ibm.websphere.personalization.resources.ResourceContext Method Explanation getPropertyValue(java.lang.Object propertyName) Retrieves objects from the ResourceContext. setPropertyValue(java.lang.Object propertyName, java.lang.Object propertyValue) Store objects in the ResourceContext. If your resources use the resource context object (ResourceContext), then your application must: Check whether the ResourceContext already exists on the session, and instantiate the ResourceContext object if it does not exist and reference from the session object Set the value or values that are required by your resource implementation Note: Other applications or services might be setting values within the ResourceContext, so you should check to see if an instance of the resource context already exists before creating your own instance. 10.3.10 RuleTrigger class The com.ibm.websphere.personalization.resources.RuleTrigger class used to trigger an Accessible Business Rules (ABR) rule that corresponds to the personalization binding-type rule. ABR is the Personalization rules engine component to separate their business rules from your application logic. Typically, the RuleTrigger class makes resources available through an indexed content property. The RuleTrigger class will initialize the ABR Trigger Point Framework if it has not already done so, using the InitialContext it obtains from the PersonalizationContext. In relation to content spots, the most important methods of the RuleTrigger class are as follows. Table 10-9 Class com.ibm.websphere.personalization.resources.RuleTrigger 522 Method Explanation getClassifications() Returns the full set of applicable classifications in an array. getClassification(int which) Provides access to the indexed classification property. IBM WebSphere Portal V4 Developer’s Handbook Method Explanation getContent() Returns the full set of content for the applicable rule. getContent(int which) Used to obtain the indexed content object identified by which. getPreviewAnchorTag() Returns a string which represents the preview anchor link for PersWorkspace. getRuleName() Returns the name of the applicable rule. isClassifiedAs(java.lang.String c) Returns true if the designated classification is applicable in the business context captured in the named classifier. setRequest(javax.servlet.http.HttpServlet Request sr) Invoked by the jsp to give us the servlet request so that we can obtain the Personalization context. 10.4 Using WebSphere Personalization components The WebSphere Personalization components that are most important for implementing your Personalization solution are: Resource Console Personalization Workspace Wizards for WebSphere Studio In the following sections, we will describe these components in detail. In addition, we included some important configuration aspects regarding the Personalization Runtime which you might consider. 10.4.1 Personalization Runtime During the installation, Personalization Runtime will be added to the specified application server as enterprise application. Within Personalization Runtime, you will find the Personalization Resource console as Web module PersAdmin. Personalization Runtime also uses its own JDBC driver instance and datasource for accessing the Personalization database specified during installation. They can be found in Resources -> JDBC Providers -> Pers DB Driver -> Data Sources in the WebSphere Application Server Admin Console. However, for e-mail campaigns, a separate enterprise application Personalization Email will be installed on the application server. This application Chapter 10. Personalization 523 will only be accessed by the runtime and has no user interface other than PersWorkspace. Personalization Email uses Java Mail sessions to send e-mails. Therefore, a Java Mail Session is created during the installation with properties which have to be configured, if you want to use the e-mail campaign feature of Personalization. Figure 10-5 shows a Personalization Java Mail Session sample configuration. Figure 10-5 Java Mail Session properties for Personalization Runtime emailconfig.xml An e-mail trigger notifies the system when to send the e-mail. The default e-mail trigger checks mail every 60 minutes to see if an e-mail campaign needs to be processed. You can set the trigger delay for sending e-mails generated by your e-mail campaigns by entering the delay in minutes in the emailconfig.xml. This file can be found at <was_root>/personalization/pnzConfig. The default trigger delay for e-mail is set to 60 minutes as shown in Example 10-1. Example 10-1 emailconfig.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE personalizationConfigurator SYSTEM "PznEmailconfig.dtd"> 524 IBM WebSphere Portal V4 Developer’s Handbook <emailDescriptor emailTimerStartDelay="60" emailTimerDelay="60" > </emailDescriptor> If an e-mail cannot be sent (because of a mail server, network problem, etc.), the system will attempt to send the e-mail in the next trigger. All active campaigns that have a start time less than the current time will be sent. persconfig.xml To be able to publish resources from WebSphere Studio to Personalization Runtime, the user/role mapping for Runtime have to be set in WebSphere Application Server. In the Admin Console, go to Enterprise Applications -> Personalization Runtime and select the User/Role Mappings tab. The entries should look like those displayed in Figure 10-3. Figure 10-6 Personalization Runtime user/role mapping in WebSphere Application Server In addition to mapping users to the security roles defined in the Personalization Runtime ear, you must also define a userid and password for the runtime cache thread and the e-mail dispatcher to use. These must be supplied as shown in Example 10-2. Chapter 10. Personalization 525 Example 10-2 persconfig.xml <websphere-personalization> <database> <schema>PZNADMIN</schema> <datasource>persDS</datasource> <userid>db2admin</userid> <password>thePassword</password> </database> <runtimeRoleUser> <userid>wsdemo</userid> <password>wsdemo1</password> </runtimeRoleUser> </websphere-personalization> As with the database information, you can use an obfuscated password. The file is located in <was_root>/personalization/pnzConfig. databaseAccess.config The resource classes generated by the WebSphere Studio wizards include database specific properties and values for userid, password, driver, URL, and datasource. However, database access information may differ as the Web site moves from server to server through staging, for example, from a development server to a test server, then to a production server. Therefore, you can define these values in an external configuration file which will be used instead of the properties and values inside the generated code. The external configuration file is called databaseAccess.config. The default databaseAccess.config file is shown in Example 10-3. You will find this file installed with Personalization in the <was_root>\personalization directory . Example 10-3 databaseAccess.config #Database access config #This file must be placed in the <was install root>\bin directory to be picked up. #In the commented example, the Companynews will use the Companynews qualified fields. All #other classes will use the userid and password fields for userid and password respectively #and for their other fields they will use their class specified instance variables. 526 IBM WebSphere Portal V4 Developer’s Handbook #userid=db2admin #password=db2admin #Companynews.userid=wsdemo #Companynews.password=wsdemo1 #Companynews.driver=COM.ibm.db2.jdbc.app.DB2Driver #Companynews.url=jdbc:db2:sample #Companynews.datasource=jdbc/jdbcdb2sample To invoke the databaseAccess.config file, copy it to the <was_root>\bin directory. Uncomment the lines you want to use and change the properties and values to reflect your specific database access information. In the default databaseAccess.config, Companynews is an example of a resource for which the values generated by the wizard would be overridden. You can create an entry for each specific resource, or use an unqualified key for a global override. At runtime, the resource engine checks for values in the following order, and will use the first one it finds: 1. A qualified value in the databaseAccess.config file (for example, Companynews.userid=wsdemo) 2. An unqualified value in the databaseAccess.config file (for example, userid=db2admin) 3. A value specified in the ResourceManager class, as generated by the wizard 10.4.2 Resource Console You use the Resource Console to define resource collections and resource hierarchies. For all resources created with WebSphere Studio wizards, resource collections will be created automatically for you. You can use the same resource collection in more than one resource hierarchy. However, you cannot use the same resource classes in more than one resource collection. Personalization is installed such that each application server has its own Personalization rules engine and related components. When you create a resource collection, you must assign it a unique name. That name must be unique among all of the resource collections for that Personalization resource engine, because all of the collections share a common, flat, case-sensitive namespace called the resource collection namespace. The namespace includes names for resource collections, resource hierarchies and resources. Group names and dynamic properties are stored per resource hierarchy and are not global to the namespace. Chapter 10. Personalization 527 In cases where application servers participate in a cluster, you would likely use the same Personalization namespace on each server in the cluster. Depending on the cluster design, you might also have some namespaces that are on some (but not all) of the servers in the cluster. If the namespaces differ among the clustered application servers, be sure to specify the correct Personalization database during the installations on the cluster machines. In such cases, the same Personalization database would not be used for each machine. To use the Resource Console, enter the following URL in your Web browser: http://<host_name>/wps/PersAdmin/adminframe.jsp If your application server has security enabled, you might be prompted for a username and password. The Resource Console will look like that shown in Figure 10-7. Figure 10-7 Personalization Resource Console The Resource Console consists of five main categories (Resource Collections, Resource Hierarchies, Application Objects, Campaigns, Log Settings, Security), accessible through the tabs in the top navigation bar. 528 IBM WebSphere Portal V4 Developer’s Handbook Resource collections In Personalization, a resource collection specifies a customer data store that contains user, content, or other resources for your Personalization solution. When you add a resource collection, you map to a customer data store by identifying the Java classes used to access the resources. You cannot specify the same resource access classes in more than one resource collection definition. Be sure that the resource access classes are in the Web application classpath and the application server classpath. The classes must be in the application server classpath to enable the Resource Console to verify the classes when you add this resource collection. Adding a resource collection 1. Click the Resource Collections tab. The task buttons for resource collections will appear. 2. Click the Add button. The parameter input fields will appear as shown in Figure 10-8. Figure 10-8 Resource Console: adding a new resource collection 3. Specify the values for the new collection as explained in Table 10-10. Chapter 10. Personalization 529 Table 10-10 Parameter for new resource collections Parameter Explanation Collection Name The unique name you want to assign to this resource collection. Because Personalization uses a common namespace, the name must be unique among all of the collections you will use on this application server. The name is case-sensitive. Single quote and double quote characters are not permitted. Resource Type Specifies the type for this resource collection. Select a type from the list or type a user-defined type in the input field. The predefined types are user and content. Resource Class The Java class that defines the resource in the collection. Typically this would be the plain class you created for your resource using WebSphere Studio User or Content wizards. You have to specify the fully qualified name of your class. Resource Domain Class The Java class that is used to search your customer data store in read only mode for resource data. If you created your resource with the WebSphere Studio wizards, this would be the resourcenameManager class, otherwise the class implementing the ResourceDomain2 interface. You have to specify the fully qualified name of your class. Resource Manager Class The Java class that is used to add, delete and retrieve resources in the customer data store. If you created your resource with the WebSphere Studio wizards, this would be the resourcenameManager class, otherwise the class implementing the ResourceManager2 interface. You have to specify the fully qualified name of your class. 4. To add the collection, click the Create Collection button. To return without adding the collection, click the Cancel button. 530 IBM WebSphere Portal V4 Developer’s Handbook After the resource collection is created, its name will appear in the list of collections. If you decide to change the name of the collection after you create the collection definition, you must delete the collection and create another one with the new name. Viewing a resource collection You can view the specified resource collections and their properties by selecting the target collection in the Collections list (and clicking the View button). The information about the selected resource collection appears, including the collection name, the Java classes used to access the resources in the customer data store and the resource type as shown in Figure 10-9. Figure 10-9 Resource Console: information on existing resource collection When you view a resource collection, the parameters are viewable but not editable. After you add a resource collection, you cannot modify the collection. If you need to modify a collection to change the Java classes, you must delete the collection and create a new one. Assign the new collection the same name as the deleted collection, if you have created resource hierarchies and Personalization rules based on the deleted collection. Deleting a resource collection When you delete a resource collection, the collection definition is removed from the Personalization database and Personalization cannot use this resource collection anymore. Chapter 10. Personalization 531 Consider the following points before you delete a resource collection: If you delete a collection, any hierarchies based on that collection will be automatically deleted. If you delete a resource collection and there are resource hierarchies built on the deleted collection, any Personalization rules based on the deleted resource hierarchies will not work correctly. If you are deleting the resource collection so that you can change the name of the collection, you should perform the deletion as part of this sequence of steps: a. Export the Personalization resources to an export file. b. Delete the resource collection as described below. c. Create a new collection with the new name. d. Import all of the Personalization resources, except the deleted resource collection, from the export file. To finally delete a resource collection select the target collection in the Collections list and click the Delete button. Then click the Yes button to confirm the deletion request or the B button to stop the deletion. Resource hierarchies Note: Resource hierarchies are deprecated in Personalization V4.0. You may continue using them, but should not start to use them in V4.0, since support for resource hierarchies will be removed in a future release. A resource hierarchy facilitates Personalization by naming collections of resources. Personalization rules refer to a resource hierarchy name to identify the user and content data (the resource collection). Creating resource hierarchies is also a method of categorizing user profiles and content resources. The resource hierarchy is stored in the Personalization database, not in your customer data store where the user and content resources are stored. A resource hierarchy is a tree-structured collection of leaf nodes and group nodes where leaf nodes represent resources and group nodes represent groupings of resources. It is up to you to determine the groupings in your hierarchy. In most cases, resource hierarchies are based on user or content data. However, you can create hierarchies that are based on other types of data. Optionally, you can assign dynamic properties to groups and leaf nodes. A dynamic property can be retrieved using the explicit property name. Unlike fixed properties, dynamic properties often are not stored in the same repository as the user or content properties. In cases when dynamic properties are not part of the 532 IBM WebSphere Portal V4 Developer’s Handbook schema, they can be added, deleted, or modified without affecting the customer data store and the Java classes for accessing the resources. Dynamic properties for resources (leaf and group nodes) are inherited (coalesced) along the path from the root group to the target group by following the path of parent groups. At a node, the dynamic properties set in the parent group can be overridden. Adding a resource hierarchy 1. Click the Resource Hierarchies tab. The task buttons for Resource Hierarchies appears. 2. Click the Add button. The parameter input fields will show up as in Figure 10-10. Figure 10-10 Resource Console: adding a resource hierarchy 3. Specify the values for the new hierarchy as explained in Table 10-11. Chapter 10. Personalization 533 Table 10-11 Parameters for new resource hierarchies Parameter Explanation Hierarchy Name The unique name you want to assign to this resource hierarchy. Because Personalization uses a single namespace for all resources, the name must be unique among all of the hierarchies you will use on this application server. The name is case-sensitive. Single quote and double quote characters are not permitted. What is the resource collection for this hierarchy? The name of the resource collection upon which this hierarchy is based. The resource collection maps to resources in your customer data store. Select the resource collection from the list. If the list indicates None defined, no resource collections have been defined. If collections have been defined, but you do not want to specify a collection because the resources for this hierarchy should be stored in the Personalization data store, select None. Specify a root node name (Optional) The name of the root node of the hierarchy. The default value is hierarchy_name-root. For example, the hierarchy employees, the root node name is employees-root. The name is case-sensitive. Single quote and double quote characters are not permitted. Where should the Resource Console store dynamic properties? Specifies whether to store dynamic properties for this resource hierarchy in the Personalization database or in your customer data store with the user or content resources. If you select customer data store, you must specify a resource collection and the resource access classes specified in the associated resource collection must support dynamic properties. 4. To add the hierarchy, click the Create Hierarchy button. To return to the previous dialog without adding the hierarchy, click the Cancel button. 534 IBM WebSphere Portal V4 Developer’s Handbook After the hierarchy is created, its name will appear in the list of selectable hierarchies and the root node name will appear in the graphic display of the hierarchy. Adding a subgroup Once you have created the hierarchy root node, you can add subgroups to the hierarchy. 1. In the graphical view of the hierarchy, select the group to which you want to add a subgroup. 2. Click the Add subgroup task. 3. In the input field, type the name of the new subgroup. The name is case-sensitive. Single quote and double quote characters are not permitted. 4. Click the Add subgroup button to proceed or the Cancel button to return to the previous window without changes. Managing the group membership For any group except of the root node, you can change the membership after the group is created. 1. In the graphical view of the hierarchy, select the group to which you want to add a dynamic property. 2. Click the Manage group membership task. 3. To change the parent group, click the Change Parent button; to add or change the secondary groups, click the Change Group Membership button. 4. In the list of available groups, select the appropriate group for your task (set as parent, add/remove membership). If the list of groups is empty, no valid group is available. 5. Click the task button to execute or the Cancel button to return to the previous window. Deleting a group 1. In the graphical view of the hierarchy, select the group to which you want to delete. 2. Click the Delete group task. 3. In the confirm dialog, click the Yes button to delete the group or cancel by clicking the No button. Note: To delete the complete hierarchy, click the task button Delete in the task menu below the Resource Console top navigation bar. Chapter 10. Personalization 535 Managing dynamic properties 1. In the graphical view of the hierarchy, select the group to which you want to add a dynamic property. 2. Click the Manage group properties task. 3. In the table of the dynamic properties, to add a dynamic property, enter a name for it, specify a default value and the type of the property. 4. Select the property by marking the radio button and click Update to add the property to the group or Delete Property to remove it from the group. Dynamic properties inherited from the parent group are not editable. 5. To cancel without changes, click the Return button. Manage resources If you want to add a resource to a group and the resource is not in your customer data store, you can use the Resource Console to create the new resource and add it to the group. If you have defined a resource collection for the resource hierarchy, you specify the resource ID and fixed properties for the newly created resource. The fixed properties are added to your customer data store. The resource ID and group membership information are added to the resource hierarchy in the Personalization database. If you have not defined a resource collection for the resource hierarchy, you specify only the resource ID. You can add dynamic properties for the resource later. The resource will also inherit any dynamic properties from the parent group. You can concurrently add multiple resources from your customer data store to the same group, by using the following Resource Console tasks. Assign by ID This function enables you to specify a list of resource IDs (primary keys) that map to user and content data in your customer data store. The Console treats the resource IDs as string data and adds the resources to the specified group. Assign by query This function enables you to search for resources in your customer data store using specified fixed property values. The Resource Console treats the property values as strings. If any resources match the query, the Resource Console permits you to add those resources to the group. Import/export of resources The Resource Console provides an import function that enables you to define resource collections, hierarchies, and other Personalization resources on one 536 IBM WebSphere Portal V4 Developer’s Handbook application server and then use them on other application servers. This function is useful when moving from a development to a production server. Note: The resource description file (xml or hrf file) to be imported has to be accessible on the file system of the node where the resource engine is running. When you use the Resource Console to export Personalization resources in XML format, a valid Personalization resources file is created matching the Personalization Resources Document Type Definition (DTD), which is located at: <was_root>\installedApps\PersonalizationRuntime.ear\PersAdmin.war\WEB-INF\d td\PznResources.dtd As indicated by the DTD: A Personalization resource file contains definitions for zero or more resource collections, zero or more resource hierarchies, zero or more session objects and zero or more security mappings. A ResourceCollection element contains information needed to access the customer data store for user and content resources. Each resource collection has a name and consists of a ResourceType, ResourceClass, ResourceDomainClass and ResourceManagerClass. The ResourceType element is a user-defined description of the kind of resources in the collection. The ResourceClass, ResourceDomainClass and ResourceManagerClass elements contain the names of the classes used to access the customer data store. These classes are implementations of the Personalization APIs used to access the customer data store. The action attribute for ResourceCollection, ResourceHierarchy, Group and Resource specifies how the Personalization resource engine processes the element when the XML file is being imported using the Resource Console import function. For a resource collection, the options are create or delete. For other elements, the options are create, update, or delete. When Personalization resources are exported, the action attribute is always set to create for resource collections and update for the other elements. A ResourceHierarchy element can include an optional RootIdentity element that is a user-defined label for the root node. ResourceHierarchy also has zero or more nodes that are Group or Resource elements. If you use the Resource Console to group resources, the resource hierarchy includes those group definitions. A ResourceHierarchy has a unique name. If the hierarchy refers to resources in your customer data store, the hierarchy definition specifies the name of the associated ResourceCollection. The hierarchy definition also indicates Chapter 10. Personalization 537 whether any dynamic properties (set using the Resource Console) are stored in the Personalization database. Each Group element (a subgroup of the root node) consists of zero or more Property elements (dynamic properties) and zero or more Membership elements. Every group has a name and a parent group. A group can also be a member of one or more other groups. The additional group memberships (secondary group memberships) are specified by Membership elements. Each Resource element has a name and a parent group. All secondary group memberships are specified by Membership elements. A resource can have zero or more Property elements (dynamic properties). Fixed properties of a resource are not stored in the Personalization database. Consequently, they are not included in the Personalization resource file. A Personalization resource file can contain zero or more definitions of HTTP session objects. The HttpSessionObject element is independent of the ResourceHierarchy element. You can create classifier rules for session objects. A Personalization resource file can contain zero or more definitions of SecurityMappings. If login user IDs do not match the resource IDs for the user data, you will need to manually define the ID mappings or create a translator. A SecurityMapping consists of zero or more hierarchy elements and zero or more collection elements. Those elements identify the resource hierarchy or resource collection for the security mapping. A hierarchy element has a name (the name of the associated ResourceHierarchy element) and an EnableSecurity attribute that indicates whether the mapping is enabled. A hierarchy element consists of zero or one Translator elements or zero or one Manual elements. A collection element has a name (the name of the associated ResourceCollection element) and an EnableSecurity attribute that indicates whether the mapping is enabled. A collection element consists of zero or one Translator elements or zero or one Manual elements. A Translator element has a classname that is the full name of the Java class implementation of the AuthIDTranslator interface. A Manual element consists of one or more IDMappings. Each IDmapping specifies a userid and the associated mapid (the resource ID for the corresponding user data). Note: The import and export functions make the resource collections and hierarchies that you have defined available to user applications and support sharing this information with remote application servers. 538 IBM WebSphere Portal V4 Developer’s Handbook Application objects An application object is a session object (such as a shopping cart) that you want to use in your Personalization solution. Typically, you would define application objects using the HRF Editor in WebSphere Studio Advanced Edition. Alternatively, you can use the Personalization Resource console to specify the name or key used for storing the Java object in the HttpSession and specify the name of the Java class for the object. Be sure the session object class is accessible to your Web application and the application server classpath. Adding an application object 1. Click the Application Objects tab. The task buttons for application objects appear. 2. Click the Add button. 3. Specify values for the new application object, where the Object Handle is the name of the Java handle to the object and the Object Class is the full Java class name for this application object. Be sure this class is in your Web application classpath and the application server classpath. 4. To add the application object, click the Add button. To return without adding the application object, click the Cancel button. Deleting an application object 1. Select the application object you want to delete from the list of application objects. 2. Click the Delete button. 3. Confirm deleting by clicking the Yes button or cancel by clicking the No button. Campaigns The e-mail or Web site campaign data stored in the personalization database may be orphaned in certain circumstances. You can use the Resource Console to delete a campaign from the Personalization database. Select the Campaigns tab. The task buttons for campaigns and all Web site campaigns will appear. To display the e-mail campaigns, select E-mail from campaign list. To delete one or more campaigns, identify the campaigns you want to delete, mark the checkbox and click the Delete button. Chapter 10. Personalization 539 Log Settings In Log Settings, you can create logs that can be analyzed using WebSphere Site Analyzer in order to gauge effectiveness of campaigns and rules. You have the choice of three available loggers: HttpLogger To use the HttpLogger, enter the fully qualified URL to the Web Tracker servlet on the Site Analyzer server in the input field Web Tracker URL and enter the Site Analyzer project name for tracking the site in the input field Site Name. DatabaseLogger To write logging information to a database using the DatabaseLogger, you have to provide the following input: – Admin UserID: a database user ID with administrator authority – Admin Password: the password for the database administrator user ID – Schema.Table Name: the schema and table names, in the format Schema.Table – DataSource Name: the datasource name FileLogger To use the FileLogger, enter the name of the file to which you want to save logging information. To enable logging, enter the required information for the logger you want to use, select the radio button for the logger, set the radio button for Enable Rule Logging to Yes, and click the Save button. Security For WebSphere Personalization, you can specify the user's identity by using one of the following methods: Use WebSphere Application Server security, in which case the authenticated ID is used to retrieve the correct user profile. Store an ID in the HTTP session object using the Personalization context key pzn.userName. If you are using WebSphere Application Server security and the user authentication ID (the login ID) is different from the user profile ID (resource ID), you have two options for mapping the authenticated ID to a user profile ID: Manually define a mapping of the authenticated ID to the user profile ID. Implement the Personalization AuthIDTranslator and specify the class to use for mapping. 540 IBM WebSphere Portal V4 Developer’s Handbook Note: If Personalization finds that a security mapping is enabled for a resource collection and a mapping is enabled for a resource hierarchy based on the collection, the mapping enabled for the resource collection is used. Adding/deleting a translator 1. Click the Security tab. The task buttons for security will appear. 2. From the resource list, select the resource collection or hierarchy, for which you want to add the translator. 3. Click the Add Translator button. 4. Specify the fully qualifying class name of your translator class. 5. Click the Add/Change button to save your setting or the Delete button to reset the translator setting. 6. Click the Enable Security button. Adding/Deleting ID mappings 1. Click the Security tab. The task buttons for security will appear. 2. From the resource list, select the resource collection or hierarchy for which you want to add the translator. 3. Click the Add Mapping button. 4. Add a mapping of an authorization ID to a resource ID and click the Add button to add this mapping to the list of defined ID mappings. 5. To delete an existing mapping entry, select it from the Defined ID mappings list and click the Delete button. 6. When you specified all the ID mappings you need for your security IDs, click the Enable Security button. Note: When you add a security mapping (translator or ID mapping), you specify a resource collection or a resource hierarchy to which the mapping applies. Security mappings to all resource hierarchies that have been defined are not applicable. 10.4.3 Personalization Workspace The Personalization Workspace (PersWorkspace) is the browser-based interface that provides you with integrated access to the tasks that you perform most often, such as creating rules, in order to create personalized Web pages. PersWorkspace includes four main sections: Campaign Manager, Rule Composer, Preview Launcher, and Global Settings. Chapter 10. Personalization 541 To access the Personalization Workspace, enter this URL at you browser: http://<host_name>/wps/PersWorkspace/index.jsp where <host_name> is the name of the authoring or workspace server where the PersWorkspace is installed. If your application has a different context root or has a cookie path, your URL may be different. The PersWorkspace will show up as in Figure 10-11. Figure 10-11 Personalization Workspace (PersWorkspace) Note: If global security is not enabled on your application server, the logon window for PersWorkspace will only prompt for the username. Campaign Manager Campaigns are sets of rules that are active for a specific period of time. A Web site campaign is used to display time-sensitive personalized content. When a campaign is active, the Web site uses the campaign's rules for selecting content instead of using the Normal View's rules. You can have multiple Web site campaigns for a specific content spot. Each campaign can be effective at any 542 IBM WebSphere Portal V4 Developer’s Handbook time for any duration. Web site campaign priorities determine which rule is chosen to fill a content spot when campaigns overlap. The Campaign Manager is the area where you assign rules that you have created to content spots. When you assign rules to content spots as part of your Web site's Normal View as illustrated in Figure 10-12, these rules define the Web site's default behavior. Figure 10-12 PersWorkspace: Campaign Manager Rules that are part of a campaign are given priority to supersede the default behavior of the Web site, during the times that the campaign is active. You can also prioritize which campaign's rule assignment should prevail when multiple, overlapping campaigns exist as demonstrated in Figure 10-13. Chapter 10. Personalization 543 Figure 10-13 PersWorkspace: Campaign priority and split of campaigns When campaigns overlap in time, the rule assigned to the content spot in the campaign with the highest priority is used to personalize content. When campaigns share the same priority, and each of the campaigns has a rule assigned to a particular content spot, split percentages are used to determine which campaign's rule is applied to that content spot. Although splits are defined in terms of percentages, it is not necessary to make them add up to 100%. The chance an active campaign's rule is used is calculated using the ratio of its split to the total of all splits for campaigns with the same priority. Also, the split that is used is determined once for each visit. As a result, if a user had one content spot filled with the rule from NewsForRaleigh, then of all the content spots, for which NewsForRaleigh had a mapping, would use the rule defined in this campaign when selecting content for this user during his visit. The Campaign Manager also allows you to control e-mail campaigns. You can identify a file to use as the body of an e-mail message, use Personalization rules to identify the list of recipients and their e-mail addresses, and specify the date and time to send the e-mail message as illustrated in Figure 10-14. 544 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-14 PersWorkspace: Setting properties for e-mail campaigns There are no limitations for the e-mail body. When an e-mail body is processed at runtime, the ”current user” is each recipient. WebSphere Personalization can use rules to define a list of e-mail recipients, but the rule used to retrieve the list of e-mail recipients does not have a 'current user'. You can use actions, rules, and classifiers to personalize the e-mail message as the e-mail body is essentially the same as any other JSP with content spots and assigned rules. Security prevents the generation of personalization content from multiple servers. Therefore, if the e-mail body is a JSP with content spots for delivering personalized content, the servlet that generates the e-mail body must be served from localhost. Since this servlet is customer-defined, it may be located anywhere on localhost. If the content of the e-mail body is not personalized, the servlet is not required to be on localhost. If an e-mail cannot be sent (because of a mail server, network problem, etc.), the system will attempt to send the e-mail in the next trigger. All active campaigns that have a start time less than the current time will be sent. Chapter 10. Personalization 545 E-mail campaigns have the following exception handling rules: No e-mail address: customers without e-mail addresses will be ignored. Incorrect e-mail address: incorrect e-mail addresses will be ignored. Overdue e-mail: e-mail that is over a week old will be set to inactive. This is intended to prevent sending old e-mail that is in the database when a server is started. The user may republish the e-mail using a new send time to reactivate the e-mail. Cannot locate mail server: the connection attempt is retried three times, then the state of the campaign is set to failed. An error message is logged to the WebSphere Application Server logs. No mail server account: the state of the campaign is set to failed. JSP errors: if there is an error or exception generated from a JSP when generating the data for an e-mail, the error will be logged and processing will continue with the next customer. Verify that JavaMail 1.1 is installed on the WebSphere Application Server. JavaMail provides the SMTP required to send e-mail. You can manage e-mail responses from customers and outgoing error conditions (for example, unknown e-mail address) using a standard e-mail client. Under the JavaMail Session of WebSphere Application Server, verify that the Protocol is SMTP and that the hostname of the SMTP server is in the Server entry field. If the SMTP server is authenticating, a valid Username and Password must also be set. Rule Composer The Rule Composer is the area of the workspace where you can create, edit, and delete rules. The navigation bar on the left displays the folders that are defined for the current project. Classifiers are used to define visitor segments or classify other conditions by evaluating the current user properties, the current date and time, and other implicit and explicit application object properties. Actions determine what data or content will be selected or updated, including the ability to sort the order of returned results. Bindings combine actions and classifiers, so you can specify what actions to perform when your defined conditions are encountered. You can work on only one type of rule at a time (classifiers, actions, or bindings). Select the type of rule from the drop-down list and click a folder name to open it. Rules of the type selected will be displayed in any of the open folders where rules of that type exist. 546 IBM WebSphere Portal V4 Developer’s Handbook The rule editors for Classifier, Action, and Binding use hot links to help you identify the variables (items you can or must change) and colors to help you recognize what you need to do and when you are done. When you click a hot link, the editor opens a new window that displays a list of values that you can select, as shown in Figure 10-15. When you make a selection, the variables are replaced with meaningful values. Figure 10-15 PersWorkspace: Action rule editor The colors of the hot links are as follows: Blue indicates that the item is OK or complete. You can change the item by selecting it again. Red indicates that the item is required to finish the rule and it is not complete. You must specify a value for this item. Magenta indicates that the item is optional. You can complete the rule with or without specifying a value. As you click the links and make selections, the colors will change to let you know that you have completed a rule definition. Chapter 10. Personalization 547 Classifier rule editor The fields of the Classifier rule editor dialog are: Name of the Classifier Create a name to identify the classifier. This name will be used as the file name. Do not use special characters. Also, if you rename an existing classifier, any binding rules that reference the rule by the former name may no longer work. Comment about the Classifier You can optionally enter a more detailed description about the classifier's function. Classifier Description The default classifier structure looks like this: NewClassifier is” Classification when Resource.Attribute is equal to value add Condition add Classification Otherwise Classification NewClassifier This is the name of your classifier. To rename your classifier to something meaningful, change the text in the Name of the Classifier field. When you complete the Add Classifier dialog and click Save, the classifier is renamed. If you do not rename the classifier in the Name of the Classifier field, the classifier will be named NewClassifier. Classification Select Classification to specify an arbitrary name (of your choice) to differentiate a set of circumstances or conditions about the visitor at the Web site, or the date and time the visit occurs. Resource.Attribute Select Resource.Attribute to choose a specific attribute that will be evaluated to decide if the visitor or situation fits the classification. 548 IBM WebSphere Portal V4 Developer’s Handbook Attributes can be data you maintain for or about your Web site visitors, information in page requests or session objects, or the date. You can also define classifications that evaluate against Web page input such as page requests or session objects, like an online shopping cart. The default options for Resource.Attribute are described below: current Date: make classifications based on the date, day or time current Page Request: make classifications based on information passed as a page request current Category Count: make classifications based on implicit user profiling current User Session: make classifications based on information stored in the user session current BrowserCapability: make classifications based on various attributes of the browser that the Web site visitor is using In order for your resources to appear in the selection windows, they must be set up as Personalization resources and the .hrf files must be accessible at the project resource paths and resource class path settings identified within Global Settings. Resources marked current means the resource attributes relate to an actual Web site visitor. If your resources include objects that are created during a visitor's session such as what the visitor has selected while at the site, these objects will also be designated as current. is equal to Select is equal to to specify the evaluation between the resource attribute and a value. The default evaluation is is equal to, but other evaluations are possible depending on the type of the resource being evaluated. includes includes any of is between is between but not equal to is equal to is greater than is greater than or equal to is included in is less than or equal to Chapter 10. Personalization 549 is less than is not equal to value Select value to choose a specific value for the resource attribute evaluation. This can be a value you enter or the value of another resource attribute. When you define the resource attribute and select is equal to as your relationship, then you would specify the exact value to satisfy the condition of your classification. You can enter the value or select another resource attribute that you want it to match. The other resource attribute does not have to be related to the Web visit. It can be from any other resource available in your collection of resources. When selecting another resource attribute, you will only be able to select one that has a compatible data type. For example, if you evaluate an attribute that has the type Number, you can compare it to another resource attribute that has the type Number or Decimal Number. The editor will not let you choose other resource attributes with incompatible types. When making comparisons against resources in a database, Personalization respects the column type and size; therefore, to compare a value to a column typed as CHAR(10), you must include all ten characters. For example, assuming you have a table with a column named DAY which is typed as CHAR(10) and a row in the table has a value of “Monday™ “ for the DAY column, if DAY is used to compare against in a classifier condition, the value to compare must have all ten characters defined. If, however, the column was typed as VARCHAR, then the value compared to in the classifier condition could be “Monday” (without the four additional blanks). add Condition Select add Condition to add another resource attribute, evaluation, and value combination that will further define the same classification. When you add another condition, the word and appears at the end of the previous condition as connecting condition. When you have more than one attribute/value condition in a classification, you can decide if all of the conditions have to be true to satisfy the classification, or just some of them. If all the conditions have to be true, select and to connect them If only some of the conditions have to be true, select or When you have three or more attribute/value conditions, you can group two or more of them within parentheses so that they can be evaluated together as one set of circumstances. A group can be connected to another attribute/value condition or to another group of conditions by and or or. 550 IBM WebSphere Portal V4 Developer’s Handbook add Classification Select add Classification to define another related classification within this classifier. Although a classifier can have several classifications, the classifications are evaluated individually. Otherwise Classification Select Otherwise Classification to create a classification that will be true when none of the other conditions are met. Action rule editor The fields of the Action rule editor dialog are: Name of the Action Create a name to identify the action. This name will be used as the file name, so do not use special characters. Also, if you rename an existing action, any binding rules that refer to the previous name may not work. Comment about the Action You can optionally enter a more detailed description about the action. Type of Action Choose either Select content or update from the drop-down list. Select content is for retrieving data and update is for storing data such as Web site visitor preferences. Select content is the default. The conditions in the Update action rule are related to updating content. You can update any “current” object. Action Description for Select content The default action structure is: Select Content whose Resource.Attribute is equal to value add Condition order as is show all items Chapter 10. Personalization 551 Select Content The conditions in the default Action rule for Select content are related to selecting one type of content. The content you select can be images, text, links, and values retrieved from a database - anything that can be displayed or included on a Web page. Resource.Attribute Select Resource.Attribute to choose a specific attribute of a content resource. This attribute is evaluated to determine if the content is displayed. Content resource attributes are information you keep in your data store about your content. The default options for Resource.Attribute are: current Date: make classifications based on the date, day or time current Page Request: make classifications based on information passed as a page request current Category Count: make classifications based on implicit user profiling current User Session: make classifications based on information stored in the user session current BrowserCapability: make classifications based on various attributes of the browser that the Web site visitor is using is equal to Select Is equal to to evaluate the relationship between the resource attribute of the content and its value. If the resource attribute is of the data type list (array, vector, or enumeration), the available evaluations become includes and includes any of. Otherwise, the choices are: includes includes any of is between is between but not equal to is equal to is greater than is greater than or equal to is included in is less than or equal to is less than is not equal to 552 IBM WebSphere Portal V4 Developer’s Handbook value Select value to specify values for the content resource attribute evaluation. For example, if you choose is equal to as your relationship, then you should specify the exact value the content resource attribute must have to satisfy the condition. This value can be one you enter or the value of another resource attribute. As with classifiers, when choosing another resource attribute, you can select only one attribute with a compatible data type. The editor prevents you from choosing other resource attributes with incompatible types. In addition to predefined resource properties, you can enter properties of a resource that are not in the list. If you know the resource to handle dynamically, specify the name of the property. If the resource manages properties dynamically, their values are retrieved when the rule is evaluated. add Condition Select add Condition to define another attribute, evaluation, and value combination for selecting this content. When you have more than one attribute/value in an action, you can decide if all of the conditions have to be true to satisfy the rule and display the content, or just some of them. When you add another condition, the word and appears at the end of the previous condition as Connecting condition. When you have more than one attribute/value condition in a classification, you can decide if all of the conditions have to be true to satisfy the classification, or just some of them. If all the conditions have to be true, select and to connect them If only some of the conditions have to be true, select or When you have three or more attribute/value conditions, you can group two or more of them within parentheses so that they can be evaluated together as one set of circumstances. A group can be connected to another attribute/value condition or to another group of conditions by and or or. order as is Select order as is to specify the order in which you want the selected content to be displayed on the Web page. The default, order as is, will return data in the order in which it is stored in the repository. You can also choose order randomly or order by. Order by allows you to sort the content by any of its attributes, sort by more than one attribute (and specify the order the attributes are used to sort), and specify whether you want each attribute in ascending or descending order. Order randomly will return the data in a different order each time the page is displayed. Chapter 10. Personalization 553 show all items Select Show all items to identify a numerical limit to the number of items that will be selected. Any property or request or session object of type Integer can be used to specify this limit. The default setting is to show all items or to have no limit. Action Description for Update The default update action structure is: Update Resource.Attribute set to value add Expression Resource.Attribute Select Resource.Attribute to choose a specific attribute of a current resource. This attribute will be updated according to its type and the operation you choose to perform. Only current instance-based resources, such as current Personnel and current User Session, can be updated. Others, such as Current Page Request, Current Date, and Current Browser, cannot be updated. Attributes of application objects can also be updated. You cannot update a primary key of a table. set to Select Set to to choose from a list of operations that can be performed on the attribute. Valid alternatives are: set to (applies to all types) increment by (Number and Decimal Number) decrement by (Number and Decimal Number) multiply by (Number and Decimal Number) divide by (Number and Decimal Number) append (Text and List types) remove (List types) remove all (List types) 554 IBM WebSphere Portal V4 Developer’s Handbook value Select value to specify the value by which the attribute will be updated. For example, if your operand is increment by, then you should specify the value by which the resource attribute is incremented. You can enter a specific value or reference the value of another attribute. As with classifiers, when choosing another resource attribute, you can only select one that has a compatible data type. The editor prevents you from choosing other resource attributes with incompatible types. If the resource attribute is a list, the operations append and remove will accept both single values and multi-value lists for the value. add Expression You can have more than one update expression by selecting add Expression. Additional expressions will be joined together by and. For multiple mathematical operations, and for multiple append operations on the same attribute, expressions are performed in the order in which they are presented, and results are cumulative. When updating multiple expressions, it is not possible to change and to or, nor is it possible to group or parenthesize expressions. Binding rule editor The fields of the Binding rule editor dialog are as follows. Name of the Binding Create a name to identify the binding. This name will be used as the file name. Do not use special characters. Comment about the Binding You can optionally enter a more detailed description about the binding's function. Binding Description The default binding rule structure looks like this. When Classifier is Classification do Action Otherwise do Action Always Chapter 10. Personalization 555 do Action Exclude do Action order as is show all items Classifier Select Classifier to choose from a list of the available classifiers in your project, or select the quick classifier option. Quick classifiers are simple condition classifiers defined inside the binding, without the need for a specific classifier rule. However, if you need to specify multiple conditions or define groups using and and or, you must use a separate classifier rule. Selecting Use Attribute allows you to specify the attribute to use in the binding in the same way you select them for actions and classifiers. Classification Select Classification to choose the name of one of the classifications within the classifier. However, if you choose to use an attribute using a quick classifier, this option will change to is equal to value. do Action Select do Action to choose one or more actions in your project. You can also select another classifier and classification to define a combination of conditions to evaluate. These actions run when the condition in the preceding classification (or set of classifications) are met. If there are multiple actions in a binding, they must all work with resources of the same type. otherwise do Action Select otherwise do Action to choose one or more actions in your project that run when none of the preceding conditions in the classification or set of classifications are met. Within the otherwise clause, you can also select another classifier and classification to define a combination of conditions to evaluate. always do Action Select always do Action to choose one or more actions in your project that will execute whether or not any of the preceding conditions in the classifications are met. 556 IBM WebSphere Portal V4 Developer’s Handbook exclude do Action Select exclude do Action to identify one or more actions in your project that will execute and whose results returned will be removed from the result set generated by the other actions in the binding. The “exclude” takes precedence over “always”. order as is Select order as is to choose the ordering of the final result set of the binding. The options for binding ordering are the same as for action ordering: order as is order randomly or order by The option order as is returns the items in the same order in which they are stored in the database. The option order randomly returns the items in a random order each time the rule runs. The option order by allows you to sort the content by any of its attributes, sort by more than one attribute, and specify whether you want each one in ascending or descending order. Order at the binding level will override any order defined within an individual action. If you want to preserve the order as defined by each individual action, specify the default order as is within the binding. show all items Select Show all items to identify a numerical limit to the number of items that will be selected. Any property or request or session object of type Integer can be used to specify this limit. The default setting is to show all items. Preview Launcher The ability to preview your personalized Web site is incorporated into WebSphere Personalization through the Preview Launcher. Previewing allows you to test the operation of your Personalization rules and campaigns during development, so that you can see how the rules will respond to visitors with varying attributes or at different times. All users who can access the workspace may select a project and preview it using the Preview Launcher. Because Personalization rules processing during runtime is dependent on who the current user is, the day, date, or time, you must first assume a user profile and declare what the date and time are to be before you preview the Web site. Instead of relying on actual users, you can create fictitious user profiles. Those profiles are comprised of information you define for any or all of the attributes of the typical users of your site. Chapter 10. Personalization 557 Once you have defined and selected a profile, you specify the day and time you want to simulate to view your site as demonstrated in Figure 10-16. Figure 10-16 PersWorkspace: preview criteria The preview will then display the site the way it would appear according to the user characteristics of your chosen profile, on the day and time you have determined. During Web site preview, content spots on the Web pages appear as small blue spheres as shown in Figure 10-17. Figure 10-17 PersWorkspace Preview: Content spots placeholders Note: If you do not see the content spot placeholders on your personalized Web page, check that you included the getPreviewAnchorTag() method of your content spot wrapper bean in your JSP! You can obtain information about the rule and campaign (if applicable) used to fill the content spot, change the rule applied to the content spot (in either the Normal View or campaign), and open the rule editor from within preview by clicking a content spot. The content spot dialog, as shown in Figure 10-18, will open up an offer the applicable rules for the selected content spot. 558 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-18 PerWorkspace Preview: Changing assigned rule for a content spot The top box of the window displays the name of the content spot that you are working with, the type of content the spot can accept, and the campaign that is currently filling the content spot. The middle box shows the rule you have selected to fill the content spot when there are no active campaigns. The bottom box displays a list of all campaigns and whether they have rules assigned to content spots. To change the rule that fills the content spot, click the drop-down list in the Rule column and choose a different rule. Only rules that use the same content type can be selected. By clicking the Edit Rule button next to the rule drop-down list, you can edit the currently selected rule and make changes to the way the rule functions. The appropriate rule editor will launch and let you modify the rule as you would do within the Rule Composer. When you save your changes and refresh the site preview window, you will see your changes take effect. Global Settings Within Global Settings, you define your project and the parameters PersWorkspace needs to access them. For publishing your projects, you can Chapter 10. Personalization 559 define your publish servers and trigger the publishing. In addition, the PersWorkspace access control and user management is defined in the Global Settings. When you click the Global Settings tab, a new browser window will open up and display the available sections. As PersWorkspace handles access to the different controls based on a set of user roles, if some of the describes controls are not available to you, check whether your user role allows the specific action as described in the section Manage Access Control. Manage Projects By default, the Global Settings starts up with the Manage Projects section. Here you find a list of all projects defined in PersWorkspace. You can add, edit or delete a project from the list by selecting it and clicking one of the buttons on the right of the list. To add a new project, you have to specify the project path and the project name, as illustrated in Figure 10-19. Figure 10-19 PersWorkspace: adding a project 560 IBM WebSphere Portal V4 Developer’s Handbook If the project path you entered does not exist, PersWorkspace will create the directories. The project path cannot be changed after the project is created. However, you can change the project name at any time. If you want to add an existing project, mark the Open existing radio button and specify the full path name to the PersWorkspace project properties file (.prj). Note: All path settings you enter will be mapped to the application server file system. When you click the Edit button, a new browser window will open where you can edit the settings of the selected project, as shown in Figure 10-20. Figure 10-20 PersWorkspace: setting the project properties Manage Publish Servers In the Manage Publish Servers section, you can add, edit or delete servers where you publish the current project. You must be logged on to PersWorkspace in the role of Administrator or Developer to be able to perform these tasks. Chapter 10. Personalization 561 To add a server, click the Add button and enter the properties for your server as illustrated in Figure 10-21. Figure 10-21 PersWorkspace: adding a publish server Publish Files The Publish Files section allows publishing of rules, campaigns and e-mail campaigns to Personalization servers. To publish, select the target server from the list of publish servers and specify whether to publish only the changed files or all files. Note: Only the files of the current project will be published. After you have clicked the Publish button, a small window will pop up, displaying the current status. After publishing is finished, an info box will show up as illustrated in Figure 10-22. 562 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-22 PersWorkspace: publish files Manage Access Control In this section, you will find the list of current users for PersWorkspace and their assigned roles. The role concept within the Personalization Workspace distinguishes between five user roles (Publisher, Author, Editor, Developer, or Administrator) each with a specific set of tasks the particular user is allowed to perform. Figure 10-23 summarizes this role concept and shows the mapping of the different roles and the tasks. Chapter 10. Personalization 563 Figure 10-23 PersWorkspace: user roles/tasks mapping Depending on your installation, there is one explicit user assigned to the PersWorkspace Administrator role and only this user can manage the access control list. This Administrator user is entered during the installation (see Chapter Installation) and authentication is handled by the application server. However, if you cannot add or edit the user list even though your user is supposed to act as Administrator, you could check the PersWorkspace role mappings in the following folder: <was_root>\installedApps\Personalization_Workspace.ear\PersWorkspaceMain .war\servers\accesscontrol\ There you should find a <username>.uac file which contains the settings for this user. If needed, copy and/or modify the particular file. As example, the wpsadmin.uac is shown in Example 10-4. Example 10-4 PersWorkspace access control settings for user wpsadmin <?xml version="1.0" encoding="UTF-8"?> <user defaultProject="Default" name="wpsadmin" role="65535" tip="2"></user> The value for defaultProject specifies the current project. Set this to the value Default and later select the appropriate current project from the Global Settings. The attribute name specifies the logon name for that user. Role identifies the PersWorkspace user role code and the code value for tip specifies whether or not to show PersWorkspace tips after the logon. 564 IBM WebSphere Portal V4 Developer’s Handbook Table 10-12 PersWorkspace user role codes Role Code Administrator 65535 Developer 61951 Publisher 32831 Author 63 Editor 18 For further PersWorkspace user management, you should use the browser-based tool rather than copying and modifying the access control file. You can add, edit and delete users, but only if you are logged on to PersWorkspace in the role of an Administrator. Figure 10-24 shows the Manage Access Control dialog for adding a new user. Figure 10-24 PersWorkspace: Manage Access Control add user dialog Chapter 10. Personalization 565 10.4.4 Plugins for WebSphere Studio Application Developer (Wizards) To implement the resources and content spots, Personalization offers wizards for WebSphere Studio which guide you through and create the needed Java classes as well as the resource description files (href files). The V4 wizards come as plugins and can be used with WebSphere Studio Application Developer (WSAD), WebSphere Studio Advanced Edition and WebSphere Studio Site Developer. Note: By default, the Personalization Wizards are available in the Web and Java perspectives. To add them to additional perspectives such as the portal perspective, open the perspective, and choose Perspective -> Customize from the menu. Select the Other category and click the checkbox next to Personalization Wizards. Once installed and added to a perspective, the Personalization wizards will be available as three buttons on the toolbar. For WebSphere Studio Application Developer, this is shown in Figure 10-25. Figure 10-25 WebSphere Studio Application Developer: Personalization wizards General settings The source path is set by default to the first source path specified on the Java Build Path properties page of the corresponding project. For Java projects, the resource and rule paths are set by default to \wcm-resourceCollections and \wcm-rules, respectively. For Web and Portal projects, the paths are webApplication\WEB-INF\wcm-resourceCollections and webApplication\WEB-INF\wcm-rules. The appropriate folder is created the first time you use the wizard, and is not configurable. If you change the folder names, resources may no longer be visible to the wizards. The Personalization plug-in will automatically add some JARs to your project's classpath which it needs to compile resources. If you receive compile errors, check your project's classpath to make sure all variable entries are correctly resolved and move the variable entries added by Personalization to the top of the classpath. Before adding Personalization resources or content spots to a JSP, you may want to enable BeanInfo introspection for your project. To do so, right-click the 566 IBM WebSphere Portal V4 Developer’s Handbook project name, click Properties, click BeanInfo Path, and select Enable BeanInfo Introspection on this Project. If introspection is not enabled, properties of the bean may not be correctly listed in Page Designer dialogs. The file publish.properties located in the plug-in folder com.ibm.wcm.resource.wizards identifies the location of the PersAdmin application in the runtime environment. If you have changed the context for the PersAdmin Web Module in the Personalization Runtime enterprise application from the default, update the servlet locations in the publish.properties file. Do not modify or remove the XML_ENCODING line. Example 10-5 Default publish.properties # ------- Publish URL entries ------RULE_PUBLISHER=wps/PersAdmin/servlet/com.ibm.servlet.personalization.PznRulePub lisher CAMPAIGN_PUBLISHER=wps/PersAdmin/servlet/com.ibm.servlet.personalization.PznCam paignPublisher EMAIL_PUBLISHER=wps/PersAdmin/servlet/com.ibm.servlet.personalization.PznEmailP romotionPublisher HRF_PUBLISHER=wps/PersAdmin/servlet/com.ibm.servlet.personalization.ImportExpor t.ImportServlet XML_ENCODING=UTF-8 Note: Personalization wizards may only be run from a Java, Web or Portal Project. Content Wizard V4 The Content Wizard V4 will assist you in creating content resources for your Personalization rules. The Content Wizard helps you define attributes of your content that you want to define in your Personalization rules. The rules can evaluate these attributes before deciding to display the content on a Web page. The Content Wizard V4 adds the ability to create resources for EIP databases, and adds database joins support when creating resources for a relational database. To create a content resource, point to the project where you want the resource to be added. Select Content Wizard V4 from the toolbar. Logon In the Content Wizard, click Next or the Logon tab to move on to the database logon window shown in Figure 10-26. Chapter 10. Personalization 567 Figure 10-26 WebSphere Studio Application Developer Content Wizard: database logon window When you select a Driver identifier, the Driver class and DataSource class fields will automatically populate. If you select Other for a Driver identifier, then you will need to complete the Driver class and DataSource class fields. The DataSource class is the JDBC 2.0 connection pooling driver that is used by WebSphere Application Server V4.0 at runtime. If the DataSource class is not specified, the Driver class will be the standard JDBC driver that WebSphere Studio Application Developer uses to connect to the database to allow you to select tables and columns, and that is used for legacy connection pooling (WAS 3.x). If you specify both drivers, the code generated is WebSphere Application Server V4.0 connection pooling, however, if you leave the DataSource class field blank, the code generated will use the WebSphere Application Server V3.0 connection pooling. Table 10-13shows the supported drivers and required syntax. 568 IBM WebSphere Portal V4 Developer’s Handbook Table 10-13 Supported drivers and required syntax Driver Database URL IBM DB2 UDB local jdbc:db2:[database] IBM DB2 UDB remote jdbc:db2://[host]:[port]/[database] AS/400® Toolbox for Java jdbc:as400://[host] JDBC-ODBC Bridge jdbc:odbc:[database] Oracle jdbc:oracle:thin:@[host]:[port]:[database] Sybase jdbc:sybase:tds:[host]:[port]/[database] Other use the database URL as specified by your database vendor Lotus Domino lotus.jdbc.domino.DominoDriver When you click Connect, the wizard tries to establish the connection to the specified database. If the connection could not be established, an error message will come up. After you have connected successfully to the database, the Content Wizard V4 dialog will show the following five additional tabs: Tables, Columns, Joins, Mapping, and Finish, as illustrated in Figure 10-27. Chapter 10. Personalization 569 Figure 10-27 WebSphere Studio Application Developer Content Wizard: Table selection Note: You can use the Back, Next, and Finish buttons to navigate through the dialog. The Tables and Columns section are required to finish the dialog. Joins and Mapping are optional. Tables Within the Tables tab, select the table(s) that you want to use to build your resource. You must select at least one table to continue. Multiple tables may be selected. To narrow the displayed list of tables, click the Filter Tables button and type a table name filter. For example, D% will narrow the list to just the table names starting with the letter D. Columns At the Columns tab, select the column(s) representing resource attributes on which to base personalization decisions. You must select at least one column. Multiple columns may be selected. 570 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-28 WebSphere Studio Application Developer Content Wizard: Column selection The primary key is indicated in bold. The table from which the primary key is selected is assumed to be the base table. All joins should be done against this table. To change the primary key, select a different column and click the Primary Key button. You can rename a column name. To do this, under Selected columns, select the Name of the column and type the new name. Both names, the original and the one you have entered, will be carried along into the resource wrapper bean. Joins If you have selected more than one table, you can add joins to them within the Joins tab. Therefore, click a column name in the base table and a column name in the association table. Click the Join button to join the tables. Chapter 10. Personalization 571 Figure 10-29 WebSphere Studio Application Developer Content Wizard: Joins You can specify the type of join, INNER or LEFT OUTER JOIN, by clicking the Join Type button. A join can be removed by selecting one of the joined columns and clicking the Unjoin button. If the base table is joined with the primary key of another table, then the relation is one-to-one and the columns selected are single value. In other cases, values are multi-value. For multi-value cases, if more than one column from the association table is selected, then it is a compound multi-value. The wizard will generate a bean for these columns and the multi-value will be an array of this bean. You can specify the name of this multi-value property by clicking the Set Property Name button.When creating a one-to-many multi-value join, the wizard generates an Association class file. Mapping Mapping columns to defined variables is optional. If a resource attribute has a set of valid values, you can map those to meaningful words that will appear in the 572 IBM WebSphere Portal V4 Developer’s Handbook Personalization rule editors. This can make it easier to create a rule, because it will be possible to select from a list of the words rather than the actual values. For example, if a particular column in the database held the integer value of 1, 2, or 3 indicating Yes, No, or Maybe, you could map the integer values to the words. To map a column to a defined value, from within the Mapping tab, do the following: 1. Click the column that will be mapped 2. Click the Edit button 3. In the Define Type Value dialog, enter the value and the description 4. Click the Add button 5. When finished, click the OK button For longer lists, you can use the Populate button to map values. For example, let's assume you have a column in your EMPLOYEE table named WORKDEPT (EMPLOYEE.WORKDEPT). You also have a table named DEPARTMENT which contains a DEPTNO column (DEPARTMENT.DEPTNO) and a DEPTNAME column (DEPARTMENT.DEPTNAME). Using the Populate button, you can map the values (DEPARTMENT.DEPTNO) and descriptions (DEPARTMENT.DEPTNAME) of the DEPARTMENT table to the EMPLOYEE.WORKDEPT column. To map a column using the Populate button, from within the Mapping tab, do the following: 1. Click the column that will be mapped 2. Click the Populate button 3. Select a column for values 4. Select a column for descriptions 5. When finished, click the OK button Finish On the Finish tab, the names of the files to be generated can be modified and adapted to particular coding guidelines. Before generation, a list of all files to be generated is displayed as a summary. To modify the filename, select the file from the list and click the Edit button. Then, enter the new filename and confirm by clicking OK. The Content Resource Wizard will generate the following files. Content Resource (Java) Content Resource Manager (Java) Chapter 10. Personalization 573 BeanInfo (Java) Server Resource Configuration (.hrf) User Wizard The User Wizard V4 will assist you in creating user resources for your Personalization rules. The User Wizard helps you define attributes of your Web site visitors that you want to define in your Personalization rules. With the User Wizard, you can create user resources from a relational database or from an LDAP Directory. To create a user resource, point to the project where you want the resource to be added. Select User Wizard V4 from the WebSphere Studio Application Developer toolbar. Logon In the User Wizard, click Next or select the Logon tab to specify the datasource you want to use and to log on to the datasource. The Logon window is shown in Figure 10-30. Figure 10-30 WebSphere Studio Application Developer User Wizard: LADAP Logon window 574 IBM WebSphere Portal V4 Developer’s Handbook Note: When you change the Protocol to Database(SQL), the window will display the logon settings as described in the Content Wizard section. When you entered your LDAP properties and click Connect, the wizard tries to establish the connection to the specified LDAP. If the connection could not be established, an error message will come up. After you have connected successfully to the LDAP, the User Wizard dialog window will show the following four additional tabs: Attributes, User Preferences, Mapping, and Finish. Note: As for databases, the User Wizard is the same as described in the Content Wizard section with identical procedure and selection possibilities, so we will focus on using LDAP in this section. Attributes From the list of available attributes on the left, you must select at least one attribute. You can add single attributes to your user resource by marking them in the attribute list and clicking on the single right arrow button or you can add all available attributes by clicking the double right arrow button. Added attributes will be moved from the list of available attributes (left) to the list of selected attributes (right). To remove attributes from the list of selected attributes, mark them and click the single left arrow button or click the double left arrow button to remove all selected attributes. The primary key is indicated in bold as shown in Figure 10-31. Chapter 10. Personalization 575 Figure 10-31 WebSphere Studio Application Developer User Wizard LDAP: Select attributes To change the primary key, select a different attribute and click the Primary Key button. You can rename an attribute name. To do this, under Selected attributes, select the name of the attribute and type the new name. Both names, the original and the one you have entered, will be carried along into the resource wrapper bean. User Preferences User Preferences are optional. User Preferences generate JSPs that allow Web site users to update their preferences. To create a User Preference page, within the User Preference tab, select the columns that you want to use as your user preferences. Under the Style column, use the drop-down list to select a style for the JSP presentation page (for example, list, checkbox, text, radio button). When creating User Preferences, the wizard generates the following files: User Preference Update page (.jsp) User Preference Modification page (.jsp) Update Preference Rule page (.act) 576 IBM WebSphere Portal V4 Developer’s Handbook Update Preference Rule Wrapper Bean (.java) User Rule Wrapper Bean (Java) Get Current Rule User (Act) Mapping Mapping to defined variables is optional. If a resource attribute has a set of valid values, you can map those to meaningful words that will appear in the Personalization rule editors. This can make it easier to create a rule, since it will be possible to select from a list of the words rather than the actual values. To map an attribute to a defined value, from within the Mapping tab, do the following: 1. Click the column that will be mapped 2. Click the Edit button 3. In the Define Type Value dialog, enter the value and the description 4. Click the Add button 5. When finished, click the OK button Finish On the Finish tab, the names of the files to be generated can be modified and adapted to particular coding guidelines. Before generation, a list of all files to be generated is displayed as a summary. To modify the filename, select the file from the list and click the Edit button. Then, enter the new filename and confirm by clicking OK. The User Wizard will generate the following files: User Resource (Java) User Resource Manager (Java) BeanInfo (Java) Server Resource Configuration (.hrf) HRF Editor The HRF Editor allows you to create application objects and define resource collections within Studio, tasks previously reserved for the Resource Console. The ability to perform these tasks within Studio reduces the need to import and export resources between Personalization servers and WebSphere Studio. Chapter 10. Personalization 577 Note: The HRF Editor is only available in WebSphere Studio V4 Advanced Edition. In WebSphere Studio Application Developer, you can use the included XML or text editors if you need to modify .hrf files. When you create your resources with one of the Personalization wizards, the corresponding .hrf file will be automatically created and added to your project as illustrated in Figure 10-32. Figure 10-32 WebSphere Studio Application Developer: Generated .hrf files Within WebSphere Studio Application Developer, you can edit the hrf file with the internal Editor by double-clicking it. Figure 10-6 shows the .hrf file for a user resource. Example 10-6 WebSphere Studio Application Developer Editor: User resource .hrf file <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ibm-websphere-personalization SYSTEM "PznResources.dtd"> <ibm-websphere-personalization> <ResourceCollection action="delete" name="YourCoUser"> <ResourceType>User</ResourceType> <ResourceManagerClass>com.yourco.resource.YourCoUserManager</ResourceManagerCla ss> <ResourceDomainClass>com.yourco.resource.YourCoUserManager</ResourceDomainClass > <ResourceClass>com.yourco.resource.YourCoUser</ResourceClass> 578 IBM WebSphere Portal V4 Developer’s Handbook </ResourceCollection> <ResourceCollection action="create" name="YourCoUser"> <ResourceType>User</ResourceType> <ResourceManagerClass>com.yourco.resource.YourCoUserManager</ResourceManagerCla ss> <ResourceDomainClass>com.yourco.resource.YourCoUserManager</ResourceDomainClass > <ResourceClass>com.yourco.resource.YourCoUser</ResourceClass> </ResourceCollection> <ResourceHierarchy InternalDataStore="yes" ResourceCollectionName="YourCoUser" action="update" name="YourCoUser"/> </ibm-websphere-personalization> Content Spot Wizard The Content Spot Wizard creates the bean for a content spot. You can create content spots which return the actual content according to the assigned rule or content spots which represent a classification. To create a content spot, click the Content Spot Wizard button in WebSphere Studio Application Developer. In the wizard window, click the Rule Type tab and enter a name for your content spot. If your rule will return content, select the content type from the drop-down list as shown in Figure 10-33. Chapter 10. Personalization 579 Figure 10-33 WebSphere Studio Application Developer Content Spot Wizard: Selection of content type Note: The content type list is generated by the Content Spot Wizard, using the names of the .hrf files within the resources folder of your project. Under the Finish tab, you can change the class name for your content spot before the wizard finally creates the bean. To rename the class, select the class name and type in the new name. Then click the Finish button to create the bean. Accessing the help The com.ibm.wcm.resource.wizards.doc plug-in adds several files to the WebSphere Studio help system. To access these help files, click Help -> Help Contents from the WebSphere Studio tool bar. Select Application Developer Documentation in the help system drop-down list. Under Concepts -> Personalization you will find an overview and under Tasks -> Using Personalization is a section which provides further information on Personalization in WebSphere Studio. 580 IBM WebSphere Portal V4 Developer’s Handbook 10.5 Implementing personalization In this section, we will guide you through the implementation of some personalization scenarios based on the YourCo application. We will provide a step-by step guide to show how we implemented the examples. In addition, we discuss authorization and logging topics as they are directly related to our examples and will be included in the implementation. 10.5.1 Authorization considerations For Personalization, you can handle user authorization by using one of the following methods: Use WebSphere Application Server authentication Store the user login ID in the HTTP session object, using the Personalization context key pzn.userName. If the user login is different from the resource ID for the user data, you must select the method for mapping the current user to the stored user data. Adding the current user name to the session object If your Web application does not use WebSphere Application Server authentication, you must manually add the user name to the HttpSession object. The user is specified using the Personalization context key pzn.userName, where userName is the primary key of the target user profile. Example 10-7 Adding the current user name to the session object // Create the session object HttpSession session = request.getSession(true); // Intervening code to handle the authentication // the login and authentication is not shown. // The String primary_key is set to the primary // key for the current user. // // // // // Store the primary key for the user profile in the session. The primary_key variable was set using information obtained during login. Whether to authenticate the user is your decision. session.setAttribute("pzn.userName", primary_key); Chapter 10. Personalization 581 You may use session.putValue("pzn.userName", primary_key); this method is deprecated but is still acceptable. Mapping the current user to user data If the user authorization ID (the login ID) is different from the resource ID for the stored user data, you have two options for mapping the current user to a user resource in your customer data store: Use the Resource Console to manually define mappings of user authorization IDs to resource IDs. Implement the AuthIDTranslator interface and use the Resource Console to specify that class as your translator. For both the security mapping and the translator options, the resource IDs are treated as string data. If the primary key for the user data is not a string, your resource access classes must perform the following tasks: The getId method of your Resource implementation must convert the primary key to a string. In addition to modifying the getId method, you can define another method that returns the primary key in the appropriate type. The findById method of your ResourceDomain2 interface must convert the ID (passed in as a string) to the appropriate type before queries are made. If the primary key is referenced by your findResourcesByProperty method or findResourcesByQueryString method, make the same modification to those methods. 10.5.2 Logging options Logs are stored in a persistent data store using the Analytic Logging Service (ALS) of the WebSphere Application Server. You can use the WebSphere Personalization Resource Console to configure log settings. The log type options you can choose from are listed below. HttpLogger: when logging is enabled, HttpLogger is the default setting. HttpLogger uses the Site Analyzer Web Tracker to log information directly into the Site Analyzer database. DatabaseLogger: you can use the DatabaseLogger by providing the database connection parameters of the defined log storage database. FileLogger: you can use FileLogger to write to a file. For more details on how to enable logging, please refer to “Log Settings” on page 540. 582 IBM WebSphere Portal V4 Developer’s Handbook Note: Disable Logging is the default selection for Personalization V4. You manually have to select a log type to enable logging. Rule logging Rule information logging occurs when a rule is fired. Rule Logging can be controlled at the site level or at the individual rule level. You can disable rule logging for all rules, or you can enable it and then control (set on/off) the logging of each rule individually so that you can just log the rules of interest. If you have rule logging enabled, when the rule is fired information about the rule is automatically logged using the content spot beans. You can choose not to log a particular rule by turning off the instance variable that controls rule logging. The following information is logged when a rule is fired: LogType - RL (Rule Log) UserId - current user (String) CampaignName RuleName - top-level rule that was fired (String) ActionType - select/other RCName - name of resource collection (String) ResourceCount ResourceIds - returned if select action, list of Ids returned by the rule (comma delimited string) Timestamp For performance reasons, the logs will be flushed out once for every 50 records or when the session is ended, whichever happens first. You can force the flush by calling the PnzLogFinalizer flush() method. Example 10-8 Force log flush out if (session.getAttribute("pzn.logFinalizer") != null) { ((com.ibm.websphere.personalization.util.PznLogFinalizer) session.getAttribute("pzn.logFinalizer")).flush(); } Note: The flush of the logs applies to Rule Logging, ClickThru and Implicit Profiling. Chapter 10. Personalization 583 ClickThru logging You can insert a logging bean into a Web page. You can use the bean to log information about a Web site visitor's actions, an item, and the item's current status. When you want to log if a Web site visitor views the details of a particular item, include a logging bean in the details page. Item information and its corresponding status code is passed to this bean by the JSP programmer. To implement ClickThru logging, you must call setRequest(HttpServletRequest req) in each JSP. Example 10-9 ClickThru logging <jsp:useBean class="com.ibm.websphere.personalization.util.ClickThru" id="clickThru"/> <% clickThru.setRequest(request); %> <% clickThru.log("itemId",statusCode); %> Note: You have to set the values for "itemId",statusCode. Other ClickThru log methods include: ClickThru.log(String campaignName, String RuleName, String itemid, int statusCode); ClickThru.log(RuleTrigger myContentSpot, String itemid, int statusCode); The campaignName (CName) and ruleName (Rule) information is also logged in the ClickThru log. The default value for both attributes is "Unknown". The following information is logged when the details of an item are displayed: LogType - CT™ (ClickThru log) UserId - current user (String) ItemId - item ID (String) ResultCode - an integer from -10 to 10, assumption is that outcomes below zero are degrees of failure and that outcomes above zero are degrees of success Timestamp Implicit profiling with Category Beans As a user navigates your Web site, the Category bean can log the topics and topical hierarchies into the persistent data store using the Analytic Logging 584 IBM WebSphere Portal V4 Developer’s Handbook Service (ALS) of the WebSphere Application Server. You can use Site Analyzer to generate reports about most popular topics, least popular topics, etc. The reports can be based on individual users or groups of users. The Category bean uses the ALS to log the following information: LogType - IP (Implicit Profiling) UserId - User id for the session (String) Category - String indicating current category To implement Category beans, you must call the setRequest(HttpServletRequest req) in each JSP that will log topics and topical hierarchies. Example 10-10 Category Bean <jsp:useBean class="com.ibm.websphere.personalization.util.Category" id="category" scope="session"/> <% category.setRequest(request); %> <% category.log("CategoryParent/CategoryChild"); %> Note: You have to replace CategoryParent/CategoryChild with the topics you defined for profiling. As a user navigates through several Web pages, the Category bean with session scope tracks the different topics viewed in a session. The JSP only makes one call to a method to log a category (Category.log(String yourCat), and that one bean updates its own count for each category and calls the logging API. It constantly updates the counts for each hierarchy based on user navigation. This bean allows the JSP Programmer to set the topic in the page or be able to retrieve it from the Resource properties. For example, if a user visited four football pages in one session, his profile can updated to say Football fan. In the Category bean, if a user visits a page whose topic is Baseball/American/Boston, then the counts are updated as below: Baseball/American/Boston = Baseball/American/Boston + 1 Baseball/American = Baseball/American + 1 Baseball = Baseball + 1 Since the Category bean has session scope, you can create rules based on the counts and hierarchies stored to update the user profile. The user profile can be updated after running the Site Analyzer reports, or you can write a rule to use the Chapter 10. Personalization 585 current information stored in the session to update the profile or trigger rules based on the counts. Implicit profiling assumes that all content categorization is hierarchical. WebSphere Site Analyzer reports use the '/' character to establish each level. If the category is part of a hierarchy it must be a "/" delimited String, as in Baseball/American. However, you don't need to define a hierarchical model for your categories. In some cases, simply logging Football, Baseball and Basketball is sufficient. In other cases, you will want to create a hierarchy and have multiple levels of counts updated at once. WebSphere Site Analyzer for rule/campaign effectiveness Since you can set up Personalization to log information directly into the Site Analyzer database using the Site Analyzer Web Tracker, information on your Personalization solution can easily be visualized by Site Analyzer reports. You can generate reports to measure campaign and rule effectiveness, and modify content and rules accordingly. For Personalization in general, you can log the following. Top ten fired rules Least ten fired rules Most successful campaigns Least successful campaigns For each rule: Number of times fired Percentage of time at least one item was selected Percentage of time some amount of success Average number of items recommended For each campaign: Number of successes Number of failures 10.5.3 Applying Personalization to the YourCo sample The scenarios for our YourCo example will include examples for personalized content, Web site campaigns including priority and split and an e-mail campaign with a personalized e-mail page. First, we will create our sample portlet where we later include personalized content for logged in users. There we will demonstrate how to create the user resources, content resources, content spots, 586 IBM WebSphere Portal V4 Developer’s Handbook rules and all the basic settings for Personalization. Then we will create additional Web site campaigns to show how the assigned rules can be modified for a period of time. Finally, we will create the e-mail campaign. Creating the portal application project As our personalized content will be displayed in a portlet, we start with creating a new portlet application. 1. In WebSphere Studio Application Developer, select File -> New -> Portal application project. The create Portlet project wizard will open up. 2. Enter YourCoWelcome as the project name and YourCoPortalEAR as the enterprise application project name. Click Next. 3. Select Basic portlet from the list of portlet types and click Next. 4. On the following Basic portlet parameter window, modify the preset entries for Concrete portlet title to YourCoWelcome and Portlet class name to com.yourco.portlet.YourCoWelcome. Click Finish to create the portal application. You should now have a new YourCoWelcome project as shown in Figure 10-34 in the WebSphere Studio Application Developer Navigator view. Chapter 10. Personalization 587 Figure 10-34 WebSphere Studio Application Developer: YourCoWelcome portal project structure Creating the user resources In the Navigator view in WebSphere Studio Application Developer, select the YourCoWelcome -> source -> com -> yourco folder and add a new folder labeled resource. 1. Select the resource folder and click the User Wizard button. The User Resource Wizard V4 will open up. 2. Click Next to switch to the Logon tab of the User Wizard. 3. Enter the connection properties to your LDAP as illustrated in Figure 10-35. Use the settings that match your LDAP installation. 588 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-35 WebSphere Studio Application Developer User Wizard: LDAP logon 4. Click Connect to establish the connection to your LDAP. If you get an error, verify your settings and make sure that your LDAP server is running. 5. The wizard will continue to the Attribute tab and the available attributes from your LDAP schema will be displayed. Select the attributes as displayed in Figure 10-36. Chapter 10. Personalization 589 Figure 10-36 WebSphere Studio Application Developer User Wizard: Select attributes 6. In the list of selected attributes, select the uid and click the Primary Key button. Notice that the uid source will then appear in bold. 7. You can skip User Preferences and Mapping and click the Finish tab. 8. Select the User Resource from the File Description list and click the Rename button. 9. In the input window, replace InetOrgPerson with YourCoUser and click OK. Notice that in all the file names listed this change will be dealt with automatically. 10.Click Finish to have all listed files created. In the Navigator view of WebSphere Studio Application Developer, you will find the user resource files added to the YourCoWelcome project as marked in Figure 10-37. 590 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-37 WebSphere Studio Application Developer: User resource files added to YourCoWelcome project Creating the content resources The content we will use for our examples and for which we will create the content resources as next steps is in our DB2 databases, located in different tables: WSSAMPLES.Articles, WSSAMPLES.Companynews, WSSAMPLES.Product and YOURCOCM.Your_co_news. 1. Select the YourCoWelcome -> source -> com -> yourco -> resource folder and click the Content Wizard button. The Content Resource Wizard V4 will open up. 2. Click Next to switch to the Logon tab of the Content Wizard. 3. Enter the connection properties to your database as illustrated in Figure 10-38. Chapter 10. Personalization 591 Figure 10-38 WebSphere Studio Application Developer Content Wizard: Database Logon 4. Click Connect to establish the connection to your database. If you get an error, verify your settings and make sure that your database server is running. 5. The wizard will continue to the Tables tab and the available tables from your database will be displayed. Select the ARTICLES table as shown in Figure 10-39. 592 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-39 WebSphere Studio Application Developer Content Wizard: Table selection 6. Click Next. The Columns tab will appear. 7. Add all columns by clicking the double right arrow. 8. Select the Finish tab reassign the file names by selecting Content Resource from the File Description list and clicking the Rename button. 9. Replace Articles with YourCoArticles in the input window and click OK. All file names in the list will automatically be changed. 10.Click Finish to have the listed files created. Repeat these steps for the tables Companynews and Product from the WSSAMPLE database and the table Your_co_news from the YOURCOCM database. Rename the resources at the Finish tab to YourCoNews, YourCoProduct and CMNews. In the Navigator view of WebSphere Studio Application Developer, you will find the content resource files added to the YourCoWelcome project as shown in Figure 10-40. Chapter 10. Personalization 593 Figure 10-40 WebSphere Studio Application Developer: Content resource files added to YourCoWelcome project Creating the content spots After we have created the resources, we can create the content spots for our example. In the Navigator view in WebSphere Studio Application Developer, select the YourCoWelcome -> source -> com -> yourco folder and add a new folder labeled spot. 1. Select the spot folder and click the Content Spot Wizard button. The Content Spot Wizard V4 will open. 2. Click Next to switch to the Rule Type tab of the Content Spot Wizard. 3. Enter EmployeeData as the name for the content spot. Choose com.yourco.resource.YourCoUser from the return type list as illustrated in Figure 10-41. 594 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-41 WebSphere Studio Application Developer Content Spot Wizard: Selecting the return type 4. Click Next and then Finish. Repeat this steps to create a YourCoNews content spot returning com.yourco.resource.YourCoNews, a YourCoArticles content spot returning com.yourco.resource.YourCoArticles, a CMNews content spot returning com.yourco.resource.CMNews and a EmployeeType content spot that does not return anything (return type None). You should then see content spots in the WebSphere Studio Application Developer Navigator view of the YourCoWelcome project as indicated in Figure 10-42. Chapter 10. Personalization 595 Figure 10-42 WebSphere Studio Application Developer: Content spots added to YourCoWelcome project Creating the translator class Since we have global security activated for the application server and use LDAP for authorization, we have to implement a translator class for the uid. 1. Select the YourCoWelcome -> source -> com -> yourco -> resource folder. 2. Select File -> New -> Java Class. 3. The Java Cass dialog will open. Enter YourCoAuthIDTranslator as the name for the new class and add com.ibm.websphere.personalization.security.AuthIDTranslator to the list of extended interfaces. Mark the checkbox for creating inherited abstract methods. 4. Click Finish to create the class. 5. Open the YourCoAuthIDTranslator class in the WebSphere Studio Application Developer editor and implement the translateAuthID method as illustrated in Example 10-11. Example 10-11 WebSphere Studio Application Developer: YourCoAuthIDTranslator class import com.ibm.websphere.personalization.security.AuthIDTranslator; public class YourCoAuthIDTranslator implements AuthIDTranslator { /** * @see AuthIDTranslator#translateAuthID(String) */ public String translateAuthID(String name) { 596 IBM WebSphere Portal V4 Developer’s Handbook /**** if ldap, set to uid ****/ /***** find uid= *******/ System.out.println("uid to convert: " + name); String delim = new String("uid="); int x = name.indexOf(delim); /****** find comma **********/ String comma = new String(","); int y = name.indexOf(comma, x); /******* get uid *********/ if ((x >= 0) && (y>=0) ) name = name.substring(x+4,y); System.out.println("converted uid: " + name); return name; } } 6. Save the changes by pressing Crtl + s. Preparing the JSP Now we can modify the JSP to integrate and display the personalized content.In the WebSphere Studio Application Developer Navigator view, select YourCoWelcome -> webApplication -> jsp -> html -> View.jsp and double-click it. The JSP will be opened in the WebSphere Studio Application Developer Page Designer. 1. Click the Design tab and erase all of the existing content so that your page looks empty. 2. In the WebSphere Studio Application Developer Navigator view, select YourCoWelcome -> webApplication -> WEB-INF -> classes -> com -> yourco -> spot -> EmployeeDataSpot.class, press the left mouse button, and drag and drop the file to the top of the View.jsp in the edit window. An Attributes window opens. Click OK to accept the default values. 3. In the same way, add the EmployeeTypeSpot, the YourCoNewsSpot and the CMNewsSpot to the View.jsp. 4. Select the Source tab in the edit window and add the setRequest method to each of the beans in the JSP as shown in Example 10-12. Chapter 10. Personalization 597 Example 10-12 WebSphere Studio Application Developer: Adding the setRequest methods <jsp:useBean class="com.yourco.spot.EmployeeDataSpot" id="employeeDataSpot"> <% employeeDataSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.EmployeeTypeSpot" id="employeeTypeSpot"> <% employeeTypeSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.YourCoNewsSpot" id="yourCoNewsSpot"> <% yourCoNewsSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.YourCoArticlesSpot" id="yourCoArticlesSpot"> <% yourCoArticlesSpot.setRequest(request);%> </jsp:useBean> Creating the basic table construct Now we will create the table construct which we will populate with the personalized content. Switch to the Design tab and position the cursor behind the Bean icons, then select Insert -> Table from the menu. 1. In the Table dialog, enter 2 for Rows and Columns. Click OK. 2. Select the upper left cell of the created table and add another table with two rows and one column. This table will take our welcome messages. 3. Select the lower left cell, type YourCo internal news and click Enter. Insert another table with two rows and one column for YourCoNews. 4. In the same cell, click Enter again and type Other interesting articles, then click Enter. Then insert another table with two rows and one column for the YourCoArticles. You should now have a table construct as shown in Figure 10-43. 598 IBM WebSphere Portal V4 Developer’s Handbook Message table Image cell News table Articles table Figure 10-43 WebSphere Studio Application Developer: Adding the table construct Creating the personalized welcome message output To create the personalized welcome message, we have to associate the content spot with the table. Double-click the message table to get the table attributes dialog. 1. Select the Dynamic tab and mark the Loop checkbox. 2. Click the Browse button to get the Bean Property Selection dialog. 3. Select employeeDataSpot -> ruleContent[] as shown in Figure 10-44 and click OK. Chapter 10. Personalization 599 Figure 10-44 WebSphere Studio Application Developer: Setting the dynamic table attributes 4. The Loop property is now set to the ruleContent[]. Click OK to close the table attributes dialog. 5. Select the upper cell of the message table and enter Welcome. Select Insert -> Dynamic Elements -> Property Display. The property attributes dialog will open. 6. Click the Browse button and select ruleContent[] -> cn from the selection dialog as illustrated in Figure 10-45. 600 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-45 WebSphere Studio Application Developer: Setting the dynamic property 7. Click OK to confirm your selection. 8. Click OK to set the attribute. You can enter a message and further dynamic properties in the lower cell of the message table. Creating the personalized YourCo news output Next, we create the personalized YourCo news in the news table. Double-click the news table to get the table attributes dialog. 1. Select the Dynamic tab and mark the Loop checkbox. 2. For the Row/Column range enter 1 for Start and 2 for End. 3. Click the Browse button to get the Bean Property Selection dialog. 4. Select yourCoNewsSpot -> ruleContent[] and click OK. 5. The Loop property is now set to the ruleContent[]. Click OK to close the table attributes dialog. 6. Select the upper cell of the news table. Select Insert -> Dynamic Elements -> Property Display. The property attributes dialog will open. Chapter 10. Personalization 601 7. Click the Browse button and select ruleContent[] -> Title from the selection dialog. Click OK to confirm your selection. 8. Click OK to set the attribute. 9. Select the lower cell of the news table. Select Insert -> Dynamic Elements -> Property Display. The property attributes dialog will open. 10.Click the Browse button and select ruleContent[] -> Content from the selection dialog. Click OK to confirm your selection. 11.Click OK to set the attribute. Creating the personalized articles output For the articles section, we will now populate the table in the same way. Double-click the articles table to get the table attributes dialog. 1. Select the Dynamic tab and mark the Loop checkbox. 2. For the Row/Column range, enter 1 for Start and 2 for End. 3. Click the Browse button to see the Bean Property Selection dialog. 4. Select yourCoNewsSpot -> ruleContent[] and click OK. 5. The Loop property is now set to the ruleContent[]. Click OK to close the table attributes dialog. 6. Select the upper cell of the articles table. Select Insert -> Dynamic Elements -> Property Display. The property attributes dialog will open. 7. Click the Browse button and select ruleContent[] -> Title from the selection dialog. Click OK to confirm your selection. 8. Click OK to set the attribute. 9. Select the lower cell of the articles table. Select Insert -> Dynamic Elements -> Property Display. The property attributes dialog will open. 10.Click the Browse button and select ruleContent[] -> Content from the selection dialog. Click OK to confirm your selection. 11.Click OK to set the attribute. Creating a personalized image output Finally, we will add an image to be displayed in our welcome portlet depending on the user type. Since we will classify our users into executives, managers, employees and others, we add an image for each of these to our project. 1. Select YourCoWelcome -> webApplication and add a new image folder. 2. Import four images from the file system to the image folder and rename them to emp.gif, exec.gif, mgr.gif and other.gif. 602 IBM WebSphere Portal V4 Developer’s Handbook 3. Select the image cell from the table and switch to the Source tab of the edit window. The cursor is positioned in the cell you just selected. 4. Add the code shown in Example 10-13 into the image cell. Example 10-13 WebSphere Studio Application Developer: Adding images based on classification <% String imagePath = response.encodeURL("/images/"); if (employeeTypeSpot.isClassifiedAs("Executive")) { %> <IMG src="<%= imagePath %>exec.gif" width="177" height="109" border="0"> <% } if (employeeTypeSpot.isClassifiedAs("Manager")) { %> <IMG src="<%= imagePath %>mgr.gif" width="148" height="178" border="0"> <% } if (employeeTypeSpot.isClassifiedAs("Employee")) { %> <IMG src="<%= imagePath %>emp.gif" width="101" height="126" border="0"> <% } else { %> <IMG src="<%= imagePath %>other.gif" width="121" height="91" border="0"> <% } %> 5. Press Ctrl + s to save View.jsp. Note: You can modify the output table and, for example, use background colors and different headings to make the content easier to read. Deployment of the sample portlet As the main components of our YourCoWelcome portlet are ready now, we can deploy the portlet to the Portal Server. 1. Select the YourCoWelcome project, right-click it to get the context menu. 2. Select Export WAR. The WAR export dialog will open. 3. Enter c:\yourco\YourCoWelcome.war for the export location and click Finish. The WAR will be created and the WAR export dialog will close. 4. Log on to your Portal Server as Administrator and go to the Portal Administration place. 5. Select Portlets -> Install Portlets. 6. Enter c:\yourco\YourCoWelcome.war in the directory input field and click Next. 7. You will see the summary of the portlets to install (which is, in our case, simply the YourCoWelcome portlet). Click Install. Chapter 10. Personalization 603 8. The portlet will be added and you will get the message Portlets successfully installed. Now, we have to set the permissions for the portlet. 9. Select Portal Administration -> Security -> Access Control List and mark the Special Groups radio button. Select All authenticated users as the group for which to assign the rights and select portlets from the list of objects for the permission. 10.Click the Go button to load the portlet security permissions for your selected properties. 11.At the table of all portlets, look for the YourCo Expiring HTML portlet and mark the radio button in the None column. Look for the YourCoWelcome portlet and mark the radio button in the View column. This will result in showing the YourCo Expiring HTML portlet only to anonymous users and the YourCoWelcome portlet only to logged in users. 12.Click Save to save your changes. 13.Click the Get groups and users link. 14.Search for groups using the wildcard character. 15.Mark the wpsuser group and add this group to the selected groups list, then click OK to return. 16.Click the Go button to load the portlet security permissions for the wpsuser group. 17.Set the permission for the YourCo Expiring HTML portlet to None. 18.Click Save. 19.Switch to the Work with Pages place and select the Edit Layout and Content tab. From the place list, select YourCo and from the page list, select Home. 20.The layout manager will show the setup of the YourCo start page. Click Show layout controls. 21.Delete all row containers by clicking the X. In the confirm dialog, click the OK button. You should then only have the default page container. 22.Click the Get Portlets link. 23.Mark the Search for Portlets radio button and enter yourco in the name contains input field. 24.Click the Go button. 25.In the table of search results, click the add button in front of the YourCo Expiring HTML portlet and the YourCoWelcome portlet. The portlets will appear in the portlet list. 26.Click the OK button to get back to the layout manager. 27.Click the Add a column container button to create a new container. 604 IBM WebSphere Portal V4 Developer’s Handbook 28.In the portlet list, mark both portlets and click the Add selected portlets to container button. Your page should then look like the one shown in Figure 10-46. Figure 10-46 Portal Administration: YourCo start page layout 29.Click Activate to save your changes. Publish the resources to Personalization Runtime To register the resources to the Personalization Runtime, we need to export our class and .hrf files from the YourCoWelcome portal application project and import them at the Resource Console. Export the resources from WebSphere Studio Application Developer 1. Select the YourCoWelcome project in the WebSphere Studio Application Developer Navigator view. 2. Select File -> Export to open the export dialog. 3. Select File System and click Next. Chapter 10. Personalization 605 4. Deselect the YourCoWelcome project, as we do not want to export all files. In the tree structure, open YourCoWelcome -> webApplication -> WEB-INF -> classes. Check only the com folder. 5. Enter c:\yourco\classes as the export destination and click Finish. 6. When asked whether to create the folders, click OK. The class files will be exported. 7. Redo Steps 1 to 3. 8. Deselect the YourCoWelcome project, as you do not want to export all files. In the tree structure, open YourCoWelcome -> webApplication -> WEB-INF -> wcm-resourceCollections -> com -> yourco. Check only the resource folder. 9. Enter c:\yourco as the export destination and click Finish. This time, the hrf files will be exported. 10.In your Windows Explorer, you should now find the structure as shown in Figure 10-47. Figure 10-47 Windows Explorer: Structure of exported resources Importing the resources to the Resource Console First, you have to make the exported files accessible to the application server. If the application server runs on a different node, copy the yourco directory to that node. Open the Resource Console and log on. Also, copy the yourco\classes\com folder to the classes folder of the Resource Console. 1. Switch to the Resource Hierarchies tab. 2. Click the Import button. 3. Enter the path and file name for the resources as shown in Figure 10-48. 606 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-48 Resource Console: Specify a resource to import 4. Click the Import File button. 5. After the resource is imported, a confirmation message is displayed. Click the Import button again and import YourCoProduct.hrf, YourCoNews.hrf, YourCoArticles.hrf and CMNews.hrf in the same way. 6. Then, switch to the Security tab. 7. Select YourCoUser from the hierarchy section of the resource list as shown in Figure 10-49. Chapter 10. Personalization 607 Figure 10-49 Resource Console: Selecting the hierarchy for adding a translator 8. Click the Add Translator button and enter com.yourco.resource.YourCoAuthIDTranslator as the class name for the translator. 9. Click Add/Change to add the translator. A confirmation window will pop up saying that your translator has been set. Click OK. If you get an error message, verify that the class is accessible to the Resource Console. 10.Click the Enable Security button. A confirmation window will pop up saying that security is enabled. Click OK. Creating the Personalization project and rules The next step is the creation of rules and binding them to the content spots in our portlet to actually retrieve personalized content. We first have to set up our Personalization project in the Personalization Workspace. Open the PersWorkspace in your browser and log on. Setting up the Personalization project 1. In the PersWorkspace, click Global Settings. The Global Settings window will open up. 2. Switch to the Manage Publish Servers tab and click the Add button to add a new Publish Server, pointing to your application server (we assume that you run your application server locally and use localhost to continue). Enter the values as illustrated in Figure 10-50. 608 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-50 PersWorkspace: Adding a publish server 3. Click Save to add the publish server. 4. Switch to the Manage Projects tab. Add a new project by clicking the Add button. 5. Enter YourCoPersonalization as the project name and c:\yourco\personalization as the project path and click the Create new radio button in the add project dialog. Click OK to save your settings. 6. The Edit Project dialog will open up. Enter the values as shown in Figure 10-51. Chapter 10. Personalization 609 Figure 10-51 PersWorkspace: Project settings for YourCo 7. Click Save to save your settings and return to the Global Settings window. 8. Click the Make Current button to work with the new project. 9. The Global Setting window will be closed and PersWorkspace will show the Rule Composer tab. Creating the rules For a first approach, we will simply create some basic rules at that point. Later, when we use concurrent campaigns, we will create and add more sophisticated rules. In PersWorkspace, switch to the Rule Composer tab. 1. Start with creating the classifiers. a. From the list of rule types, select Classifiers. 610 IBM WebSphere Portal V4 Developer’s Handbook b. Click the Add button as demonstrated in Figure 10-52. The Add Classifier dialog will open up. Figure 10-52 PersWorkspace: Adding a classifier rule c. Enter classifyEmployeeTitle as the name for the classifier. d. As a comment, enter Classifies the employee title based on LDAP.title. e. Click the Classification link. The classification name dialog will open up. f. Enter Executive and click the Save button. g. Click the Resource.Attibute link. The attribute dialog will show up. h. From the resource list, select the current YourCoUser and mark title in the attribute list. i. Click the is equal to link. The evaluation dialog will open up. j. Select includes from the evaluation list and click Save. k. Click the value link to open the value dialog. l. Enter CEO and click the Save button. m. Click the add Condition link to insert another evaluation for this classifier. n. Repeat Steps h to l but enter CIO as the value in Step l. o. By default, both evaluations are linked by the and condition. Change that by clicking the and link and marking or in the selection dialog. Click the Save button to save the condition. p. Click the add Classification link. q. Repeat Steps f to l, adding a “Manager” classification, checking the title attribute for “manager“. r. Click the Classification link at the Otherwise part of this rule. s. Enter Employee for the classification name and click the Save button. Chapter 10. Personalization 611 t. Click the Save button to save the rule. Your classifyEmployeeType rule should now look like in Figure 10-53. Figure 10-53 PersWorkspace: classifyEmployeeTitle classifier rule 2. Next, create actions to retrieve content. As you created three content spots to display personalized content, create three basic content retrieval actions: user data, YourCo news and articles. a. From the list of rule types, select Actions. b. Click the Add button. The Add Action dialog will open up. c. Enter getUserData as the name of the action. d. In the comment input field, enter Retrieve user data from LDAP. e. As the type of action, select Select content. f. Click the Resource.Attribute link. The attribute dialog will open up. g. Mark the YourCoUser resource and the uid attribute as shown in Figure 10-54. 612 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-54 PersWorkspace Add Action: Selecting resource attributes h. Click Save. i. Click the value link. The specify value dialog will open up. j. Click the Browse button. Another attribute dialog will open up. k. Select again the YourCoUser resource and the UID attribute and click Save to return to the specify value dialog. l. There, click Save to add the selected value to your action rule. Note that even though selecting the same attributes, they refer to different objects: the first YourCoUser points to the LDAP users the second to the current user (as indicated by the key current). m. Click the Save button to save the action rule. The rule will now show up on the Rule Composer, as illustrated in Figure 10-55. Chapter 10. Personalization 613 Figure 10-55 PersWorkspace Rule Composer: getUserData action rule n. Repeat Steps a to m to create these additional rules: • getYourCoNewsConf (as shown in Figure 10-56). Figure 10-56 PersWorkspace: getYourCoNewsConf action rule 614 IBM WebSphere Portal V4 Developer’s Handbook • getYourCoNewsNotConf (as shown in Figure 10-57). Figure 10-57 PersWorkspace: getYourCoNewsNotConf action rule • getYourCoNewsByUserDept (as shown in Figure 10-58). Figure 10-58 PersWorkspace: getYourCoNewsByUserDept action rule Chapter 10. Personalization 615 • getYourCoArticlesByUserDept (as shown in Figure 10-59). Figure 10-59 PersWorkspace: getYourCoArticlesByUserDept action rule 3. As the next step, create the bindings to combine actions and classifiers. a. From the list of rule types, select Bindings. b. Click the Add button. The Add Action dialog will open up. c. Enter BindNews2EmpTitle as the name of the action. d. In the comment input field, enter Bind the actions for retrieving news to the employee title. e. Click the Classifier link. The classifier selection dialog will open. f. Select classifyEmployeeType and click the Save button. g. Click the first Classification link. The classification dialog will open. h. Mark the checkboxes for Manager and Executive and click the Save button. i. Click the first do Action link. The Select Action dialog will open up. j. In the list of available actions, mark the getYourCoNewsConf action rule and click Save. k. Click the next Classification link. l. Mark Employee in the classification dialog and click Save. m. Click the do Action link. The Select Action dialog will open up. n. In the list of available actions, mark the getYourCoNewsNotConf action rule and click Save. 4. Finally, assign the rules to the content spots. a. Switch to the Campaign Manager tab. 616 IBM WebSphere Portal V4 Developer’s Handbook b. From the campaign type list, select Web site. c. Select Normal View (which is the default campaign). d. You will see all your content spots listed in the rules usage table. As no rules were assigned to content spots so far, all entries in the rule column are set to empty. e. Click the rule (empty) link for the EmployeeDataSpot. The Fill Content Spot dialog will open up. f. Select the getUserData rule and click OK. In the same way, assign rules to your content spots as shown in Figure 10-60. Figure 10-60 PersWorkspace: rule usage table Previewing the Personalized Portlet To make use of the Personalization Workspace preview capabilities, we have to modify/enhance our Portlet as demonstrated in Example 10-14. Example 10-14 YourCoWelcome portlet: Modification in View.jsp for preview <%@ page contentType="text/html"%> <jsp:useBean class="com.yourco.spot.EmployeeDataSpot" id="employeeDataSpot"> <% employeeDataSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.EmployeeTypeSpot" id="employeeTypeSpot"> <% employeeTypeSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.YourCoNewsSpot" id="yourCoNewsSpot"> <% yourCoNewsSpot.setRequest(request);%> Chapter 10. Personalization 617 </jsp:useBean> <jsp:useBean class="com.yourco.spot.YourCoArticlesSpot" id="yourCoArticlesSpot"> <% yourCoArticlesSpot.setRequest(request);%> </jsp:useBean> <%= employeeDataSpot.getPreviewAnchorTag() %> <TABLE border="0" align="left"><TBODY><TR> <TD valign="top" align="left"> <%--METADATA type="DynamicData" startspan <TABLE border="0" innerloopproperty="employeeDataSpot.ruleContent[]" innerloopdirection="vertical" innerloopstartindex="0" innerloopendindex="2" dynamicelement> <TBODY> <TR> <TD align="left"><B><FONT size="+1">Welcome <WSPX:PROPERTY property="employeeDataSpot.ruleContent[].cn"></FONT></B></TD> </TR> <TR> <TD align="left">YourCo Intranet now offers personalized services for employees!</TD> </TR> <TR><TD> </TD></TR> </TBODY> </TABLE> --%><% try { com.yourco.resource.YourCoUser[] _a0 = employeeDataSpot.getRuleContent(); com.yourco.resource.YourCoUser _p0 = _a0[0]; // throws an exception if empty. %> <TABLE border="0"> <TBODY><% for (int _i0 = 0; ; ) { %> <TR> <TD align="left"><B><FONT size="+1">Welcome <%= _p0.getCn() %></FONT></B></TD> </TR> <TR> <TD align="left">YourCo Intranet now offers personalized services for employees!</TD> </TR> <TR> <TD> </TD> </TR><% _i0++; try { _p0 = _a0[_i0]; 618 IBM WebSphere Portal V4 Developer’s Handbook } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { break; } } %> </TBODY> </TABLE><% } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { } %><%--METADATA type="DynamicData" endspan--%> </TD> <TD rowspan="2" valign="top" bgcolor="#CCCCCC"> <%= employeeTypeSpot.getPreviewAnchorTag() %> <% String imagePath = response.encodeURL("/images/"); if (employeeTypeSpot.isClassifiedAs("Executive")) { %> <IMG src="<%= imagePath %>exec.gif" width="177" height="109" border="0"> <% } else if (employeeTypeSpot.isClassifiedAs("Manager")) { %> <IMG src="<%= imagePath %>mgr.gif" width="148" height="178" border="0"> <% } else if (employeeTypeSpot.isClassifiedAs("Employee")) { %> <IMG src="<%= imagePath %>emp.gif" width="101" height="126" border="0"> <% } else { %> <IMG src="<%= imagePath %>other.gif" width="121" height="91" border="0"> <% } %> </TD></TR><TR><TD> <DIV align="left"> <%= yourCoNewsSpot.getPreviewAnchorTag() %> <%--METADATA type="DynamicData" startspan <TABLE border="0" innerloopproperty="yourCoNewsSpot.ruleContent[]" innerloopdirection="vertical" innerloopstartindex="1" innerloopendindex="3" dynamicelement> Chapter 10. Personalization 619 <TBODY> <TR> <TD align="left"><B><FONT size="+1">YourCo internal news</FONT></B></TD> </TR> <TR> <TD bgcolor="#CCCCCC" align="left"><WSPX:PROPERTY property="yourCoNewsSpot.ruleContent[].TITLE"></TD> </TR> <TR> <TD align="left"><WSPX:PROPERTY property="yourCoNewsSpot.ruleContent[].CONTENT"></TD> </TR> <TR> <TD></TD> </TR> </TBODY> </TABLE> --%><% try { com.yourco.resource.YourCoNews[] _a0 = yourCoNewsSpot.getRuleContent(); com.yourco.resource.YourCoNews _p0 = _a0[0]; // throws an exception if empty. %> <TABLE border="0"> <TBODY> <TR> <TD align="left"><B><FONT size="+1">YourCo internal news</FONT></B></TD> </TR><% for (int _i0 = 0; ; ) { %> <TR> <TD align="left" bgcolor="#CCCCCC"><%= _p0.getTITLE() %></TD> </TR> <TR> <TD align="left"><%= _p0.getCONTENT() %></TD> </TR> <TR> <TD></TD> </TR><% _i0++; try { _p0 = _a0[_i0]; } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { break; } } %> </TBODY> </TABLE><% 620 IBM WebSphere Portal V4 Developer’s Handbook } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { } %><%--METADATA type="DynamicData" endspan--%> </DIV> <BR> <DIV align="left"> <%= yourCoArticlesSpot.getPreviewAnchorTag() %> <%--METADATA type="DynamicData" startspan <TABLE border="0" innerloopproperty="yourCoArticlesSpot.ruleContent[]" innerloopdirection="vertical" innerloopstartindex="1" innerloopendindex="3" dynamicelement> <TBODY> <TR> <TD align="left"><B><FONT size="+1">Other interesting news</FONT></B></TD> </TR> <TR> <TD bgcolor="#CCCCCC" align="left"><WSPX:PROPERTY property="yourCoArticlesSpot.ruleContent[].TITLE"></TD> </TR> <TR> <TD align="left"><WSPX:PROPERTY property="yourCoArticlesSpot.ruleContent[].CONTENT"></TD> </TR> <TR> <TD> </TD> </TR> </TBODY> </TABLE> --%><% try { com.yourco.resource.YourCoArticles[] _a0 = yourCoArticlesSpot.getRuleContent(); com.yourco.resource.YourCoArticles _p0 = _a0[0]; // throws an exception if empty. %> <TABLE border="0"> <TBODY> <TR> <TD align="left"><B><FONT size="+1">Other interesting news</FONT></B></TD> </TR><% for (int _i0 = 0; ; ) { %> <TR> <TD align="left" bgcolor="#CCCCCC"><%= _p0.getTITLE() %></TD> </TR> <TR> <TD align="left"><%= _p0.getCONTENT() %></TD> Chapter 10. Personalization 621 </TR> <TR> <TD> </TD> </TR><% _i0++; try { _p0 = _a0[_i0]; } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { break; } } %> </TBODY> </TABLE><% } catch (java.lang.ArrayIndexOutOfBoundsException _e0) { } %><%--METADATA type="DynamicData" endspan--%> </DIV> </TD> </TR></TBODY></TABLE> Save the changes, create a new war file from the project, update/redeploy the YourCoWelcome Portlet and then, switch to the Preview Launcher tab. Since we are using the preview for the first time, we first have to create the preview users: 1. Click Add Profile. The add profile dialog will open up. 2. As the name for the profile, enter YourCoManager, then enter mgr as uid, YourCo as sn, YourCo Manager as cn, Corp as ou, Manager as givenName and Manager as title. Click the Save button. 3. Copy the YourCoManager by clicking the Duplicate Profile button. 4. Modify the profile attributes by clicking the Edit Profile button. 5. As the name for the profile, enter YourCoEmployee, then enter empl as uid, YourCo as sn, Mfg as ou, Employee as givenName and Programmer as title. Click the Save button. Now you can preview the portlet with one of the profiles. 1. Click the Preview button. 2. In the Preview dialog, select YourCoEmployee as the profile as shown in Figure 10-61. 622 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-61 PersWorkspace: Preview profile selection 3. Click OK. The Internet browser will open and display the page as shown in Figure 10-62. Figure 10-62 Preview of YourCoWelcome Portlet On the preview page, you will have interactive buttons representing the content spots in your portlet. They correspond to the scriptlets highlighted in Example 10-14. When you select the YourCoManager profile in the preview dialog, you will realize the different personalized content for this user profile. Chapter 10. Personalization 623 You can change the rule assigned to a content spot on the preview page by clicking the content spot. Then a dialog will open, offering all assignable rules for this content spot. Figure 10-63 illustrates the Fill Content Spot dialog for the YourCoWelcome portlet preview page. Figure 10-63 PersWorkspace Preview: Fill Content Spot dialog If the preview date falls into a specific campaign other than the default Web site campaign, this campaign will be displayed in bold. You can assign different rules not only to the active campaign but also to all other campaigns of your current project. Publishing As the next step, we will publish the rules to the application server. 1. Open the Global Settings and select the Publish Files section. 2. As the publish server, select localhost and as the publish method, select Publish All. 3. Click the Publish button. Confirmation dialogs will inform you about the progress, as illustrated in Figure 10-64. 624 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-64 PersWorkspace: Publish files Additional campaigns To use splitting and prioritizing of campaigns, we will add three additional campaigns. Before adding the campaigns, we need two more rules: getYourCoNewsForRaleigh, returning all news articles where the attribute FORSITE is equal to Raleigh getYourCoNewsForSeattle, returning all news articles where the attribute FORSITE is equal to Seattle Create these rules as described in “Creating the rules” on page 610. Then switch to the Campaign Manager tab of PersWorkspace and click the Add Campaign button. In the dialog, enter NewsForRaleigh as the name of the campaign, but leave the default values for the begin and end dates; click the Save button. The campaign will be added with an empty rule mapping table. Click the rule link for the YourCoNewsSpot, select the getYourCoNewsForRaleigh action rule in the rule selection dialog and save your change by clicking the OK button. Your new campaign should look like that shown in Figure 10-65. Chapter 10. Personalization 625 Figure 10-65 PersWorkspace: NewsForRaleigh campaign Copy this campaign by clicking the Duplicate Campaign button. You will get a new campaign named Copy of NewsForRaleigh. Modify this new campaign as shown in Figure 10-66. Figure 10-66 PersWorkspace: NewsForSeattle campaign 626 IBM WebSphere Portal V4 Developer’s Handbook Copy this campaign again by clicking the Duplicate Campaign button. You will get a new campaign named Copy of NewsForSeattle. Modify this new campaign as shown in Figure 10-67. Figure 10-67 PersWorkspace: NewsForUserDept campaign Switch to the Priorities section. You will see that the three campaigns are added with different priorities. Click the Edit Priorities button. The dialog for manipulating the campaign priorities will open. Change the properties as shown in Figure 10-68. Chapter 10. Personalization 627 Figure 10-68 PersWorkspace: Campaign properties, priority and split of campaigns Now you can preview the Web site at different dates, having executed the rules defined in the campaigns for this particular date. Creating e-mail campaigns As e-mail campaigns, we will send a personalized e-mail announcing a new YourCo product to the YourCo users. Creating additional content spots for e-mails To personalize the e-mail, we need some more content spots. As described in “Creating the content spots” on page 594, add three new content spots in YourCoWelcome -> source -> com -> Yourco -> spot in WebSphere Studio Application Developer: EmailHelperSpot, returning com.yourco.resource.YourCoUser EmailRecipientSpot, returning com.yourco.resource.YourCoUser EmailProductSpot, returning com.yourco.resource.YourCoProduct Creating the e-mail template JSP 1. In the Navigator view of WebSphere Studio Application Developer, click YourCoWelcome -> webApplication -> jsp and click File -> New -> JSP File. The JSP File dialog will open. 2. Enter email_template as the file name and click the Finish button. 628 IBM WebSphere Portal V4 Developer’s Handbook 3. The JSP will be created and opened in the editor. 4. Modify the JSP source according to Example 10-15. Example 10-15 Personalized e-mail campaign: email_template.jsp <HTML> <HEAD> </HEAD> <BODY background="/wps/themes/html/YourCo/bg.gif"> <jsp:useBean class="com.yourco.spot.EmailRecipientSpot" id="emailRecipientSpot"> <% emailRecipientSpot.setRequest(request);%> </jsp:useBean> <jsp:useBean class="com.yourco.spot.EmailProductSpot" id="emailProductSpot"> <% emailProductSpot.setRequest(request);%> </jsp:useBean> <TABLE border="0" width="300"> <TBODY> <TR> <TD> <img src="/wps/themes/html/YourCo/topBanner.gif"> <p> </TD> </TR> <TR> <TD><h3> <%= emailRecipientSpot.getPreviewAnchorTag() %> <P>Dear <%=emailRecipientSpot.getRuleContent(0).getCn()%>, </TD> </TR> <TR> <TD> YourCo just announced <b><%=emailProductSpot.getRuleContent(0).getNAME()%></b>. Here is an exclusive description of the new product for you.</P> </TD> </TR> <TR> <TD><%= emailProductSpot.getPreviewAnchorTag() %> <h3> <%=emailProductSpot.getRuleContent(0).getNAME()%></TD> </TR> <TR> Chapter 10. Personalization 629 <TD><p><%=emailProductSpot.getRuleContent(0).getDESCRIPTION()%></TD> </TR> </TBODY> </TABLE> </BODY> </HTML> Creating and assigning rules for e-mails In PersWorkspace, switch to the Rule Composer tab and as described in “Creating the rules” on page 610, and add an action rule as shown in Figure 10-69. Figure 10-69 PersWorkspace: getYourCoProducts action rule Switch to the Campaign Manager tab of PersWorkspace, select Web site -> Normal View and assign rules to the content spots for e-mails as illustrated in Figure 10-70. 630 IBM WebSphere Portal V4 Developer’s Handbook Figure 10-70 PersWorkspace: Assigning rules for e-mail content spots Note: Even though the rules will be used for e-mail campaigns, the mapping of content spot and rule is done at the default Web site campaign. Adding and configuring e-mail campaigns To set up an e-mail campaign, switch to the Campaign Manager tab. Select E-mail from the campaign type list. Click the Add E-mail Campaign button and enter the values as shown in Figure 10-71. Chapter 10. Personalization 631 Figure 10-71 PersWorkspace E-mail campaign: configure settings Click the Save button to activate your e-mail campaign. It will then appear in the list of e-mail campaigns as illustrated in Figure 10-72. Figure 10-72 PersWorkspace: active e-mail campaign 632 IBM WebSphere Portal V4 Developer’s Handbook Note: The e-mail campaign will not be executed until you publish it. Make sure that you republish all components to the appropriate locations on the application server! Previewing the personalized e-mail Before you actually send out your e-mails, you might want to check what they would look like. For our set up, you will have to copy the classes and the email_template.jsp from your deployed YourCoWelcome project on the application server to the PersEmail Web application. Then switch to the Preview Launcher tab of PersWorkspace and click the Preview button. In the upcoming preview dialog, enter /wps/PersEmail/yourco/email_template.jsp as Page and click OK. Your Web browser will open up and display the e-mail body as illustrated in Figure 10-73. Figure 10-73 PersWorkspace: Preview of e-mail body 10.6 Migration of Personalization V3.5.x solutions While there are a number of new capabilities, existing rules and resource classes created with WebSphere Personalization V3.5.x will run without change on WebSphere Personalization V4.1. However, because of the upgraded function, there are a few things that you will need to do to use your existing V3.5.x Personalization solution after you install WebSphere Personalization V4.1. Chapter 10. Personalization 633 1. Define a new Personalization project within the WebSphere Personalization V4.1 workspace server. There are a few directories that you define, including: – One or more directories where rules will reside – One or more directories where resource definition files will reside (resource_name.hrf files) – One or more directories where resource class files will reside – One or more directories where content spots (and rule wrapper beans from Version 3.5) will reside 2. Load existing rule files into the WebSphere Personalization V4.1 authoring server. You will need to do this for each existing WebSphere Studio project which contains rules you want to use within the new Version 4.1 Personalization project. There is one .rul, .act or .clf file per rule. Do this by copying all of the files within <studioprojectroot>\projects\<project_name>\rules to the directory or directories you defined for rules within the Version 4 project (these directories are defined in Global Settings in the Personalization workspace). 3. Load your existing resource definition files into the WebSphere Personalization V4.1 authoring server. Do this for each existing WebSphere Studio project with resource definitions that you want to use within the new Version 4.1 Personalization project. There is one .hrf file per resource definition. Do this by copying all of the files within <studioprojectroot>\projects\<project_name>\resources to the directory or directories you defined for resource definitions within the Version 4 project. 4. Copy your existing resource class files into the WebSphere Personalization V4.1 authoring server. You need to do this for each existing WebSphere Studio project with resource classes that you want to use within the new Version 4.1 Personalization project. There are typically two or three .class files per resource definition. Do this by copying the resource class files from within <studioprojectroot>\projects\<project_name>\servlets to the directory(s) you defined for resource classes in the Version 4.1 workspace. Since these are class files, make sure that you put them into the same relative directories as they were in within the Studio project. 5. Copy your existing rule wrapper bean classes into the WebSphere Personalization V4.1 workspace server. Do this for each existing WebSphere Studio project with rule wrapper bean classes that you want to use within the new Version 4.1 Personalization project. Do this by copying the rule wrapper bean class files from within <studioprojectroot>\projects\<project_name>\servlets to the directory or directories you defined for resource classes in the Version 4.1 workspace. Since these are class files, make sure that you put them into the same relative directories as they were in within the Studio project. 634 IBM WebSphere Portal V4 Developer’s Handbook 6. Go to the Campaign Manager within the Personalization workspace and create a default rule mapping to map each rule wrapper bean (now a content spot) to the corresponding rule. 7. Publish the newly defined project to the server on which you installed Personalization Version 4.1. 8. In order to take full advantage of the new preview support (specifically, the ability to link from a content spot on a page directly to the rule editor for that content spot), you will need to add the content spot references within the existing JSPs. This involves adding the following scriptlet in your JSPs wherever you invoke Personalization rules: <%=contentspotbean.getPreviewAnchorTag()%> where contentspotbean is the reference to the personalization content spot bean (rule wrapper bean in V3.5.x). If you developed an application using Personalization V3.5 (without fix 1, PQ41844) and the application uses resource classes that have multi-value properties, you will need to modify the resource classes for use with Personalization V4.0. Migration is necessary, because this release of Personalization does not support the HRFINCLUDES string that Personalization V3.5 uses to handle multi-value properties. To use Personalization 3.5 resource classes in Personalization 4.1, you must remove the line import com.ibm.ejs.dbm.jdbcext.* from the Manager class and recompile the java file. Alternatively, you can change the connection pooling to the WebSphere Application Server V4 connection pooling. Chapter 10. Personalization 635 636 IBM WebSphere Portal V4 Developer’s Handbook 11 Chapter 11. Content management This chapter discusses the content management tools shipped with WebSphere Portal. A sample scenario will be used to guide you through the essential steps for content publishing using Web Content Publisher. Various ways to display published contents using portlets will also be exemplified. At the end of the chapter, a generic approach of leveraging third-party content management software with WebSphere Portal will be discussed. By the end of the chapter, you should be able to: Obtain an understanding of Web Content Publisher Create and administer a Web Content Publisher project Create and deploy structured contents Create authoring and generation templates Define channel contents Perform resource-to-resource transformation Publish contents from Web Content Publisher to multiple publishing servers Serve published contents in WebSphere Portal Create a customized workflow using Lotus Workflow™ Architect and Lotus Workflow Configure and use Portal Content Organizer (PCO) for file sharing among Portal users Understand how to integrate third-party content management software with WebSphere Portal © Copyright IBM Corp. 2003. All rights reserved. 637 11.1 Introduction This chapter focuses on the development aspect of content management. However, it includes configuration steps worth emphasizing during the development process. The Internet has evolved to become one of the major channels for information distribution. One of the challenges that many organizations face today is the increasing demand for timely and accurate information updates on their Web sites. The challenge is further complicated by the advent of mobile Internet access with various non-PC devices such as cell phones and PDAs, as organizations now need to deliver contents in various formats such as WML, XHTML, etc. In addition, content published in a company’s Web site is usually created, edited, and approved by different personnel. These processes made publishing a simple piece of content to a Web site extremely cumbersome. With the number of personnel involved in content publishing, creating published material with a consistent look and feel has also become a tricky task. Content management systems were invented to solve these problems. Content management systems should include the ability to: Act as a centralized document management system for Web sites that store large amounts of persistent content information Encapsulate data of various types and formats (PDF, XML, Word, JSPs) Enable users to create, view, edit, delete, format, organize, search and publish contents Create and administer workflow tasks Enable content manipulation based on workflow and user roles Support resource access permission based on user identity Support content versioning Deliver large amounts of content to a variety of devices Schedule content publication 11.1.1 Support for content management in WebSphere Portal Server WebSphere Portal ships with two content management tools: Web Content Publisher (WCP) and Portal Content Organizer (PCO). Web Content Publisher supports all the features that a content management system should contain as described in the previous section. Portal contents are usually contributed by Web Content Publisher. Web Content Publisher is discussed in “Web Content Publisher” on page 641, along with a sample 638 IBM WebSphere Portal V4 Developer’s Handbook scenario detailing how content can be created, edited, approved, published and eventually displayed in the portal. Portal Content Organizer is a small built-in content organizer in WebSphere Portal. It is a basic content management system that enables users to create, edit, upload, share, organize, view, and search content contributed by Portal Content Organizer users. However, content contributed by Portal Content Organizer is not accessible by the portal. Portal Content Organizer will be discussed in detail in “Portal Content Publisher (PCO)” on page 771. Third-party content management systems such as Documentum, Vignette and Interwoven, etc. can be integrated with WebSphere Portal. This topic will be discussed in Third-party content management collaboration. 11.2 Software Requirements The focus of this redbook is on the development perspective of WebSphere Portal and its components. The following section simply outlines the necessary components of Web Content Publisher install and does not explore the details of the actual installation. 11.2.1 Web Content Publisher Web Content Publisher is composed of two core environments: the Web Content Publisher authoring environment and the Web Content Publisher publishing environment. These two components should be installed on separate machines. Note: It is possible to install both the authoring server and publishing server on the same machine. However, such a configuration is not supported. There are two main drawbacks to using a single machine for authoring and publishing. First of all, Portal Content Organizer, which is installed as part of WebSphere Portal, and Web Content Publisher use classes of the same name. Thus, if you have installed WebSphere Portal on the same machine, syndicated channels functionalities in Web Content Publisher do not work. Secondly, an authoring project and the corresponding publishing server should use the same context root. Thus, in a single machine configuration, users of the Portal Server who are not users of the Authoring Server would not be able to access any of the files published since the Authoring Server precludes users who are not authorized to use the Authoring Server from viewing those contents. Chapter 11. Content management 639 Web Content Publisher authoring The Web Content Publisher authoring environment integrates with Lotus Workflow engine, which enables users to create, edit, approve, and publish content to the Web Content Publisher publishing environment. The following components need to be installed for the Web Content Publisher authoring environment to run. Domino LDAP DB2 IBM HTTP Server WebSphere Application Server WebSphere Personalization Server Lotus Workflow Lotus Architect Web Content Publisher WebSphere Content publishing The Web Content Publisher publishing environment displays contents published from the Web Content Publisher authoring environment. The following components need to be installed for the Web Content Publisher publishing environment to run. DB2 IBM HTTP Server WebSphere Application Server WebSphere Personalization Server Web Content Publisher - Publishing Server To display the published contents in a portal, WebSphere Portal also needs to be installed along with the publishing server. Note that Web Content Publisher does not require WebSphere Portal to be installed in order to run. Note: The above components need to be installed and configured in a particular sequence. 640 IBM WebSphere Portal V4 Developer’s Handbook Web Content Publisher developers’ tools The following development tools are useful in creating Web Content Publisher projects. WebSphere application developer Portal toolkit for WebSphere application developer Personalization wizards for WebSphere application developer WebSphere personalization workspace 11.2.2 Portal Content Organizer (PCO) The Portal Content Organizer is installed as part of the WebSphere Portal Server installation. 11.3 Web Content Publisher Web Content Publisher is a content management system shipped with WebSphere Portal. However, it can be run in the absence of WebSphere Portal. We will now discuss the different features of WebSphere Content Publisher. 11.3.1 Features of Web Content Publisher Figure 11-1 Web Content Publisher Overview Chapter 11. Content management 641 Authoring templates One of the main purposes of Web Content Publisher is to enable business users, subject experts as well as any non-technical content writers to contribute contents to the Web site. Authoring templates are Web pages that enable content contributors to add and edit any content by filling out Web forms. Presentation templates Presentation templates are also called generation templates. All the contents submitted through the authoring templates are stored in the database. Presentation templates are used to generate views from the content stored in the database as files. Multiple templates can be created to generate different views for different devices and target users. Preview Preview allows Web Content Publisher users to preview how an individual piece of content would appear in the actual Web page. Workflow Web Content Publisher provides workflow management by utilizing Lotus Workflow. Each task initiated in Web Content Publisher must specify a workflow process. You can use the default workflow processes installed with Web Content Publisher, or create your own workflow processes using Lotus Workflow Architect. Syndicated Content Web Content Publisher enables content contribution through syndicated sources. Syndicated contents are information provided by external content contributors to be used on Web pages. Typical syndicated contents include news headlines, financial information and weather information. Access Control Web Content Publisher provides access control on content resources as well as user actions. Versioning Web Content Publisher supports project level version control and asset level version control using CVS. 642 IBM WebSphere Portal V4 Developer’s Handbook Browser UI Web Content Publisher is accessed through a browser interface. It enables users to create any Web resources such as images and JSP files in an external editor and subsequently upload to Web Content Publisher. 11.3.2 A brief tour of WebSphere Content Publisher Note: From this point on, it is assumed that you have configured Lotus workflow and verified your Web Content Publisher install. Now that you are familiar with the different features of Web Content Publisher, let’s take a tour of Web Content Publisher. First, you need to start Web Content Publisher. 1. To start Web Content Publisher, you first start LDAP and Workflow server on Lotus Domino. Click Start->Lotus Applications->Lotus Domino Server. A DOS window as shown in Figure 11-2 opens. Wait until the server is completely started. Figure 11-2 Lotus Domino Server Window Note: Lotus Domino Server is completely started when you see the > sign at the bottom of the server window. Chapter 11. Content management 643 Note: Do not close the Lotus Domino Server window. Lotus Domino Server needs to be running to provide LDAP and workflow services for Web Content Publisher. 2. Click Start -> Settings -> Control Panel. Double-click Administrator Tools. Double-click Services. Right-click IBM WS AdminServer and select Start as shown in Figure 11-3. Figure 11-3 Starting WebSphere Admin Server Note: If a message pops up saying the service did not respond in a timely fashion, this could mean that Domino has problems, is not running or is taking longer than the normal waiting period. Wait a while and refresh the Services Window to see if it is started. 3. Open a browser window and enter the URL http://your_host_name//wps/wcp/index.jsp. You should see the login page for WebSphere Content Publisher, as shown in Figure 11-4. 644 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-4 Web Content Publisher login page 4. Type dave in the user ID field and dave in the password field. Press Enter. 5. You will then see a window similar to Figure 11-5. You will not see the job Post a new article on your window. Figure 11-5 WebSphere Content Publisher Tasks Page The tasks page summarizes the tasks that are currently assigned to a specific user according to the defined workflow process. There are two submenu items: “I own” and “I could own” under Tasks on the left pane. Jobs listed under “I could own” are jobs that are being assigned to the user but where the user has not taken any actions yet. Jobs listed under “I own” are jobs that are being assigned to the user where the user has explicitly Chapter 11. Content management 645 clicked Work On and confirmed that he is working on the particular job. In Figure 11-5, Dave has been assigned a job titled “Post a new article” and is currently working on it since the job is listed under “I own” in the Task menu. Details and possible actions of a particular job are shown in the panel on the lower right. Based on the user’s privileges, a user may click New job to create a new job. 6. Click the Content tab next to Tasks in the upper left hand corner. You should see a window similar to Figure 11-6. Figure 11-6 WebSphere Content Publisher content page The content page lists all the files of the active project that are currently stored in the content management database. Only one project is active at any time. The current active project name is displayed in the upper right hand corner of the page. In Figure 11-6, the current active project is “WCMSample”. There are three types of file contents: structured content, syndicated content and plain files. These three file types are categorized according to their types on the left pane. 7. Click the Administration tab in the upper right hand corner. A page similar to Figure 11-7 is displayed. 646 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-7 WebSphere Content Publisher administration page Depending on the user’s access control level, different menu items will be available on the left panel. Log out and log in again using the user ID “wcpadmin” and password “password”. You should see all the menu items as displayed on the left pane in Figure 11-7. The administration page allows users to set the various access control levels, define file types, create and version projects, set the current active project, register structured content resources, schedule and monitor background events, define new channels, and set up publish servers. 11.3.3 Web Content Publisher architecture Before discussing content publishing with Web Content Publisher, it is important to understand how Web Content Publisher accomplishes its tasks. As mentioned in previous sections, Web Content Publisher is made up of two core environments: the authoring environment and the publishing environment. Both the authoring and publishing environments are in fact Web applications installed on WebSphere Application Server. Note that Web Content Publisher does not require WebSphere Portal to be installed in ordr to run. Figure 11-8 illustrates the Web Content Publisher topology. Chapter 11. Content management 647 Figure 11-8 Web Content Publisher topology Authoring environment The authoring environment consists of Web Content Publisher authoring server, personalization server, DB2 database, Domino (LDAP and Workflow), Notes client and Web client. The Web Content Publisher’s main responsibility is to coordinate content management activities such as managing content resources, coordinating workflows activities, managing user access controls, etc. Web Content Publisher accomplishes these tasks by collaborating with various service providers. Web Content Publisher uses the personalization engine to register and transform structured content resource. Both the personalization engine as well as the Web Content Publisher server obtains user credentials from the Domino LDAP server. All workflow activities are driven by Lotus Workflow that resides on the Domino server. All content information is stored in the WCM database in DB2. Publishing environment The publishing environment consists of a Web Content Publisher publishing server and a personalization server. The Web Content Publisher authoring server publishes contents to the publishing server, which is typically a staging or production server for the Web site. The Web Content Publisher authoring server can publish to a publishing server without WebSphere Portal installed. However, if WebSphere Portal is installed on the publishing server, the portlets will gain 648 IBM WebSphere Portal V4 Developer’s Handbook access to the contents being published and published contents can be displayed in the portal. 11.3.4 Step-by-step guide to content publishing This section is a step-by-step guide to content publishing using Web Content Publisher. It describes the details of how to create a project, import contents files, create and register structure content resources, create authoring and presentation templates, define channels for syndicated contents, schedule automatic content generation, create and work on jobs assigned by the workflow engine, publish contents and display contents on the portal. To better demonstrate the various capabilities mentioned for Web Content Publisher, this step-by-step guide is built around the following scenario. YourCo would like to include a news page in their company’s portal. All news contents are contributed by business users. However, YourCo would like to ensure that contents have the same look and feel. The Portal designer proposes to build the news page with two panels: a news headlines navigation panel on the left and the news details panel on the right. By clicking the headline on the navigation panel, the detailed contents of the corresponding news article appear on the details panel on the right. Based on the scenario described, we will now implement the solution by following these steps. Identify the content Develop content models Create a Web Content Publisher project Import files to the content management system Implement structured content Create authoring templates Create generation templates Displaying static portal content Displaying dynamic portal content Identify the content The first step in content management is to identify the type of content that needs to be presented to the users. Web Content Publisher supports three generic content types: structured content, syndicated contents and file contents. Chapter 11. Content management 649 Structured contents Structured contents are also called template-driven contents. This type of content focuses on the actual content rather than presentation. During design time, the content design team decides what attributes a certain type of content should contain. For instance, for an employee profile page, the attributes for the employee profile content type would be name, department, location, phone number, e-mail, fax, date of hire, etc. The employee profile content type is thus called a structured content. It is being represented in Web Content Publisher as a Java class with all the attributes as properties of the class. All these attributes are mapped and stored in a persistent data store such as a database, an XML file or an LDAP repository. The content management team then creates forms called authoring templates. These forms enable users to input values for each of the attribute defined in the structured content. Business users log on to Web Content Publisher and fill out these authoring pages to submit the contents. All contents submitted are then stored in the WCM database. Since all the contents are stored in a uniform format, it enables Web developers to create Web pages by selectively inserting these contents information from the database. These Web pages are called presentation templates. Such a method of generating content has various advantages. First, it enables non-business users to contribute content. In addition, through template driven content generation, all contents will have the same look and feel. It also facilitates content delivery for multiple devices. Storing content data in a structure format also makes personalization a much easier task. The development team can include meta data for each content that is contributed. During runtime, the personalization engine utilizes the metadata to select the most appropriate content to display to the user. For more information on personalization, refer to Chapter 10, “Personalization” on page 501. Syndicated content Syndicated contents are licensed use of information from an external source. A common example of syndicated content is pulling news articles from Reuters and including the articles in your Web site. Content syndicators use a number of formats in publishing their content. Most of them are XML-based. The format supported by Web Content Publisher is called Rich Site Summary (RSS). To define a syndicated source, you need to define a channel in Web Content Publisher. Syndicated contents are constantly updated by content syndicators. The content administrator should schedule periodic updates for each channel. 650 IBM WebSphere Portal V4 Developer’s Handbook File contents File contents are simply files of any format such as HTML, PDF, GIF, JPG, etc. File contents need to be imported to the Web Content Publisher project in order to be stored in the content management system and published to the designated publishing server. The decision about content type can be based on the nature of the content source itself. For instance, how frequent are similar contents being published? Is a consistent look and feel important when similar materials are published? Is there a need to generate contents for multiple devices frequently? Is the content contributed from external resources in a specified format? In our sample scenario, internal news are contributed by business users. These users’ primary focus is to compose actual news articles for their respective departments. They should not need to understand all the technical intricacies of Web graphics design and Web publishing. Moreover, since news articles should conform to a consistent format in the portal, it makes sense to use the structured content for internal news. Develop content models You need to develop content models only if you are implementing structured content types. You can skip this section otherwise. For each structured content type, a content model needs to be defined. You should identify all the information that might appear in this type of content. In our sample scenario, we need to enable business users to contribute news articles to the portal. Thus the required content attributes are: headline image active date/time stop date/time content confidential During content model development, you should also think about including metadata in your content model. Personalization uses metadata to select the most appropriate content to be shown to the user, so it is important to include metadata for your content from the start. In our sample scenario, we have included a few attributes that can be used by personalization in creating dynamic contents. These attributes are listed next. Chapter 11. Content management 651 department location Interests Now that all the attributes are identified, we are ready to create the database model. We will create a database called YOURCOCM. In this database, we will create a tables: YOUR_CO_NEWS. The YOUR_CO_NEWS table will contain all the necessary attributes to be displayed to the portal visitors as well as the metadata that can be used by the personalization engine. 1. Open a db2 command window by selecting Start->Programs->IBM DB2->Command Line Processor. 2. Navigate to /db/createyourcocm.bat where you have saved the demo files. Type createyourcocm dbuserid dbpassword. Use a valid DB2 user ID and password. Once the script has completed, check whether the database tables have been created successfully. 1. Select Start->Programs->IBM DB2->Control Center. 2. A new database called YOURCOCM should be created. Click the + sign next to the YOURCOCM database and select the Tables folder. You should see the newly created YOUR_CO_NEWS table. 3. Right-click the YOUR_CO_NEWS table and click Alter. 4. Click the Columns tab in the Alter table window. You should see the table definition as shown in Figure 11-9. 652 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-9 YOUR_CO_NEWS table schema Create a Web Content Publisher project Now that the design of the content model is completed, we can go ahead and create Web Content Publisher project. This involves two steps. First, you need to create and deploy a specially configured enterprise application to be used by the new Web Content Publisher project. This enterprise application serves as a container to enable JSP templates to be served to the users of Web Content Publisher. If this step is omitted, the users will not be able to preview any pages generated using custom templates. Finally, you create a Web Content Publisher project using the browser interface. Note: These operations are performed on the Authoring Server. Create and deploy an enterprise application container 1. Start WebSphere Application Developer. Select Start -> Programs -> IBM WebSphere Studio Application Developer -> IBM WebSphere Studio Application Developer. 2. Choose the Web Perspective. Select Perspective -> Open -> Web. Note: If you do not see the Web Project menu item, select Perspective->Open->Other.... The Select Perspective window comes up. Select Web and click OK. Chapter 11. Content management 653 3. Create a new Web project. Select File -> New -> Web Project. 4. The Create a Web Project dialog box comes up. In the Project name field, enter YourCoCMAuthor. In the Enterprise Application project name, enter YourCoCMAuthor.ear. Your window should look like Figure 11-10. Figure 11-10 Create a Web Project 5. Click Finish. 6. Once your project is created, expand the folders under the YourCOCMAuthor project. Double-click the file web.xml by clicking webApplication -> WEB-INF. 7. The file web.xml file is displayed as shown in Figure 11-11. Click the Source tab. 654 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-11 web.xml 8. Comment out the Welcome-file-list section and add the XML code needed for the authoring environment as shown in Example 11-1. All JSP files will be handled by the com.ibm.wcm.jasper.runtime.JspServlet and the rest of the files will be handled by com.ibm.wcm.servlets.FileResourceServlet. Example 11-1 web.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app id="WebApp"> <display-name>YourCoCMAuthor</display-name> <servlet id="Servlet_1"> <servlet-name>Files</servlet-name> <description>Files Servlet</description> <servlet-class>com.ibm.wcm.servlets.FileResourceServlet</servlet-class> <security-role-ref id="SecurityRoleRef_1"> <role-name>AuthenticatedUser</role-name> <role-link>RuntimeRole</role-link> </security-role-ref> </servlet> <servlet id="Servlet_2"> <servlet-name>Jsps</servlet-name> <description>JSP Servlet</description> Chapter 11. Content management 655 <servlet-class>com.ibm.wcm.jasper.runtime.JspServlet</servlet-class> <security-role-ref id="SecurityRoleRef_2"> <role-name>AuthenticatedUser</role-name> <role-link>RuntimeRole</role-link> </security-role-ref> </servlet> <servlet-mapping id="ServletMapping_1"> <servlet-name>Files</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping id="ServletMapping_2"> <servlet-name>Jsps</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping> <security-constraint id="SecurityConstraint_1"> <web-resource-collection id="WebResourceCollection_1"> <web-resource-name>AuthenticatedUsers</web-resource-name> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint id="AuthConstraint_1"> <description>AllAuthenticatedUsers:+:</description> <role-name>RuntimeRole</role-name> </auth-constraint> <user-data-constraint id="UserDataConstraint_1"> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config id="LoginConfig_1"> <auth-method>BASIC</auth-method> </login-config> <security-role id="SecurityRole_1"> <role-name>RuntimeRole</role-name> </security-role> </web-app> 9. Save web.xml by pressing Ctrl-S. Ignore the error messages in the task folder shown in Figure 11-12. 656 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-12 web.xml errors 10.We will now export the Web application so that it can be installed at the WebSphere Application Server. Select File -> Export. 11.The Export dialog comes up. Select WAR file. Click Next. 12.Under “What resources do you want to export?”, make sure YourCoCMAuthor is selected. 13.Under “Where do you want to export resources to?”, click Browse and choose a folder to export the WAR file, for instance, c:\temp\YourCoCMAuthor.war. Make a note of this export folder. 14.Click Finish. 15.Now we are going to deploy this empty Web application container to WebSphere. Bring up the WebSphere Administrator’s Console by selecting Start -> Programs -> IBM WebSphere -> Application Server V4.0 -> Administrator’s Console. Note: If you encounter any problems while starting the WebSphere Administrator’s Console, it might be because your Domino LDAP server or WebSphere Admin Server has not started. 16.Expand the tree on the left pane on the Administrative Console. Right-click Enterprise Applications and select Install Enterprise Application. 17.The Install Enterprise Application wizard comes up. Select the Install stand-alone module (*.war, *.jar) radio button. Click Browse for the Path field and choose the WAR file that you exported in Step 13. 18.Type YourCoCMAuthor in the Application name field. 19.Type /wps/YourCoCM for the context root. Make a note of this context root. Chapter 11. Content management 657 Note: The context root that you specified here must match the context root of the Web Content Publisher project that you are going to define. 20.Click Next. 21.In the Mapping Users to Roles window, you should see a Runtime role under the Roles column as shown in Figure 11-13. Click Select. Figure 11-13 Mapping users to roles 22.The Select Users/Groups - RuntimeRole window comes up. Select all authenticated users (*). Click OK. 23.Click Next. 24.Keep clicking Next until you come to the window used to select Application Servers. Click Select Server. 25.Select WebSphere Portal (<YOUR_NODE_NAME>) and click OK. 26.Click Next. 27.You should be at the Completing the Application Installation Wizard window. Click Finish. 28.When the enterprise application finishes installing, an information dialog pops up saying EnterpriseApp.install completed successfully. Click OK. 658 IBM WebSphere Portal V4 Developer’s Handbook 29.You will now need to regenerate the link between the application server and the Web server, so that all requests routed to the new context root of the enterprise application that was just installed will be handled by WebSphere Application Server. Select the node where you installed Web Content Publisher. Right-click and select Regen Webserver Plugin as shown in Figure 11-14. Figure 11-14 Regenerate Web server plugin 30.You now need to restart the Web server. Bring up the Services window by clicking Start -> Settings -> Control Panel. Select Administrative Tools. Double-click Services. 31.Right-click IBM HTTP Server and select Stop. 32.When the HTTP Server has been stopped completely, right-click IBM HTTP Server again and select Start. 33.You now need to start YourCoCMAuthor enterprise application that you just installed. Go back to the WebSphere Administrative Console. Locate YourCoCMAuthor under Enterprise Application folder. Right-click YourCoCMAuthor and select Start. 34.Once an information dialog saying Command “YourcoCMAuthor.start” completed successfully, click OK. 35.Click + to expand the YourCoCMAuthor enterprise application. Select the Web Modules folder. 36.Right-click the YourCoCMAuthor Web application and select Start. Chapter 11. Content management 659 After the enterprise application for the Web Content Publisher project has been created, we can log in to Web Content Publisher using the browser interface to create a Web Content Publisher project. Create a Content Publisher project 1. Open a browser window and enter the URL http://your_fully_qualified_host_name/wps/wcp/index.jsp 2. Type wcpadmin in the user ID field and password in the password field. 3. Once you log in to Web Content Publisher, click the Administration tab in the top right hand corner. 4. You will see a window similar to Figure 11-15. Click Projects/Editions on the left pane. Figure 11-15 Web Content Publisher projects window 5. To create a new project, click Add Project. 6. The Add Project window comes up. In the name field, type YourCoCMAuthor. Type a brief description for your authoring project. In the context root field, enter wps/YourCoCM. This value should be the same as the context root specified when you installed the enterprise application container for Web Content Publisher. Do not put a leading slash before the value of the context root. 7. In the root path field, enter a valid folder name. 660 IBM WebSphere Portal V4 Developer’s Handbook Note: The root path is only used during project import and export. Any files placed under the root path can be imported into the content management system. However, it is important to understand that placing files in this directory does not mean that the files are stored in the content management system! You need to explicitly import files from the file system to Web Content Publisher. 8. Select Simple Change Process as the default workflow process. 9. QuickEdit allows any authorized users to make any content changes even though they have not been assigned a task according to the workflow processes. Select the radio button Yes to enable QuickEdit. 10.Select the radio button Yes to enable locking. 11.Version enables versioning using an external version control system. Web Content Publisher allows file level versioning using CVS as the version control system. However, we will not be using any version control system in this demo. 12.Your window should look like Figure 11-16. Click Add to add the Web Content Publisher project. Chapter 11. Content management 661 Figure 11-16 Add a Web Content Publisher project 13.The new project is now added to the list of Web Content Publisher projects. You should see the YourCoCMAuthor project in the list of Web Content Publisher projects. Import files to the content management system After successfully creating a Web Content Publisher project, you need to import all the files from your Web site into the content management system. Note: Files placed under the project root directory are not be stored in the content management system. All files need to be explicitly imported to the content management system in order for them to be stored and published. 662 IBM WebSphere Portal V4 Developer’s Handbook 1. Copy your Web files (HTML, image files, etc.) to the root directory that you defined in Step 7 on page 660 (for example c:\wcp\YourCoCM) when you created your Web Content Publisher project. 2. Log in to Web Content Publisher if you have not already done so. 3. Click the Administration tab. 4. If you don’t see a wrench on the edition of the YourCoCMAuthor, it means that YourCOCMAuthor project is not active yet. Click the edition of YourCoCMAuthor and click Work On. Note: There is only one Web Content Publisher project at any time. If you need to work on another Web Content Publisher project, you need to go to the Administration tab, select the version of the specific project that you would like to work on and click Work On. 5. Click Import. You will see a window similar to Figure 11-17. Notice that only files placed under the root path can be imported to the project. Since we would like to import all the files in the project root directory, accept all defaults and select Import. Figure 11-17 Importing files for a Web Content Publisher project Chapter 11. Content management 663 6. A summary page listing all the files being imported as well as the total files count is shown. Click Cancel to go back to the Administration window. 7. Click the Contents tab. You should now see all the files that you have imported under the Files menu item. 8. Click each file to view its contents. If the file is an image file, the image can be displayed in the Preview tab. Implement structured content This section guides you through the creation and deployment of structured content resources. You can skip this section if you are not using structured content resources. For a detailed explanation of the concept of structured content resources, refer to “Structured contents” on page 650. Structured content is implemented using structured content resources. Each structured content resource is composed of a Java bean and a resource file descriptor. The Java bean contains all the properties of the structured content. Each property maps to a column of the back-end datastore. In relational database terms, the Java bean class corresponds to the schema of the database table(s) and each property maps to a column. Note: It is possible for a resource to span multiple tables. In this particular scenario, a database join is needed when creating the resource. The resource file descriptor is an XML file with a .hrf extension. It contains information about the resource and is used for importing the resource into WebSphere. Another concept that needs to be introduced in the concept of a resource instance. A resource instance would then be an instance of a Java class. In relational database terms, a resource instance corresponds to a row in the database table. The last concept that needs to be introduced is the concept of resource collection. A resource collection is a set of Java instances that belong to the same resource type. In relational database terms, a resource collection is represented by all the rows in a tables. Let’s take the YourCo internal news structured content as an example. A Java bean class needs to be created based on the database schema created in “Develop content models” on page 651. This Java bean class is the structured 664 IBM WebSphere Portal V4 Developer’s Handbook content resource. The contents of each piece of news article contributed by the business users will be stored as a new row in the content management database. Each news item is a resource instance. All the news articles contributed are thus defined as the news resource collection. The resource concept is in fact used by WebSphere Personalization to select the most appropriate resource to be displayed to the user. Web Content Publisher uses this concept to implement the concept of template driven content using the content resources. With all the basic concepts of content resource explained, we are now ready to create a content resource. Create a structured content resource 1. Start WebSphere Studio Application Developer by selecting Start -> Programs -> IBM WebSphere Studio Application Developer -> IBM WebSphere Studio Application Developer. 2. Create a new portlet project by selecting File -> New -> Portlet Application Project. If you do not see Portlet Application Project listed in the menu, select File -> New -> Other. Select Portlet Development on the left pane and Portlet Application project on the right pane and click OK. Note: If you still do not see the portlet development project, you probably do not have the Portal Toolkit installed. Refer to Chapter 3, “Using the Portal Toolkit” on page 119 for installation instructions. 3. In the Create a Portlet project window, type YourCoCMPortlet for the project name, and YourCoCMPortlet.ear for the enterprise application project name. Your window should look like Figure 11-18. Chapter 11. Content management 665 Figure 11-18 Create YourCoCMPortlet project 4. Click Finish. A new portlet application project is created. 5. It is always a good practice to package your files. Right-click the source folder under the YourCoCMPortlet project and select New -> Folder. 6. In the New Folder dialog box, type the new folder name YourCoCM. Click Finish. 7. Now we will add a content resource using the personalization wizard. First select the YourCoCM folder. Then click the content wizard icon . It should be located on the toolbar as shown in Figure 11-19. If you do not see the content wizard, select Perspective -> Customize. The Customize Perspective dialog pops up. Click + to expand Other on the left pane and check the Personalization Wizards checkbox as shown in Figure 11-20. The content wizard should now be placed on the toolbar. Note: If you do not see the Personalization Wizards in the Customize Perspective dialog box, you might not have Personalization Wizards installed on WebSphere Studio Application Developer. 666 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-19 Content wizard Figure 11-20 Customize Perspective 8. The content wizard appears. Select the Logon tab. We now enter the credentials to log on to the database that we created for employee internal Chapter 11. Content management 667 news. In the Database URL field, type jdbc:db2:YOURCOCM; in the User ID field, type your DB2 administrator ID; and in the password field, type your DB2 administrator password. Your window should look similar to Figure 11-21. Figure 11-21 Content wizard database entries 9. Click Connect to validate your entry. 10.If you have entered the database information correctly, you should see a list of available tables on the window. Select YOUR_CO_NEWS and click > to move the table to the Selected tables pane. Click YOUR_CO_NEWS in the Selected tables pane and click the Primary table button. Your window should look similar to Figure 11-22. Click Next. 668 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-22 Select table in Content Wizard 11.You will see all the available columns in the YOUR_CO_NEWS table. Click >> to move all the columns over to the selected columns on the right pane. Select the ID row and the Primary key button. Your window should look like Figure 11-23. Click Next. Chapter 11. Content management 669 Figure 11-23 Select column in content wizard 12.Since we are only using one table to define the structured content resource, we do not need to perform any column joins. Click Next.. 13.You can define the values for each output column. In our scenario, we would like to define the values for the column CONFIDENTIAL. This column can contain a value of “Y” which corresponds to “Yes” or “N” which corresponds to “No”. Select the row DB2ADMIN.YOUR_CO_NEWS_CONFIDENTIAL and click Edit. 14.The Define Type Value dialog box pops up. Click the empty row and type Y under the Value column and Yes under the Description column. Click Add. Repeat the process again and type N under the Value column and No under the Description column. Your window should look like Figure 11-24. Click OK. Note: By specifying the type-value mapping, the default authoring template discussed in “Create authoring templates” on page 679 will be generated according to these values. 670 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-24 Define types in content wizard 15.Click Next. 16.You will see the list of files that will be generated. It includes the content resource Java file, the content resource file descriptor, as well as other helper methods for performing the insert, update and delete operations on the resource collection. You can choose to rename these classes. In our example, we have rename the classes to YourCoCMNews. Click Rename and type the new name of the resource classes. Click OK, then click Finish. Chapter 11. Content management 671 Figure 11-25 Content wizard final page 17.All the Java resources files are added to the webApplication/WEB-INF/classes/YourCoCM folder. The resource descriptor is added to the webApplication/WEB-INF/wcm-resourceCollections/YourCoCM folder. 18.You will then export these files so that WebSphere Personalization can gain access to them. Select the YourCoCM project under webApplication/WEB-INF/classes. Select File -> Export. 19.The file export window comes up. Make sure that all the Java class files under YourCoCMPortlet/webApplication/WEB-INF/YourCoCM are selected. Then expand the folder wcm-resourcesCollections and select the YourCoCM folder underneath it. The file YourCoCMNews.hrf should also be selected. Under the Directory field, type an export path. In our scenario, we have chosen c:\wcp\YourCoCMPortlet. Your window should look like Figure 11-26. 672 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-26 Export resource files 20.Click Finish. Note: The sample code in this example can be found in YourCoCMPortlet.war. Register a resource in the Personalization engine Web Content Publisher uses the implementation of resource collection of the WebSphere Personalization Server. Thus, you will first need to register the resources in WebSphere Personalization. 1. In order for WebSphere Personalization Server to use the resource file, you will need to copy the class files to the WebSphere_Install_Directory\lib\ext. In our case, copy the YourCoCM folder under c:\wcp\YourCoCMPortlet to c:\WebSphere\AppServer\lib\ext. Make sure to copy the entire folder as shown in Figure 11-27. Note: When you place the files under Websphere_Install_Directory\lib\ext, make sure you retain the package structure of your class files. Chapter 11. Content management 673 Figure 11-27 File contents of resource library 2. Open a browser and enter the URL http://<YOUR_FULLY_QUALIFIED_HOST_NAME>/wps/adminframe.jsp. Click the Resource Hierarchies tab. Note: If you have security enabled for WebSphere Personalization Server, you may be prompted for a user ID and password. Enter the same user ID and password that you use when you start your WebSphere Administrative Console. 3. Click the Import button. 4. Under the Specify the path and file name field, type the full file name of the resource descriptor file that you exported. In our scenario, it is c:\wcp\YourCoCMPortlet\YourCoCM\YouroCMNews.hrf. Your window should look similar to Figure 11-28. 674 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-28 Import resource descriptor file 5. Click the Import File button. 6. Your window should display The file to be imported is <YOUR_FULL_HRF_FILE_NAME>. Import finished. 7. Now, if you select the resource Hierarchy drop-down menu, you should see Yourconews. Register a resource in Web Content Publisher After the resource is registered in WebSphere Personalization, you can register the resource in Web Content Publisher. Note: You only need to register the same resource once in WebSphere Personalization. The resource can then be registered and used in various Web Content Publisher projects. 1. Open a browser and type the URL http://<YOUR_FULLY_QUALIFIED_HOST_NAME>/wps/wcp/index.jsp to log in to Web Content Publisher. Use the User ID “wcpadmin” and password “password”. 2. Click the Administration tab. Make sure the active project is YourCoCMAuthor. If not, select the Projects/Editions menu item on the left pane, then select YourCoCMAuthor and click Work On. Chapter 11. Content management 675 3. Click Registration on the left pane. On the top of the right pane, click the Add new collection icon as shown in Figure 11-29. Figure 11-29 Register a resource collection in Web Content Publisher 4. The Add Collection to Project window comes up. Select YourCoCMNews in the resource list as shown in Figure 11-30. Make sure the Publishable checkbox is selected. Click Add. 676 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-30 Add collection to project 5. YourCoCMNews is now registered to the YourCoCMAuthor project in Web Content Publisher, as shown in Figure 11-31. Chapter 11. Content management 677 Figure 11-31 Resource collection list in Web Content Publisher 6. Click the Contents tab. You should now see YourCoCMNews appear under the Structured Content menu, as shown in Figure 11-32. 678 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-32 Structured content in Web Content Publisher Create authoring templates This section covers the details of creating authoring templates for structured contents. If you are not using structured content types in your content management solution, you can skip this section. For structured content types, developers from the content management team need to create HTML forms so that content contributors can add, edit and preview the contributed content. These HTML forms are called authoring templates. The developers can create four types of authoring templates for each structured content type, namely, the add template, the edit template, the show template and the preview template. As the name suggests, the add form is used to add content; the edit form is used to edit content where all previously entered data is pre-populated; the show form is used to show the details of every attribute of the content; and the preview form is used to show how the content would look on the Web page. Web Content Publisher creates default authoring templates for each structured content type registered. However, you probably want to create your own custom authoring templates for a variety of reasons. You may want to change the look and feel of the authoring templates, so that they will be consistent with the rest of your Web site; you may want to implement additional data validations to ensure mandatory data is entered and all input data is valid. Furthermore, the design Chapter 11. Content management 679 and development team may want to guide the user through a series of windows when entering the data instead of presenting all the information on one large form. In addition, there is one shortcoming of the default authoring template. Web Content Publisher does not generate input fields properly for date-related datatype. You would need to add your customized code in order to enable content contributors to add and modify any date entries. This will be discussed in detail later in this section. The quickest way to create a customized template is to modify the default template. Web Content Publisher enables content contributors to add and edit contents using the default authoring templates. Download the default template 1. Select the Content tab and click YourCoCMNews on the left pane. 2. Click the templates icon as shown in Figure 11-33. Figure 11-33 Download authoring templates 680 IBM WebSphere Portal V4 Developer’s Handbook 3. The Templates page appears. Click the template wizard as shown in Figure 11-34. Figure 11-34 Templates form 4. The Create Author Template page then appears. We would like to create an add template for YourCoCMNews and store all these authoring templates in a folder called templates. Type templates/YourCoCMNewsAdd.jsp as shown in Figure 11-35. Click Create. Figure 11-35 Create author template 5. Repeat the two steps above for the edit form, shows form and preview form by specifying the different JSP names as shown in Figure 11-36. Click Save. Chapter 11. Content management 681 Figure 11-36 Create authoring templates 6. On the Contents tab, click Files on the left pane. You should see a new folder called templates being created. Click the templates folder and you should see the default template files created, as shown in Figure 11-37. 682 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-37 New authoring template files 7. Select the row YourCoCMNewsAdd.jsp and click Download. Note: Select the row of the template file instead of clicking the actual link to the file. If you click the link to the file, the actual JSP page will open up in a new window. 8. Save the file in a temporary directory, for instance c:\wcp\temp. 9. Repeat the two steps above for YourCoCMNewsEdit.jsp, YourCoMNewsPreview.jsp, and YourCoCMNewsShow.jsp. Technical details of the authoring template Now that you have downloaded the four authoring templates, you can create all the enhancements that you desire. Here are all the technical details that you need to explore the internal workings of the authoring templates. Web Content Publisher generates the default authoring forms for add, edit, show, and preview by Java introspection of the resource class to create the HTML form Chapter 11. Content management 683 elements for each property type of the content resource. When the user submits the authoring form to the server, all form attributes are submitted as text and are converted to their respective type on the server. The supported conversions of property types to text, and vice versa, are listed below: Java primitive types: byte, int, boolean, short, long, float, and double java.lang.Byte java.lang.Integer java.lang.Boolean java.lang.Short java.lang.Float java.lang.Long java.lang.Double java.math.BigDecimal java.math.BigInteger java.sql.Time java.sql.Date java.sql.Timestamp Note: java.sql.Time, java.sql.Date and java.sql.Timestamp are not supported in the default authoring template. Customized templates need to be created. Refer to Manipulating date and time later in this section. All authoring templates need to be Java Server Pages (JSPs). Therefore, you can use any JSP constructs or include any Java scriptlets within the authoring templates. Adding and editing content for all Web Content Publisher projects is handled by a single servlet. The URL for this target servlet is http://<YOUR_FULLY_QUALIFIED_HOST_NAME>/wps/wcp/command. This servlet performs the addition and modification of structured resource content based on the parameters submitted. Therefore, you should place any input parameters within the following form: <FORM ACTION="/wps/wcp/command" METHOD="POST"> <!-All input fields and submit button --> </FORM> 684 IBM WebSphere Portal V4 Developer’s Handbook Add page The following needs to be added within the form of the add page to provide the necessary information for the command servlet to process an add request. <FORM ACTION="/wps/wcp/command" METHOD="POST"> <INPUT TYPE="hidden" NAME="command" VALUE="addItem"/> <INPUT TYPE="hidden" NAME="beanName" VALUE="class_name"/> <BR>Resource id <INPUT TYPE="text" NAME="RESIDNAME" VALUE="" SIZE="25" /> <BR>property_name1 <INPUT TYPE="text" NAME="property_name1" VALUE="" SIZE="25" /> <BR>property_name2 <INPUT TYPE="text" NAME="property_name2" VALUE="" SIZE="25" /> <!-- Additional property fields--> <INPUT type="submit" name="formAction" value="Add"> </FORM> where class_name is the name of the resource class you are using (for example, YourCoCM.YourCoCMNews). RESIDNAME is the name of the resource's unique ID property. You can create a resource ID generation routine or allow the user to enter the ID value. property_name is the name of whatever property each input field is setting. Note: When the form is submitted, the data entered will be passed to the authoring server and identified by the property_name specified. These names are case-sensitive, so make sure that you use the same cases as when the names were defined. Edit page The following tags need to be added within the form of the edit page to provide the necessary information for the command servlet to process an edit request. <jsp:useBean class="com.ibm.wcm.GetGenericResource" id="getResource" type="com.ibm.wcm.GetGenericResource"> <% getResource.getResource(request); %> </jsp:useBean> <jsp:useBean id="resObj" type="class_name" scope="request"/> <FORM ACTION="/wps/wcp/command" METHOD="POST"> <INPUT TYPE="hidden" NAME="command" VALUE="updateItem"/> <INPUT TYPE="hidden" NAME="beanName" VALUE="class_name"/> <INPUT TYPE="hidden" NAME="RESIDNAME" VALUE="<%= resObj.getId() %>"/> <BR>property_name1 Chapter 11. Content management 685 <INPUT TYPE="text" NAME="property_name1" SIZE="25" VALUE="<%=resObj.getproperty_name1() %>"/> <BR>property_name2 <INPUT TYPE="text" NAME="property_name2" SIZE="25" VALUE="<%=resObj.getproperty_name2() %>"/> <!-- Additional property fields--> <BR><INPUT type="submit" name="formAction" value="Save"> </FORM> where class_name is the name of the resource class you are using (for example, YourCoCM.YourCoCMNews). RESIDNAME is the name of the resource's unique ID property. It is not recommended that you change the resource’s unique ID property. You pass this value back as a hidden field. property_name is the name of whatever property each input field is setting. Web Content Publisher provides a generic resource class com.ibm.scm.GetGenericResource for representing any resource content type created and defined by the content management developers. When the user requests the edit page, the content resource data object is passed to the JSP page via the request object. After retrieving the object using the useBean tag, the content resource is cast to the specific data type using <jsp:useBean id="resObj" type="class_name" scope="request"/>. All field values are pre-populated with the corresponding property values using the bean’s getter methods. Note: It is required that the content data object be called resObj. Do not use any other name. Preview and Show page The Preview and Show page mainly uses the content resource object passed from the request to display the information about the object. <jsp:useBean class="com.ibm.wcm.GetGenericResource" id="getResource" type="com.ibm.wcm.GetGenericResource"> <% getResource.getResource(request); %> </jsp:useBean> <jsp:useBean id="resObj" type="class_name" scope="request"/> <P>Property name 1 is: <%=resObj.getproperty_name1() %>"/> <BR>Property name 2 is: <%=resObj.getproperty_name2() %>"/> <!--Display more properties--> 686 IBM WebSphere Portal V4 Developer’s Handbook Other useful techniques Browsing file resources In many cases, you might want to provide your users with the ability to browse for a particular file stored in the content management system. For instance, the graphics designer may have created and stored an image of a new product to the content management system. The marketing manager who is writing a promotional article of the product would like to include this image reference to the article. Thus, you would want to put a Browse button on an image URL field on the authoring template. To accomplish this, you need to add the following JavaScript to your authoring template page. <SCRIPT LANGUAGE="JavaScript"> function listUrls(fn) { var openUrl = '/wps/wcp/wcmsearch.jsp?fieldName=' + fn; window.open(openUrl,'browseDlg','width=500,height=320,resizable=1, toolbar=0,location=0,menubar=0,titlebar=0,directories=0, status=0,scrollbars=0'); } function useUrl(fn,u) { document.forms[0].elements[fn].value = u; } </SCRIPT> Within your form, you will add the following <BR>property_name_for_browse <INPUT TYPE="text" NAME="property_name_for_browse" SIZE="25"/> <INPUT type="button" onclick="listUrls('property_name_for_browse')" name="IMAGEURL_url" value="Browse"> Manipulating date and time data type It is common to use date and time datatype in the attributes of a content datatype. However, they are not supported in the default authoring template. To enable date and time information entered by the user to be accurately updated on the server, all that is required is to ensure that when the date/time value is submitted to the server, it adheres to the format as shown in Table 11-1. Chapter 11. Content management 687 Table 11-1 Date/Time datatype and text format Date/Time datatype Text format java.sql.Time hh:mm:ss java.sql.Date yyyy-mm-dd java.sql.Timestamp yyyy-mm-dd hh:mm:ss.ffffffff where – hh is hours (0-23) – mm is minutes – ss is seconds – yyyy is the year – mm is the month (1-12) – dd is the day – ffffffff is subseconds (optional) Note: The above format is locale-independent. It must be passed in the above format regardless of country or language code. Instead of instructing the user to type in the date/time value in a specific format, you should provide a more user-friendly interface for entering the date value. This can be accomplished by enabling the user the select the day, month and year values in three separate combo boxes and utilizing a hidden field and some JavaScript code to compose the final date string to be sent to the server, as shown in Example 11-2. Example 11-2 Authoring form with date attribute <input type="hidden" name="myDateProperty" value=""> <table border=0 cellpadding=3 cellspacing=0> <tr> <td nowrap colspan=4 align="left">Date</td> </tr> <tr><% Calendar rightNow = Calendar.getInstance(); DateFormatSymbols symbols = new DateFormatSymbols( request.getLocale() ); String[] months = symbols.getMonths(); int currentMonth = rightNow.get(Calendar.MONTH); int maxDay = rightNow.getActualMaximum(Calendar.DAY_OF_MONTH); 688 IBM WebSphere Portal V4 Developer’s Handbook int currentDay = rightNow.get(Calendar.DAY_OF_MONTH); int currentYear = rightNow.get(Calendar.YEAR); %> <td align="left"><select name="month"><% for( int i=0; i<(months.length-1); i++ ) { String selected = ""; if( currentMonth==i ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"> <%= months[i] %></option><% } %> </select> </td> <td align="left"><select name="day"><% for( int i=0; i<maxDay; i++ ) { String selected = ""; if( currentDay==(i+1) ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"><%=(i+1)%></option><% } %> </select> </td> <td align="left"><select name="year"> <option selected value="<%=currentYear%>"> <%=currentYear%></option> <option value="<%=(currentYear+1)%>"> <%=(currentYear+1)%></option> <option value="<%=(currentYear+2)%>"> <%=(currentYear+2)%></option> </select> </td> </tr> </table> <input type="button" value="Add" onclick="submitForm()"> <script language="JavaScript"> function submitForm() { var month = document.forms[0].month.value; var day = document.forms[0].day.value; var year = document.forms[0].year.value; Chapter 11. Content management 689 // validate values for date // and other fields in the form // format the date for java.sql.Date.valueOf document.forms[0].myDateProperty.value = year + "-" + month + "-" + day; // submit the form document.forms[0].submit(); } </script> Sample scenario for customizing authoring templates Based on the technical information described for authoring templates, we will now demonstrate how to customize the authoring template based on the YourCo example. We are going to make modifications to the template files using WebSphere Studio Application Developer. First, we need to create a project in Application Developer and import the default template files that we downloaded in “Download the default template” on page 680. 1. Open WebSphere Studio Application Developer by selecting Start -> Programs -> IBM webSphere Studio Application Developer -> IBM Websphere Studio Application Developer. 2. Create a new Web project called YourCoCMTemp to hold the JSPs. Open the Web perspective if it is not already opened. Select Perspective -> Open -> Web. Select File -> New -> Web Project. 3. In the Create a Web Project dialog box, enter YourCoCMTemp as the project name, and YourCoCMTemp.ear as the Enterprise Application project name. Click Finish. 4. Expand the newly created YourCoCMTemp project. Right-click the webApplication folder and select New -> Folder. Name the new folder templates. 5. Select the templates folder. Click File -> Import. 6. In the Import dialog, select File system. Then click Next. 7. Click the Browse button next to the Directory drop-down box. Select the directory where you placed the default template files downloaded from Web Content Publisher and click OK. 8. Check all four authoring template files: YourCoCMNewsAdd.jsp, YourCoCMNewsEdit.jsp, YourCoCMNewsPreview.jsp, and YourCoCMNewsShow.jsp. Your window should look like Figure 11-38. Click Finish. 690 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-38 Import default authoring templates to WebSphere Application Developer First, we’ll take a look at the add and edit events. We would like to divide the data entry page into two pages (YourCoCMNewsAdd.jsp and YourCoCMNewsMeta.jsp). The user first enters the all the basic information about the news article on the first page. Then he provides all the metadata for the article on the second page. Thus the two pages should look like Figure 11-39 and Figure 11-40. The pages for add and edit events look the same except that data is pre-populated on the edit pages. The two pages shown in Figure 11-39 and Figure 11-40 use common JSP techniques to pass information from one page to the another. An intermediate page, YourCoCMNewsFormValidation.jsp, is used for data validation and page redirection. When the user clicks Next on YourCoCMNewsAdd.jsp, the form is submitted to the intermediate page YourCoCMNewsFormValidation.jsp. Three sets of validations are currently implemented on YourCoCMnewsFormValidation: checking for the mandatory headline field and content field, as well as verifying the date range for start date and end date. If all the validations pass, the resource ID is generated and the user proceeds to YourCoMNewsMeta.jsp page to enter the metadata for the news article; otherwise, the user is redirected back to the Chapter 11. Content management 691 YourCoCMNewsAdd.jsp page where an error message is displayed. The same is true for the edit operation. Note that the intermediate form validation page and the metadata page is shared by the add and edit operations. Figure 11-39 Add a news article, step 1 Figure 11-40 Add a news article, step 2 692 IBM WebSphere Portal V4 Developer’s Handbook Note: It is a good practice to generate the unique resource ID by using some common ID generating routine instead of relying on the user to type in an ID. Now let’s look at how these pages are actually implemented. Note: Instead of going through the step-by-step changes of these pages, the changes are outlined below. These sample pages can be found in the YourCoCMTemp.war file in the source directory. YourCoCMNewsAdd.jsp 1. Open YourCoCMNewsAdd.jsp. The page contains information for all the fields for the YourCoCMNews structured content type. However, we need to remove the Path, ID, and INTERESTS fields. Search for and delete the following lines. <tr> <td valign="top" align="right">Path:</td><td valign="top" align="left"> <% String folderPath = request.getParameter("folderPath"); folderPath = (folderPath==null ? "" : folderPath); %> <INPUT readonly STYLE="width:200px;background:CCCCCC;color:black" TYPE="text" NAME="PATH" VALUE="<%= folderPath %>" SIZE="25" MAXLENGTH="200"> </td> </tr> <tr> <td valign="top" align="right">ID:</td><td valign="top" align="left"><input name="ID" type="text" style="width:200px" size="25" maxlength="15"></td> </tr> <tr> <td valign="top" align="right">INTERESTS:</td><td valign="top" align="left"><input name="INTERESTS" type="text" style="width:200px" size="25" maxlength="80"></td> </tr> <tr> 2. The add page can be called from YourCoCMnewsFormValidation.jsp if any validation fails. In that scenario, we would need to pre-populate all the fields with the original values entered. Original values are passed back via the request object. Thus for every field, you should add code such as the following. <tr> <td valign="top" align="right">CONFIDENTIAL:</td><td valign="top" align="left"><select style="width:200px" name="CONFIDENTIAL"><option value="Y" <%= request.getParameter("CONFIDENTIAL") != null && request.getParameter("CONFIDENTIAL").equals("Y") ? "SELECTED" : "" Chapter 11. Content management 693 %>>Yes</option><option value="N" <%= request.getParameter("CONFIDENTIAL")!= null && request.getParameter("CONFIDENTIAL").equals("N") ? "SELECTED" : "" %>>No</option></select></td> </tr> <tr> <td valign="top" align="right">HEADLINE:</td><td valign="top" align="left"><input name="HEADLINE" type="text" style="width:200px" size="25" maxlength="80" value="<%= request.getParameter("HEADLINE")==null ? "" : request.getParameter("HEADLINE").toString() %>"></td> </tr> We also need to add the following code to the page to display any error if there is a redirection from YourCoCMNewsFormValidation.jsp. <% //check if it is an error call boolean error = false; String errorMsg = request.getParameter("ERROR"); if (errorMsg != null){ error = true; } if (error){ %> <FONT color="#cc0000"><B> <%=errorMsg%> </B></FONT> <%}%> 3. A Browse button would be nice for browsing an image file. Before the </td> tag for the image cell, enter the following. <INPUT type="button" onclick="listUrls('IMAGE')" name="IMAGE_url" value="Browse"> The Java script, listUrls, already exists on the default template page. 4. It is a good practice to control user entries by enabling the user to choose from a pre-defined list. In our scenario, we have changed the location and department fields from text fields to drop-down lists. <tr> <td valign="top" align="right">LOCATION:</td><td valign="top" align="left"><select style="width:200px" name="LOCATION"><option value="all" <%= request.getParameter("LOCATION")!= null && request.getParameter("LOCATION").equals("all") ? "SELECTED" : "" %>>All</option><option value="aus" <%= request.getParameter("LOCATION")!= null && request.getParameter("LOCATION").equals("aus") ? "SELECTED" : "" %>>Austin,TX</option><option value="dur" <%= request.getParameter("LOCATION")!= null && request.getParameter("LOCATION").equals("dur") ? "SELECTED" : "" %>>Durham,NC</option><option value="ny" <%= 694 IBM WebSphere Portal V4 Developer’s Handbook request.getParameter("LOCATION")!= null && request.getParameter("LOCATION").equals("ny") ? "SELECTED" : "" %>>New York,NY</option><option value="ral" <%=request.getParameter("LOCATION")!= null && request.getParameter("LOCATION").equals("ral") ? "SELECTED" : "" %>>Raleigh,NC</option></select></td> </tr> 5. In order to conform to the date format required by Web Content Publisher, we would use five drop-downs to enable the user to enter the year, month, day, hour and minute for the active and stop timestamp for the article. We will replace code for the date fields with the following. <% Calendar rightNow = Calendar.getInstance(); DateFormatSymbols symbols = new DateFormatSymbols( request.getLocale() ); String[] months = symbols.getMonths(); int int int int int currentMonth = rightNow.get(Calendar.MONTH); currentDay = rightNow.get(Calendar.DAY_OF_MONTH); currentYear = rightNow.get(Calendar.YEAR); currentHour = rightNow.get(Calendar.HOUR_OF_DAY); currentMinute = rightNow.get(Calendar.MINUTE); int int int int int startMonth = currentMonth; startDay = currentDay; startYear = currentYear; startHour = currentHour; startMinute = currentMinute; int int int int int stopMonth = currentMonth; stopDay = currentDay; stopYear = currentYear; stopHour = currentHour; stopMinute = currentMinute; if (request.getParameter("start_month") != null){ startMonth = Integer.parseInt(request.getParameter("start_month")); startDay = Integer.parseInt(request.getParameter("start_day")); startHour = Integer.parseInt(request.getParameter("start_hour")); startMinute = Integer.parseInt(request.getParameter("start_minute")); startYear = Integer.parseInt(request.getParameter("start_year")); stopMonth = Integer.parseInt(request.getParameter("stop_month")); stopDay = Integer.parseInt(request.getParameter("stop_day")); stopHour = Integer.parseInt(request.getParameter("stop_hour")); stopMinute = Integer.parseInt(request.getParameter("stop_minute")); stopYear = Integer.parseInt(request.getParameter("stop_year")); } Chapter 11. Content management 695 %> <tr> <td valign="top" align="right">START DATE:</td> <td valign="top" align="left"> <select name="start_year"> <option value="<%=currentYear%>" <%= startYear == currentYear ? "SELECTED" : "" %>> <%=currentYear%></option> <option value="<%=(currentYear+1)%>" <%= startYear == currentYear+1 ? "SELECTED" : "" %>> <%=(currentYear+1)%></option> <option value="<%=(currentYear+2)%>"<%= startYear == currentYear+2 ? "SELECTED" : "" %>> <%=(currentYear+2)%></option> </select> <select name="start_month"><% for( int i=0; i<(months.length-1); i++ ) { String selected = ""; if( startMonth ==i ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"> <%= months[i] %></option><% } %> </select> <select name="start_day"><% for( int i=0; i<=31; i++ ) { String selected = ""; if( startDay ==(i+1) ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"><%=(i+1)%></option><% } %> </select> <select name="start_hour"><% for( int i=0; i<=23; i++ ) { String selected = ""; if( startHour ==(i+1) ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"><%=(i+1)%></option><% } 696 IBM WebSphere Portal V4 Developer’s Handbook %> </select> <select name="start_minute"><% for( int i=0; i<=59; i++ ) { String selected = ""; if( startMinute==(i+1) ) selected = "Selected"; %> <option <%=selected%> value="<%=(i+1)%>"><%=(i+1)%></option><% } %> </select> </td> </tr> We will do the same for the stop date. Note that for the above code to compile, you also need to import the appropriate classes to the page. At the top of the page, enter the following code. <%@page import="java.util.*, java.text.*"%>Change the title and page name of the page. 6. Change the target of the form to YourCoCMFormValidation.jsp. 7. All field names are generated using Java bean introspection. Thus, change the display field names accordingly. 8. If you are using a style sheet for your templates, add the CSS reference to your page and make sure to import it to Web Content Publisher. 9. Make any other graphical changes as you wish. YourCoCMFormValidation.jsp Refer to the sample YourCoCMFormValidation.jsp in the YourCoCMTemp.war file. This page is shared by the add and edit functions. It should validate all the entries from the user entry forms and redirect the user to the next page. In addition, if it is an add operation, it should also consist of the unique resource ID generation routine. YourCoCMMetaData.jsp This page is shared by the add and edit functions to allow users to specify any metadata information about the news article. All the information collected from the previous form is stored on this page using hidden fields, including the command field and the beanName field. In our scenario, we use checkboxes to enable the user to select the categories that the news article relates to. When the user submits the form, a script will be invoked to assign the hidden variable INTERESTS with a comma delimited string composed of the values of all the Chapter 11. Content management 697 checked items. Then all the input values are submitted to the generic command servlet /wps/wcp/command for processing. YourCoCMNewsEdit.jsp This page is similar to YourCoCMNewsAdd.jsp except that the fields are always populated with all the values of the content resource to be edited. The resObj specified in the following code is used to pre-populate all the form values. <jsp:useBean id="getResource" class="com.ibm.wcm.GetGenericResource" type="com.ibm.wcm.GetGenericResource"><% getResource.getResource(request); %></jsp:useBean> <jsp:useBean id="resObj" scope="request" type="YourCoCM.YourCoCMNews"/> In addition, the command hidden field should be updateItem instead of addItem, and you need to pass a hidden field to specify the unique resource item associated with the content resource item that is being edited. <input type="hidden" name="command" value="updateItem"> <input type="hidden" name="ID" value="<%=resObj.getID()%>"> YourCoCMNewsShow.jsp and YourCoCMNewsPreview.jsp The show page is intended to show the users all the information that is entered for a piece of content whereas the preview page is intended to show the users how the piece of content should appear on a Web page. In our sample, YourCoCMNewsShow.jsp and YourCoCMNewsPreview.jsp are displayed in Figure 11-41 and Figure 11-42. To implement these pages, simply insert the following code on the page and use the getters of the resObj to display any content information. <jsp:useBean id="getResource" class="com.ibm.wcm.GetGenericResource" type="com.ibm.wcm.GetGenericResource"><% getResource.getResource(request); %></jsp:useBean> <jsp:useBean id="resObj" scope="request" type="YourCoCM.YourCoCMNews"/> 698 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-41 YourCoCMNews show page Figure 11-42 YourCoCMNews preview page Chapter 11. Content management 699 Install authoring templates Now that you have created and modified all the authoring templates, you need to export them to the file system. 1. Export the files from WebSphere Studio Application Developer to the file system. Select templates folder under YourCoCMTemp project. Select File -> Export. 2. In the Export dialog, select the directory where you would like to export the files, for instance, c:\wcp\temp. 3. Click Finish. Then you need to import these files to Web Content Publisher. 1. Log in to Web Content Publisher if you have not already done so. Ensure that the active project is YourCoCMAuthor. Click the Content tab. 2. Click Files on the left pane and select the templates folder underneath it. Click Import as shown in Figure 11-43. Figure 11-43 Import templates in Web Content Publisher 3. In the Import Files dialog, select the File system import radio button. Under the Server directory field, type the name of the directory where you have 700 IBM WebSphere Portal V4 Developer’s Handbook exported your templates. Your window should look similar to Figure 11-44. Click Import. Figure 11-44 Import Dialog for Web Content Publisher 4. You should see a window similar Figure 11-45 confirming that seven files were imported to your project. Chapter 11. Content management 701 Figure 11-45 Confirm file import Test the authoring templates All the authoring templates are now set up. You are now ready to test your authoring templates. 1. Click the Content tab. Select YourCoCMNews under Structured Content. 2. Click in the right pane to contribute content. 3. The add window as shown in Figure 11-39 comes up. 4. Click Browse. The Search Criteria for File dialog as shown in Figure 11-46 comes up. Figure 11-46 Search for files in Web Content Publisher 5. Enter %.jpg in the filename field and click Search. 6. A window similar to Figure 11-47 comes up. Select one of the images and click OK. 702 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-47 Search resource results 7. Fill in the rest of the fields and click Next. 8. You should see a window similar to Figure 11-40. Select a few of the checkboxes and click Submit. 9. Your new content entry should be listed in the structured content list as shown in Figure 11-48. Chapter 11. Content management 703 Figure 11-48 Structured content list 10.Click Edit properties; an edit window similar to the add window should come up. Make some changes and submit them. The content should be updated. 11.Click Show Details. A window similar to Figure 11-41 should show up. 12.Click the link of the content. A window similar to Figure 11-42 should show up. Create generation templates The term generation template is used interchangeably with presentation template. Generation templates are used to generate views of structured content and store the output in the form of files which will be ultimately published. The key advantage of using generation templates is that multiple views of the same content can be generated in a quick and uniform fashion. There are two types of generation templates: detail and summary template. Both of them can be implemented using JSP or XSL. You can use the generation templates in the sample application for Web Content Publisher as a starter. These samples can be found in <WASHOME>\wcm\samples\WCMSample\content\webApplication\templates\W CMSample. 704 IBM WebSphere Portal V4 Developer’s Handbook Note: If you are using personalization to display contents, you do not need to create any generation templates. Detail templates Detail templates, as the name suggests, show the detailed contents of an individual resource as they appear on the published Web site. Most of the time, it is the same as the preview authoring template so that whatever the content contributor sees in his preview window will be the same as what is being published. When you specify a detail template, you will also specify a generation folder. Once an association is made for detail template generation, whenever an add, edit or delete operation is performed on the resource, a background process will be scheduled to update the particular generated file automatically. All generated files are placed in the folder generated/class_name/gen_folder/resource_path in Web Content Publisher. It is also possible to generate a new resource based on the current resource contents. This will be discussed in “Resource to resource transformation” on page 723. When creating detail templates, all you need to do is to use the following code to obtain a reference to the resObj object and use getters to retrieve the specific content attribute. <jsp:useBean id="getResource" class="com.ibm.wcm.GetGenericResource" type="com.ibm.wcm.GetGenericResource"><% getResource.getResource(request); %></jsp:useBean> <jsp:useBean id="resObj" scope="request" type="YourCoCM.YourCoCMNews"/> In our sample YourCo internal news scenario, we will be using the same code as the preview authoring template with the exception that we are removing the cancel link and changing the reference for any CSS files since the generated file will be placed in a different directory. We assume that you have created a new file YourCoCMNewsDetails.jsp, exported the file from WebSphere Studio Application Developer and imported it into the templates folder of Web Content Publisher. Please refer to “Sample scenario for customizing authoring templates” on page 690 if you need instructions for similar procedures. Now you need to specify the details template in Web Content Publisher. 1. In Web Content Publisher, select YourCoCMNews under structured contents. Click to bring up the templates dialog. 2. Click the Details tab. 3. Click Browse. Chapter 11. Content management 705 4. The Search Criteria window comes up. Enter %.jsp for the filename field and click Search. 5. Select /templates/YourCoCMnewsDetails.jsp and click OK. 6. In the generation folder field, enter yourCoNews and click should look similar to Figure 11-49. . Your window 7. Select the checkbox Regenerate content files affected by this type. If this checkbox is not selected, views for all the file content already stored will not be generated. Figure 11-49 Details template page 8. You can preview how the page will look. Click Preview. A form with all the attributes for the specific content type appears. Click Search. A list of content instances is shown. Select one of them and click OK. 9. After you are done previewing, click Save. 10.If you click the Files on the left pane of the Content tab, you should find a new file structure created, as shown in Figure 11-50. 706 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-50 Generated detail files The detail files generated are named by their resource ID. They are created under the folder Files/generated/YourCoCM.YourCoCMNews/yourCoNews. YourCoCM.YourCoCMNews is the structured content type that is being used to generate the contents and yourCoNews is the path supplied when you specify the detail template. You can click each one of them and see how they look. Summary templates Summary templates show the headlines or titles of a resource collection in the form of a list and enable the user to click a particular item and view the details. As opposed to detailed templates, generated files are not created automatically. After an association is made for the summary templates and the resources, the user needs to explicitly click the Generate button to generate the contents. The generate summary file will be placed in the /generated/class_name/gen_folder/target_filename of Web Content Publisher. To create a summary template, the following code is needed to retrieve the resource collection of a particular content type. <jsp:useBean class="com.ibm.wcm.GetGenericResourceList" id="getResourceList" type="com.ibm.wcm.GetGenericResourceList"> <% getResourceList.setRequest(request); %> </jsp:useBean> Chapter 11. Content management 707 <% java.util.Enumeration enumObjs = getResourceList.getResourceList(); if( enumObjs==null ) { out.println("<br>getResourceList.getResourceList() returned null object"); return; } %> Once you get a reference of the collection, you can then iterate through the resource list and display the appropriate attribute on the summary page as follows. <% while( enumObjs.hasMoreElements() ) {%> YourClass yourClass = (YourClass)enumObjs.nextElement(); // Retrieve any information from the class and display // on the page. eg. yourClass.getABC() <%}%> If you need to retrieve the folder information of the generated content, the information can be retrieved by using resObj.get(“PATH”). If you need to know the name of the generated file, you can get the information by using resObj.getId(). Now we will demonstrate this technique using the YourCo example. We will create a summary page with a list of internal news headlines. When the user clicks each of these headlines, the detail page will be shown. 1. Create a new file called YourCoCMNewsSummary.jsp under the templates folder of YourCoTemp project. 2. Click the Design view. 3. We will now create a table to hold the headlines items. Select Table -> Table... from the menu bar. 4. In the Insert Table dialog box, enter 2 for the rows field and 1 for the column field. Click OK. 5. Click the first cell of the table and type YourCo internal news. 6. Select the source tab. 7. Enter the following at the beginning of the code to retrieve a reference of the resource list. <%@page import="java.util.*, java.text.*"%> <jsp:useBean class="com.ibm.wcm.GetGenericResourceList" id="getResourceList" type="com.ibm.wcm.GetGenericResourceList"> <% getResourceList.setRequest(request); %> </jsp:useBean> 708 IBM WebSphere Portal V4 Developer’s Handbook <% java.util.Enumeration enumObjs = getResourceList.getResourceList(); if( enumObjs==null ) { out.println("<br>getResourceList.getResourceList() returned null object"); return; } %> 8. Enter the following code highlighted in bold in the second <TR> tag. <% while( enumObjs.hasMoreElements() ) { YourCoCM.YourCoCMNews yourCoNews = (YourCoCM.YourCoCMNews)enumObjs.nextElement(); %> <TR><TD><ahref="<%=yourCoNews.getID()%>.html"><%=yourCoNews.getHEADLINE()%> </a><</TD></TR> <%}%> 9. Make any cosmetic changes, as necessary. Note: As you might have noticed in the getResource() code, a setRequest method is required to retrieve the content. GetGenericResource and GetGenericResourceList cannot be used in JSPs outside of the authoring environment of Web Content Publisher as an authoring-environment request object is required to set the request properly. Now that the summary template is created, you need to import the file in the templates folder for the YourCoCMAuthor project. If you need similar instructions for importing templates, refer to “Sample scenario for customizing authoring templates” on page 690. 1. In Web Content Publisher, select YourCoCMNews under structured contents. Click to bring up the templates dialog. 2. Click the Summary tab. 3. Click Browse. 4. The Search Criteria window comes up. Enter %.jsp for the filename field and click Search. 5. Select /templates/YourCoCMNewsSetails.jsp and click OK. 6. In the generation folder field, enter yourCoNews and click should look similar to Figure 11-51. . Your window Chapter 11. Content management 709 Figure 11-51 Summary template 7. Select the check box Regenerate content files affected by this type. If this checkbox is not selected, views for all the file content that is already stored will not be generated. 8. You can then click Preview to see how the summary page would look. 9. Click Save. 10.Select the Content tab. Select YourCoCMNews under structured contents on the left pane. On the right pane, click Generate. 11.The Generate Items dialog comes up as shown in Figure 11-52. Click Generate. 710 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-52 Generate summary page 12.You should then get a message similar to that shown in Figure 11-53, confirming that the summary file was generated. Figure 11-53 Confirmation of summary page 13.Click the folder /generated/YourCoCM.YourCoCMNews/yourCoNews. There should be a file called summary.html. Click the file to view the generated summary page. You should see something similar to Figure 11-54. Chapter 11. Content management 711 Figure 11-54 Generated summary page Tip: If the generated file is a JSP file, it will most probably contain Java scriptlets. The problem in writing templates with Web Content Publisher is that any JSP or Java code is compiled by the compiler when the generated view is created. Thus, even though the generated file is still a JSP file, all the dynamic contents are already interpreted. This problem can be solved by outputting the JSP code in an out.println statement. Example: <%out.println("<" + "% out.println(new java.util.Date().toString()); %" + ">");%> Web Content Publisher will output <%out.println(new java.util.Date().toString())%> 11.3.5 Create channel contents As described in “Syndicated content” on page 650, syndicated contents are information provided by external parties to be used by licensed parties to provide content to their users. Syndicated contents are delivered in XML format. Web Content Publisher supports syndicated contents in Rich Site Summary (RSS) format, a popular XML format commonly used for describing syndicated contents. Currently, Web Content Publisher supports RSS V0.91 and V0.92 only. The version of a channel can be found in the <rss version> tag in an RSS content file. An example of a RSS channel content is shown in Example 11-3. Example 11-3 A channel <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE rss PUBLIC "-//Netscape Communications//DTD RSS 0.91//EN" "http://p.moreover.com/xml_dtds/rss-0_91.dtd"> <rss version="0.91"> 712 IBM WebSphere Portal V4 Developer’s Handbook <channel> <title>Moreover - IBM news</title> <link>http://www.moreover.com</link> <description>IBM news - news headlines from around the web, refreshed every 15 minutes</description> <language>en-us</language> <image> <title>moreover...</title> <url>http://i.moreover.com/pics/rss.gif</url> <link>http://www.moreover.com</link> <width>144</width> <height>16</height> <description>News headlines from more than 4,000 sources, harvested every 15 minutes...</description> </image> <item> <title>Big Blue Big on Self-Managing Computers</title> <link>http://c.moreover.com/click/here.pl?r50156008</link> <description>AtNewYork Oct 22 2002 3:02AM ET</description> </item> <item> <title>IBM's hybrid CPU--do you need it?</title> <link>http://c.moreover.com/click/here.pl?r50140175</link> <description>ZDNet Oct 21 2002 8:24PM ET</description> </item> <item> <title>IBM looks to self-healing computers</title> <link>http://c.moreover.com/click/here.pl?r50129979</link> <description>MSNBC Oct 21 2002 5:18PM ET</description> </item> </channel> </rss> In Web Content Publisher, you can use syndicated content by defining channels. A channel is an XML file in RSS format. Using the Web Content Publisher interface, you can specify a number of channel sources by and schedule periodic updates to the channel so that the channel information refreshes periodically by itself. Channel contents are raw materials for your Web content. What usually happens is that a preview template is created for Web content administrators to review the channel contents and retain the ones that could be published. A summary template is then used to generate the list of approved channel contents to be shown on the Web site. We will now guide you through the process of using syndicated contents in Web Content Publisher. Chapter 11. Content management 713 Defining a channel In order to receive syndicated content, you first need to define a channel. You can easily find channel sources by doing a simple Web search on RSS. However, make sure that you read the licensing agreement before using the syndicated contents. In this example, our channel source is from Moreover. Note: If you have installed the Authoring server on the same machine as WebSphere Portal, you might get an error such as java.lang.IllegalArgumentException: object is not an instance of the declaring class. The reason is that Portal Content Organizer, which is installed as part of WebSphere Portal, uses classes of the same name as Web Content Publisher. Thus if you have WebSphere Portal installed, you need to temporarily disable Portal Content Organizer. To disable Portal Content Organizer, go to <WAS_HOME>/lib/app and make a copy of wpspco.jar. Then open wpspco.jar using Winzip and delete the six RssChannel item classes. Then restart WebSphere Admin Server. 1. Click the Administration tab in Web Content Publisher. 2. Select Channel on the left pane. 3. Click on the right pane to create a new channel. 4. The new channel dialog box comes up. Provide a name for your channel under Path field. In the channel field, type http://p.moreover.com/cgi-local/page?c=IBM%20news&o=rss 5. Click Preview. You should see the channel content similar to Figure 11-55. 714 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-55 Channel contents preview 6. Click Create. 7. The channel should be created and your window should look similar to Figure 11-56. Chapter 11. Content management 715 Figure 11-56 Channel list 8. Click the Contents tab. Select the Syndicated Content menu on the left pane. You should see your newly created channel underneath it. Click the new channel; you should see a list of contents for the channel as shown in Figure 11-57. Figure 11-57 Channel contents 716 IBM WebSphere Portal V4 Developer’s Handbook Channel scheduling Syndicated content changes as frequently as the content syndicators update their content. Thus, you should schedule regular updates for your channel. 1. In Web Content Publisher, click Administration tab. Select Channels on the left pane. 2. Select the channel that you would like to schedule and click . 3. The Edit Schedule dialog box comes up as shown in Figure 11-58. Select the frequency, start date and end date for your schedule and click Save. Figure 11-58 Scheduling a channel Preview template for a channel Preview template is a type of authoring template. For information on authoring templates, refer to “Create authoring templates” on page 679. Preview templates for channels are used for the content management team to screen the channel content to decide whether it should be used for publishing. Any contents that should not be published can be deleted after previewing. You would code the preview template in a way similar to how you would code your structured content preview template in “Create authoring templates” on page 679. 1. In WebSphere Application Developer, open the project YourCoTemp that you created previously. 2. Right-click the folder template and create a new JSP File called YourCoCMChannelPreview.jsp. 3. Just like creating a preview template for structured content, you use the com.ibm.wcm.GetGenericResource to retrieve the channel content object. However, instead of casting it to a structured content type, you cast it to Chapter 11. Content management 717 com.ibm.wcm.resources.Rsschannelitem. Click source and type the following code at the beginning of the page. <jsp:useBean id="getResource" class="com.ibm.wcm.GetGenericResource" type="com.ibm.wcm.GetGenericResource"><% getResource.getResource(request); %></jsp:useBean> <jsp:useBean id="resObj" scope="request" type="com.ibm.wcm.resources.Rsschannelitem"/> 4. Once you obtain a reference of the channel content object resObj, you use the following methods to get the contents. getCHANNELTITLE() getTITLE() getDESCRIPTION() getLINK() 5. After you have created the JSP, you need to import the JSP file to Web Content Publisher. Go to the Content tab on Web Content Publisher and select the templates folder under Files. 6. Click Import on the right pane. 7. In the Import Files window, select the File system import radio button, and type the directory where the JSP file resides. Click Import. 8. You should see a message indicating that your file has been successfully imported. 9. Select IBMNews under Syndicated Content. Click . 10.In the Authoring tab of the templates window, click Browse for the Template for preview form. 11.The search criteria window comes up. Type %.jsp in the filename field and click search. 12.Select the file templates/YourCoCMChannelPreview.jsp and click OK. 13.Your window should look similar to Figure 11-59. Click Save. 718 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-59 Specify channel preview template 14.To view the preview template, click one of the channel contents as shown in Figure 11-57. You should see the channel information, similar to Figure 11-60. Figure 11-60 Channel Preview 15.Click the link and you should see the actual content from the external site. Summary template for a channel Summary template is a type of generation template. For more information about summary template, refer to “Create generation templates” on page 704. Summary template for a channel is used to show a list of channel contents available to the reader. The reader can then click a link from the list and view the Chapter 11. Content management 719 contents from the external site. Here is a step-by-step guide to creating a summary template for a channel. 1. In WebSphere Application Developer, open the project YourCoTemp that you created previously. 2. Right-click the folder template and create a new JSP file called YourCoCMChannelSummary.jsp. 3. Just like creating a summary template for structured content, you use the com.ibm.wcm.GetGenericResourceList to retrieve the list of channel contents. Click Source and type the following code at the beginning of the page. <jsp:useBean class="com.ibm.wcm.GetGenericResourceList" id="getResourceList" type="com.ibm.wcm.GetGenericResourceList"><%getResourceList.setRequest(requ est); %></jsp:useBean> <% java.util.Enumeration enumObjs = getResourceList.getResourceList(); String path=""; if( enumObjs==null ) { out.println("<br>getResourceList.getResourceList() returned null object"); return; } %> 4. Using enumObjs, you can go through each channel item of type com.ibm.wcm.resources.RssChannelitem and create a table of contents for the channel. Your code might look similar to the following. Example 11-4 YourCoCMChannelSummary.jsp code fragment <%try {%> <TABLE border="0"> <TBODY> <TR> <TD align="left" valign="top"><B>News Story</B></TD> </TR> <% while( enumObjs.hasMoreElements() ) { com.ibm.wcm.resources.Rsschannelitem news = (com.ibm.wcm.resources.Rsschannelitem)enumObjs.nextElement(); %> <TR> <TD align="left" valign="top"><U><A href="<%= news.getLINK() %>"><%= news.getTITLE() %></U> 720 IBM WebSphere Portal V4 Developer’s Handbook </A></TD> </TR> <%}%> </TBODY> </TABLE><% } catch( Exception exc ) { out.println( exc ); exc.printStackTrace(); } %> 5. After you have created the JSP, you need to import the JSP file to Web Content Publisher. Go to Content tab on Web Content Publisher and select templates folder under files. 6. Click Import on the right pane. 7. In the Import Files window, select the File system import radio button, and type the directory where the JSP file resides. Click Import. 8. You should see a message indicating that you file has been successfully imported. 9. Select IBMNews under Syndicated Content. Click . 10.Select the summary tab of the templates window, click Browse for the Template for preview form. 11.The search criteria window comes up. Type %.jsp in the filename field and click search. 12.Select the file templates/YourCoCMChannelSummary.jsp. Click OK. 13.Type moreOverNews in the generation folder field and click . 14.Select the checkbox Generate summary file using this template. 15.Your window should look similar to Figure 11-61. Click Save. Chapter 11. Content management 721 Figure 11-61 Summary template for channel contents 16.Summary templates need to be explicitly generated. Select IBMNews under the Content tab. 17.On the right pane, select Generate. 18.The Generate Items window appears. Click Generate. 19.A message indicating that the summary file is generated should be displayed. Click Cancel. 20.Click the generated folder under the Files folder. You should see a new folder named com.ibm.wcm.resources.Rsschannelitem. Under this folder, you should see a folder named moreOverNews similar to Figure 11-62. 722 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-62 Summary file for channel contents 21.Select the moreOverNews folder and click the summary.html file on the right pane. 22.The summary of the IBMNews channel contents appears. Click each link to view the actual article. 11.3.6 Resource to resource transformation Another useful technique is resource to resource transformation. This means that whenever content for a resource source is created, a corresponding content for the resource target is generated. This technique could be useful in many circumstances to create particular types of content automatically. For instance, YourCo receives syndicated news content from a content syndicator. The company’s content management team would convert the news information into the YourCoNews format so that information such as start date, stop date, and any meta information could be associated with the article. The content team would first screen the syndicated content, then would add meta information for the article by editing the content using the authoring templates similar to those shown in Figure 11-39 and Figure 11-40. Subsequently, the news articles can be personalized and served to the employee based on the meta information for each news article. Resource transformation is done using XSL. We will illustrate how the scenario described above can be implemented. Chapter 11. Content management 723 The first step is to get a sample of the source XML content and the target XML content. In this example, the source resource content is the syndicated content and the target resource content is YourCoCMNews structured content. We assume that you have defined a channel and retrieved syndicated content through that channel, as well as set up YourCoCMNews structured content and created some content based on this structured content type. Then you can obtain the resource contents in XML format by exporting the project. 1. Click the Administration tab. 2. Select Project/Editions from the left pane. 3. Make sure the project that you would like to export is active. In our example, the active project should be YourCoCMAuthor. Note: The export utility in Web Content Publisher exports the active project. So even though you may select a different project, the project to be exported is still the active project. To make a particular project active, select the project and click Work On. 4. Click Export. 5. The Export Project window comes up. Select the Export to File System radio button. Click Export. Note: All projects are exported to the file system relative to the root path. If you specify baseline1 in the server directory field and your root path is c:/wcp/YourCoCMAuthor, the project will be exported to c:/wcp/YourCoCMAuthor/baseline1. Therefore, do not put c:/temp in the server directory field since this will create an incorrect directory structure c:/wcp/YourCoCMAuthor/c:/temp. 6. You should see a message window detailing all the files being exported. 7. Open Windows Explorer and go to the project root directory. You should see the exported project similar to Figure 11-63. 724 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-63 Exported project hierarchy Note: A sample of the project export can be found in the WebSphere Content Publisher Project directory. Under the project root directory, c:/wcp/yourCoCMAuthor, you should see three directories: WCM-META, WCM-RESOURCES and webApplication. Each resource (structured content/syndicated content/file content) stored in Web Content Publisher is associated with a resource meta information file. This meta information file is an XML file that stores information such as the last modified date, the file path relative to the project root, access control information, etc., associated with a particular resource. A sample of a meta information file is shown in Example 11-5. All of these meta information files are stored under the WCM-META folder according to the project hierarchy. Chapter 11. Content management 725 Example 11-5 Meta information file for a content resource <?xml version="1.0" encoding="UTF-8"?> <YourCoCM.YourCoCMNews resourceId="20031028182250"> <metaData name="LASTMODIFIED" type="java.lang.Long">1035847377562</metaData> <metaData name="PATH" type="java.lang.String">/</metaData> <metaData name="SHAREDACL" type="java.lang.String">0</metaData> <metaData name="PROJECTID" type="java.lang.String">21</metaData> <metaData name="WORKSPACE" type="java.lang.String">base</metaData> </YourCoCM.YourCoCMNews> All structured content resources and syndicated content resources are stored as XML files in the WCM-RESOURCES folder. They are placed in the folder according to the name of the content type. Each resource is named according to their corresponding resource ID appended with the file extension .wcp. Files under the webApplication directory corresponds to the files that you see under the File folder in Web Content Publisher. All file content and generated file content is stored in this directory. In order to create the XSL to transform the content source to the content target, we now inspect the source content resource and a target content in the WCM-RESOURCES folder. Using any text editor, open one of the files with extension .wcp from the folder Project_Root/WCM-RESOURCES/com.ibm.wcm.resources.Rsschannelitem/ IBMNews. The source file content should look similar to the sample shown in Example 11-6. Example 11-6 Sample source content <?xml version="1.0" encoding="UTF-8"?> <com.ibm.wcm.resources.Rsschannelitem> <description>wcp.channelItem</description> <displayName>wcp.channelItem</displayName> <properties resourceId="Big Blue Big on Self-Managing Computers"> <property name="CHANNELTITLE" type="java.lang.String">Moreover - IBM news</property> <property name="LINK" type="java.lang.String">http://c.moreover.com/click/here.pl?r50118179</property > <property name="CONTENT" type="java.lang.String">No content stored for this channel</property> <property name="CATEGORY" type="[Ljava.lang.String;" array="true"> </property> <property name="DESCRIPTION" type="java.lang.String">Internet News Oct 21 2002 2:49PM ET</property> <property name="TITLE" type="java.lang.String">Big Blue Big on Self-Managing Computers</property> </properties> 726 IBM WebSphere Portal V4 Developer’s Handbook </com.ibm.wcm.resources.Rsschannelitem> Now open one of the target files with extension .wcp from the folder Project_Root/WCM-RESOURCES/YourCoCM.YourCoCMNews. The target file should look similar to Example 11-7. Example 11-7 Target source content <?xml version="1.0" encoding="UTF-8"?> <YourCoCM.YourCoCMNews> <description>YourCoCMNews</description> <displayName>YourCoCMNews</displayName> <properties resourceId="20021021162518"> <property name="LOCATION" type="java.lang.String">Durham,NC</property> <property name="CONFIDENTIAL" type="java.lang.String">Y</property> <property name="HEADLINE" type="java.lang.String">Dragon has joined our team!</property> <property name="INTERESTS" type="java.lang.String"> bus comp cult edu</property> <property name="STOP_DT" type="java.sql.Timestamp">2002-10-05 16:25:00.0</property> <property name="ID" type="java.lang.String">20021021162518</property> <property name="DEPT" type="java.lang.String">HR</property> <property name="ACTIVE_DT" type="java.sql.Timestamp">2002-10-05 16:25:00.0</property> <property name="IMAGE" type="java.lang.String">/wps/YourCoCMAuthor/images/dragon.jpg</property> <property name="CONTENT" type="java.lang.String">A new dragon has joined our team! Wow! </property> </properties> </YourCoCM.YourCoCMNews> 8. By looking at the required target format, you should be able to create an XSL file, for instance resourceTransformation.xsl, to convert the source file to the target file. Your XSL file should look similar to Example 11-8. Example 11-8 Resource transformation file <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:template match="com.ibm.wcm.resources.Rsschannelitem"> <YourCoCM.YourCoCMNews> <description>Rsschannelitem</description> <displayName>Rsschannelitem</displayName> <xsl:apply-templates select="properties" /> </YourCoCM.YourCoCMNews> </xsl:template> <xsl:template match="properties"> <xsl:element name="properties"> Chapter 11. Content management 727 <xsl:attribute name="resourceId"><xsl:value-of select="@resourceId" /></xsl:attribute> <property name="LOCATION" type="java.lang.String">All</property> <property name="CONFIDENTIAL" type="java.lang.String">N</property> <property name="HEADLINE" type="java.lang.String"><xsl:value-of select="@resourceId" /></property> <property name="INTERESTS" type="java.lang.String"></property> <property name="STOP_DT" type="java.sql.Timestamp">2002-10-05 16:25:00.0</property> <property name="ID" type="java.lang.String"><xsl:value-of select="@resourceId" /></property> <property name="DEPT" type="java.lang.String">All</property> <property name="ACTIVE_DT" type="java.sql.Timestamp">2002-10-05 16:25:00.0</property> <property name="IMAGE" type="java.lang.String"></property> <xsl:apply-templates select="property" /> </xsl:element> </xsl:template> <xsl:template match="property"> <xsl:if test="@name='LINK'"> <xsl:element name="property"> <xsl:attribute name="name">CONTENT</xsl:attribute> <xsl:attribute name="type">java.lang.String</xsl:attribute> <xsl:value-of select="." /> </xsl:element> </xsl:if> </xsl:template> </xsl:stylesheet> In the example above, the resource ID, title and link of the source content is mapped to the resource ID, headline, and content field of the target content, respectively. All of the remaining fields other than the interests field in the target content are required. However, the source content does not provide such information. Therefore, we have created default values for all these fields in the XSL. Note: When you create an XSL, make sure that the datatype of all source fields maps to the compatible data type of the target fields. Also, ensure the maximum allowable length of the source field does not exceed the maximum allowable length of the target field. 9. Now that you have created the XSL file, resourceTransformation.xsl, you should import the file to Web Content Publisher. Import the file to the templates folder. 10.Select IBMNews under syndicated content and click 728 IBM WebSphere Portal V4 Developer’s Handbook . 11.The templates window comes up. Select the Details tab. 12.Click Browse. 13.In the Search Criteria window, type %.xsl in the filename field and click Search. 14.Select resourceTransformation.xsl and click OK. 15.Type resources under the New generation folder field and click . 16.Select the Resource Collection radio button and select YourCoCMNews from the drop-down menu. 17.Select the Regenerate content files affected by this template checkbox. Your window should look similar to Figure 11-64. Click Save. Figure 11-64 Resource to resource transformation detail template 18.Select the Content tab. A new folder, IBMNews, is created under the YourCoCMNews structured content. All syndicated contents from the IBMNews channel is transformed and created in this folder. Your window should look similar to Figure 11-65. Chapter 11. Content management 729 Figure 11-65 YourCoCMNews structured contents from resource transformation 19.Select one of the newly generated structured content and click Edit Properties. You should now be able to add meta information to the structured content. 11.3.7 Publishing contents In previous sections, we have discussed how to enable users to create contents via structured contents as well as channel contents. We have also discussed how detail and summary files of these contents are generated. In this section, we will focus on publishing these content files to the publishing server from the authoring server. Note: As a reminder, Web Content Publisher is made up of two components: the Authoring Server and the Publishing Server. All the content creation that we implemented in previous sections are performed on the Authoring Server. After contents are created, they are published on the Publishing Server. We first need to create and deploy an empty Web application on the publishing server using the same context root as the Web Content Publisher project. 730 IBM WebSphere Portal V4 Developer’s Handbook Here are the steps to create the Web application. 1. Open WebSphere Studio Application Developer. 2. Select File -> New -> Project. 3. In the New Project dialog, select Web Project, then click Next. 4. In the Project name field, type YourCoCMRuntime. In the Enterprise Application project name field, type YourCoCMRuntime.ear. 5. Click Finish. 6. Select YourCoCMRuntime project. Select File -> Export. 7. In the Export dialog, select WAR file. Click Next. 8. In the Export Resources to a WAR File dialog box, make sure that YourCoCMRuntime is selected in the first drop-down list. Click Browse to select a folder to export the WAR file, for instance, c:\wcp\YourCoCMRuntime\YourCoCMRuntime.war. Click Finish. Here are the steps to deploy the Web application. 1. On your publishing server, start WebSphere Administrative Console by selecting Start -> Programs -> IBM WebSphere -> Application Server V4.0 -> Administrative Console. If the Administrative Console does not start, it may be because Domino or WebSphere Admin Server is not started. 2. On the WebSphere Administrative Console, right-click Enterprise Application and select Install Enterprise Application. 3. In the Install Enterprise Application Wizard, select the Install stand-alone module radio button. In the Path field, browse or type the file location where you exported the WAR file, for instance c:\wcp\YourCoCMRuntime\YourCoCMRuntime.war. Type YourCoCMRuntime in the Application name field. Type /wps/YourCoCM in the Context root for the Web module. Click Next.. 4. Click Next until you reach the Selecting Application Servers window. Click Select Server. 5. Select WebSphere Portal and click OK. 6. Click Next. 7. Click Finish. You should receive a message dialog indicating that the enterprise application install has completely successfully. After you install the enterprise application, you need to regenerate Web server plugins so that any request for the context /wps/YourCoCM can be routed from the Web server to WebSphere. Chapter 11. Content management 731 1. In the WebSphere Administrative Console, click your node name. Right-click and select Regen Webserver Plugin. 2. Stop and restart IBM HTTP Server. Go to Services and select IBM HTTP Server. Right-click and select Stop. When the HTTP Server is completely stopped, right-click and select Start. 3. Go back to the WebSphere Administrative Console. Select YourCoCMRuntime under Enterprise Applications. Right-click and select Start. You should receive a message indicating that YourCoCMRuntime has been started successfully. 4. Expand the YourCoCMRuntime folder and select WebModules. You should see the YourCoCMRuntime Web module on the right pane. Right-click and select Start. When the Web module is started, you should receive a message indicating that the YourCoCMRuntime Web module has been started successfully. Next, you need to set up the correct publish paths for the static files. 1. On your publishing server, open the file <WebSphere Portal Home>\app\WCMPznPublish.ear\WCMPznPublish.war\WEB-INF\web.xml in Notepad (or any text editor that you prefer). 2. Add a new publish server definition, Publish Server 2, along with its security constraints and mapping marked in bold in Example 11-9. Note: You may simply replace your web.xml with this one. However, make sure that your WebSphere installedApps path is correct. There are two places where the file path is specified on the web.xml file. Example 11-9 web.xml for publishing server <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> <web-app id="WebApp_1"> <display-name>WCM Publish Web App</display-name> <description>WCM Publish Web App</description> <servlet id="Servlet_1"> <servlet-name>PznPublish</servlet-name> <description>Pzn Publish Target</description> <servlet-class>com.ibm.wcm.servlets.PznPublishServlet</servlet-class> <init-param id="InitParam_1"> <param-name>baseDir</param-name> <param-value>c:/WebSphere/AppServer/installedApps</param-value> </init-param> <init-param id="InitParam_2"> <param-name>defaultWebAppDir</param-name> 732 IBM WebSphere Portal V4 Developer’s Handbook <param-value>WCMPznPublish.ear/WCMPznPublish.war</param-value> </init-param> </servlet> <servlet id="Servlet_2"> <servlet-name>PznPublish 2</servlet-name> <description>Pzn Publish Target</description> <servlet-class>com.ibm.wcm.servlets.PznPublishServlet</servlet-class> <init-param id="InitParam_3"> <param-name>baseDir</param-name> <param-value>c:/WebSphere/AppServer/installedApps</param-value> </init-param> <init-param id="InitParam_4"> <param-name>defaultWebAppDir</param-name> <param-value>YourCoCMRuntime.ear/YourCoCMRuntime.war</param-value> </init-param> </servlet> <servlet-mapping id="ServletMapping_1"> <servlet-name>PznPublish</servlet-name> <url-pattern>/publishtarget</url-pattern> </servlet-mapping> <servlet-mapping id="ServletMapping_2"> <servlet-name>PznPublish 2</servlet-name> <url-pattern>/publishruntime</url-pattern> </servlet-mapping> <security-constraint id="SecurityConstraint_1"> <web-resource-collection id="WebResourceCollection_1"> <web-resource-name></web-resource-name> <url-pattern>/publishtarget/*</url-pattern> <url-pattern>/publishruntime/*</url-pattern> <http-method>DELETE</http-method> <http-method>GET</http-method> <http-method>POST</http-method> <http-method>PUT</http-method> </web-resource-collection> <auth-constraint id="AuthConstraint_1"> <description>Users that are allowed to publish and update documents</description> <role-name>WCM Publisher Role</role-name> </auth-constraint> <user-data-constraint id="UserDataConstraint_4"> <transport-guarantee>NONE</transport-guarantee> </user-data-constraint> </security-constraint> <login-config id="LoginConfig_1"> <auth-method>BASIC</auth-method> Chapter 11. Content management 733 </login-config> <security-role id="SecurityRole_1"> <description>WCM publisher role</description> <role-name>WCM Publisher Role</role-name> </security-role> </web-app> 3. In the WebSphere Administrative Console, select the WCM Publish Web application, right-click it and select Stop. Once the application is stopped successfully, right-click again and select Start. The changes made in the web.xml file are now in effect. After all the configuration on the publishing server is completed, we need to specify this publishing server in our authoring environment. 1. Open Web Content Publisher by typing http://<YOUR_FULLY_QUALIFIED_HOSTNAME>/wps/wcp/index.jsp. Log on as wcpadmin. 2. Make sure that the active project is YourCoCMAuthor. Click the Administration tab. 3. Select Publish Servers in the left pane. 4. Click to add a publish server. 5. Enter the information of your publish server, for instance, http://Your_fully_qualified_publish_server_hostname/WCMPznPublish/publis hruntime. Select the Realm checkbox and type wpsbind for the user ID and password for the password. Your window should look similar to Figure 11-66. Click Add. 734 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-66 Adding a publish server All the setups are now completed. You can take the following steps whenever you want to publish contents to the publishing server. 1. In Web Content Publisher, click the Content tab. 2. Select as shown in Figure 11-67. Note: If you do not see the publish icon, you may not have the authority to publish. Log in as a cuser who has the permission to publish. Chapter 11. Content management 735 Figure 11-67 Publish content 3. The Publish Content window comes up. Select the publish server YourCoCMPublish and click .Your window should look similar to Figure 11-68. Then click Publish. Note: You can choose to publish all the items or only items that have been changed since the last publish operation. You can schedule you publish by selecting the Publish content in a background process radio button and specifying the date and time that such an operation should be performed. 736 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-68 Publish Content 4. Your should see a window similar to Figure 11-69 displaying all the contents that are being published. Chapter 11. Content management 737 Figure 11-69 List of published contents 5. To validate the publish operation, open DB2 Control Center by selecting Start -> Programs -> IBM DB2 -> Control Center. 6. Select the YOUR_CO_NEWS table in the YOURCOCM database. Right-click YOUR_CO_NEWS and select Sample Contents. You should see all the structured contents that are being entered. Note: The database table defined for structured contents is populated only after you have published the contents. At authoring time, the information is stored in the WCM database. 7. Open Windows Explorer on the Publishing Server. Go to <WebSphere HOME>/installedApps/YourCoCMRuntime.ear/YourCoCMRuntime.war. In this directory, you should see all the files published. Your directory should look similar to Figure 11-70. 738 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-70 Published content directory structure 8. Open a browser and point to the URL http://Your_Publishing_Server/wps/YourCoCMRuntime/wps/YourCoCM/gener ated/YourCoCM.YourCoCMNews/yourcoNews/summary.html. You should see the YourCoCMNews summary page that you created. 11.3.8 Serving content in the portal If you have installed WebSphere Portal on the publishing server, you will be able to display the contents that are published from the Authoring server. There are two types of contents: static and dynamic. Displaying static portal content Static portal content refer to any contents displayed in the portlet by serving static files from the server. In most cases, these are the files being published from the authoring server. There are mainly two ways to display static files, using an IFrame or reading static contents directly from the files. Displaying static contents using IFrame The key advantage to using IFrame to display static HTML pages is that all the information on the page will be rendered properly without any modifications to the static page. The drawback is that the look and feel of the page might not conform to that of the Portal. Also, if the theme is changed, you would need to manually change the background, for instance, to match the changed theme. Chapter 11. Content management 739 Displaying static contents using an IFrame is a relatively simple task. All you need to do is to create a simple portlet to render a JSP that uses IFrame tags. A good practice is to make attributes of the IFrame (URL, height, and width) configurable so that no code change is necessary if any of the attributes need to be updated. The following steps describe how that is accomplished. 1. In WebSphere Studio Application Developer, create a new portlet development project. Select File -> New -> Project. 2. In the New Project window, select Portlet development on the left pane, and Portlet application project on the right pane. Click Next. 3. In the Define the Project project window, enter YourCoCMIFrame for the project name field, and YourCoCMIFrame.ear for the Enterprise Application project name as shown in Figure 11-71. Click Next. Figure 11-71 Create IFrame project 4. Select the Basic portlet radio button. Click Next. 5. Click Finish. 6. Since we would like to make the attributes of the IFrame configurable, we would like to put the attributes as parameters in portlet.xml. Double-click the portlet.xml file under the folder web-Application/WEB-INF. Your window should look similar to Figure 11-72. 740 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-72 portlet.xml configuration window 7. Select Portlet_1 under the Concrete portlet application. Click the Add button in the Settings section as shown in Figure 11-72. 8. In the parameter field, type pagename. In the value field on the same row, type the URL of the page that you would like to display. In our example, we would like to display the summary page that we generated using structured contents in previous sections, so we type http://Your_fully_qualified_hostname/wps/YourCoCM/generated/YourCoCM .YourCoCMNews/yourCoNews/summary.html. 9. Repeat the two steps above and enter the parameter-value pairs according to Table 11-2. Table 11-2 Parameters for portlet settings Parameter Value pageheight 400 pagewidth 50% scrolling NO 10.Save the portlet.xml file. Chapter 11. Content management 741 11.Open the MyPortlet.java file by double-clicking MyPortlet.java under the folder source/portlet. 12.After the comment //Save name in bean, enter the following code to retrieve the IFrame attributes from the portlet settings and pass them on to the JSP page. request.setAttribute(“pagename”,request.getPortletSettings().getAttribute(“ pagename“)); request.setAttribute(“pagewidth”,request.getPortletSettings().getAttribute( “pagewidth“)); request.setAttribute(“pageheight”,request.getPortletSettings().getAttribute (“pageheight“)); request.setAttribute(“scrolling”,request.getPortletSettings().getAttribute( “scrolling“)); 13.Save the file MyPortlet.java. 14.Open the view.jsp file by double-clicking view.jsp under the folder webApplication/jsp. 15.Select the source tab of view.jsp. Replace all the code with the following. <IFRAME ID=IFRAME1 FRAMEBORDER=0 WIDTH=”<%=request.getAttribute(“pagewidth”)%>” HEIGHT=”<%=request.getAttribute(“pageheight”)%>” SCROLLING=”<%=request.getAttribute(“scrolling”)%>” SRC=”<%=request.getAttribute(“pagename”)%>” 16.Save the file view.jsp. Now we can export the WAR file. 1. Select YourCoCMIFrame project. Click File -> Export. 2. In the Select export destination window, select WAR file. Click Next. 3. In the WAR Export window, type (or browse for) the location to export the WAR file. In our case, we use c:\wcp\temp\YourCoCMIFrame.war 4. Click Finish. 5. You can now install the portlet in WebSphere Portal using the WAR file. For information on how to install portlets and put them on a page, refer to Chapter 6, “Portal customization” on page 261. 6. We have put the IFrame portlet on the news page of YourCo. Your page should look similar to Figure 11-73. Try to click the links and verify that they are working properly. 742 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-73 IFrame portlet Note: You can modify the attributes of the IFrame by modifying the portlet parameters in the administration section of WebSphere Portal. Displaying static contents by reading static files Another way to display static contents is to read from a static file and display the contents being read. The advantage of using this approach is that you have more control in responding to user actions and managing events. The drawback is that you need to make changes to your links so that all requests are posted to your own portlet. We will illustrate how this can be accomplished in the following example. We will create two portlets: a news navigation portlet and a news details portlet. These two portlets are intended to be put on the same page. The navigation portlet reads its contents from a news headline summary file. When the user clicks one of the news headlines, a message is sent to the details portlet, providing the file location information of the specific news article. Then the details portlet reads the file contents from the location specified and display them on the Chapter 11. Content management 743 details portlet. To accomplish this, we first need to create the two portlets and the corresponding JSPs, then we need to modify our news summary generation template. First we need to create a portlet application project in WebSphere Studio Application Developer. 1. Select File -> New -> Other. 2. The Create new project window appears. Select Portlet development on the left pane and Portlet application project on the right pane. Click Next. 3. Enter YourCoCMNews in the project name field and YourCoCMNews.ear in the Enterprise Application project name field. Click Finish. Secondly, we will create the navigation portlet and the corresponding JSP. 1. Create a new folder called YourCoCM under source directory. Right-click source and select New -> Folder. Enter YourCoCM as the folder name and click Finish. 2. Then, create a portlet called YourCoCMNewsNavPortlet. Right-click the folder YourCoCM and select New -> Other. 3. Select Java on the left pane and Java Class on the right pane. Click Next. 4. In the name field, enter YourCoCMNewsNavPortlet. 5. In the superclass field, browse for or type the value org.apache.jetspeed.portlet.PortletAdaptor. 6. Click Add for the extended interfaces field. A window similar to Figure 11-74 pops up. 744 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-74 Extended interface selection 7. Type ActionListener and select org.apache.jetspeed.portlet.event in the packages list. Click Add. Then click OK. 8. Select the Inherited abstract methods checkbox. 9. Your window should look similar to Figure 11-75. Click Finish. Chapter 11. Content management 745 Figure 11-75 Create YourCoCMNewsNavPortlet 10.Replace all the import statements with the following. import java.io.*; import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlet.event.*; 11.Add the following doView method. This method retrieves the context of the source file as well as the name of the source file from the portlet settings and passes the information to the JSP being called. public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { request.setAttribute("newslist",request.getPortletSettings().getAttribute(" newslist")); request.setAttribute("publishcontext",request.getPortletSettings().getAttri bute("publishcontext")); getPortletConfig().getContext().include(“/jsp/nav.jsp“, request, response); } 12.Fill in the actionPerformed method as follows. This method is being called when the user clicks one of the news headlines on the nav.jsp page. It then 746 IBM WebSphere Portal V4 Developer’s Handbook sends a message to all the portlets on the same page with the filename of the news articles being selected. public void actionPerformed(ActionEvent event) throws PortletException { DefaultPortletAction action = (DefaultPortletAction)event.getAction(); PortletRequest request = event.getRequest(); DefaultPortletMessage dpm = new DefaultPortletMessage(request.getParameter("message")); getPortletConfig().getContext().send(null,dpm); } 13.Now we will create the JSP file called by YourCoCMNewsNavPortlet. Right-click the webApplication folder and select New -> Folder. Type jsp for the new folder name and click Finish. 14.Right-click the jsp folder and select New -> JSP File. 15.In the file name field, type nav.jsp. 16.Click Finish. 17.Open nav.jsp by double-clicking the file. 18.Replace the code in nav.jsp with the code in Example 11-10. Then save the file. The code in nav.jsp will be explained later in this section. Example 11-10 nav.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ page import="java.io.*,java.net.*"%> <SCRIPT LANGUAGE="JAVASCRIPT"> function viewDetails(url){ document.viewnews.<portletAPI:encodeNamespace value='message' />.value=url; document.viewnews.submit(); } var prefixURL='<%=response.encodeURL("/")%>'; function getURL(suffix,imgObj){ url = prefixURL + suffix; imgObj.src= url; } </SCRIPT> <FORM NAME=viewnews METHOD="POST" ACTION="<portletAPI:createURI><portletAPI:URIAction name='message'/></portletAPI:createURI>"> <INPUT TYPE=hidden NAME="<portletAPI:encodeNamespace value='message' />"> </FORM> <% Chapter 11. Content management 747 try{ String generatedFileName = (String) request.getAttribute("newslist"); String publishContext = (String) request.getAttribute("publishcontext"); String path = config.getServletContext().getContext(publishContext).getRealPath("/"); java.io.BufferedReader bIn = new java.io.BufferedReader(new java.io.FileReader(path + generatedFileName)); String in = null; while ((in = bIn.readLine()) != null) out.println(in); }catch(Exception e){ System.out.println("An Error occurred, please check the error log"); e.printStackTrace(); } %> We will create the details portlet and the corresponding JSP. 1. Under YourCoCM, create a portlet called YourCoCMNewsDetailsPortlet. Follow the same steps as you would to create YourCoCMNewsNavPortlet. However, instead of selecting ActionListener as the interface to implement, select org.apache.jetspeed.portlet.event.MessageListener as shown in Figure 11-76. Your window should look like Figure 11-77. Click Finish. Figure 11-76 Extended interfaces selection - MessageListener 748 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-77 Create YourCoCMNewsDetailsPortlet 2. Replace all the import statements with the following code. import java.io.*; import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlet.event.*; 3. Add the following doView method. This method retrieves the context of the source file as well as the name of the source file from portlet settings and passes the information to the JSP being called. public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { getPortletConfig().getContext().include(“/jsp/newsdetails.jsp“, request, response); } 4. Fill in the messageReceived method as follows. This method will be called to process any messages that are received. public void messageReceived(MessageEvent event) { DefaultPortletMessage pm = (DefaultPortletMessage) event.getMessage(); PortletRequest request = event.getRequest(); Chapter 11. Content management 749 String pathName = request.getPortletSettings().getAttribute("newspath") + pm.getMessage(); request.setAttribute("publishcontext",request.getPortletSettings().getAttri bute("publishcontext")); request.setAttribute("page",pathName); } 5. Now we will create the JSP file called by YourCoCMNewsDetailsPortlet. Right-click the jsp folder and select New -> JSP File. 6. In the file name field, type newsdetails.jsp. 7. Click Finish. 8. Open newsdetails.jsp by double-clicking the file. 9. Replace the code in newsdetails.jsp with the code in Example 11-11. Then save the file. Example 11-11 newsdetails.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ page import="java.io.*,java.net.*"%> <% if (request.getAttribute("page") != null){ String pathName = (String)request.getAttribute("page"); String publishContext = (String) request.getAttribute("publishcontext"); String path = config.getServletContext().getContext(publishContext).getRealPath("/"); try{ BufferedReader bIn = new BufferedReader(new FileReader(path + pathName)); String in = null; while ((in = bIn.readLine()) != null) out.println(in); }catch (java.io.FileNotFoundException e){ out.println("File not found: " + path + pathName); }catch (Exception e){ e.printStackTrace(); } } else {%> <P>This page shows details of Yourco News Portlet</P> <%}%> Finally, we need to modify the web.xml and portlet.xml files. 1. Double-click web.xml under the folder webApplication/WEB-INF. Select the Servlets tab. 2. Click Add. The Add Servlet or JSP window comes up. 3. Type YourCoCMNewsNavPortlet in the Add servlet field. Click OK. 750 IBM WebSphere Portal V4 Developer’s Handbook 4. Click Add in the URL mapping field. Type /yourcocmnewsnav/*. 5. Repeat the two steps above and add YourCoCMNewsDetailsPortlet. Use /yourcocmnewsdetails/* as the URL mapping. Your window should look similar to Figure 11-78. Then save the web.xml file. Figure 11-78 web.xml for YourCoCMNews 6. Double-click portlet.xml under the folder webApplication/WEB-INF. Select the Portlets tab. 7. Remove the default portlets that were generated when you created the project. Click Portlet_1 under the Portlet application and click the Remove button as shown in Figure 11-79. Chapter 11. Content management 751 Figure 11-79 portlet.xml for YourCoCMNews 8. Select Portlet application as shown in Figure 11-79 and click the Add portlet button. 9. The Select Servlet window comes up. Select YourCoCMNewsNavPortlet and click OK. 10.Change the display name to YourCoCMNewsNavPortlet. 11.Click Add portlet again. 12.The Select Servlet window comes up. Select YourCoCMNewsDetailsPortlet and click OK. 13.Change the display name to YourCoCMNewsDetailsPortlet. 14.Select Concrete portlet application and click Add Concrete portlet. 15.Select Portlet_1 and click OK. 16.Change the display name from New Concrete portlet to YourCoCMNewsNavPortlet. Also, change the title to Your news navigation. 17.Click Add in the Settings field. 18.Enter newslist in the parameter field and /generated/YourCoCM.YourCoCMNews/yourCoNews4Portal/summary.html in the value field. 752 IBM WebSphere Portal V4 Developer’s Handbook 19.Click Add again in the Settings field. 20.Enter publishcontext in the parameter field and /wps/YourCoCM in the value field. 21.Select Concrete portlet application again and click Add Concrete portlet. 22.Select Portlet_2 and click OK. 23.Change the display name from New Concrete portlet to YourCoCMNewsDetailsPortlet. Also, change the title to News. 24.Click Add in the Settings field. 25.Enter newspath in the parameter field and /generated/YourCoCM.YourCoCMNews/yourCoNews4Portal/ in the value field. 26.Click Add again in the Settings field. 27.Enter publishcontext in the parameter field and /wps/YourCoCM in the value field. 28.Save portlet.xml. You can then export the project and install the WAR file on WebSphere Portal. You then need to place both portlets on the same page. However, before you can run the application successfully, you need to create a new summary and detail template, generate the contents, and publish the generated contents to the publishing server based on these two newly created templates. 1. Open the YourCoCMTemp project that you created in “Sample scenario for customizing authoring templates” on page 690. 2. In the templates directory, under the webApplication folder, create a new JSP file called YourCoCMNewsDetails4Portlet.jsp. 3. Copy the contents of YourCoCMNewsDetails.jsp to YourCoCMNewsDetails4Portlet.jsp. 4. Remove all non-body tags, for instance, <!DOCTYPE>, <HTML>, <HEAD><BODY>. Also remove the style sheet link and all the custom colors. We will be using the theme and stylesheets supplied by WebSphere Portal. 5. Your code should look similar to Example 11-12. Save the file. Example 11-12 YourCoCMNewsDetails4Portal.jsp <%@page import="java.util.*, java.text.*"%> <jsp:useBean id="getResource" class="com.ibm.wcm.GetGenericResource" type="com.ibm.wcm.GetGenericResource"><% getResource.getResource(request); %></jsp:useBean> <jsp:useBean id="resObj" scope="request" type="YourCoCM.YourCoCMNews"/> <TABLE border="0"> <TBODY> Chapter 11. Content management 753 <TR> <TD width="30%" valign="top" align="center"><IMG src="<%=resObj.getIMAGE()%>" border="0" align="top"></TD> <TD width="70%" valign="top" align="left"><center><font size="+2"><b><%=resObj.getHEADLINE()%></b></font></center><br><br><%=resObj.get CONTENT()%></TD> </TR> </TBODY> </TABLE> 6. Again, in the templates directory under webApplication folder, create a new JSP file called YourCoCMNewsSummary4Portlet.jsp. 7. Copy the contents of YourCoCMNewsSummary.jsp to YourCoCMNewsSummary4Portlet.jsp. 8. Remove all non-body tags, for instance, <!DOCTYPE>, <HTML>, <HEAD><BODY>. Also remove the style sheet link and all the custom colors. 9. Replace the code <a href=”<%=yourCoNews.getID()%>.html”> with <a href=”#” ONCLICK=viewDetails(‘<%=yourCoNews.getID()%>’)>. The method viewDetails is a Java script that is defined in nav.jsp. When the user clicks a headline, the corresponding file name will be sent as the message value to YourCoCMNewsNavPortlet. The method actionPerformed in YourCoCMNewsNavPortlet will then be called and send a message to YourCoCMNewsDetailsPortlet. When the messageReceived method is invoked, the page information will be sent to newsdetails.jsp where the corresponding news article file will be read and displayed. 10.Your file should look similar to Example 11-13. Example 11-13 YourCoCMNewsSummary4Portlet.jsp <%@page import="java.util.*"%> <jsp:useBean class="com.ibm.wcm.GetGenericResourceList" id="getResourceList" type="com.ibm.wcm.GetGenericResourceList"> <% getResourceList.setRequest(request); %> </jsp:useBean> <% java.util.Enumeration enumObjs = getResourceList.getResourceList(); if( enumObjs==null ) { out.println("<br>getResourceList.getResourceList() returned null object"); return; } %> <TABLE border="0"> <TBODY> <TR> <TD><B>YourCo internal news</B></TD> 754 IBM WebSphere Portal V4 Developer’s Handbook </TR> <% while( enumObjs.hasMoreElements() ) { YourCoCM.YourCoCMNews yourCoNews = (YourCoCM.YourCoCMNews)enumObjs.nextElement(); %> <TR> <TD><A href="#" ONCLICK=viewDetails('<%=yourCoNews.getID()%>.html')><%=yourCoNews.getHEADLINE() %></a></TD> </TR> <% } %> </TBODY> </TABLE> 11.You then need to import these templates into Web Content Publisher. First export YourCoCMNewsSummary4Portlet.jsp and YourCoCMNewsDetails4Portlet.jsp to the file system. 12.Open the browser and go to the URL http://<YOUR_FULLY_QUALIFIED_HOST_NAME>/wps/wcp/index.jsp. Log in as wcpadmin. 13.Make sure that your active project is YourCoCMAuthor. 14.Click the Contents tab. 15.Select templates on the left pane and click Import on the right pane. 16.In the Import Files window, select File system import and specify the directory where you exported the two new JSP files. 17.Click Import. You should get a message indicating that two files are imported successfully. 18.Click YourCoCMNews below Structured content. Click templates for this structured content type. to specify the 19.Click the Details tab. Click Browse. 20.In the search criteria window, type %.jsp. Click Search. 21.Select templates/YourCoCMNewsDetails4Portlet.jsp and click OK. 22.Select the Generate contents files affected by this template checkbox. 23.In the New generation folder field, type yourCoNews4Portal and click . 24.Your window should look similar to Figure 11-80. Chapter 11. Content management 755 Figure 11-80 Details template page 25.Click the Summary tab. Click Browse. 26.In the search criteria window, type %.jsp. Click Search. 27.Select templates/YourCoCMNewsSummary4Portlet.jsp and click OK. 28.Select the Generate contents files affected by this template checkbox. 29.In the New generation folder field, type yourCoNews4Portal and click 30.Your window should look similar to Figure 11-81. 756 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-81 Summary templates page 31.Click Save. 32.Click the Content tab. You should see a new directory called yourCoNews4Portal under the folder found when clicking Files-> generated/YourCoCM.YourCoCMNews. Click the yourCoNews4Portal folder. You should see the summary file and all the details files being generated. 33.Now you need to publish all the newly generated files to the portal server. Click to bring up the publish window. 34.In the publish window, select the publishing server and click Publish. . Then click If you log in to WebSphere Portal and go to the news page of YourCo, you should see something similar to Figure 11-82. Select one of the news articles on the navigation portlet on the left, and the details of the news article should be shown on the detail news portlet. Chapter 11. Content management 757 Figure 11-82 News page on WebSphere Portal Displaying dynamic portal content Dynamic contents means that instead of serving static HTML files to all the users, contents are selected at runtime. Runtime contents can be retrieved from the publishing database using JDBC or from the results returned by the personalization engine. This topic will be discussed in Chapter 10, “Personalization” on page 501. 11.3.9 Workflow In most organizations, contents published on a Web site are initiated, created, modified and approved by various personnel. A workflow process needs to be in place to automate these sequence of tasks. Web Content Publisher integrates with Lotus Workflow to provide this functionality. This section walks you through a scenario in creating a simple workflow using Lotus Workflow Architect, and highlights the integration points with Web Content Publisher. It is not intended to be an advanced tutorial of using Lotus Workflow and Lotus Workflow Architect. 758 IBM WebSphere Portal V4 Developer’s Handbook Note: This section assumes that you have the workflow knowledge of using Web Content Publisher. Before getting into the design details for workflow, it is important to understand how Web Content Publisher creates a shared authoring environment behind the scenes. Web Content Publisher uses a Web interface to enable many users to work in parallel on the same project. Thus it is important to ensure that changes made by users are retained in their own views and any work in progress is not viewable by the public. To accomplish this, Web Content Publisher implements the concept of workspaces. For each project that is created, Web Content Publisher maintains a base edition for the project. All users working on the project will then see the contents based on the base edition of the project. When a task is being assigned to a specific user, all the changes made by the user are placed into a specific workspace associated with the task. Whenever the user subsequently chooses to work on the particular task, Web Content Publisher overlays the workspace of the particular task on the base edition of the project. If a task is shared by a number of users, the workspace will be overlayed for these users so that these users have the ability to view any changes in progress as well. When the task is complete and the changes can be viewed by the public, you need to promote the content so that the changed content merges with the base edition of the project. The promotion step is an automated step that is defined near the end of a process and before the content is published. We will now demonstrate how to create a simple workflow application using Lotus Workflow Architect and Lotus Workflow. We assume that you have set up the Web Content Publisher sample database since we are going to use the user and user groups created from the sample install of Web Content Publisher. We will create a simple workflow process that enables anyone to initiate a request for creating a news article. Then the content contributor will take over and write the article. Finally, the domain expert will approve and publish the article. Create a workflow using Lotus Workflow Architect 1. Start Lotus Workflow Architect by selecting Start -> Programs -> Lotus Workflow Architect -> Lotus Workflow Architect. 2. You should see a window similar to Figure 11-83. I Figure 11-83 Lotus Workflow Architect login Chapter 11. Content management 759 3. If the login ID is not WCPAdmin, cancel out of Lotus Workflow Architect. Open Lotus Domino Administrator and switch the ID to WCPAdmin. Select Start -> Programs -> Lotus Applications -> Lotus Domino Administrator. Select File -> Tools -> Switch ID. Then select WCPAdmin.ID from the folder Lotus/Domino/data. Click Open. Type the password and click OK. Then exit out of Lotus Domino Administrator. Re-open Lotus Workflow Architect; you should be able to log in as WCPAdmin. 4. Enter the password for WCPAdmin. Then click OK. Lotus Workflow Architect should then start. 5. Select File -> Open databases. You should see a window similar to Figure 11-84. Figure 11-84 Lotus Workflow Architect data sources 6. This window selects which Lotus Workflow database stores the information of the workflow to be created. We will use the default database that was created during installation. Make sure that the server shows your server name and not local. Click OK. 7. We will now create a new workflow process. Select File -> New process. 8. We will then create a start process, an end process, as well as three intermediate processes. Select the start activity icon, , and drop it on the workspace. Then select the end activity icon, , and drop it on the workspace. Select the activity icon, and drop three of them on the workspace. Connect them using the process arrows, . Your window should look similar to Figure 11-85. 760 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-85 New workflow 9. We will then define each of the activities. In the first activity box, right-click and select Basic properties. 10.On the owner’s tab, click select to include an activity owner. 11.In the Select activity owner window, select Job property in the drop-down menu. Then select Initiator and click <<Add to act it to the list on the left. Your window should look similar to Figure 11-86. Click OK. Chapter 11. Content management 761 Figure 11-86 Add activity owner 12.In the activity name, type Request a news article. Your window should look similar to Figure 11-87. Click OK. Figure 11-87 Basic activity property 13.Repeat Steps 9 to 12 for the next two activities. However, select Content Contributors under Workgroup instead of Job Property as the owner for the second activity, and select Domain Expert for the owner for the third activity. Name the second activity Create a news article and the third activity Review and publish article. Your window should look similar to Figure 11-88. 762 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-88 New activity flow 14.Then, we need to add the information necessary for Web Content Publisher to perform workflow and workspace management. The attributes used by Web Content Publisher are defined in Table 11-3. Table 11-3 Required attributes used by Web Content Publisher for Workflow Required attributes Meaning of attributes WCM.StartEdit Start the edit session. When you work on an activity, Web Content Publisher makes the workspace writable. The workspace stays writable until you complete the activity and WCM.EndEdit is called. WCM.EndEdit End the edit session. Web Content Publisher makes the workspace read-only when an activity is completed. Chapter 11. Content management 763 Required attributes Meaning of attributes WCM.Promote Promote the workspace. Web Content Publisher promotes the workspace when an activity is completed. Note that this is usually the same activity that has WCM.EndEdit. If the activity is a decision, you might also set WCM.Decision. Table 11-4 Custom attributes used by Web Content Publisher for Workflow 764 Custom attributes Meaning of attributes WCM.Decision The value of this attribute specifies the positive result of the decision (for example “Accept”). This is required if the activity is a decision. This attribute is also used with WCM.Publish and WCM.Export if they are specified on an activity that has a decision. WCM.ReviewRequest Indicates that this activity is the “Review Request” activity. This attribute ensures that the Web Content Publisher user completing this activity has the authority to review the request. WCM.ReviewChange Indicates this activity is the “Review Change” activity. This attribute ensures that the Web Content Publisher user completing this activity has the authority to review the change. WCM.Publish Publish to the specified publish targets. The value of this attribute is a list of Web Content Publisher publish targets, separated by commas or semicolons. If this attribute is set, Web Content Publisher will publish to the specified targets when the activity is completed. Note that this is a foreground delta publish. The publish will do nothing if the publish server does not exist. IBM WebSphere Portal V4 Developer’s Handbook Custom attributes Meaning of attributes WCM.Export Export to the specified target when the activity is completed. The value of this attribute is the target of a Web Content Publisher Export (either a team stream or a directory). Use WCM.Export.Type to specify the type of export. If WCM.Export.Type is not specified, Web Content Publisher will export to version control. WCM.Export.Type Specify the type of export. This attribute is used in conjunction with WCM.Export. If WCM.Export.Type is equal to “filesystem”, then Web Content Publisher exports to the file system. Otherwise, Web Content Publisher exports to version control. 15.Right-click the activity Create a news article and select Advanced properties. 16.Select the Custom tab. Click the New button. In the Name field, type WCM.StartEdit. In the value field, type Yes. Your window should look similar to Figure 11-89. Click OK. Figure 11-89 Add attribute 17.Your advanced properties window should look similar to the following figure. Click OK. Chapter 11. Content management 765 Figure 11-90 Advanced activity 18.Repeat Steps 14 to 16 for the Review and publish article activity. However, enter the values as shown in Figure 11-91 instead. Figure 11-91 Advanced activity for Review and publish article activity 19.We now need to specify a job owner for the process. Select Process -> Basic Properties. In the Owners tab, click Select to include the users. 20.In the Select Job Owner window, select Job property from the drop-down menu. Select Initiator and click <<Add to add Initiator to the left pane. Click OK. 766 IBM WebSphere Portal V4 Developer’s Handbook 21.In the name field of the Basic properties window, type YourCoProcess1. 22.Select the Initiators tab and select the radio button for All. 23.Select the Forms tab and select the radio button Selected. From the drop-down menu, select Sample Form. 24.Click OK. 25.We can now save and activate the process. Select File -> Save Process. Then select File -> Activate Process. 26.A window similar to Figure 11-92 comes up. Make sure the target database name and the server name are correct. Click OK. Figure 11-92 Activate process 27.Now that the process is in the database on the Workflow server, we need to update the cache for the workflow process. Open Lotus Domino Administrator by selecting Start -> Programs -> Lotus Applications -> Lotus Domino Administrator. 28.Make sure that you are on the server where Lotus Workflow is installed. If you are on the local database, select File -> Open Server and select the appropriate server. 29.Select the Files tab. Double-click the file LWF Application R3.0. This is the Workflow application database. 30.Select Administration -> Cache in the left menu. 31.Select Update Process Cache on the right. You show see the new YourCoProcess1 workflow process as shown in Figure 11-93. Chapter 11. Content management 767 Figure 11-93 Lotus Workflow process The new workflow process is now in place. We can now verify the workflow process. Workflow in Web Content Publisher 1. Log in as tara in Web Content Publisher. 2. Select the Tasks tab. 3. Click New Job. 4. In the Initiate new job window, type in the new job name Create news for HR dept. Select YourCoProcess1 from the drop-down menu. Your window should look similar to Figure 11-94. Click Start. 768 IBM WebSphere Portal V4 Developer’s Handbook Figure 11-94 Initiate new job 5. Log out and log in again as dave. Dave belongs to the content contributor group so we expect the newly created job should now be assigned to Dave. 6. Select the Tasks tab. Click the menu I could own. You should see the job that is assigned to Dave. Click Work On. In the Work On window that comes up, enter some comment in the comment box and click +. Then click Work On. The job is now moved to the I own menu. 7. Upload a new document. Note that the newly uploaded document has an asterisk beside it, indicating that the document is not viewable by the public. 8. Click Complete. Now the job should be assigned to the domain expert, Rob. 9. Log in as rob and approve and publish the content. Chapter 11. Content management 769 11.4 Known problems and workarounds This section describes some of the shortcomings of Web Content Publisher and their workarounds. Problem: Cannot display static content in a portlet. Workaround: You might be using a lower version of Internet Explorer. Currently, Web Content Publisher only supports Internet Explorer version 5.5. Problem: You get an error: CTAC0065E: Error connecting to workflow server. Workaround: Your network connection could be different. Copy and replace diiop.txt from the Domino directory into the htdocs directory. Stop WebSphere Application Server. Then restart Domino. After Domino is fully initialized, start WebSphere Application Server again. Problem: Publish or un-publish articles at specific times. Due to publish latency, contents cannot start appearing on Portal at precise times. Workaround: The best approach to presenting and invalidating an article is to create a start time and end time property within the structured content. Then the portlet will access the published content database at runtime to determine whether the content is valid or not. Problem: Web Content Publisher does not support unpublishing. Workaround: Delete static files and stale data manually from the runtime database. Problem: After a resource is unregistered, it cannot be re-registered Workaround: When the resource is unregistered, the resource instances is not cleaned up completely. The resource instances in the table and the table that it uses do not get deleted. You can manually clean up the resources. a. Open a DB2 command window by entering db2cmd on a DOS command window b. Get the ID of the project of which you would like to unregister the resource by typing GETPROJECTS. Write down the ID of the project of which you want to un-register the resource. c. Type GETTABLES project ID to get the list of tables to be deleted. The project ID is the ID of the project you want to clean up. Write down the schema name and table name for resource collection(s) and associated multi-value storage tables for the resource collection(s) you are unregistering. d. Unregister the resource from the project via the WebSphere Content Publisher administration panel. 770 IBM WebSphere Portal V4 Developer’s Handbook e. Remove the structured resources associated with the project you are deleting by entering DELETETABLEDATA schemaName.tableName projectID for each table in Step c. f. After the table in Step e indicates that the table is empty and not being used by other projects, enter DELETETABLE schemaName.tableName projectID. Problem: Projects cannot be delete in Web Content Publisher Workaround: Projects can be deleted by following these steps: a. Open a DB2 command window by entering db2cmd on a DOS command window. b. Get the ID of the project you want to d