bergland ip over voice
Transcription
bergland ip over voice
Front cover Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Integrating existing Domino applications into a portal Integration using Domino JSP Tags, Java and Portlet Builders Step-by-step integration techniques John Bergland Martin Anderle Lea Medhurst Sami Salkosuo Peter K. Weber Leslie Weng ibm.com/redbooks International Technical Support Organization Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 April 2005 SG24-6466-00 Note: Before using this information and the product it supports, read the information in “Notices” on page xi. First Edition (April 2005) This edition applies to Domino Version 6.5.2 / 6.5.3, WebSphere Portal Version 5.02.2, and IBM Lotus Workplace Version 2.0.1. © Copyright International Business Machines Corporation 2005. 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. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiv Additional contributors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Become a published author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvi Comments welcome. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xvii Chapter 1. Introduction to portalizing Domino applications . . . . . . . . . . . . 1 1.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1.1 Portal and Domino within the context of the IBM Workplace . . . . . . . 3 1.1.2 Structure of this chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2 The vision supporting IBM Workplace. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 Introduction to IBM Workplace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.3.1 The business value of IBM Workplace . . . . . . . . . . . . . . . . . . . . . . . . 9 1.3.2 The product families that make up IBM Workplace. . . . . . . . . . . . . . 10 1.3.3 The roadmap of Lotus Notes/Domino, WebSphere Portal, and IBM Workplace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 1.4 Benefits of Domino and Portal together . . . . . . . . . . . . . . . . . . . . . . . . . . 22 1.5 Portal architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 1.5.1 Introduction to portlets. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 1.5.2 Presentation services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 1.5.3 Layout of the portal page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 1.5.4 Customization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 1.6 Integrating Domino applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 1.6.1 The portalizing process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 1.6.2 The portalizing challenge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 1.6.3 Domino applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 1.7 Portlet patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 1.7.1 Link pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 1.7.2 Display pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 1.7.3 Integrated pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 1.7.4 Migrated pattern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 1.7.5 Designing the integration portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 1.8 The integration architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 1.8.1 The Portal/Domino server infrastructure . . . . . . . . . . . . . . . . . . . . . . 52 1.9 Authentication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 © Copyright IBM Corp. 2005. All rights reserved. iii 1.9.1 Multi-server session-based authentication . . . . . . . . . . . . . . . . . . . . 54 1.9.2 Using Domino LDAP with WebSphere Portal . . . . . . . . . . . . . . . . . . 57 1.10 Development options. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 1.10.1 Target audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 1.10.2 Development environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 1.10.3 Development tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 1.10.4 When to use a specific integration approach . . . . . . . . . . . . . . . . . 61 1.11 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 Chapter 2. Integration techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 2.1 Choosing an integration technique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 2.1.1 Project considerations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 2.1.2 Step 1: Pre-project preparation and training . . . . . . . . . . . . . . . . . . . 70 2.1.3 Step 2: Identification of project requirements . . . . . . . . . . . . . . . . . . 71 2.1.4 Step 3: Selection of an appropriate portlet pattern . . . . . . . . . . . . . . 71 2.1.5 Step 4: Selection of an appropriate integration technique . . . . . . . . 72 2.2 Integration techniques and development options . . . . . . . . . . . . . . . . . . . 73 2.2.1 Using existing portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.2.2 Domino JSP tag libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 2.2.3 Developing Domino portlets using Java . . . . . . . . . . . . . . . . . . . . . . 76 2.2.4 Portlet builders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 2.2.5 Integration with Lotus Workplace . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 2.3 Case study: A simple sales tracking application . . . . . . . . . . . . . . . . . . . . 77 2.3.1 Case study overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78 2.3.2 Case study objective: Sales Workplace . . . . . . . . . . . . . . . . . . . . . . 80 2.3.3 Case study: Application details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 2.4 Deploying the case study portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 2.4.1 Install portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 2.4.2 Creating a label . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 2.4.3 Creating a page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 2.4.4 Adding portlets to a page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 Chapter 3. Using existing portlets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94 3.1.1 Skills and degree of customization - Pre-packaged portlets . . . . . . . 94 3.1.2 Technologies involved. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 3.1.3 Software and tools used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 3.2 Integration techniques and overview of portlets . . . . . . . . . . . . . . . . . . . . 97 3.3 Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way . . . . . . . . . . . . . . . . . . . . . . . . . . . 100 3.3.1 Portlets that make up Extended Products Portlets . . . . . . . . . . . . . 103 3.3.2 Considerations for the Domino Extended Products Portlets . . . . . . 105 3.3.3 Implementation details for Extended Products Portlets . . . . . . . . . 107 iv Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3.3.4 Configuring the Document Manager portlet . . . . . . . . . . . . . . . . . . 117 3.3.5 Configuring the Domino Application portlet. . . . . . . . . . . . . . . . . . . 118 3.3.6 Configuring the Domino Databases (Notes View) portlet . . . . . . . . 120 3.4 Integration Option 2 - The Domino Application Portlet . . . . . . . . . . . . . . 122 3.4.1 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 3.4.2 Implementation details for the Domino Application Portlet . . . . . . . 123 3.5 Integration Option 3 - using specific Portlets . . . . . . . . . . . . . . . . . . . . . . 130 3.5.1 Integrate using Lotus Notes View Portlet . . . . . . . . . . . . . . . . . . . . 130 3.5.2 Integrate using the Domino Web Access (iNotes) portlet . . . . . . . . 139 3.5.3 Lotus Web Conferencing (Sametime) . . . . . . . . . . . . . . . . . . . . . . . 144 3.5.4 Lotus Instant Messaging Contact List (Sametime Contact List) . . . 151 3.5.5 My Lotus Team Workplaces (QuickPlace) . . . . . . . . . . . . . . . . . . . 155 3.5.6 People Finder Portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 3.5.7 Domino.Doc (Document Manager) Portlet . . . . . . . . . . . . . . . . . . . 170 3.6 Reference material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 Chapter 4. Using custom Domino JSP Tag libraries . . . . . . . . . . . . . . . . 175 4.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 4.1.1 Skills and degree of customization - Domino JSP Tags . . . . . . . . . 176 4.2 Technologies involved. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 4.2.1 J2EE overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178 4.2.2 JavaServer Pages. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180 4.3 Software and tools used . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 4.3.1 WebSphere Studio Application Developer V5.1.2. . . . . . . . . . . . . . 186 4.3.2 WebSphere Portal Toolkit for WebSphere Studio V5.0.2.2 . . . . . . 189 4.3.3 Lotus Domino Toolkit for WebSphere Studio V1.3 . . . . . . . . . . . . . 192 4.4 Integration techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 4.5 Integration using Domino custom JSP Tag libraries . . . . . . . . . . . . . . . . 198 4.5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 4.5.2 Domino custom JSP tag libraries . . . . . . . . . . . . . . . . . . . . . . . . . . 199 4.5.3 The Lotus Domino Object architecture . . . . . . . . . . . . . . . . . . . . . . 202 4.5.4 Types of Domino JSP tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 4.5.5 Limitations and considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212 4.5.6 Session management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213 4.5.7 Object Pooling. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 4.5.8 Implementation example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222 4.5.9 Conclusions to the custom Domino tags integration technique . . . 286 4.6 Integration via Click-to-Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 4.6.1 Click-to-Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 4.6.2 Considerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 4.6.3 Implementation of the technique . . . . . . . . . . . . . . . . . . . . . . . . . . . 291 4.7 Integration via people awareness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303 4.7.1 People awareness. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 304 Contents v 4.7.2 Implementation of the technique . . . . . . . . . . . . . . . . . . . . . . . . . . . 307 4.8 Reference Material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310 Chapter 5. Portlet development using Java: Technology review . . . . . . 313 5.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314 5.1.1 Skills and degree of customization with API integration approach . 314 5.2 Domino Java API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 5.2.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315 5.2.2 Domino Java classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321 5.3 IBM Portlet API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 5.3.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336 5.3.2 Elements of the IBM Portlet API . . . . . . . . . . . . . . . . . . . . . . . . . . . 342 5.4 JSR 168 Java Portlet Specification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 5.4.1 Relationship to servlet API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 5.4.2 Comparing common portlet API concepts. . . . . . . . . . . . . . . . . . . . 354 5.4.3 Comparing portlet packaging and descriptors. . . . . . . . . . . . . . . . . 356 5.5 Struts framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 364 5.5.1 Basic elements of Struts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 5.5.2 Struts support in WebSphere Portal . . . . . . . . . . . . . . . . . . . . . . . . 366 5.6 JSF framework . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371 5.6.1 JSF application concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372 5.6.2 JSF support in WPS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 5.7 Other technologies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 5.7.1 JSTL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374 5.7.2 Object pooling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 5.7.3 Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 5.7.4 Domino XML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 5.7.5 Collaborative Services API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 379 5.7.6 Web services. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 380 5.7.7 WSRP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 5.8 Portal application design guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381 5.8.1 Introduction to object-oriented design patterns . . . . . . . . . . . . . . . . 382 5.8.2 Design principles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387 5.9 Additional information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388 Chapter 6. Portlet development using Java: Integration examples . . . . 391 6.1 WebSphere Studio Application Developer . . . . . . . . . . . . . . . . . . . . . . . 393 6.2 Portalization project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 395 6.2.1 Sales Tracking Domino application. . . . . . . . . . . . . . . . . . . . . . . . . 395 6.2.2 Portal application functionality. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397 6.3 Accessing Domino data. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 6.3.1 DominoAccess project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 400 6.3.2 DominoSessionFactory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403 vi Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.3.3 CustomerBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408 6.3.4 CustomerContactBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410 6.3.5 SalesPersonBean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412 6.3.6 BeanUtils. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 6.3.7 DominoAccess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417 6.3.8 Exporting DominoAccess . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 6.4 Sales Tracking application using IBM Portlet API . . . . . . . . . . . . . . . . . . 428 6.4.1 SalesTrackingIBMAPI project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428 6.4.2 CredentialVaultManager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431 6.4.3 CustomersPortlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 6.4.4 CustomersPortlet JSP files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 6.4.5 Testing the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 6.4.6 CustomerDetailsPortlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456 6.4.7 CustomerDetailsPortlet JSP files . . . . . . . . . . . . . . . . . . . . . . . . . . 466 6.4.8 Testing the application, part two . . . . . . . . . . . . . . . . . . . . . . . . . . . 469 6.4.9 CustomerContactsPortlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472 6.4.10 CustomerContactsPortletView.jsp. . . . . . . . . . . . . . . . . . . . . . . . . 475 6.4.11 Testing the application, part three . . . . . . . . . . . . . . . . . . . . . . . . . 477 6.4.12 Enabling Click-to-Action . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 6.4.13 Testing the application, part four . . . . . . . . . . . . . . . . . . . . . . . . . . 481 6.4.14 Deployment descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484 6.4.15 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489 6.4.16 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497 6.5 Sales Tracking application using Struts . . . . . . . . . . . . . . . . . . . . . . . . . 498 6.5.1 Adding classes to DominoAccess . . . . . . . . . . . . . . . . . . . . . . . . . . 498 6.5.2 SalesTrackingStruts project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504 6.5.3 Drawing a Struts application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505 6.5.4 Realizing JSPs and JavaBeans . . . . . . . . . . . . . . . . . . . . . . . . . . . 511 6.5.5 Realizing actions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 520 6.5.6 Adding global forwards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531 6.5.7 Testing the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533 6.5.8 Deployment descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 535 6.5.9 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 540 6.5.10 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 6.6 Sales Tracking application using JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 6.6.1 SalesTrackingJSF project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 546 6.6.2 index.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548 6.6.3 SalesTrackingJSFView.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551 6.6.4 CustomerDetails.jsp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 562 6.6.5 Deployment descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 568 6.6.6 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 573 6.6.7 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 575 6.7 Sales Tracking application using JSR 168 . . . . . . . . . . . . . . . . . . . . . . . 575 Contents vii 6.7.1 Adding functionality to DominoAccess . . . . . . . . . . . . . . . . . . . . . . 575 6.7.2 SalesTrackingJSR168 project. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577 6.7.3 SalesTrackingJSR168Portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579 6.7.4 JSP files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 581 6.7.5 Test the application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583 6.7.6 Deployment descriptors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584 6.7.7 Deployment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 6.7.8 Summary. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586 6.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587 Chapter 7. Portlet builders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591 7.1 IBM Portlet Builder for Domino . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593 7.1.1 Implementation details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596 7.1.2 Implementation example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608 7.1.3 Adding People Awareness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608 7.1.4 Enhancing further with Click-to-Action . . . . . . . . . . . . . . . . . . . . . . 612 7.2 Bowstreet Portlet Factory for WebSphere. . . . . . . . . . . . . . . . . . . . . . . . 619 7.2.1 Implementation details . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 625 7.2.2 Implementation example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 652 7.2.3 Installing the sample application . . . . . . . . . . . . . . . . . . . . . . . . . . . 657 7.3 CONET Knowledge Director 3.0 for WebSphere Portal . . . . . . . . . . . . . 660 7.3.1 Knowledge Director components . . . . . . . . . . . . . . . . . . . . . . . . . . 661 7.3.2 Implementation issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 667 7.3.3 Portlet creation methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 671 7.4 Implementing the Sales Workplace example . . . . . . . . . . . . . . . . . . . . . 674 7.4.1 Write Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683 7.4.2 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685 Chapter 8. Integration with Lotus Workplace . . . . . . . . . . . . . . . . . . . . . . 687 8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688 8.1.1 Skills and degree of customization - Workplace Builder . . . . . . . . . 689 8.2 Adding Workplace portlets to Domino portlets . . . . . . . . . . . . . . . . . . . . 690 8.3 Adding Domino Portlets to Workplace Applications . . . . . . . . . . . . . . . . 692 8.3.1 Applications and templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692 8.3.2 Workplace Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 695 8.3.3 Using the Workplace Builder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 696 8.4 Working with the Workplace API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708 8.4.1 Using the JSP Tag Library to enhance a Domino Portlet . . . . . . . . 711 8.5 Workplace API and SRI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717 8.5.1 Collaborative Application Component Interface . . . . . . . . . . . . . . . 718 8.5.2 Workplace Mail Messaging SPI . . . . . . . . . . . . . . . . . . . . . . . . . . . 719 8.5.3 Workplace Instant Messaging SPI . . . . . . . . . . . . . . . . . . . . . . . . . 720 8.5.4 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721 viii Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Appendix A. General portlet development guidelines. . . . . . . . . . . . . . . 723 Portlet coding guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724 Refrain from using instance variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 724 Pass data to the view (JSP) as a bean in the request object . . . . . . . . . . 725 Use the portlet logging facility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 725 Adopt good code documentation habits . . . . . . . . . . . . . . . . . . . . . . . . . . 725 Use the ContentAccessService to fetch external content if necessary . . . 726 Cache portlet settings or portlet data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 726 Follow design guidelines for Struts portlets. . . . . . . . . . . . . . . . . . . . . . . . 726 Portlet packaging guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727 Make common functions available externally to portlets . . . . . . . . . . . . . . 727 Combine portlets with similar functions into a single portlet with multiple configuration settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727 Data management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 727 Use portlet settings to store user-independent configuration data . . . . . . 728 Use portlet data to store user-dependent configuration data . . . . . . . . . . 728 Use a servlet configuration for storing the static initialization information for a portlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 728 General session management guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . 728 Limit the use of the portlet session for storing portlet state information . . 728 Do not rely on portlet sessions if the portlet allows anonymous access . . 729 Always request an existing portlet session . . . . . . . . . . . . . . . . . . . . . . . . 729 Prevent temporary sessions from being generated in the JSP . . . . . . . . . 729 Other general development guidelines. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 730 All portlet strings should be fetched from resource bundles . . . . . . . . . . . 730 Organize portlet help files by language. . . . . . . . . . . . . . . . . . . . . . . . . . . 731 Use portlet messaging to communicate (send messages) to other portlets on the same page. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 731 Avoid the use the HttpSession to share data with other portlets/servlets . 731 Avoid the use of HttpSession to share data with other portlets/servlets . . 732 Performance consideration guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732 Do not spawn threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732 Do not use threads to access J2EE resources . . . . . . . . . . . . . . . . . . . . . 732 Limit temporary storage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 732 Avoid synchronized methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733 Avoid long-running loops. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733 Use JSPs instead of XML/XSLT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733 Use caching as much as possible. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733 Appendix B. Data dictionary for case study . . . . . . . . . . . . . . . . . . . . . . . 735 Product form. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736 Sales person form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 736 Customer form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 737 Contents ix Customer contact form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 738 Sales activity form . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739 Appendix C. Additional material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741 Locating the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 741 Using the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 How to use the Web material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 742 Related publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743 IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 743 Other publications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744 Online resources . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 745 How to get IBM Redbooks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748 Help from IBM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 748 Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 749 x Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 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. 2005. All rights reserved. xi Trademarks The following terms are trademarks of the International Business Machines Corporation in the United States, other countries, or both: CICS® iNotes™ Redbooks™ Cloudscape™ iSeries™ Sametime® DB2® Lotus Discovery Server™ Tivoli® developerWorks® Lotus Enterprise Integrator® WebSphere® Domino Designer® Lotus Notes® Workplace™ Domino.Doc® Lotus Workflow™ Workplace Client Technology™ Domino® Lotus® Workplace Collaborative Eserver® Monday™ Learning™ Eserver® Notes® Workplace Messaging™ Everyplace® QuickPlace® Workplace Team Collaboration™ ibm.com® Rational® Workplace Web Content IBM® Redbooks (logo) ™ Management™ The following terms are trademarks of other companies: 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. Windows and the Windows logo are trademarks of Microsoft Corporation in the United States, other countries, or both. UNIX is a registered trademark of The Open Group in the United States and other countries. Linux is a trademark of Linus Torvalds in the United States, other countries, or both. Other company, product, and service names may be trademarks or service marks of others. xii Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Preface This IBM Redbook provides an overview of the options and techniques for integrating and “portalizing” Domino® applications into WebSphere® Portal and Lotus® Workplace™. For each of the integration options, we provide an overview of the technology, an introduction to the software and tools used, and step-by-step examples of using the techniques to portalize a sample Domino application. We begin by explaining why portal integration is so useful for any company that has a Domino environment, and the importance of integrating Domino applications into WebSphere Portal and Lotus Workplace. To provide the proper context, we address the concept and strategy of the IBM Workplace and explain how Domino, WebSphere Portal, and Lotus Workplace fit into this strategy. We also explain some of the key concepts of portals and Domino application integration, and outline some recognized design patterns for Domino application integration. We cover a broad range of integration options, from using existing collaborative portlets which ship with Domino and Portal, to using Portlet Builders, or ultimately, using the Java™ API to customize the integration of the application. Topics that are covered in detail include: Using existing portlets that ship with WebSphere Portal, and Domino V6.5.3 including a technical review of the Domino Application Portlet (DAP). Using custom Domino JSP tag libraries Using Java programming Using portlet builders, including software products from IBM, and leading third-party providers. Integrating portlets into the Lotus Workplace This book is aimed at Domino application developers or anyone else who wants to learn how to portalize Domino applications. © Copyright IBM Corp. 2005. All rights reserved. xiii 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, Cambridge, Massachusetts Center. John Bergland is a project leader at the International Technical Support Organization, Cambridge Center. He manages projects that produce Redbooks™ about Lotus Software products. Before joining the ITSO in 2003, John worked as an Advisory IT Specialist with IBM Software Services for Lotus (ISSL), specializing in Notes and Domino messaging and collaborative solutions. Martin Anderle is a independent consultant who works with AdHoc Ltd., Prague, Czech Republic (http://www.adhoc.cz). He has in-depth Linux®, Domino, and WebSphere knowledge. As a principal WebSphere consultant, he leads and participates in projects focused on system architecture, planning and overall system tuning. Martin has over seven years of experience in system administration and integration. His time is dedicated mainly to the European pharmaceutical giant Alliance-Unichem CZ. Lea Medhurst is a Principal Consultant for Eos Solution in Brisbane, Australia. In this role, he is responsible for implementing, administering, and developing applications within the Lotus and WebSphere Brands. Lea originally started developing using Lotus Notes® and has since moved on to J2EE and in particular WebSphere Portal. Lea has been working with WebSphere Portal since V4.0 and has recently gained vast experience with the Lotus Workplace platform. xiv Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Sami Salkosuo is a Software Architect from Helsinki, Finland where he has worked at IBM for the past six years. He has eight years of experience in Java programming and lately his main focus area has been portlet development on WebSphere Portal Server and Lotus Workplace. Peter K. Weber is a Senior Consultant with IBM Software Services for Lotus (ISSL) in Munich, Germany and has been working on various international development and deployment projects of Lotus software over the last several years in the EMEA region. Peter holds a diploma in Mechanical Engineering and is a certified IBM Application Developer in Lotus Notes and Domino 6. He has been programming computers since 1989 at the beginning with C (on UNIX®), started development with Lotus Notes and Domino in 1995, and joined Lotus in 1999. Leslie Weng is a Senior I/T Specialist with IBM Software Services for Lotus (ISSL) based in Cambridge, MA. She has over eight years of IT consulting experience and technical knowledge in Lotus Domino and related products. Her areas of expertise include analysis, application design, application development, and system integration. Over the course of her career, she has had the opportunity to provide technical leadership for a wide variety of projects. She is an IBM Certified Advanced Professional in Lotus Notes Application Development in R4, R5, and ND6. She holds a Bachelor of Science degree in Computer Science from Northeastern University. We also wish to acknowledge and give thanks to the team of authors who produced the original version of this book, Portalizing Domino Applications for WebSphere Portal, SG24-7004. The original authors were: Tommi Tulisalo Christopher Heltzel Camilo Rojas Preface xv Michael Ticknor Oliver Trabert Marko Viksten Additional contributors Thanks to the following people for their contributions to this project: Peter Janzen, Senior Product Manager, Lotus Software IBM, Cambridge, MA, USA Steve Leland, Lotus Software IBM, Westford, MA, USA Thomas Reske, Student Intern, Applied Computer Science IBM, Stuttgart, Germany Philip Monson, ITSO Project Leader IBM, Cambridge, MA, USA Tommi Tulisalo, IT Architect, IBM Software Services, EMEA IBM, Helsinki, Finland Oliver Trabert, WebSphere Portal Architect, WP Experts (http://www.wpexperts.com) Cologne, Germany Special thanks to Ted Snyder and Brian Chaput at Bowstreet (http://www.bowstreet.com) for their help in providing information about Bowstreet’s Portlet Factory. Special thanks for Markus Marenbach and Petra Leuchtenberg at Conet AG (http://www.conet.de). Their help in providing the information about Conet Knowledge Director 3.0 for WebSphere Portal was extremely valuable. 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 customers. Your efforts will help increase product acceptance and client satisfaction. As a bonus, you'll develop a network of contacts in IBM development labs, and increase your productivity and marketability. xvi Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Find out more about the residency program, browse the residency index, and apply online at: ibm.com/redbooks/residencies.html 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 e-mail to: redbook@us.ibm.com Mail your comments to: IBM® Corporation, International Technical Support Organization Dept. JLU Mail Station P099 2455 South Road Poughkeepsie, New York 12601-5400 Preface xvii xviii Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1 Chapter 1. Introduction to portalizing Domino applications In this chapter, we introduce WebSphere Portal, and discuss the importance and benefits of integrating Domino applications with Portal and Lotus Workplace. We will illustrate that for companies moving towards a portal based solution, it is essential to be able to seamlessly integrate Domino applications. Within a larger context, we discuss how WebSphere Portal, Domino, and the Domino Extended products are key components that make up the IBM Workplace strategy. The term “Workplace” is taking on an increasingly important and broad meaning for IBM Software. The IBM Workplace strategy represents the people side of IBM's software business. It is made up of new and existing products and technologies that connect people with other people, business processes, information, and applications. We discuss in detail how WebSphere Portal, Domino, and Lotus Workplace play a key role in forming the IBM Workplace and ultimately making this vision a reality. There are many options for Domino integration, and no single method fits all needs. Using a portalizing methodology can assist the reader in making the right choice for specific requirements. We introduce the range of options, from using the ‘out of the box’ collaborative portlets that ship with Domino V6.5.1 and Portal, to using Java programming to reach a fully customized solution that best meets your organization’s needs. © Copyright IBM Corp. 2005. All rights reserved. 1 Finally, we introduce the important architectural aspects that need to be understood for successful integration of Domino applications within WebSphere Portal. Note: Throughout this book, we refer primarily to integrating Domino applications with WebSphere Portal. In specific instances, we also discuss the benefits of ‘portalizing’ applications for integration with Lotus Workplace. Since Lotus Workplace is built upon WebSphere Portal technology, note that for all practical purposes, the methods we describe for integrating with WebSphere Portal will also apply to Lotus Workplace as well. Finally, in Chapter 8, “Integration with Lotus Workplace” on page 687, we address specific methods that apply directly to Lotus Workplace. We discuss the Lotus Workplace API and the Workplace Application Builder. 2 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1.1 Overview Within this chapter, we introduce the key concepts, technical considerations, and integration options that apply to portalizing Domino Applications with WebSphere Portal and Lotus Workplace V2.0.1. This chapter is intended to provide an overview of the key issues, while subsequent chapters go into much greater detail on how to implement the different integration methods. Some of the key questions and issues to be introduced in this chapter are the following: What are the benefits of integrating Domino applications with WebSphere Portal? What do we mean by the term and concept of the “IBM Workplace” family of products? As this family of products for IBM Workplace gains greater significance within IBM and this vision takes shape, how do Portal, Domino, and Lotus Workplace V2.0.1 fit into this? Exactly what does the term “portalizing” mean, and what are the different options for integrating Domino applications within WebSphere Portal? For which situations is each of the different integration methods most appropriate? Does one specific method of integration provide the most benefit? What are the required skills and level of complexity involved with each of the integration methods? What are the specific portlet development patterns that apply to each level of integration? Portlet patterns will help to classify what type of integration level should be used; this information is relevant when deciding what integration technique to use. 1.1.1 Portal and Domino within the context of the IBM Workplace Before discussing issues and integration methods that are specific to Portal, Domino, and Lotus Workplace V2.0.1, it is important to establish a foundation based upon the concept of an electronic working environment, or more commonly referred to as a “workplace’. (At the time of this redbook’s publication, this term is being used broadly within IBM and the IT industry. There is some confusion, as certain IBM Software products contain the name “Workplace’, while IBM is also laying out the concept and vision of the “IBM Workplace”.) In the upcoming sections, we will clarify this issue. Chapter 1. Introduction to portalizing Domino applications 3 In the most basic sense, think of the term workplace as a unified electronic working environment. It serves as a simple, unified access point to applications. It is the ‘front end’ environment on which an end user performs their work and collaborates with others. The productivity and efficiency of an employee can be directly impacted by the following factors: The degree to which this front end ‘workplace’ is intuitive and easy to use Provides a single point of access to required applications Allows for real time collaboration within the context of a specific task The following sections illustrate how we introduce the strategy and concept of the IBM Workplace and then address the issues more specific to WebSphere Portal and Lotus Domino. 1.1.2 Structure of this chapter Introduction to the concept of the unified electronic working environment and the specific IBM Workplace strategy – 1.2, “The vision supporting IBM Workplace” on page 5 discusses the underlying vision beneath the IBM Workplace by highlighting the concepts and benefits of the unified electronic working environment. – 1.3, “Introduction to IBM Workplace” on page 6 introduces IBM Workplace with its family of products - and what their particular role is in IBM Workplace. In particular, we want to also clarify the role of Portal, Domino, and Lotus Workplace within the greater IBM Workplace vision. Introduction to Portal Architecture, Portal functionality, and portlets – 1.5, “Portal architecture” on page 23 gives an overview about WebSphere Portal and shows what a portlet is. – 1.6, “Integrating Domino applications” on page 35 points out the key facts of the “portalizing” process, what patterns can be used to identify possible integration techniques, and talks about the integration architecture. Authentication Considerations for Portal and Domino – 1.9, “Authentication” on page 54 details what authentication is about when having WebSphere and Domino “talking” to each other. Development options, skills, and degree of customization – 1.10, “Development options” on page 58 gives the reader recommendations on what the appropriate “tool” is to get it done. 4 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1.2 The vision supporting IBM Workplace Portals serve as a simple, unified access point to applications. This front end of computing is the people side, the environment where users live and do their work. A unified electronic work environment represents a flexible, standards-based model that can be assembled from various combinations of componentized capabilities. It brings together whatever users need - business processes, collaboration capabilities, information, documents, or productivity tools - and presents these to the user through a unified workplace interface. This online environment is tailored to the user, based on role. With all required resources at hand and presented within the business context, users can conveniently stay in this environment to do all facets of their work throughout the day. Synchronization services enable users to continue accessing their workplaces even when disconnected from the network. This means they can access the same resources whether in the office, at a client site, or in a car or plane. They can also access their workplaces through server-managed clients of choice, whether a Web browser, a rich client, or a mobile device. Figure 1-1 on page 6 shows the users and IT perspective of a unified electronic work environment. Chapter 1. Introduction to portalizing Domino applications 5 Figure 1-1 The users and IT perspective of workplace The vision of IBM Workplace is that people can use whatever access point they choose throughout the day, in order to access the people, information, and business applications they need, when and where they need them. Whatever their mode of access, users see their online work environments through a consistent user interface. In addition to employees, external constituents such as business partners, suppliers, or customers may also be connected to information sources and business processes appropriate to their roles. 1.3 Introduction to IBM Workplace IBM Workplace represents a unified electronic work environment for people productivity, built with products and technologies from IBM. It is supported by a family of specific IBM products and technologies that make more people more productive in the context of the business they do every day. It is made up of new and existing products that connect people to business processes, information, applications, and other people. 6 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The concept of the IBM Workplace represents the front end of computing. Its mission is to make more people more productive in the context of the business they do everyday. It enables people to easily connect to the information, applications, and business processes they need, when they need them, via a wide spectrum of access points ranging from enterprises desktops to pervasive devices. IBM Workplace is comprised of new and existing products and technology, including Lotus Notes and Domino, WebSphere Portal, Lotus Workplace, WebSphere Everyplace®, and Workplace Client Technology™, and provides high-performance, role-based Workplaces that are provisioned directly to users. IBM Workplace also includes industry specific solutions, based upon the IBM Workplace family of products. Finally, IBM Workplace uniquely combines the productivity gains of the desktop with the cost advantages of the network. Over the years, many organizations have utilized Domino (and continue to use it) for a countless number of collaboration solutions. The following sections outlines why Lotus Domino takes a key position in the IBM Workplace strategy, what possibilities for integration within are available, and how to make the decision for an appropriate integration technique. We will take a deeper look into portal architecture and portlet technology - always keeping the perspective of the key issues for integrating Domino with Portal. We will show what integration techniques are available and how to select “the one” that fits. So what does IBM Workplace mean in practice for a user? Things a typical user might need to do in the course of a day: 1. Talk to colleagues one-on-one or in meetings 2. Write/find/share some documents 3. Execute actions to advance a business process 4. Seek quick answers to questions 5. Contribute to a team project 6. Look up personal benefits information 7. Learn about a new company initiative This user could do all the above without ever leaving his Workplace or opening and closing different applications. Entering his Workplace with a single sign-on, the user would have immediate access through portlets in a unified interface to: The application supporting his business process The company's intranet, with an HR site for benefits information, and an e-learning knowledge repository to get up to speed on the new initiative Chapter 1. Introduction to portalizing Domino applications 7 E-mail, instant messaging, group calendaring and scheduling, Web conferencing, "people finder," and team project workspaces for communicating, meeting, interacting and advancing group projects with colleagues Document management, built-in editors, and other productivity tools for creating, accessing, and sharing written outputs. Figure 1-2 shows the front-end integration of IBM Workplace and the corresponding back-end integration of business processes. Figure 1-2 IBM Workplace Various users would have access to the specific business processes, applications, information sources, and collaboration capabilities required for their roles and job functions, and they could access these resources through their clients of choice. Products that fall within IBM Workplace family of products include: IBM Lotus Notes and Domino WebSphere Portal 8 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Lotus Workplace IBM Workplace Client Technology, including both the Micro Edition and the Rich Edition WebSphere Everyplace Note: While WebSphere Everyplace is one of the products that make up the IBM Workplace, we do not focus on this specific product within the context of this redbook. 1.3.1 The business value of IBM Workplace Organizations will adopt the IBM Workplace model in differing configurations to serve particular sets of objectives, but all will benefit from the advantages inherent in the model itself. Server-managed clients: The server-managed client model, which enables applications to be extended to a full spectrum of client types that are deployed, and managed from the server, allows applications to more easily follow a user across their day, whether the user is working from a disconnected mobile computer using a managed rich client, a connected workstation via a browser, or a mobile client via a "sometimes connected" mobile device. Server managed control of the user environment ensures that everyone has the latest applications and upgrades in a timely fashion. Flexibility and choice: The standards-based flexibility and choice inherent in the IBM Workplace family of capabilities supports both preservation of existing investments and future extensibility. The IBM Workplace model adapts to the client's IT strategy by offering flexibility across operating systems, clients, document editors, and applications. The Linux, Windows®, and Mac OS environments will be supported. This flexibility facilitates streamlining business processes incorporating customers, partners, and suppliers, and allows the IT infrastructure to grow and change with the evolving needs of the business. Support for standards: Interoperability is achieved by the open standards approach, which enables easier and more effective integration with customers' existing IT investments. The extensible client platform permits extending the value of existing Web, Java, .Net, C++, and Notes applications, developing new applications, leveraging existing investments such as Office documents and Java.Net and C++ applications, and integrating processes across the enterprise. Security: Robust, policy managed access and control with built-in data management and security features protect an organization's information assets. Applications utilizing IBM Workplace Client Technology benefit from Chapter 1. Introduction to portalizing Domino applications 9 local and server-managed encrypted data stores, in which the local data store can synchronize with the server, allowing policies and ACLs to be applied. When documents are moved into the data store, they are effectively managed and are more secure than if left on the file server where they are vulnerable to attack. Total Cost of Ownership: Simplification and server managed control of the user environment, with “no touch” deployment, administration, and client updates, radically reduces the costs of managing the environment. Standards-based interoperability with existing IT investments preserves their value and eliminates the costs of forced “rip-and-replace” requirements. Provisioning capabilities to users on demand based on role, rather than “one size fits all” provisioning further helps to lower the Total Cost of Ownership. Productivity and responsiveness: The IBM Workplace model makes people more productive in the context of the business they do every day by giving them anytime/anywhere access to everything they need to do their jobs. Users benefits from the simplified user interface, easy access to applications, business processes and documents, componentized capabilities immediately available in the context of their work, a new rich user experience for Web-based applications, and disconnected use and synchronization of applications once tied to the network. The cumulative effect is increased organizational productivity, efficiency, and responsiveness. 1.3.2 The product families that make up IBM Workplace The versatile, componentized capabilities available for assembling an IBM Workplace are drawn from product families from IBM Software Group, all based on a common technology platform. Lotus Notes and Domino A family of messaging, collaborative applications and collaboration products that can be integrated into a business environment IBM WebSphere Portal Offers integrated access to information, applications, and business processes across the organization in a single role-based interface Lotus Workplace A family of integrated, Web-based collaborative products providing a single role-based interface to the collaboration tool a user needs IBM Workplace Client Technology – Micro Edition 5.7 Mobile products and technologies for extending applications and information out to users working on remote devices, such as PDAs or cell phones 10 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Rich Edition Enables development of applications that combine the benefits of a rich user experience with the ease of deployment and manageability of browser-based applications Lotus Notes and Domino and its role within IBM Workplace Lotus Notes and Domino and its family of collaboration products provide individual collaboration components of an IBM Workplace. These products continue to provide large enterprises as well as small and mid-size businesses with collaboration solutions for their business challenges. Over the past years, thousands of collaborative applications have been built to support functions such as HR, quality assurance, ERP, supply chain management, CRM, and Helpdesk. Lotus Notes and Domino is central to enterprises and is an integral part of IBM Workplace, which is why Versions 7, 8, and future versions are currently being planned. Sharing today in the attributes of the IBM Workplace model, Lotus Notes and Domino offers a choice of e-mail clients to fit the varying needs of different kinds of users, and flexibility and choice in hardware platforms and operating systems. With Lotus Notes and Domino V6.5, users have a single point of access to their most valuable e-mail, collaboration, and personal information management (PIM) resources through the new Lotus Workplace for Notes welcome page (Figure 1-3 on page 12). Chapter 1. Introduction to portalizing Domino applications 11 Figure 1-3 Lotus Notes V6.5.3 workplace There is continuing support for disconnected use, and Domino's multi-tier security enables centralized control of access rights ranging from the server level down to individual fields on a form. The extended portfolio of Notes and Domino products leverages the same administrative framework. Lotus Notes and Domino capabilities and applications can readily be integrated via portlets into WebSphere Portal and with Lotus Workplace products, thanks to standards-based interoperability. Meanwhile, the development roadmap for Lotus Notes calls for leveraging the IBM Workplace Client Technology in future releases (targeting release 8) so that Notes customers can enjoy the benefits of Lotus Workplace. 12 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 WebSphere Portal and its role within IBM Workplace A key part of the IBM Workplace strategy, WebSphere Portal integrates applications, content, processes, and people in a single point of interaction for the user. It provides the simplified, role-based user environment that allows people to interact with the on demand world in a personalized way. The user interface enables collaboration in the context of the work at hand. With a single sign-on, users can quickly access the dynamic information they need, execute business processes across critical applications, and collaborate with portal users inside and outside the organization. WebSphere Portal is an open, standards-based framework supporting a wide array of options for customers across databases, directories, platforms, and security. With pre-integrated portlets, cross-portlet integration for all application types, and tools for easy creation of new portlets, WebSphere portal helps organizations move beyond fragmented application "silos" while hiding the complexity of the IT infrastructure. It is a particularly cost-effective solution for self-service applications or for any interactive applications that cross organizational boundaries. Product and component matrix WebSphere Portal V5.0.2 Table 1-1 shows the products and components that are packaged in each WebSphere Portal offering. Table 1-1 Product and component matrix WebSphere Portal V5.0.2 Product or component Express Express Plus Enable Extend WebSphere Portal X X X X IBM WebSphere Application Server Enterprise Edition X X X X IBM Directory Server X X X X Lotus Collaborative Components X X X X Portal Toolkit X X X X IBM WebSphere Studio Site Developer X X X X X X DB2® Enterprise Edition IBM Lotus Domino Enterprise Servera X X X Chapter 1. Introduction to portalizing Domino applications 13 Product or component Express Express Plus Enable Extend IBM Lotus Team Workplace (QuickPlace) b * IBM Lotus Instant Messaging and Web Conferencing (Sametime) * * Collaboration Center X X WebSphere Portal content publishing (including Personalization) X X WebSphere Translation Server X X IBM Lotus Extended Search X IBM Tivoli® Web Site Analyzer X a. The license for Portal includes the IBM Lotus Domino Enterprise Server to support the inclusion of Lotus Instant Messaging (Sametime®) and Team Workplace (QuickPlace®). Please refer to your IBM Sales representative for exact licensing details. b. IBM Lotus Instant Messaging and Web Conferencing and IBM Lotus Team Workplace are limited to portal use only. Lotus Workplace and its role within IBM Workplace Lotus Workplace is an integrated family of collaborative products based on open standards. Lotus Workplace offers flexible server-managed client choices to deliver the right capability to different types of users in a secure, dynamic work environment. Collaborative capabilities, such as sending e-mail, scheduling calendar events, taking training courses, exchanging instant messages with subject matter experts, creating and managing shared documents or discussions, holding Web conferences, and creating new workplace applications, are integrated into a single user experience. Lotus Workplace capabilities can be activated, administered, and provisioned from a single location, which simplifies management of the collaboration infrastructure. Lotus Workplace employs a standards-based platform delivered on top of the WebSphere and J2EE infrastructure. The base includes WebSphere Application Server, WebSphere Portal, WebSphere Member Manager, IBM Directory Server (optional), and a relational data store provided by IBM DB2 UDB. 14 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 With its J2EE platform, Lotus Workplace is easy for IT to deploy and manage because it leverages a central administration, deployment, and provisioning model. All collaborative capabilities can be easily activated and controlled from a single point of administration, even as new Lotus Workplace products are installed. When more capabilities are added, these can be displayed and managed within the same Workplace. Figure 1-4 gives an overview of Lotus Workplace and its parts. Figure 1-4 Lotus Workplace Lotus Workplace products and features Lotus Workplace consists of the following set of integrated products: IBM Lotus Workplace Team Collaboration™ IBM Lotus Workplace Team Collaboration lets users participate in online meetings, create libraries, and interact with team members through online chats, threaded discussion forums, and document sharing. Lotus Workplace Team Collaboration includes the following features: – Team Spaces are places in which members participate in discussions and chats, share documents and a team calendar, and search for information related to a project. – Web Conferences are online meetings in which moderators make presentations to conference participants. Chapter 1. Introduction to portalizing Domino applications 15 – Applications provide users with access to workplace applications, HTML-enabled Domino applications, and applications assembled from templates that were created or customized in Lotus Workplace Builder. – Documents contains online document libraries. Users can create and maintain a list of favorite document libraries. – Workplace Builder is a tool for creating and managing templates for assembling workplace applications and for editing existing workplace applications. Users can also design and customize forms for workplace applications. IBM Lotus Workplace Collaborative Learning™ IBM Lotus Workplace Collaborative Learning is a scalable, flexible product for managing classroom-based and online learning activities, resources, curricula, and courseware catalogs. Lotus Workplace Collaborative Learning includes the following features: – Learning student experience provides an easy-to-use interface where students access courses. Students can search for courses and organize them in personalized folders, as well as preview, enroll in, and participate in courses online. Information about courses is stored on the Learning Server, while the courses themselves are presented on the Delivery Server. – Learning management and delivery system components provide an administrative interface that course developers and instructors can access from the Web to manage resources, learning programs, and skills development. – Authoring Tool lets course developers create course structure and content, assemble course packages, and import them to Lotus Workplace Collaborative Learning servers. The Authoring Tool is used by course developers at their own workstations. IBM Lotus Workplace Messaging™ IBM Lotus Workplace Messaging is a cost-effective, standards-based messaging product that is security-rich, scalable, and easily deployed. It integrates with an organization's existing corporate infrastructure and uses the organization's LDAP directory to automatically create, delete, and authenticate user accounts, resolve addresses, and route mail. Lotus Workplace Messaging supports a choice of client experiences from a standard browser to a rich client experience. Lotus Workplace Messaging includes the following capabilities: – Mail lets users send and receive e-mail messages. – Calendar and Scheduling lets users maintain and manage calendar events and schedule meetings. 16 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Personal Address Book lets users maintain and manage contact information for people and for group mailing lists. IBM Lotus Workplace Documents IBM Lotus Workplace Documents provides systematic, controlled access to critical documents and provides a fundamental document management capability that is standards-based and has integrated collaborative capabilities. Lotus Workplace Documents includes the following features: – Document library capabilities provide document check-in and check-out, document locking, and version control. – Structured access provides an easy method for setting up library access so that information needed organization-wide can be easily viewed, but selective information can be viewed only by a limited audience. – Document editors provide the power to modify popular document types even when native editors are unavailable. – Choice of client experience provides either a browser or rich client experience. – Document author/owner/editor awareness through integrated instant messaging and chat capabilities. – Offline support through the rich client provides a secure method for users to create, import, edit, and save documents, presentations, and spreadsheets by supporting offline use and synchronization between local and server stores. – Security lets users store documents outside the file system to increase protection from viruses and other risks. IBM Lotus Workplace Web Content Management™ IBM Lotus Workplace Web Content Management delivers powerful end-to-end Web content management through multiple Internet, intranet, extranet, and portal sites. Lotus Workplace Web Content Management includes the following features: – Content authoring is template-based, with a WYSIWYG rich text editor providing a guided process that does not require technical skills. – Versioning and rollback provides a method for creating multiple content versions that can be used at different times or restored to previous versions, as needed. – Automatic workflow processing ensures that the right people approve Web content before it is published and assures accuracy and relevancy of content. Chapter 1. Introduction to portalizing Domino applications 17 – Integration of information from various sources allows reuse of information from back-end systems, improving transactional performance. – Personalized delivery lets authors create content once and reuse it in different sites for users with different roles or preferences. – Multiple database support allows use of Domino, DB2, Oracle, or DB2 Content Manager as repositories. Note: Please refer to the redbook Lotus Workplace Web Content Management, SG24-6309-00 for much greater detail on the features, functions, and recommended method for deployment of this product. You can find it on the Web at: http://www.redbooks.ibm.com/abstracts/sg246309.html IBM Workplace Client Technology and its role within IBM Workplace IBM Workplace Client Technology, Micro Edition V5.7 is a family of products and technologies that allow enterprises to extend access to business processes and information to remote and mobile workers anytime, anyplace, and over a wide range of mobile devices. Typically, mobile workforces are deployed in functions such as sales or field service/ support; public safety, inspection, utility and delivery services; claims adjustment, and so on. Workers deployed in the field must do things like check prices, fill orders, verify status or locations, get and adjust schedules, report problems, input client data, and manage inventories. They may need only to look up information, or they may need to get fully engaged with their company's back-end systems. Some workers require multiple or complex applications on their mobile devices, or are frequently out of range of network services. Others require only a simple browser- or forms-based application, or perhaps just e-mail / PIM access and instant messaging. Some need critical time-sensitive information "pushed" to them in an emergency, or the ability to "pull" maps and directions when traveling between client sites. The IBM Workplace Client Technology, Micro Edition family provides different capabilities to different people. Figure 1-5 on page 19 gives an overview of IBM Workplace Client Technology and its capabilities. 18 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 1-5 IBM Workplace Client Technology IBM Workplace Client Technology, Rich Edition is a client-side framework, based on Eclipse, for the deployment and management of business applications. It addresses the rich-client experience that can be deployed and managed affordably. Because of the way IBM Workplace Client Technology shares code and processing work between clients and middleware servers, organizations that embrace this technology and the applications built on it will have the flexibility of client-side applications combined with the server-side control associated with Web-based computing. Effectively, they will have the best of both worlds. Not only will this be a boon to IT administrators, but the end user will be able to enjoy the richness of a traditional client with security, fast response time, user interface (UI) consistency, off-line support, and tighter integration with desktop productivity applications. Chapter 1. Introduction to portalizing Domino applications 19 Note: This redbook does not provide an in-depth review of the IBM Workplace Client Technology family of products. For further information about these products, specifically for the IBM Workplace Client Technology, Rich Edition, please refer to the following two Redpapers: IBM Workplace Client Technology (Rich Client Edition) Technology Overview, REDP-3884-00, found at: http://www.redbooks.ibm.com/abstracts/redp3884.html IBM Workplace Client Technology (Rich Client Edition) ISV Integration Guide, REDP-3883-00, found at: http://www.redbooks.ibm.com/abstracts/redp3883.html For documentation covering the architecture and integration of IBM WebSphere Everyplace, please refer to the product documentation (http://www.ibm.com/websphere), or the more detailed information on the IBM developerWorks® site (http://www.ibm.com/developerworks/websphere/). 1.3.3 The roadmap of Lotus Notes/Domino, WebSphere Portal, and IBM Workplace Currently, countless numbers of Lotus Domino applications are used by customers who will opt to remain on the Notes/Domino platform for a foreseeable future. In the near future, more and more of these customers will have the need to integrate these applications within WebSphere Portal. To help customers and users of Domino understand the key features (and key planned features for upcoming releases), we provide the following “roadmap” of features within Lotus Notes/Domino, WebSphere Portal, and IBM Workplace. Attention: Many of the statements and features contained in this product roadmap are based on high level functional goals of future products. They are intended to provide a general direction and provide insight into major functional goals. Accordingly, items such as time frames and specific features in any given release are subject to change. Lotus Notes/Domino Lotus Notes/Domino V6.5.x – New portlets and sample portal page, including the Domino Applications Portlet (DAP) – Better integration (and support) with WebSphere Portal server – Domino as Workplace directory support 20 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Lotus Notes/Domino V7.0 – DB2 common data store – Notes plug-in for Workplace rich client – Common Mail portlet support Lotus Notes/Domino V7.x – Workplace documents integration Lotus Notes/Domino V8.0 – Notes client on Workplace Client Technology (WCT) – Optional J2EE mail and Calendering and Scheduling service on Domino Lotus Workplace Lotus Workplace V2.0.1 – New Rich Client (including disconnected use) – New Lotus Workplace Documents – New Workplace Builder – Additional database support for Oracle and Cloudscape™ – Significant enhancements to all V1.1 products – Portal V5.0.2.2 IBM Workplace V2.5 – Enhanced Tooling and API – Mobile Access – Rich Clients for Portlets – Enhanced scalability – iSeries™ and Solaris Servers – MS SQL server – Portal V5.0.2.2 WebSphere Portal Server WebSphere Portal V5.0.2 – Lotus Workplace Web Content Management (LWWCM) V2.0 – iSeries support for Express – WSRP and JSR 168 Chapter 1. Introduction to portalizing Domino applications 21 WebSphere Portal V5.1 – Enhanced Integration and deployability – Integrated LWWCM V2.5.1 – Business Process Integration – JSR 170 support – Workflow integration – HPUX Platform – WebSphere Application Server V5.1 WebSphere Portal V6.0 – Merge J2EE Team Collaboration (instant messaging, presence awareness, and team spaces) into Portal – Extreme deployment – WebSphere Application Server V6.x 1.4 Benefits of Domino and Portal together By integrating Domino and WebSphere, you can take advantage of each product's strengths and create applications that deliver more functionality than either platform can provide on its own. Such a combination can have many advantages, since it is: Deeply integrated: WebSphere Portal provides the most robust integration with IBM's entire software portfolio, including your Lotus infrastructure. Open: WebSphere Portal offers integration of best-of-breed applications. IBM is helping define the key open standards for the portal industry. Comprehensive: WebSphere Portal provides a complete framework that gives answers to all requirements for integrating existing Lotus Domino assets with a single, powerful portal infrastructure. Right for Contextual Collaboration: WebSphere Portal weaves the advanced collaborative capabilities of Lotus into a portal, enabling organizations to achieve the highest level of productivity. Secure: WebSphere Portal provides granular security for applications and content. Therefore, the Lotus Domino directory or other LDAP sources can be used. Flexible: WebSphere Portal offers the presentation of data for a wide range of client devices. 22 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Easily delegated: Sections of the portal can be delegated to various “downstream” groups, enabling them to manage their segment of the portal. Personalized: Users can personalize content within portlets based on profiles and business rules. Global: WebSphere Portal supports multiple languages, enabling the support of global organizations. 1.5 Portal architecture In this section, we discuss certain aspects of the Portal architecture that will be important to portalizing Domino applications. WebSphere Portal offers a framework to help meet the issues of presentation, security, scalability, and availability. This chapter gives an overview of the architecture and design of WebSphere Portal, including its presentation and portlet framework, its security, user management, personalization, content management, performance and scalability, and search and enterprise information connectivity features. Figure 1-6 illustrates the overall architecture for WebSphere Portal. Figure 1-6 IBM WebSphere Portal overall architecture For additional information about the Portal architecture, please refer to the IBM WebSphere Portal Information Center, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html Chapter 1. Introduction to portalizing Domino applications 23 1.5.1 Introduction to portlets Portlets are the heart of a portal. The term portlet refers to a small portal application, usually depicted as a small box on a Web page. Figure 1-7 shows a sample Web page that contains several portlets. A portlet is a reusable Web module that runs on a portal server. Portlets have predefined roles, such as retrieving news headlines, searching a database, or displaying a calendar. Web pages, Web services, applications, and syndicated content feeds can be accessed through portlets. Figure 1-7 Dynamic workplace example Portlet applications Portlets are more than simple views of existing Web content. A portlet is a complete application, following a standard model-view-controller design. Portlets have multiple states and view modes, plus event and messaging capabilities. 24 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Portlets run inside the portlet container of the WebSphere Portal component, similar to the way a servlet runs on an application server. The portlet container provides a run-time environment where portlets are instantiated, used, and finally destroyed. Portlets rely on the WebSphere Portal infrastructure to access user profile information, participate in window and action events, communicate with other portlets, access remote content, look up credentials, and store persistent data. Generally, portlets are administered more dynamically than servlets. For example, portlet applications consisting of several portlets can be installed or removed while the WebSphere Portal component is running. The settings and access rights of a portlet can be changed by an administrator while WebSphere Portal is running, even in a production environment. Portlet modes allow a portlet to display a different user interface, depending on the task that is required of the portlet. A portlet has several modes of display that can be invoked by icons on the portlet title bar: Configure, Help, and Edit. A portlet is initially displayed in its View mode. As the user interacts with the portlet, the portlet can display a sequence of view states, such as forms and responses, error messages, and other application-specific states. Help mode provides user assistance. Edit mode provides a page for users to change portlet settings. For example, a weather portlet might provide an Edit page for users to specify location. Users must be logged in to WebSphere Portal to access Edit mode. If Configure mode is supported by a portlet, it provides a page for portal administrators to configure portlet settings that are shared by all users. The portlet shown in Figure 1-8 is currently displayed in view mode. Figure 1-8 Portlet modes Each portlet mode can be displayed in normal, maximized, or minimized states. When a portlet is maximized, it is displayed in the entire body of a page, replacing the view of other portlets. When a portlet is minimized, only the portlet title bar is displayed on the page. Chapter 1. Introduction to portalizing Domino applications 25 Web application deployment descriptor As seen before, a portlet produces markup and is rendered in a rectangular area in the portal page. A collection of related portlets make up a portlet application and are packaged together in a Web archive (WAR) file. Portlets packaged together in a single WAR file may share images, stylesheets, JSP components, and other kinds of resources. A WAR file is a specially structured JAR file that includes a special XML descriptor called the Web application deployment descriptor. The filename for the XML descriptor file is web.xml. This file is always stored in the "web-inf" directory of the WAR file. Portlet API Portlets are a special subclass of HttpServlet, with properties that allow them to easily plug in to and run in WebSphere Portal. Portlets are assembled into a larger page, with multiple instances of the same portlet displaying different data for each user. Portlets rely on WebSphere Portal infrastructure to access user profile information, participate in window and action events, communicate with other portlets, access remote content, look up credentials, and store persistent data. The Portlet API provides standard interfaces for these functions. The portlet API defines a common base class and interfaces for portlets to cleanly separate the portlet from WebSphere Portal infrastructure. In most respects, the portlet API is an extension of the servlet API, except that it restricts certain functions to a subset that makes sense for portlets running in the context of a portal. For example, unlike servlets, portlets cannot send errors or redirects as a response. This is done only by WebSphere Portal itself, which controls the overall response page. Usually, many portlets are invoked in the course of handling a single request, each one appending its content to the overall page. Some portlets can be rendered in parallel, so that WebSphere Portal assembles all the markup fragments when all the portlets finish or time out. Portlets that are not considered thread-safe are rendered sequentially. The markup fragments that portlets produce can contain links, actions, and other content. The Portlet API defines URL rewriting methods that allow portlets to transparently create links, without the portlet needing to know how URLs are structured in the particular portal. Portlet communications WebSphere Portal provides a way for portlets to communicate with each other. In a production portal, portlet communication could be used to copy common data between portlets. This saves redundant typing for the user and makes WebSphere Portal easier to use. For example, one portlet might display 26 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 information about accounts while a second portlet displays information about transactions that have occurred for one of the accounts over the last 30 days. To do this, the transactions portlet needs to obtain the corresponding account information when it displays the transaction details. This is accomplished by communication between the two portlets, using portlet actions and portlet messages. In this example, the 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 is called, which then sends a portlet message to send the necessary data. Using this event and message feature helps unify portlet applications that access disparate back-end applications. Cooperative portlets Cooperative portlets subscribe to a model for declaring, publishing, and sharing information with each other using the WebSphere Portal property broker. Portlets subscribe to the broker by publishing typed data items, or properties, that they can share, either as a provider or as a recipient. At runtime, the property broker matches the data type of output properties from a source portlet with the data type of input properties from one or more target portlets. If a match is determined, the portlets are capable of sharing the property. The actual transfer of the property can be initiated by one of the following methods: A user launches a Click-to-Action event from an icon on the source portlet. The icon presents a pop-up menu containing the list of targets for the action. After the user selects a specific target, the property broker delivers the data to the target in the form of the corresponding portlet action. Using the Click-to-Action delivery method, users can transfer data with a simple click from a source portlet to one or more target portlets, causing the target react to the action and display a new view with the results. The user can also broadcast the property to all portlets on the page that have declared an action associated with a matching input property. A user holds the Ctrl key while clicking an action and chooses to have the selection saved persistently as a connection between two portlets, called a wire. If a wire is present the next time the user clicks on the icon, no selection menu is shown. Instead the wired action(s) are automatically fired. Subsequent updates to that property are transferred without further deliberate user choice. Wires can also be created using the Portlet Wiring Tool. The source portlet can do a programmatic publish of properties to the broker when it determines that property values have changed. Such property values are transferred to the target(s) only if wires have been created. Chapter 1. Introduction to portalizing Domino applications 27 IBM Portlet Wiring Tool With WebSphere Portal Server V5, IBM introduced the Portlet Wiring Tool. The Portlet Wiring Tool allows you to configure connections, or wires, between portlets on a page that register with the property broker. Through the property broker, portlets can exchange information, or properties, with each other. Such portlets are called cooperative portlets. Cooperative portlets can react to changes to other cooperative portlets on the page, resulting in a simultaneous update to multiple portlets with minimal user intervention. Refer to the WebSphere Portal V5.0 InfoCenter (http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.h tml) for a complete description of cooperative portlets. WebSphere Portal V5.0 introduced wires as an enhancement to the Click-to-Action features of V4.2. Users' transfer selection choices can be saved as wires between the portlets. The wire may be used to automatically transfer properties to target portlets when specific interactions are performed in the portlet without displaying the pop-up menu prompting the user for more information. Wires are created by holding the Ctrl key and clicking an icon or hotspot in the portlet. A dialog is displayed that allows the user to create a wire to other portlets on the page. Portlet Wiring Tool allows you to view the properties that portlets on the page can send or receive. If a match is available between two portlets, you can create a wire between the two portlets. Existing wires may also be deleted using the tool. This is an alternative to the wire creation or deletion while interacting with the portlets as described above. The wiring tool allows wires to be created in situations that are not handled by the interactive approach. For example, the tool does not require the existence of Click-to-Action menus to initiate wire creation, and can be used to create multiple wires from a single source property (using the interactive approach, a single source can be wired to a single target or all targets, not an arbitrary subset). Example of a place with portlet cooperation Figure 1-9 on page 29 illustrates an example of a place that incorporates portlet cooperation. This example shows an HR workplace. In the upper left corner, an employee directory has been placed. The other portlets show employee details (top right), skills (bottom left), and the projects (bottom right) the employee is currently working on. Instead developing separately, portlet cooperation features are used to present the information in a new context. When searching for an employee in the directory and clicking on the person’s entry, other portlets can react to the selection made. The employee’s detail 28 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 information and skills, as well as the projects they are currently working on, will be shown in the other portlets. All this is triggered by a click the employee link. Figure 1-9 Example of a workplace with portlet cooperation This example illustrates why portlet cooperation is a great concept that helps us to build new kind of applications, just by exposing existing Domino applications inside the portal. 1.5.2 Presentation services The WebSphere Portal framework produces a customized and personalized home page for users where content for the page is aggregated from a variety of content and application data sources. The content areas or portlets display according to what is available and how users customize their portal pages. Chapter 1. Introduction to portalizing Domino applications 29 The portal engine WebSphere Portal provides a pure Java portal engine, which runs on multiple hardware platforms and operating systems. The main responsibility of the portal engine is to aggregate content from different sources and to serve the assembled content to multiple devices. Additionally, the portal engine de-couples the presentation details for the portal page from the characteristics of the portlets. This separation enables each portlet to be developed and maintained as a discrete component, which in turn, enables faster, easier, and more specialized development for the overall portal site. Figure 1-10 shows portal engine components, including: An authentication component. A standard WebSphere security or a third party authentication proxy server is in front of the portal engine. The portal servlet. The central component in the portal engine examines the Internet address or URL and header fields of each request and invokes the appropriate handler. The portal servlet handles the request in two phases. In the first phase, portlets have an opportunity to send event messages to other portlets. For example, portlets may send events to update data that will be rendered in the next phase. In the second phase, the appropriate aggregation module for the user device renders multiple portlets in a single page. The aggregation modules accumulate information from each portlet, add standard decorations around the portlet (such as a title bar, an edit button, and an enlarge button), position it on the page, and generate the overall page markup. Portlet access. Access to portlets is controlled by checking access rights during page aggregation, page customization, and other access points, such as viewing the portlet in its maximized state. Figure 1-10 Portal engine components 30 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Page content aggregation The portal should provide the user with a consistent view of portal applications and allow the user to define specific sets of applications that are presented to the user in a single context. Depending on the device of the user, the rendering of this application set has to vary to fulfill the requirements of the device. Consider, for example, a set of applications that include News, Stocks, Weather, and Search, which have to be rendered to a conventional phone using voice interactions, a WML device with a limited display and keyboard, or a PC-based browser. The tasks of the aggregation, which are repeated with each request coming from the device, are: Gather information about the user, the device, and the selected language. Select the active portlets from the set of applications to which the user has access. Aggregate the output of the active portlets into a coherent, usable display. Once the active page is determined, the layout of this page has to be used to aggregate the content of the defined applications, arrange the output, and integrate everything into a complete page. WebSphere Portal provides fully dynamic aggregation of pages from page descriptors held in the portal database. Rendering of page components is done using Gasps, images, style sheets, and other resources. Figure 1-11 on page 32 shows the three WebSphere Portal aggregation modules: The HTML aggregation component produces pages for desktop computers and other devices with HTML Web browsers. The Wireless Markup Language (WML) aggregation component produces WML content for Wireless Access Protocol (WAP) devices, such as mobile phones. The imode aggregation component produces the cHTML markup for mobile devices in the NTTDoCoMo network. Chapter 1. Introduction to portalizing Domino applications 31 Figure 1-11 Page content aggregation The portal also has the ability to easily add aggregation components, including a voice aggregation module for devices with VoiceXML Web browsers and a personal digital assistant (PDA) aggregation module for PDA devices. Each user can customize a unique home page for each device, selecting the content and applications that are most useful on the device. When the home page is requested, page aggregation works by first detecting the type of device making the request and then assembling the portlets that render their contents in the appropriate markup language. Multidevice portlets When a user customizes a home page for a particular device, the portlet selection list shows only portlets that can actually produce markup appropriate for that device. Thus, the list of available portlets for each device depends on what the portlets can actually do. Some portlets may be available for all the supported devices, while others may be available only on a single device. The user interface design of each portlet also varies from device to device. The user home page and each of the portlets may be very different on a mobile phone. 32 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1.5.3 Layout of the portal page Before customizing your portal site, it helps to understand the underlying structure of the portal as it is determined by the portal JSPs. The portal page is composed of JSPs for screens, themes, and skins that are typically created by the Web designer of the portal. These JSPs reside in the corresponding /screens, /themes, /skins directories under was_root/installedApps/hostname/wps.ear/wps.war. Within this location, subdirectories for markup, locale, and client types are used to support portal aggregation. Themes Determines the look and layout of the portal, including colors, fonts, and images outside of the portlet content area (Home screen). Themes often provide the initial navigation to portal pages. Screens The area of the portal that typically displays portlets (Home screen), but can also display other content in its place, for example, a login form or error message. Screens are selected from navigation icons in the theme colors. They are installed independently from themes. Skins Represent the border rendering around components, such as row containers, column containers, or portlets. Figure 1-12 shows a “shadow” skin. Skins also provide navigation to levels deeper than the navigation that is provided by the themes. Skins can use the theme name to select the graphics that match the theme colors. Skins are installed independently from themes. However, the administrator can set a default skin for a theme. Figure 1-12 Example “shadow” skin 1.5.4 Customization Customizing the user's portal experience is one of the main goals of WebSphere Portal. To achieve this, WebSphere Portal provides user and administrative portlets for customizing content and the look and layout of pages. In addition, tools are provided that allow subject matter experts to personalize content to the needs and interests of each site visitor. Chapter 1. Introduction to portalizing Domino applications 33 Figure 1-13 gives an example of a page that has the following layout: A row container that contains: – Two column containers, each containing: • Two portlet containers, with a portlet in each Figure 1-13 Page layout example It is important to understand that the portal “owns” the entire HTML page. Our portlet will be placed inside of an HTML table cell, and therefore only owns the real estate within that cell. This also means that we do not have to handle any opening or closing HTML or BODY tags. Those will be rendered by the portal page aggregator. It is also important to keep in mind that the portlet can be displayed in column containers of different widths. Therefore, we should not use absolute width settings in our own rendering. It is good practice to use relative width wherever possible. 34 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1.6 Integrating Domino applications In this section, we introduce the methods of portalizing Domino applications, namely transforming and embedding an application into a portal. 1.6.1 The portalizing process Before talking about the term portalizing, a common understanding of the meaning of this term needs to be established. Figure 1-14 presents a high-level outline of the overall portalizing process. Figure 1-14 From Domino applications to portlets and workplaces On the left is a list of typical Domino applications. They need to be portalized into portlets, which can then be made available for different workplaces. A Domino application can be represented by a single portlet, but there is usually not a one-to-one relationship between applications and portlets. Most cases exhibit a one-to-many relationship. Portal applications are usually made up of multiple portlets that use portlet cooperation. This way, application functionality exposed in portlets can be combined in many different ways, sometimes allowing Chapter 1. Introduction to portalizing Domino applications 35 the user to put information in a context that not even the developer of the individual portlet has thought about. It is also important to understand that the same portlet can be used in different workplace contexts with different user roles. 1.6.2 The portalizing challenge Looking at the portalizing process raises the following questions: What portlet development techniques are available? What is the effort required for portlet development? What functionality can be implemented within a portal? How can scalability and performance be ensured? In the following discussion we address these questions and describe the factors and dependencies of the portalization process. Figure 1-15 illustrates the relevant factors. Figure 1-15 Factors and dependencies 36 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 As with any development project, there are multiple factors and dependencies that influence a portalizing project. The important parameters for a Domino portlet project are: Domino application: The characteristics of the Domino application. Integration techniques: Knowledge of all the different options. Domino portlet pattern: Defines the portal integration depth and user interface requirements for the portlet. This is discussed in greater detail later in this chapter. Considerations: Overall project parameters like resources, skills, and so forth. A good understanding of the different factors and their dependencies needs to be developed to be able to successful portalize a Domino application. The following sections will dive deeper into it. 1.6.3 Domino applications The most important piece in the portalizing process is the Domino application itself. The following parameters needs to be considered to characterize the application: Number of documents Number of users and number of maximum users Usage pattern and number of concurrent users Application complexity Single or multiple database application Web-enabled or Notes client-based Figure 1-16 on page 38 can help characterize a given Domino application. It shows several Domino applications, with their database usage on the horizontal axis and the number of users on the vertical axis. The size of each bubble represents the database size, and the bar in the middle indicates the application complexity. Placing a given Domino application into this grid can help to develop a better understanding of the usage scenario for a Domino portlet. This allows you to estimate the workload on the portal and Domino servers. Chapter 1. Introduction to portalizing Domino applications 37 Figure 1-16 Domino application types Another important consideration is that a portal introduces new usage scenarios for applications. With a Notes Client, a user usually accesses Domino applications sequentially, meaning one at a time. On a workplace, there are multiple portlets active, which will concurrently access your applications. This increases the server load significantly. In addition, the portal will broaden the user community for your applications because they are now more visible. All this can have severe implications on the Domino back end and performance. Performance considerations When handling information for the user of an application, the acceptance stands or falls with the performance given to the user. When gathering information and displaying that in several portlets, it is unacceptable when the page is taking too long to load. Of course, performance is a relative thing and every user has a different understanding of it. Therefore, take a look at the following example. An employee directory has to been built and the portlet is specified to look like Figure 1-17 on page 39. 38 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 1-17 Example portlet “Employee Directory” The requirements are: Employee directory with 100,000 entries Initially, the portlet shows the first 10 Employees of the A-name category. Users can page through the Employees like in a paper phone book, or search for an Employee by Name or Employee Number. Portal user community of 40,000 users We assume a concurrency of 5% of the total portal user number for the workplace the portlet is placed on. That means there are approximately 2,000 concurrent users for the portlet. The following scenario will be assumed: The portlet is available on the portal home page for all users. On Monday morning at 8 AM, all employees are going to log on to the portal. The interesting question now is: What is going to happen to the overall portal performance and server load? 2,000 concurrent requests will be sent to display the initial view of the portlet. Creating 2,000 concurrent sessions to the Domino back end and rendering the first page for each user does not seem feasible. Chapter 1. Introduction to portalizing Domino applications 39 When planning this scenario, careful thought about caching strategies and overall session management for this use case must be made. If not, this portlet can significantly decrease the overall portal performance and put a very high load on the Domino back end. Caching strategies and session management will be discussed later on in detail. Getting Domino data in a high-performance way Special care should be taken with the design of the Domino application. A non-high-performance design in Domino can lead to the assumption the portal itself is slow - which is in the user’s perspective correct (he usually does not know about the architecture and the involved back-end systems). It is very important to understand that a portal application based on Domino is not only concentrating on the portal side. So the back end (Domino) should be analyzed if it is designed for maximum performance. Remote versus local access to Domino There are two ways to get data out of Domino and process it in the portlet. The first way is to use remote access when connecting to Domino. A typical scenario would look like Figure 1-18. For remote access the Java program requests the service from a Domino server using Common Object Request Broker Architecture (CORBA). The remote classes use CORBA to access the server over a TCP/IP network. The NotesFactory class in lotus.domino provides createSession and other methods for initiating access to the Domino Objects in Java applications and servlets. Figure 1-18 Remote access to Domino data To compile a Java program that uses the lotus.domino package, the classpath must include NCSO.jar, for example, set classpath=%classpath%;c:\lotus\domino\data\domino\java\NCSO.jar. 40 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The other way is to connect locally to Domino (see Figure 1-19). Therefore, the application server and the Domino server has to be on one physical machine. Figure 1-19 Local access to Domino data To compile a Java program that uses the lotus.domino package, the classpath must include Notes.jar. For example, set classpath=%classpath%;c:\lotus\domino\Notes.jar. Domino views When reading views in Domino, using categorized views (if possible) is always an advantage; that way, Domino delivers “only” the data of the desired category. Avoid using Reader Names fields A view index will be built for every view on a Domino server. That view index contains entries for all documents fulfilling the criteria of that view. This index will be created and updated without any reference of Reader Names fields, because the index will be used for all user of that database. If this view is being used by a user, Domino has to check if that user has the permission to read a document or not. Avoiding Reader Names fields leads to a significant performance enhancement when the number of documents that the user has read permission to is not more than roughly 5% of all documents of that view. Increase number of DIIOP threads In previous Domino versions (R5), it is possible to increase the number of DIIOP threads when connecting remotely. That gives Domino more CPU power, which may lead to reduced power for other tasks running on that server (such as indexing, mail routing, and so on). Chapter 1. Introduction to portalizing Domino applications 41 Getting Domino data without Java Sometimes (depending on the solution) it may be a good idea to use standard Domino design elements to show information. So for displaying only documents of a particular view, a simple Domino page with an embedded view can do the job very well. In that case, the property “Don’t show categories having zero documents” should be selected. Note: Portlet performance and scalability is often underestimated in Domino portlet development projects. It is a good best practice to do performance testing right from the start of the project. Performance is not only dependant on coding or the Domino back end, but also on the overall portal/Domino infrastructure. 1.7 Portlet patterns Portlets can be as simple as data display windows into existing applications, or as advanced as a replacement for complex workflow applications. They also can have a different level of integration with the portal. Portlet patterns will help to classify what type of integration level should be used; this information is relevant when deciding what integration technique to use. In this section, we describe the following patterns: Link pattern Display pattern Integrated pattern Migrated pattern As for any development project, it is a best practice to establish use cases for the portlet usage by asking the following questions: What is the use case from a user’s perspective? Does the use case vary with the role of the user? With this information, the decision can be made about what portlet pattern the application falls into. 1.7.1 Link pattern The link pattern is the easiest of all integration types. It provides the user a link that launches in the native application. This can be either a Notes-based or a browser-based application. Depending on the setup of the authentication system, 42 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 the user may need to log on to the specific application. The Notes client will challenge you for your password if you have not configured it to use your operating system login. If the application is browser-based and you did enable single sign-on (SSO), the re-authentication is not necessary. A link type integration can be achieved by using, for example, the Bookmark Portlet or Quicklinks Portlet that ship with WebSphere Portal. Figure 1-20 Link pattern example 1.7.2 Display pattern In the display pattern, portlets only display information from Domino. If the user needs to interact with the application functionality, they must launch either the Notes Client or a Browser interface. This can be a good option if an application is already Web-enabled. In the portal, we can give the user an overview of, for example, all the expense reports that needs to be approved, and then, for the approval process, launching the expense report application in a new browser window. Depending on the implementation, it would be possible to launch immediately into the expense report that the user wants to approve. Figure 1-21 on page 44 illustrates that it is not necessary to portalize the whole application to the portal. Sometimes a small view into the application might be enough. Chapter 1. Introduction to portalizing Domino applications 43 Figure 1-21 Display pattern example 1.7.3 Integrated pattern An integrated pattern lets the user perform tasks in other applications inside the portlet, rather than having to launch the other application. In the previous scenario, the user gets a list of expense reports to approve, but to perform the approval task, a different application has to be launched. Launching in a separate application might not be a problem, but being able to perform the task inside of the portlet context enhances the user experience and the usability of the portlet. The following example shows how a user can approve or decline an expense report. In the decline case, there should also be a way to give reasons for the declination. For a different user role, the creation of new expense reports from within the portal should be allowed. In these two use cases only, some of the functionality of the expense report application has been exposed to the portal. Other workflow processing of the expenses and back-end integration with an HR system will remain untouched in the native Domino application. Figure 1-22 on page 45 shows the advantages of the coexistence of portlets and Domino applications. Only the information and logic needed for certain use cases will be transferred into the portlet. 44 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 1-22 Integrated pattern example 1.7.4 Migrated pattern A migrated pattern is one that is used to replace an application and transform entire business processes into portlets. Usually an approach like this would involve a redesign of the application. 1.7.5 Designing the integration portlet This section outlines important design issues to be considered when gathering the requirements for an integration of Domino applications. To reduce the effort in building the portlet as much as possible, functionality and code of the Domino application should be reused. The reusability will greatly depend on the architecture of the original Domino application. If it is an already Web-enabled application, the possibilities for reuse are much higher. What can be reused? Views Agents Forms Field validations The options for application reuse vary with the chosen integration technique, and are discussed in detail in the corresponding chapters. Chapter 1. Introduction to portalizing Domino applications 45 Layout and functional aspects Figure 1-23 on page 47 shows a portlet user interface used to illustrate some common requirements for a Domino Portlet. Key elements of the illustrated portlet are numbered, and have the following meanings: 1. Layout definition for views and forms 2. Retrieving and aggregating documents from multiple databases For example: A product manager works with lots of departments, such as Marketing, Sales, and Research and Development. Over time, all these different departments have built there own policy databases. To find a particular policy, our product manager has to look into every single database. In the portlet context, these different policy databases should be now consolidated into one single portlet. 3. Edit-Mode: Implementing user personalization This can have two different aspects. Since a workplace is tailored for a specific user role, only a subset of information relevant for a particular user should be provided. In addition, the user should be able to filter to refine the provided information. 4. Integration of Instant Messaging capabilities (here, people awareness) 5. Advanced layout (buttons, alternating line colors, and so on) 6. Search functionality 7. Pagination Additional functionality that may be needed in the portlet: Categorization of data Write access to enable editing of existing data or creation of new documents Transactional handling, for example, calling Agents Search - full text or field level Rich Text Support for display and editing Page flow between different input screens/workflow Portlet cooperation 46 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 1-23 Elements of a portlet Portlet patterns used in designing the integration Portlets can have view and form-like display, page flows (workflow), page navigation, read and write access, transactions (for example, using agents), and portlet cooperation. For defining the degree of integration, it is useful to ask the following questions when gathering the requirements: What functionality do you need in the portlet? Do users perform transactions? Do you need simple write access to single fields or are complex forms with field validation needed? Do you have a page flow within the application? Is the portlet a replacement for a Domino application? Is your Domino application Web-enabled? Will the portlet be used to Web-enable an application? Are you going to have one complex portlet or many task-oriented portlets? Chapter 1. Introduction to portalizing Domino applications 47 It is a good practice in developing a clear and common understanding of the purpose and use cases for a portlet before starting the development. Portlets are true applications, and therefore it is important to have detailed requirements for the development. Using portlet patterns can help in the requirement gathering process, and to develop a common understanding with the business users. Portlet patterns can be characterized as requirement definitions for portlets. Portlet patterns examples News portlet (display example) (see Figure 1-24.) – Portlet description: The portlet displays news from a high-volume news database. – Portlet functions: • Displays data from one underlying Domino database. • Opens the content document in a new browser window. – Value for users: The portlet will be a mass channel for combining internal news. As an enhancement, users can personalize which news categories they want to see. Figure 1-24 News portlet 48 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 New Documents (integrated example) (see Figure 1-25.) – Portlet description: The portlet consolidates several enterprise knowledge databases based on Standard Document Library, Domino Doc, or Teamrooms. This is the key differentiation from the previous portlet. It adds the ability to select the view and a search option. Additionally, users have People awareness to get in touch with the author of the document. Figure 1-25 New Documents portlet – Portlet functions: • Combines data from several Domino databases. All databases have a different database structure, are not Web-enabled (only standard-view functionality is supported), and have high data volumes. Tools for merging the different Domino databases into one consolidated database are available, including the IBM Lotus Enterprise Integrator® (LEI). • Searches inside of the consolidated database. • Content is opened in a form-like layout embedded in the portlet. • Form display also includes Rich Text fields. Displaying Rich Text inside of a portlet requires special attention. Depending upon which technique you use to implement, handling of Rich Text objects is described in detail in Chapter 4, “Using custom Domino JSP Tag libraries” on page 175, Chapter 5, “Portlet development using Java: Technology review” on page 313, or Chapter 1. Introduction to portalizing Domino applications 49 Chapter 6, “Portlet development using Java: Integration examples” on page 391. • Allows the creation of new documents. • Has integrated people awareness. – Value: Users never miss published documents again. All relevant information and documents will be available in one portlet. Policies portlet (write access and transactions) (see Figure 1-26 on page 51) – Portlet description: The portlet displays the company’s consolidated policy databases. Users have the option to select the policy categories they are interested in. The portlet also has a built-in search function. The individual policies are opened in a form-like display and are embedded inside of the portlet. Additionally, users have people awareness to get in touch with subject matter experts. The HR staff can create and modify policies from within the portlet. The HR manager who is responsible to approve policies can perform the approval process from within the portlet. – Portlet functions: The portlet has the same functionality as the previous example, plus: 50 • Content creation and modification from within the Portlet • Integrated approval workflow for policies Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 1-26 Portlet with personalization and form display – Value: Users never miss new or updated policies. Through personalization, they only see the policies that are relevant to them. For the HR staff, it is very convenient to update and create new policies. The integrated approval workflow expedites policy publishing. Chapter 1. Introduction to portalizing Domino applications 51 1.8 The integration architecture The integration infrastructure is a condition that needs special attention. It can have tremendous impact in an integration project. 1.8.1 The Portal/Domino server infrastructure The following figures show three common Portal/Domino infrastructure options. Single server scenario In this scenario (Figure 1-27), the portal and Domino server run on one machine. Databases from remote servers get replicated onto the local Domino server. This configuration is typical for the WebSphere Portal Express offering, for Proof-of-Concept scenarios, and when maximum performance for getting data out of Domino (avoiding RMI/DIIOP) must be achieved. Figure 1-27 Single server scenario Domino hub scenario In this scenario (Figure 1-28 on page 53), the Domino and Portal servers are separate; a dedicated hub server is used for integration with the portal. 52 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 . Figure 1-28 Domino hub scenario Distributed Domino scenario In this scenario (Figure 1-29), all Domino servers hosting Domino applications are accessed directly from the portal. Figure 1-29 Distributed Domino scenario Chapter 1. Introduction to portalizing Domino applications 53 Looking at the different infrastructure scenarios can help to identify and avoid bottlenecks in the infrastructure. Here are a few checkpoints from a Domino portlet point of view: – Local Domino access is faster than remote access, but limits the scalability to one physical server. – Having a dedicated server to host the Domino applications for the portal makes the performance more predictable and scalable, but introducing a Domino cluster makes the programming more difficult. You then need to handle fail-over and load-balancing yourself. It is important to ensure a fast network connection between the Portal and Domino hub server. – Accessing multiple Domino servers helps with balancing the load, but you need to check whether the Domino servers can handle the extra load from the portlet. Depending on the access method you choose, you might have to load the HTTP or DIIOP task on the Domino server. Bandwidth constraints can also be problematic for portlet performance. 1.9 Authentication Within the following section, we discuss the techniques and concepts related to authentication, including implementing single sign-on (SSO), working with LTPA Tokens, and using Domino LDAP for directory authentication with WebSphere Portal. 1.9.1 Multi-server session-based authentication Multi-server session-based authentication, also known as single sign-on (SSO), allows Web users to log in once to a Domino or WebSphere server, and then access any other Domino or WebSphere servers in the same DNS domain that are enabled for SSO without having to log in again. The portal server provides comprehensive single sign-on (SSO) support. Users want to be able to log on only once, and be known to the different parts of the portal server with the same consistent user credentials. Users should not be asked to do multiple logons simply because they access different portal applications. The portal server supports single sign-on realms using WebSphere Application Server as well as authentication proxies. This means that the user needs to log on only once to gain access to all enterprise applications that are installed within the single sign-on realm. 54 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 With Domino, there are two single sign-on options that you can use: Lightweight Third-Party Authentication Token and credential vault. Lightweight Third-Party Authentication Token This option requires that the WebSphere and Domino server are configured to share an Lightweight Third-Party Authentication (LTPA) session cookie. Using this method has the least impact on your portlet coding, since the SSO process is handled transparently for the developer. It must be pointed out that: URLs issued to servers configured for single sign-on must specify the full DNS server name, not the host name or IP address. For browsers to be able to send cookies to a group of servers, the DNS domain must be included in the cookie, and the DNS domain in the cookie must match the server URL (this is why cookies cannot be used across TCP/IP domains). For a Domino server, authentication information can be shared across multiple Domino domains. WebSphere and Domino should both be configured for the same LDAP directory. The authentication token used for SSO stores the full Distinguished Name of the user (DN), for example, cn=john smith,ou=sales, o=ibm, c=us. To set up LDAP for SSO, Directory Assistance in Domino must be set up and configured to point to an LDAP server that the WebSphere server uses, or, load LDAP on the Domino Directory and configure WebSphere to use the Domino LDAP server. If the group of servers participating in SSO includes WebSphere servers that use a Domino LDAP directory, users with flat names in that directory cannot use SSO (if the participating servers are all Domino, then SSO will work with flat user names). It is recommended that Secure Sockets Layer (SSL) be used to protect the cookie from being intercepted and replayed. Credential vault In the case that, for example, the portal server and the Domino server use different directories or are in different DNS domains, it is necessary to handle authentication manually. WebSphere Portal provides a credential vault mechanism that portlets can use to set and retrieve credentials securely. Chapter 1. Introduction to portalizing Domino applications 55 Understanding the credential vault The credential vault is a repository where credentials are stored. Examples of credentials include certificates, private keys, user IDs, and passwords. The portal administrator can partition the vault into several vault segments. Vault segments can be created and configured only by portal administrators. A vault segment contains one or more vault slots. Vault slots are the “drawers” where portlets store and retrieve a user’s credentials. Each slot holds one credential. The credential vault provided by WebSphere Portal distinguishes between four different types of vault slots: – A system slot stores system credentials where the actual secret is shared among all users and portlets. – A shared slot stores user credentials that are shared among the user’s portlet’s. – A portlet private slot stores user credentials that are not shared among portlets. – A administrative slot allows each user to store a secret for an administrator-defined resource. A vault slot is linked to a resource in a vault implementation, the place where the credentials secrets are actually stored. A vault implementation is the place where users credentials are actually stored. Examples of vault implementations include the WebSphere Portal’s default database vault or the IBM Tivoli Access Manager lock box. The resource within the vault implementation corresponds to an application or back-end system that requires its own authentication. The CredentialVault PortletService returns credentials in form of credential objects. WebSphere Portal differentiates between passive and active credential objects: – Passive credential objects are containers for the credentials’s secret. Portlets that use passive credentials need to extract the secret out of the credential and do all the authentication communication with the back end itself. – The credential classes that are shipped with WebSphere are: 56 • SimplePassive (stores secrets in form of serializable Java objects) • UserPasswordPassive (stores secrets in the form of user ID / password pairs) • JaasSubjectPassive (stores secrets in the form of a javax.security.auth.Subject object) Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Active credential objects hide the credential’s secret from the portlet; there is no way of extracting it out of the credential. In return, active credential objects offer business methods that take care of all the authentication. The credential classes that are shipped with WebSphere are: – HttpBasicAuth stores user ID / password secrets and supports HTTP Basic Authentication. – HttpFormBasedAuth stores user ID / password secrets and supports HTTP Form-Based Authentication. – JavaMail stores user ID / password pairs and leverages the authentication functionality of the javax.mail API. – LtpaToken is a credential object for authenticating with a back-end system that is within the same WebSphere Application Server SSO domain as the portal) – SiteMinderToken is a credential object for authenticating with a back-end system that is within the same SiteMinder SSO domain as the portal. This credential should be used when SiteMinder is used as an authentication proxy for the portal. – WebSealToken is a credential object for authenticating with a back-end system that is within the same WebSEAL SSO domain as the portal. This credential should be used when a WebSEAL authentication proxy is used by the portal. 1.9.2 Using Domino LDAP with WebSphere Portal WebSphere Application Server uses LTPA tokens to provide SSO. When a user is authenticated, the portal server creates an LTPA SSO cookie containing the authenticated user credential. This encrypted cookie conforms to the format used by WebSphere Application Server and can be decrypted by all application servers in the shared domain, provided they all have the same cipher key. This cookie enables all servers in the cluster to access the user’s credentials without additional prompting, resulting in a seamless SSO experience for the user. To benefit from the LTPA method of SSO, the user’s browser must support cookies and have its support for session cookies enabled. The portal server can be configured to use Domino as its LDAP directory. The configuration process is explained in detail in the section entitled “Configuring Domino LDAP” in the Portal InfoCenter, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html#i c5 Chapter 1. Introduction to portalizing Domino applications 57 Here are just a few hints that are useful: The users WPSADMIN and WPSBIND must be created in the Domino directory. Also, the group WPSADMINS must be created, and WPSBIND and WPSADMIN must be group members. The group WPSADMINS must have proper permissions and roles in the ACL of NAMES.NSF. The correct LDAP settings in the global configuration document must be specified. When using collaboration portlets, ensure that the list of fields that can be queried by anonymous users has been extended. When installing a portal, the following settings for the LDAP must be used: user prefix="cn" user suffix="o=yourco.com" group prefix="cn" group suffix="" Portal administrator DN = "cn=wpsadmin,o=yourco.com" Portal administrator group = "cn=wpsadmins" When installing WebSphere Application Server-Domino SSO, ensure that the field for the LDAP server name in the Domino SSO document has been changed. There must be a backslash after the colon and before the Port number. 1.10 Development options To put the portlet development/building technology described in this book in context, you must understand the options available for accessing and building portlets for Domino using WebSphere Portal. The positioning includes categorizing the available options in terms of the skill level required to produce a portlet. Chapter 2, “Integration techniques” on page 69 will discuss, in detail, what the listed tools, toolkits, SDKs, and builders are all about. 1.10.1 Target audience The overview below outlines the target audience integrating Domino within WebSphere Portal via portlets: Line of business and power users Line of business and power users normally know about the business 58 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 processes, but have limited background in developing Domino or J2EE applications. Mid-level script developers Mid-level script developers have knowledge about developing Domino applications, but are limited in developing J2EE applications. Professional Domino/J2EE developers Professional Domino/J2EE developers have a broad knowledge about Domino development and J2EE. 1.10.2 Development environments When dealing with Domino and WebSphere, the recommended development environments are: Domino Designer® It is important to highlight that you should always (when possible) use the latest version in order to have the most recent tool support. WebSphere Studio WebSphere Studio is a development environment based on Eclipse. By using plug-ins to extend the functionality, all J2EE development can easily done with it. Some of these plug-ins are: – WebSphere Portal Toolkit – Lotus Domino Toolkit for WebSphere Studio Third-party Java development environments It is possible to use existing Java development environments (like Borland’s JBuilder and so on). Builders Builders are used to reducing the development effort by having a tool/environment where the development will be made. The code creation will be done “on the fly”. 1.10.3 Development tools Depending on different factors (complexity of the solution, skill set, and so on), several options are available. Existing portlets IBM Lotus Notes/Domino and Extended Products Portlets V6.5.1. (and subsequent versions) – Domino Web Access (formerly iNotes™) – Domino Applications (DAP) Chapter 1. Introduction to portalizing Domino applications 59 – Lotus Domino Document Manager (formerly Domino.Doc®) – Lotus Notes Discussion – Lotus Notes Mail – Lotus Notes Teamroom – Lotus Notes View – Lotus Web Conferencing (formerly Sametime) – Lotus Web Conferencing Contact List (formerly Sametime Contact List) – My Lotus Notes To Do – My Lotus Team Workplaces (formerly QuickPlace) – People Finder – Sample pages Common PIM Portlet Common Calendar Portlet Lotus Team Workplace XML helper and RSS portlets Web Clipping portlet Web page portlet (iFrame) QuickLinks portlet Domino JSP tag libraries Lotus Domino Toolkit for WebSphere Studio Builders WebSphere Portal Application Integrator (WPAI) – For Domino (also known as IBM Portlet Builder for Domino) Bowstreet Portlet Factory for WebSphere Workplace builder Conet Knowledge Director V3.0 for WebSphere Portal Developing using Java Domino Java API IBM portlet API JSR 168 portlet API 60 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 JSF portlet framework Struts portlet framework Lotus Workplace API 1.10.4 When to use a specific integration approach The big question for involved developers is what tool to use to get the Domino application integrated with WebSphere while balancing the following two goals: Achieving integration as fast as possible Minimal development effort The authors of this redbook cannot answer that question directly. This redbook should help you make an informed decision about the possible options, but it always depends on the specific requirements, the staff, and the time frame. Finally, one of the key questions asked by Domino developers with limited knowledge of Java is: “Which option for integration/portalizing Domino applications is the best starting point?” Additionally, developers are constantly trying to balance the following two goals: Achieving integration as fast as possible Minimal development effort The answer about which integration option to choose does not have such a simple answer, since it is influenced by each individual application and available skills. At the very least, however, this next section will help provide a greater context of what integration option may be best suited, relative to the other technical approaches for integrating Domino and Portal. Figure 1-30 on page 62 gives an overview of all the available options to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. Depending on the knowledge of developing portlets (or Java applications in general) (shown vertically) and the level of customization needed when integrating (shown horizontally), numerous options are available. Chapter 1. Introduction to portalizing Domino applications 61 high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 Bowstreet Portlet Factory / Conet Knowledge Director 2 1 IBM Portlet Builder for Domino limited Existing Portlets 4 Lotus Workplace Builder low Level of customization high Figure 1-30 Integration options The main message to take from this graphic is that there are numerous different options to choose from - each integration represents some degree of a trade-off of development skills and degree of customization required. For example, utilizing the existing Portlets approach (Box 1) represents an excellent option for solutions in which only a minimal degree of customization is required. On the other hand, using the Domino Java API (Box 6) allows for a high degree of customization, but requires advanced Java knowledge. Finally, keep in mind that depending on the solution you need, a combination of several options may be required. For example, if portlets built by the IBM Portlet Builder for Domino need to be “fine-tuned”, it may be necessary to use Domino JSP tags or to use the Domino Java API. Attention: Each of the integration approaches is detailed in subsequent chapters. 62 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Here are the key points from each integration approach: 1. Existing portlets – To use the existing portlets, relatively little J2EE knowledge is necessary. The portlet can be selected from the portlet catalog. – Only simple information must be entered (Domino Server name, database name, and so on). – Existing portlets offer only a very limited set of functionality for customizing. – Existing portlets will most likely be used by line of business and power users. . Note: Chapter 3, “Using existing portlets” on page 93 provides a full description of this development option. 2. Lotus Workplace Builder – The Lotus Workplace Builder offers the user with limited J2EE knowledge the possibility to integrate a set of portlets into Lotus Workplace. – Only simple information must be provided to build the workplace content. – The Lotus Workplace Builder will be used by line of business and power users. Note: Chapter 8, “Integration with Lotus Workplace” on page 687 provides a full description of using the Lotus Workplace Builder as an integration technique. 3. IBM Portlet Builder for Domino The IBM Portlet Builder for Domino provides a complete and rapid integration tool to bring valuable Domino-based information and data into WebSphere Portal. It is a portlet that creates other portlets that are tuned to specific tasks, databases, or sets of databases. IBM Portlet Builder is a subset of WebSphere Portal Application Integrator (WPAI) technology. The target audiences are line of business and power users. Note: Chapter 7, “Portlet builders” on page 591 provides a full description of the Portlet Builder development option and its integration techniques. Chapter 1. Introduction to portalizing Domino applications 63 4. Bowstreet Portlet Factory – The Bowstreet Portlet Factory is a third-party portlet building tool. It is comparable to the IBM Portlet Builder for Domino, but has more possibilities for building and profiling portlets. – The target audiences are line of business and power users, and developers who want to reduce time in creating portlets. Note: Chapter 7, “Portlet builders” on page 591 provides a full description of the Portlet Builder development option and its integration techniques. 5. Domino JSP tags The Lotus Domino Toolkit for WebSphere Studio is a plug-in for WebSphere Studio Application Developer and WebSphere Studio Site Developer. It allows you to add Domino 6 custom tags to Java server pages (JSP), providing a simple way to blend Domino and J2EE applications. JSP tags are XML tags embedded in a JSP, providing data access, data input, and process control. The tags abstract the Domino objects for Java (Domino Java API) and provide a quick development turnaround for building J2EE applications that use Domino data and services Domino JSP tags can be used for building portlets alone or to extend portlets created with a builder. The target audience are Java language developers and Domino developers with Java language skills. Note: Chapter 4, “Using custom Domino JSP Tag libraries” on page 175 provides a full description of this development option and its integration techniques. 6. APIs There are many APIs that can be used to create portlets for accessing Domino data. The target audience are Java language developers and Domino developers with strong Java language skills. Note: Chapter 5, “Portlet development using Java: Technology review” on page 313 provides a description of the Java development option and its integration techniques. Chapter 6, “Portlet development using Java: Integration examples” on page 391 provides integration examples using Java APIs and portlet frameworks. 64 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 When coming back to the target audience, the summary below distills the seen options to integrate Domino within WebSphere Portal via portlets, sorting by target audience. Options for line of business and power users Use the out-of-the-box Notes/Domino. Use the Lotus Workplace Builder. Use the IBM Portlet Builder for Domino. Figure 1-31 gives an overview of the options. Figure 1-31 Options for line of business and power users Options for mid-level script developers Use the IBM Portlet Builder for Domino. Use the Bowstreet Portlet Factory. Use Domino JSP tags (Domino Toolkit for WebSphere Studio). Figure 1-32 on page 66 gives an overview of the options. Chapter 1. Introduction to portalizing Domino applications 65 Figure 1-32 Options for mid-level script developers Options for professional Domino/J2EE developers Use Bowstreet Portlet Factory. Use Domino JSP tags (Domino Toolkit for WebSphere Studio). Use APIs. Figure 1-33 gives an overview of the options. Figure 1-33 Options for professional Domino/J2EE developers 66 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1.11 Summary This chapter outlined the workplace vision in general, then focused more specifically on the integration of Lotus Domino with WebSphere Portal and Lotus Workplace. It is clear that the integration of existing Lotus Domino applications is an extremely important issue for a large number of customers. We showed that existing Domino applications can be reused and exposed inside of the portal, allowing the display of existing information in new context. Bringing together Lotus Domino and WebSphere Portal enables all types of users building a new class of hybrid applications. The outline of the portal architecture offers users and developers new to J2EE what’s “behind” the scenes of WebSphere Portal. This chapter also tried to help you understand the integration challenge and how to choose an appropriate integration technique and development approach for given Domino applications within WebSphere Portal. In the following chapters of the book, we will examine the variety of Domino integration options, as seen in Figure 1-34, in greater detail. Figure 1-34 Set of integration options Chapter 1. Introduction to portalizing Domino applications 67 68 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 2 Chapter 2. Integration techniques This chapter provides an overview of the detailed integration techniques available for portalizing a Domino application. It also provides a guide to help you determine the best integration technique for your project. The chapter concludes with the introduction of a fictitious Domino application case study that will be used in subsequent chapters to provide examples of how to implement each integration technique. © Copyright IBM Corp. 2005. All rights reserved. 69 2.1 Choosing an integration technique As outlined in the previous chapter, there are four main issues to consider when choosing an integration technique: Domino applications: The characteristics of the Domino applications Integration techniques: Knowledge of all the different options Portlet pattern: Concrete requirements for the portlet Conditions: Overall project parameters, such as resources, skills, and so on Each of these issues must be addressed to ensure the successful integration of a Domino application into a useful component of WebSphere Portal. Each issue has many complex and potentially competing factors that must be considered. This can make it difficult to identify the integration technique that best satisfies the conditions at hand. 2.1.1 Project considerations While every project is different, the use of a structured approach can help reduce the complexity of this decision-making process. The following sections detail a four-step approach to identify the appropriate integration technique. These steps are: 1. Pre-project preparation and training 2. Identification of project requirements 3. Selection of an appropriate portlet pattern 4. Selection of an appropriate integration technique 2.1.2 Step 1: Pre-project preparation and training Issues addressed: Portlet patterns Integration techniques Description: Before starting a portal integration project, it is essential to obtain as much information and training as possible. Focus on understanding the portal patterns and integration techniques, keeping in mind that staff involved in an integration project must be familiar with the skills and technologies for implementing each technique. 70 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 When learning new technologies, there is no substitute for hands-on training and experience. The sample in this redbook is a guide through the various options of integration. 2.1.3 Step 2: Identification of project requirements Issues addressed: Domino application Conditions Description: While in the requirements gathering phase of an integration project, obtain the Domino application characteristics described in 1.6.3, “Domino applications” on page 37. It is important to have a solid understanding of the application design, size, performance, and usage patterns before you recommend a portlet pattern or integration technique. The project budget, the skill set of the development team, and the application environment details (including SSO, software versions, and so on) can each play a significant role in your final decision. Finally, identify specific functional requirements that your portlet will be required to perform. These requirements may affect your selection of an integration technique. Together, the Domino application characteristics, project considerations, and functional requirements define the capabilities that the selected integration technique for this project must be able to implement. 2.1.4 Step 3: Selection of an appropriate portlet pattern Issues addressed: Portlet pattern Description: Use the customer’s functional requirements to identify the best portlet pattern for this application. Table 2-1 on page 72 summarizes some of the main advantages and disadvantages of each portlet pattern. A detailed description of each portlet pattern can be found in 1.7, “Portlet patterns” on page 42. Chapter 2. Integration techniques 71 Table 2-1 Portlet pattern advantages and disadvantages Portlet pattern Advantages Disadvantages Link Quick and easy. Accesses existing applications. No modifications to existing functionality. This is a simple Web link from a portlet. No content or functionality is available within the portal framework. Display Minimal enhancements to existing application functionality. Optional link outside portal to access existing application for more advanced functionality. Minimal or no application functionality within the portal framework. Integrated Significant functionality within the portlet. Requires more development time and might be more difficult to implement. Migrated Full application functionality within the portlet. The most technically challenging and resource-intensive to implement. 2.1.5 Step 4: Selection of an appropriate integration technique Issues addressed: Integration technique Description: Identify one or more integration techniques that will work well with the portlet pattern chosen in the previous step. Guidelines for this process are in the next section. Once the set of candidate integration techniques has been identified, compare each integration technique with the considerations identified in Step 2: Identification of project requirements. If none of the integration techniques satisfies all of the considerations for this application, identify the restricting factors that are feasible to change. While every project is different, some of the more flexible factors tend to be: estimated development time, developer skill set, and non-functional requirements. You may also consider a less complex portlet pattern. Some examples of factors that may be more difficult to change are: performance requirements and Domino application characteristics (database size, usage patterns, and so on). Once an integration technique that satisfies all project parameters has been identified, the first and most important step in the process is complete. You are now ready to design, develop, and deploy your portal application. 72 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Considerations: Table 2-2 outlines many of the considerations that will influence your integration technique selection. In the following chapters, the outline of each integration technique includes a brief discussion of each of these considerations. This will prove useful when comparing and contrasting the available techniques Table 2-2 Considerations for integration technique selection Consideration Description Portlet patterns The portlet pattern or patterns most compatible with this integration technique. Development time Relative time/resources required to implement this integration technique. Developer skill set The technologies with which developers must be familiar to implement this integration technique. Range of application functionality The degree of control a developer has over the portlet features and functionality when implementing this technique. Handle rich text Can portlets implementing this technique easily display or edit the content of rich text fields? Performance and scalability How well do applications using this integration technique scale? Is session pooling used for Domino sessions? Can this technique be used in a clustered environment? Requires single sign-on Does this implementation technique require that single sign-on be enabled between WebSphere Portal and Lotus Domino servers? Required software versions Versions of server and development software are required to implement this technique? 2.2 Integration techniques and development options Developers wishing to expose Domino content and functionality within a portal environment have many integration techniques at their disposal. The integration techniques presented in this book have been categorized into four main groups, called development options. These development options are: 1. Using existing portlets 2. Domino JSP tag library 3. Java 4. Portlet builders Chapter 2. Integration techniques 73 The integration techniques within each development option share many similar characteristics. These characteristics include: The technologies and technical skill set required for implementation Development time The developer’s level of control over the application functionality This section provides a brief overview of the characteristics of each development option and outlines the integration techniques found within each option. Further details and implementation examples are provided for each option in subsequent chapters. 2.2.1 Using existing portlets Note: Chapter 3, “Using existing portlets” on page 93 provides a full description of this development option. Description There are many general-purpose portlets provided with WebSphere Portal that can be used to access Domino applications. Other general purpose portlets are available from third-party sources. If a portlet is available that meets your Domino application’s needs, this is the most expedient option. Advantages Using an existing portlet is by far the simplest option to implement and requires the least amount of development time. Developers do not need to be familiar with Java or WebSphere Portal, or often even Domino development technologies, to implement this option. Limitations The developer is limited to the functional capabilities provided by the portlet being used. Customizing the functionality of an out-of-the-box or third party portlet is not always possible. 2.2.2 Domino JSP tag libraries Note: Chapter 4, “Using custom Domino JSP Tag libraries” on page 175 provides a full description of this development option and its integration techniques. If the functionality provided by existing portlets is not adequate for your Domino portal integration requirements, the Domino JSP tag library provided in the 74 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Domino Toolkit for WebSphere Studio is a good option to consider. JSPs and the Domino JSP tag library provide a rich set of development options that are quicker and easier to implement than the Java development option discussed in Chapter 5, “Portlet development using Java: Technology review” on page 313. JSP Tag Libraries provide developers with a quick and easy technique for giving a Web application the ability to incorporate complex Lotus Domino interactions, simply by adding custom Domino JSP Tags to a JSP page. Because the WebSphere Portal framework and JSPs are both based on J2EE environment, a developer can easily use Domino JSP tags to expose Domino data and functionality in a WebSphere Portal portlet. Enhancements Great enhancements have been made to the latest Domino Toolkit for WebSphere Studio V1.3: Session management (for connections to Domino) Object pooling Applicable portlet patterns Link and display portal patterns can be implemented using the JSP tags, but are often more easily implemented using techniques described earlier in this chapter. Generally JSP tags are used when implementing integrated and migrated portlets. A great number of options and techniques are available to the developer. Some of the options are: J2EE development JSPs JSP tags Custom Domino JSP tags Click-to-Action Collaborative components Chapter 2. Integration techniques 75 2.2.3 Developing Domino portlets using Java Note: Chapter 5, “Portlet development using Java: Technology review” on page 313 provides a description of the Java development option and its integration techniques. Chapter 6, “Portlet development using Java: Integration examples” on page 391 provides integration examples using Java APIs and portlet frameworks. Java is the base programming language, ultimately used by all portlets running on WebSphere Portal. A number of options and techniques are available to the Java developer. Some of the options are: Domino Java API IBM Portlet API JSR 168 Portlet API Struts framework Java Server Faces (JSF) framework In some cases the disadvantages of developing in Java are that Java programming skills and portlet programming skills are required, and the development time can be a longer than for other integration techniques. However, a major advantage when developing applications in Java is that it allows maximum flexibility and it gives the developer total control of all aspects of the application. 2.2.4 Portlet builders Note: Chapter 7, “Portlet builders” on page 591 provides a full description of the Portlet Builder development option and its integration techniques. This option covers the tools and technologies available in the marketplace that attempt to bridge the gap between the limitations of the use of existing portlets and the complexity of the custom Java development options. It focuses on the technology offerings from vendors including IBM, Bowstreet, Conet, and others. Portlet builder technologies provide a “middle-ground” approach to portlet development. They offer significantly more development capabilities than the use of existing portlet option. In addition, they promise a shorter development time 76 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 and require less in-depth knowledge about custom portlet development than the more advanced custom development options of JSPs and Java. The portlet builders that are included in our detailed discussion in Chapter 6, “Portlet development using Java: Integration examples” on page 391 are: IBM Portlet Builder for Domino Bowstreet Portlet Factory for WebSphere Conet Knowledge Director V3.0 for WebSphere Portal These tools vary in capability, development approach, user interface and capabilities. 2.2.5 Integration with Lotus Workplace Note: Chapter 8, “Integration with Lotus Workplace” on page 687 provides a full description of the options and techniques for integrating with Lotus Workplace. This option examines possible ways of integrating and extending a Domino portlet or application to leverage some of the feature of Lotus Workplace. As with other techniques for integrating Domino applications with Portal, there are several ways to approach integration. We start by looking at some simple ways to deploy a portlet into Workplace. We illustrate how to use the Workplace Builder to customize a Lotus Workplace application. We then move on to some more advanced integration techniques utilizing the Lotus Workplace Products API Toolkit. 2.3 Case study: A simple sales tracking application The remainder of this redbook discusses each development option and integration technique in greater detail. To facilitate this discussion, a sample application is used throughout the book to provide examples of how to implement each technique. This sample application is available for download from the IBM Redbooks Web site. For information about how to download this software, see Appendix C, “Additional material” on page 741. Note: This application is intended only to provide portlet migration examples. It is not intended for use in a production setting. Chapter 2. Integration techniques 77 2.3.1 Case study overview The fictitious company Widget Corp. is using Lotus Domino to support the sales department. Over the years they have built a sales tracking application to help their sales force track interactions with their customers. The databases can be accessed from a Notes client or a Web browser. There are two main databases in the sales tracking application: the Customers database and the Sales database. Figure 2-1 and Figure 2-2 on page 79 illustrate the user interface when accessed from Lotus Notes. A third database, Products, is used for product keywords and is not accessed directly by the sales force. Figure 2-1 The Lotus Notes interface for the Sales Tracking Application Sales DB 78 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 2-2 The Lotus Notes interface for the Sales Tracking Application Customers DB There are five main types of documents used by this application. They are defined in Table 2-3. Table 2-3 Document types used by the example Sales Tracking Application Document type Database Description Customer Customers.nsf An organization that is a customer or potential customer of Widget Corp. Customer contact Customers.nsf An employee of a Widget Corp. customer who is responsible for a purchasing decision. Product Products.nsf A product sold by Widget Corp. Sales person Sales.nsf A member of Widget Corp.’s sales force. Sales activity Sales.nsf A document tracking a specific interaction between a Sales Person and a Customer Contact. Chapter 2. Integration techniques 79 2.3.2 Case study objective: Sales Workplace Widget Corp. has decided to build a Sales Force Workplace using WebSphere Portal. On the workplace, they would like to expose the content of the Domino databases that are related to the sales process. They also want to use the portlet’s cooperation functionality to create a seamless user experience. Their vision is to present the sales person all the information available on a given customer in context with the products the customer buys and the most recent sales activities with that customer. In addition, they want to use people awareness to allow better communication between the different sales people. 2.3.3 Case study: Application details The following section describes the characterstics and functionality of the application. We describe the relationships between documents, the primary user roles, typical use cases, and specific technical functionality to be included. Relationships The relationships between document types in this application are defined in Table 2-4. Table 2-4 Relationships between the record types in the sample application First Document Relationship Second Document Key Customer 1 to many Customer Contact Customer Number Sales Person 1 to many Customer Employee Number Sales Person 1 to many Sales Activity Employee Number Customer Contact 1 to many Sales Activity Contact Name Product 0-3 to many Sales Activity Product Number User roles The application is designed for two types of users, as identified in Table 2-5. Table 2-5 User roles 80 User type Access rights Access method Sales person Author access to all databases. Rights to create Customer, Customer Contact, and Sales Activity documents. No deletion rights. Notes client or Web browser Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 User type Access rights Access method Application owner Full rights to create, edit, and delete all record types. Notes client Use cases Table 2-6 summarizes the ways in which sales people interact with the system. Many of these use cases are good candidates for use within a portal Environment. Table 2-6 Use cases for the sales person role Activity Use case Document creation Create customer document Create customer contact Create sales activity document Document edit Edit customer document Edit customer contact document Edit sales activity document Edit sales person document View/Lookup/Search documents Customers by name Customer contacts by Name Customer contacts by customer Sales people by name Sales activities by sales person Sales activities by customer Sales activities by customer contact Sales activities by date Delete documents None Application owners have a super-set of the rights given to sales people. Table 2-7 summarizes the additional rights application owners have to the system. While technically feasible, there is a lower business need to provide this functionality in a portal environment. Table 2-7 Additional use cases for the application owner role Activity Use case Document creation Create sales person document Create product document Document edit Edit product document Chapter 2. Integration techniques 81 Activity Use case View/Lookup/Search documents Products by name Products by number Delete documents Delete all record types Additional application functionality In order to provide an example as close to the real world as possible, this application uses many development features used by the majority of Notes/Domino applications. These include: Keyword lists based on @DbLookups and other @Functions. Input validation and input translation formulas. Computed fields, hidden fields, and shared fields. Hide-when formulas based on keyword changes. A page with an embedded outline for the sales and customer databases to maintain consistent feel with cross-database navigation. Links between related documents from a Web browser. For example, a sales activity record has links to the corresponding customer and sales person records. Use of $$Return field on document save. Rich text for additional information. Action buttons with hide-when formulas on forms. Use of sections. Use of subforms. Categorized, sorted views. Full-text indexed databases. Data dictionary A complete description of the fields in each document type can be found in Appendix B, “Data dictionary for case study” on page 735. 82 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 2.4 Deploying the case study portlets Instructions for downloading case study Domino databases and many of the portlets used throughout this book can be found be found in Appendix C, “Additional material” on page 741. The Domino databases should be added to the /apps/ subdirectory of your Domino server. Verify that you have set Anonymous & Default access to at least editor, or that you have granted known user IDs with at least editor access. Complete the following tasks to deploy the portlets: 1. Install the portlet WAR file. 2. Create a place for the demo portlets. 3. Create pages in this place to hold the various demo portlets. 4. Add the pages to this place. 5. If needed, configure the portlets. The remainder of this section presents the detailed steps for performing each of these tasks. 2.4.1 Install portlets To install a portlet, a Web archive (WAR) file for the portlet must exist in a local directory. The install process uploads the WAR file to the server, installs the portlet, adds it to the portlet catalog, and activates the portlet. Perform the following steps to install a portlet: 1. Enter the portlet's location in the Directory field. You can also use the Browse button to navigate your file system (see Figure 2-3 on page 84). 2. Select the portlet WAR file you want to install. Chapter 2. Integration techniques 83 Figure 2-3 Browse for WAR file 3. Click Next to begin the installation process. 4. A confirmation appears that lists the portlets included in the WAR file (see Figure 2-4). Click Install to begin the installation. Click Cancel to return to Install Portlets. Figure 2-4 Check for the portlets that will be installed 84 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5. When installation is complete, you are returned to Install Portlets, and a message confirming success or failure is displayed. A successful installation indicates that the portlet has been added to the portlet catalog and activated. To allow others to use this portlet, you must set the access rights for it. Note: You must be assigned a MANAGER or ADMINISTRATOR role to install portlets. 2.4.2 Creating a label From the Portal Manage Pages tab, you can create a label to act as a separator. Labels can be used to help organize groups of pages, places, and URLs into categories. To create a new label, perform the following steps: 1. Click New label to create a new label. You will leave Manage Pages to create the new label (see Figure 2-5 on page 86). Chapter 2. Integration techniques 85 Figure 2-5 Manage label 2. Type the title of the new label in Title. This is the title for the default locale. Select Theme to determine the look of the new label (see Figure 2-6 on page 87). Continue to the next step to set advanced options. If you do not want to set advanced options, click OK to save the new label or Cancel to discard the label settings and return to Manage Pages. Click Advanced options to view optional settings in this section. Check supported markup from This page supports. Click OK to save these settings for the new label. Click Cancel if you want to return to Manage Pages without creating the new label. 86 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 2-6 New label 2.4.3 Creating a page You can create a new page under an existing page, reference an existing page, apply a layout, and select supported markups. For public pages, you must have the Administrator, Manager, or Editor role assignment. For private pages, you must have the Administrator or Privileged User role assignment. When you create a page, you always have the option to create a new page with a new layout. You may create a derived page to a derivation parent page if you have the Editor and Privileged User role assignment. If you have: Editor role on the derived page: You may change anything except markups. Privileged User role on the derived page: You may change the title, skins, or layout on the derived page. For layout, this is restricted by the derivation parent page. If you reference an existing page, layout, supported markups, locks, skins, portlet list, and locale specific titles are predetermined by the existing page you reference. Any changes to the original page results in the same change to all pages that are referenced. When creating a new page, you may give it a title. All other settings are optional. Chapter 2. Integration techniques 87 To create a new page, perform the following steps: 1. Click New Page to create a new page. You will leave Manage Pages to create the new page (see Figure 2-7). Figure 2-7 New pages 2. Type the title of the new page in Title. This is the title for the default locale. Select Theme to determine the look of the new page. 3. Click Advanced options to view optional settings in this section. 4. If you want to allow this page to be bookmarked by other users, check This page can be added to a user's My favorites list. If a user bookmarks this page, it will be available from My favorites in the banner. 5. Check The contents of this page can be shared by other pages if you want this page to be shared by others. If checked, users can reference this page when they create a new page. 6. Determine page layout by selecting an option from A content page with these properties. 7. If you want the new page to reference an existing page, check A page which uses content from a shared page and choose a shared page to reference. 88 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 2-8 New page 8. Click OK to save these settings for the new page and add new content. Click Cancel if you want to return to Manage Pages without creating the new page. 2.4.4 Adding portlets to a page Portlets are added to the page by submitting a search and then selecting from the list of available portlets; only portlets available in the portlet list can be placed on the selected page. Once you place a portlet in a row or column, you cannot modify the row or column without removing all portlets from that container. Each container is outlined. Use the following steps as a guide for customizing the page content. Click the Edit Page Layout icon (Figure 2-9). Figure 2-9 Edit Page Layout Chapter 2. Integration techniques 89 9. Click Add portlets in the container where you want the portlets located (Figure 2-10). Figure 2-10 Edit Layout 10.In the drop-down, select one of the search properties and enter your search terms in the field provided. You can search for all portlets, or you can search by title, description, keyword, last modified, or unique name. 11.Click Search to display the search results. A list of available portlets is displayed in the search results. The results may span multiple pages. 12.Place a check next to the portlets you want to place on the page. Click OK to place these portlets to the page or click Cancel to return to Edit Layout (Figure 2-11 on page 91). 13.In our example, we added Lotus Notes View to the left side of the page (left column container), as shown in Figure 2-12 on page 91. Click Done. 90 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 2-11 List of portlets Figure 2-12 Added portlet Chapter 2. Integration techniques 91 To test how the portlets are laid out on your page: 1. Select your Label. In our example, we selected My Domino Workspace. 2. You will see a page Lotus View. This is the available page in our Portal. 3. Select the Lotus View page and you should see a window like that shown in Figure 2-13. Figure 2-13 Portlets 4. The Lotus Notes View portlet is displayed on the left side of the page and it is not configured yet. Chapter 3, “Using existing portlets” on page 93 provides a full description of this configuration process. 92 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3 Chapter 3. Using existing portlets This chapter introduces the collaborative Lotus Notes/Domino and Extended Products Portlets. It provides a detailed description of the Extended Products portlets first packaged with Domino V6.5.1, while also introducing the Domino Application Portlet. For the Domino Application Portlet (DAP), we provide a detailed overview of its functionality and discuss how to configure it. Finally, the chapter also addresses several common Domino based portlets that ship with WebSphere Portal to access Domino data. The portlets we discuss include those originally introduced as Collaboration Center, including the People Finder portlet, My Team Workplaces portlet, and the Lotus Web Conferencing portlet. For each of the portlets, we provide instructions for installing and configuring the portlets on the WebSphere Portal server and demonstrate how you can use the ‘out of the box’ portlets to provide a fully functional, well integrated collaborative environment. The outline of this chapter is as follows: Overview Integration techniques and overview of portlets Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way Integration Option 2 - The Domino Application Portlet Integration Option 3 - using specific Portlets Reference material © Copyright IBM Corp. 2005. All rights reserved. 93 3.1 Overview The integration option described in this chapter relies on using existing pre-packaged portlets to integrate existing Notes and Domino applications into the WebSphere Portal environment. Depending on the extent of your Notes and Domino applications, the techniques described in this chapter may provide a quick and effective option for integration into the portal environment. The programming skills required to use these techniques are minimal, and with some portlets, no programming skills are needed. Basic WebSphere Portal administration skills are needed. It is helpful to have Notes and Domino development skills to be able to recognize which options are beneficial, but it is not crucial. 3.1.1 Skills and degree of customization - Pre-packaged portlets Figure 3-1 on page 95 gives an overview of using the “existing portlets” integration option, relative to all available options, to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. Utilizing the existing portlets approach (Box 1) represents an excellent option for solutions in which only a minimal degree of customization is required, and where a high degree of Java skills may not be available. 94 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 Bowstreet Portlet Factory / Conet Knowledge Director 2 1 IBM Portlet Builder for Domino limited Existing Portlets 4 Lotus Workplace Builder low Level of customization high Figure 3-1 Integration options 3.1.2 Technologies involved This option provides relatively simple techniques to integrate existing Notes and Domino applications into WebSphere Portal. There may be existing Notes and Domino applications that would not benefit from these technologies. The technologies presented involve taking Web-enabled data that is being generated in Domino and linking to or displaying this data using existing portlets in the portal environment. WebSphere Portal, as a complete portal solution, provides customers with integrated content and applications. It represents a unified, collaborative electronic working environment. Domino is a comprehensive application platform and customers have invested heavily to exploit the power of Domino in developing proprietary applications. As a result, they are understandably reluctant to start again with new or additional development in order to move towards the benefits of a Portal environment. The main question asked by such customers is “how do we move our Domino Applications into Portal?”. As we will explain in this chapter, pre-packaged collaborative portlets that ship with Domino Chapter 3. Using existing portlets 95 V6.5.x, as well as those which ship with WebSphere Portal V5.02, provide significant capabilities to expose existing Domino applications through Portal. More importantly, the Domino Application Portlet (DAP) provides excellent solution to render an existing Web-based Domino application within Portal. It facilitates the easy integration of Domino Web Applications into Portal Server. Attention: While 3.4, “Integration Option 2 - The Domino Application Portlet” on page 122 covers the basics of how to install and configure the Domino Application Portlet, you may also find more in-depth information in the Redpaper IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html 3.1.3 Software and tools used This section provides a brief description of the software and tools that are used in the implementation of the techniques included in this option. The software and tools used are as follows: WebSphere Portal Lotus Domino Lotus Team Workplace (QuickPlace) Lotus Instant Messaging and Web Conferencing (Sametime) Lotus Domino Document Manager (Domino.Doc) Domino Web Access (iNotes) WebSphere Portal The base requirement for this option is a fully installed, configured, and running WebSphere Portal Server V5.0.2.2 environment, including the supporting infrastructure. This base environment will include an LDAP authentication directory (which in the case for this book is Domino), for use by WebSphere Portal. In addition, the Lotus Notes and collaborative portlets must also be installed. A properly configured WebSphere Portal is vital for communication to the Domino server. Notes and Domino A fully installed, configured, and running Domino Server V6.5.3 is a base requirement for this option. A workstation Notes client should be included, because some techniques link to the supporting Notes client. Applicable versions are identified in the integration techniques section of this chapter. 96 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Lotus Team Workplace (QuickPlace) A fully installed, configured, and running IBM Lotus Team Workplace (QuickPlace) V6.5.1. QuickPlace is a self-service work space expressly designed for team collaboration. With Lotus Team Workplace, users can instantly create secure work spaces on the Web, providing them with a "Place" to coordinate, collaborate and communicate on any project or ad hoc initiative. Lotus Instant Messaging and Web Conferencing (Sametime) A fully installed, configured, and running IBM Lotus Instant Messaging and Web Conferencing (Sametime) V6.5.1. Sametime is IBM's product and platform for real-time collaboration. It is based upon three on-demand concepts: Presence awareness: You can see in advance whether a person(s) or application(s) is online and available to collaborate, share information, or take action. Instant messaging: Be able to converse and communicate in real time through the exchange of text-, audio-, or video-based information. Web conferencing: Participate in online meetings, allowing you to share information, an application, or an entire desktop, or engage in team white boarding. Lotus Domino Document Manager (Domino.Doc) A fully installed, configured, and running IBM Lotus Domino Document Manager (formerly called Lotus Domino.Doc). Domino.Doc is a ready-built solution for organizing documents for shared access by work teams. It manages versions so that each team member has the latest version and automates document-driven processes like review and approval, assembly and publishing, archiving, and records management. 3.2 Integration techniques and overview of portlets This option includes techniques that enable data from Notes and Domino applications to be accessed via existing portlets that are included with WebSphere Portal. Our examples are based on an existing Notes and Domino application that resides in the apps subdirectory of our Domino server. The application includes two Web-enabled databases: Sales Reporting (Sales.nsf) Customers (Customers.nsf) as well as an internal look-up database called Products (Products.nsf). Chapter 3. Using existing portlets 97 The databases contain design elements that can be accessed through a Web browser as well as through the Notes client. The application and these databases are described in detail in 2.3, “Case study: A simple sales tracking application” on page 77. Each of these databases included in the sample application is also included as an Additional Material, available for download. (See Appendix C, “Additional material” on page 741.) We also discuss the most commonly known collaborative portlets that provide access to a variety of Notes and Domino -based applications, such as e-mail, calendar, to-do list, discussion, team room, contacts, and notebook. Additionally, we address the Domino Extended Products portlets which access Lotus applications, such as knowledge management, instant messaging, QuickPlaces, and document management. Finally, we address the “Collaboration Center” portlets, namely People Finder, My Team Workplaces, and Lotus Web Conferencing. The following tables (Table 3-1 and Table 3-2 on page 99) list each portlet application with a brief description of its portlets and its features. Table 3-1 Lotus portlets for deployment with WebSphere Portal 98 Application Description Domino Web Access (iNotes) Provides Welcome, Mail, Calendar, To Do List, Contacts, and Notebook functions. Notes and Domino This portlet can be configured to display and provide access to the following Notes-based applications: Lotus Notes View: Displays the contents of any Lotus Notes database. Lotus Notes Mail: Displays the complete contents of a Lotus Notes mail database, including mail, calendar, and task views. My Lotus Notes Mail: Displays the contents of the user's Inbox. My Lotus Notes Calendar: Displays the user's Calendar. My Lotus Notes To Do: Displays the user's To Do view. Lotus Notes Discussion: Displays Notes databases built with the Discussion Database Template. Lotus Teamroom: Displays Notes databases built with the Team Room Database Template. Lotus QuickPlace Displays up to six different Lotus QuickPlaces in separate browser windows. Inline QuickPlace Displays a Lotus QuickPlace inside the portlet. Lotus Sametime Connect Launches Sametime portlet instant messaging in a separate browser window. Domino.Doc Provides Domino-based document management. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Application Description Lotus Discovery Server™ Allows users to browse or search the Discovery Server Knowledge Map. This portlet application contains the following portlets: Lotus Discovery Server Knowledge Map Lotus Discovery Server Mini-Search Lotus Discovery Server Search Results Quick e-Mail Allows users to send basic Internet text mail messages. Quick Appointment Allows users to create and store Notes appointments on a Domino server. Web Page Allows users to display and use a favorite page from the Internet. Collaboration Center portlets There are five Lotus portlets that comprise the Collaboration Center. The Collaboration Center is included with WebSphere Portal Extend only. Table 3-2 Collaboration Center portlets for deployment WebSphere Portal Extend Application Description Sametime Contact List Displays Lotus instant messaging list. Sametime Who Is Here displays a Lotus Sametime list of users of the portal page. People Finder Allows users to implement both quick search and advanced search for locating people and information about people. Lotus My Team Workplaces (QuickPlace) Allows users to find, work in, and request new team workplaces as well as view workplace details. Lotus Web Conferencing (Sametime) Allows users to find, attend, and schedule e-meetings as well as view meeting details. For each of the integration techniques discussed in the remainder of this chapter, the discussion includes an overview, considerations regarding when its use is appropriate and details about the portlet, and complete implementation details, configuration options, and results. Chapter 3. Using existing portlets 99 Important: This redbook assumes you already have a WebSphere Portal V5 server installed and running in your environment, so it does not include information about installing and configuring WebSphere Portal Server. For details on how to install and configure WebSphere Portal Server, please refer to the product documentation that accompanies the WebSphere Portal Server (or the InfoCenter links below) and other Redbooks. An excellent source of information for both WebSphere Application Server and WebSphere Portal Server are the online “InfoCenters” that accompany each of these products. The WebSphere Application Server Version 5 InfoCenter can be found at: http://www-306.ibm.com/software/webservers/appserv/infocenter.html The WebSphere Portal Server Version 5 InfoCenter can be found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html #ic5 There are InfoCenters available for every version of these products and they contain a wealth of installation, configuration, troubleshooting, and upgrade documentation. Whether you are new to these products or are already familiar with them, we highly recommend that you bookmark these sites and refer to them frequently before carrying out any of the configuration or upgrades described in this chapter. Finally, note that Domino V6.5.1 portlets are available for download from the WebSphere Portal and Lotus Workplace Catalog at: http://catalog.lotus.com/wps/portal/portalworkplace 3.3 Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way This section describes the Lotus Notes/Domino and Extended Products Portlets included with Domino V6.5.1 and subsequent releases. This presents an integration option that incorporates all core messaging and collaborative applications into a portal user interface (UI). The collaborative portlets provided out of the box with Domino V6.5.1 and subsequent releases are based upon Domino and Extended products, including Lotus Team Workplace (QuickPlace), Lotus Instant Messaging and Web Conferencing (Sametime), Domino Document Manager (Domino.doc), and Lotus Workflow™. The release of Notes/Domino 100 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 V6.5.1 and subsequent releases serves a bridge to the world of J2EE and open standards, extending Domino's capabilities by providing the means to connect different sources of data. Figure 3-2 illustrates the conceptual overview of the “My Workplace” portal page. The functionality for each of the Domino V6.5.3 and Extended products is integrated into a single portal page. Figure 3-2 Integration of the Domino V6.5.2 products with a common Portal interface Lotus Notes/Domino and Extended Products Portlets The Domino V6.5.1 Extended Products portlets are an enhancement to the existing WebSphere Portal Collaboration Center portlets and therefore offer the ability to integrate the application functionality of the Domino V6.5.1 platform into a intelligent common user interface served up by WebSphere Portal Server. Once the Domino V6.5.1 and Extended Products portlets have been installed, a portal user can click the My Workplace tab and access several portal pages that have been pre-configured for a well integrated, fully functional collaborative environment. Figure 3-3 on page 102 illustrates a sample page based upon the Chapter 3. Using existing portlets 101 mail portlet. Notice how in addition to the mail portlet, the user has access to both the People Finder portlet and the My Contacts portlet on the same page. Note: See 3.3.3, “Implementation details for Extended Products Portlets” on page 107 for detailed instructions on how to install and configure the Extended Products portlets. My Workplace Tab - access to fully integrated collaborative portlets People Finder portlet Integrated Mail portlet My Contacts portlet Figure 3-3 Sample portal page - including the Mail portlet, the People Finder Portlet, and My Contacts Figure 3-4 on page 103 illustrates another sample portal page, but this time based upon the Web Conferencing portlet. Notice that the placement of the People Finder portlet and the My Contacts portlet are consistent. Additionally, notice that with Sametime functionality enabled, presence awareness is enabled throughout the portlets. 102 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 People Finder portlet Integrated Web Conferencing portlet My Contacts portlet Figure 3-4 Sample portal page - based upon the Web Conferencing portlet 3.3.1 Portlets that make up Extended Products Portlets The Lotus Notes/Domino and Extended Products Portlets consist of: Domino Extended Products Portlets Welcome Page Domino Web Access (formerly iNotes) Domino Web Applications Lotus Domino Document Manager (formerly Domino.Doc) Lotus Notes Discussion Lotus Notes Mail Lotus Notes Teamroom Lotus Notes View Lotus Web Conferencing (formerly Sametime) Lotus Instant Messaging Contact List (formerly Sametime Contact List) Chapter 3. Using existing portlets 103 My Lotus Notes To Do My Lotus Team Workplaces (formerly QuickPlace) People Finder Note: Discussion, Mail, Teamroom, and To Do are installed as views in the Lotus Notes View portlet. You must create instances of Lotus Notes View and change each instance's name to be able to use these services. Sample portal pages Table 3-3 provides an overview of the portlets contained on each of the sample pages. Table 3-3 Extended Products Portlets - Predefine Portal Pages 104 Sample portal page Portlets Welcome Domino Extended Products Portlets Welcome Portlet Mail Mail (view using Domino Web Access) People Finder My Contacts (from Instant Messaging Contact List) Calendar Calendar (view using Domino Web Access) People Finder My Contacts (from Instant Messaging Contact List) Address Book Address Book (view using Domino Web Access) People Finder My Contacts (from Instant Messaging Contact List) Web Conferencing Web Conferences (from Lotus Web Conferencing) People Finder My Contacts (from Instant Messaging Contact List) Team Spaces Team Spaces (from My Lotus Team Workplaces) People Finder My Contacts (from Instant Messaging Contact List) Documents Documents (Document Manager) Domino Applications Domino Applications Domino Databases Domino Databases (Lotus Notes View portlet) Administration Bookmarks Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Note: Some of the portlets in the sample pages are instances of an installed Extended Products portlets, developed specifically for these sample pages, for example, My Contacts is an instance of Lotus Instant Messaging Contact List (formerly Sametime Contact List). 3.3.2 Considerations for the Domino Extended Products Portlets Before you begin install Lotus Notes/Domino and Extended Products Portlets, confirm that your systems are ready. To actually use them, you must first install and configure the following products: IBM WebSphere Portal IBM Lotus Domino IBM Lotus Team Workplace (QuickPlace) IBM Lotus Instant Messaging and Web Conferencing (Sametime) IBM Lotus Domino Document Manager (Domino.Doc) IBM Domino Web Access (iNotes) You will also need to configure both single sign on (SSO) between the Portal and Domino environments and configure presence awareness and instant messaging functionality to work consistently between the portlets. For details on how to install and configure this complete, collaborative environment, please also refer to the redbook Domino 6.5.1 and Extended Products: Integration Guide, SG24-6357, found at: http://www.redbooks.ibm.com/abstracts/sg246357.html As previously mentioned, the Extended Products Portlets are available for download from the WebSphere Portal and Lotus Workplace Catalog at: http://catalog.lotus.com/wps/portal/portalworkplace Important configuration prerequisites Depending on which Domino V6.5.x products you want to integrate with WebSphere Portal, it might be necessary to carry out some additional configuration on the Domino V6.5.x products. This is particularly true in the case of Lotus Team Workplace and Lotus Instant Messaging and Web Conferencing. Team Workplace and Instant Messaging requirements Within Lotus Instant Messaging and Web Conferencing and Team Workplace, there are a number of configuration changes that have to be made before installing the Extended Product portlets so that features such as awareness and online meetings will function in WebSphere Portal. Chapter 3. Using existing portlets 105 Depending on which Domino V6.5.x products you want to integrate with WebSphere Portal, it might be necessary to carry out some additional configuration on the Domino V6.5.x products. This is particularly true in the case of Lotus Team Workplace and Lotus Instant Messaging and Web Conferencing. For example, there are a number of configuration changes that have to be made to products, such as Lotus Instant Messaging and Web Conferencing and Team Workplace, so that features such as awareness and online meetings will function in WebSphere Portal. Important: Full details of these configuration changes can be found in the Lotus documentation Lotus Domino and Extended Products 6.5.1 Integration Guide, G210-1747, which can also be downloaded as an additional material for this book. See Appendix C, “Additional material” on page 741 for instructions about how to download and access this document. It is important to refer to this guide for the configuration changes you will need to make for the particular Domino V6.5.x product or products you want to integrate with WebSphere Portal; otherwise, you might find that certain features, such as awareness, might not work, or the portlet might not function at all. We therefore recommend that you download this guide prior to configuring the Domino Extended Products portlet so that you can easily refer to it. We provide a brief summary checklist of these configuration changes for the products. For Lotus Team Workplace: Specify an LDAP server (this should be the same LDAP server used by WebSphere Portal). Specify the Instant Messaging and Web Conferencing server to use if you want awareness in Team Workplace. Configure the Notes.ini to include the DIIOP Sever task. Create the servlets.properties file and copy the Team Workplace servlet from WebSphere Portal to the Team Workplace server. Modify the Notes.ini to point to the new Team Workplace servlet. Modify the Team Workplace server’s Server document so that Domino is acting as the servlet manager. 106 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 For Lotus Instant Messaging and Web Conferencing: Configure Lotus Instant Messaging and Web Conferencing to use the same LDAP server as WebSphere Portal (additional details and troubleshooting tips can also be found in Chapter 7, “Integrating Domino 6.5.1 with a third-party LDAP directory”). Modify the Sametime.ini file to trust the WebSphere Portal IP address. Enable the Purge Meeting agent in Lotus Instant Messaging and Web Conferencing. For Domino Document Manager, enable Lotus Instant Messaging and Web Conferencing integration if you want the “Who is Online” feature to work in WebSphere Portal. For Domino Web Access, if you want Lotus Instant Messaging and Web Conferencing awareness to work for Domino Web Access in WebSphere Portal, the following configuration changes need to be made: Configure Directory Assistance on the Domino Web Access server for the LDAP directory used by WebSphere Portal. Add iNotes_WA_SametimeServer=<Sametime_Server_Hostname> to the Notes.ini of the Domino Web Access server. Copy the \stlinks folder from the Instant Messaging and Web Conferencing server to the Domino Web Access server if you want awareness to work in WebSphere Portal. 3.3.3 Implementation details for Extended Products Portlets The following section describes how install the Extended Products portlets. Installing the Extended Products Portlets Follow these steps to install the Extended Products Portlets: 1. On the machine where WebSphere Portal is installed, create the directory <wp_root>/EPPUpdate and copy the Notes/Domino and Extended Product Portlets files into that directory. 2. Verify that the WAS_HOME and WPS_HOME environment variables are set. If not, you can specify them in the Deploy command line with the following parameters: -washome <wasHomeDirectory> -wpshome <wpsHomeDirectory> Chapter 3. Using existing portlets 107 Note: Directory names that contain space characters need to be enclosed in double quotes. 3. Make sure that the WebSphere Portal server is running by using the following command: <WAS_Root>\bin\serverStatus.bat –all –user wpsbind –password wpsbind 4. Change the directory to <WPS_Root>\EPPUpdate. 5. To deploy the portlets/sample pages, run the following command:. Deploy [-f] [-v] <serverdns:port> <wpsadmin> <wpspassword> [<nodename>] [<lang>] ([-portlets] | [-samplepages] | [-adminpage]) The parameters for the command are described in Table 3-4. Table 3-4 Script parameter 108 Parameter Description serverdns:port The DNS address and port of WebSphere Portal. For example, itso-wps.cam.itso.ibm.com®:9081. wpsadmin The administrative user for WebSphere Portal. wpspassword The administrator's password. nodename The name of the WebSphere Application node. This should be the same as the host name of your WebSphere Portal. The node name will appear as a subdirectory under the <wasHomeDirectory>/installedApps. If this name is different than your host name, enter the node name. lang ISO 639 two-character code to specify language of Administration bookmark page. -portlets Deploys only the portlets. -samplepages Deploys only the sample pages. -adminpage Change the language of the sample pages. This should only be used to change languages after the sample pages have already been deployed. -f Forces a copy of the portlets or theme. Normally, the deployer only copies files if they are not already present on WebSphere Portal. If you have already deployed the portlets or the theme and need to refresh the files, you can use this flag to force the files to copy again. -v Verbose mode. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Note: You can also enter simply "Deploy" and press enter, and you will be prompted for each parameter. 6. Log in to WebSphere Portal and select My Workplace to confirm that the sample portal pages and portlets have deployed, as shown in Figure 3-5. 7. Click on the different portlet tabs to view each of the portlets (mail, calendar, and Web conferences.) Figure 3-5 Domino Extended Products Welcome page Configuring the Extended Products portlets This section discusses how to configure the various Extended Products portlets, specifically: Lotus Team Workplaces (formerly QuickPlace) Lotus Web Conferencing (formerly Sametime) Lotus Instant Messaging Contact List (formerly Sametime Contact List) Domino Web Access, which consists of the Inbox, Calendar, and Contacts Lotus Domino Document Manager (formerly Domino.Doc) Domino Application Chapter 3. Using existing portlets 109 Lotus Notes View, which consists of any Domino database view, such as Discussion, Teamroom, To Do, or Notes Mail. Important: Ensure that you completed any prerequisite configuration (as described in the Lotus Domino and Extended Products 6.5.1 Integration Guide, G210-1747) before following the portlet configuration instructions in this section. This Lotus documentation can be downloaded as an additional material for this book. See Appendix C, “Additional material” on page 741 for more information about downloading this information. Configuring the Domino Web Access portlet To configure the Domino Web Access portlet, complete the following steps: 1. Click the My Workplace link. 2. Click the Mail link. 3. Click the Edit portlet properties icon on the top right side of the portlet window. 4. Specify the host name of the mail server and the location of your mail file, as shown in Figure 3-6. Figure 3-6 Configuring the Domino Web Access portlet 5. If single sign-on has been correctly configured (and your mail file has been created with the Domino Web Access template), you should see something similar to the window shown in Figure 3-7 on page 111. 110 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-7 The Lotus Notes mail (Domino Web Access) portlet 6. Repeat steps 1 through 4 for the Calendar and Address Book links (see Figure 3-8 and Figure 3-9). Figure 3-8 Calendar portlet Figure 3-9 Contacts portlet Configuring the Team Spaces portlet To configure the Team Spaces portlet, complete the following steps: 1. Log on to WebSphere Portal as an administrator, as shown in Figure 3-10 on page 112. Chapter 3. Using existing portlets 111 Figure 3-10 Logging in on WebSphere Portal as an administrator 2. In the administration section of the portal, click Portlets and then click Manage Portlets, as shown in Figure 3-11. Figure 3-11 Manage Portlets This window shown in Figure 3-12 opens. Figure 3-12 Selecting a portlet to configure 3. From the list of portlets, select the Team Spaces portlet, as shown in Figure 3-13 on page 113. 112 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-13 Modifying the Team Spaces portlet 4. For the Team Spaces portlet, click Modify parameters. The window shown in Figure 3-14 opens. Figure 3-14 Changing values for the Team Spaces portlet 5. Change the QuickPlaceHostname to the server name of your Team Workplace server, for example, quickplace651.lotus.com. 6. Verify that QuickPlacePort is set to the correct port. The default port is 80. Chapter 3. Using existing portlets 113 7. Click Save at the bottom of the window. 8. After the settings are saved, click Cancel to return to the Manage Portlets window. Figure 3-15 shows how the Team Spaces portlet looks to a user after it has been successfully configured. Figure 3-15 Team Spaces portlet Configuring the Web Conferences portlet To configure the Web Conference portlet, complete the following steps: 1. Follow steps 1 to 4 as described in “Configuring the Team Spaces portlet” on page 111, except at step 3 on page 112, select the Web Conferences portlet. 2. For the Web Conferences portlet, click Modify parameters. 3. Change the SametimeServer1 parameter to the Instant Messaging and Web Conferencing server name. 4. Change SametimeUserName1 to be an administrative user that exists in the LDAP directory and that also has manager access to the STConfig.nsf database on the Instant Messaging and Web Conferencing server. In our test environment, we used the wpsadmin user (see Figure 3-16 on page 115). 114 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-16 Specifying an administrative user in the STConfig.nsf ACL 5. Change SametimePassword1 to the password for the user specified in step 4 on page 114. 6. Verify that SametimePort1 is set to the correct port. The default port is 80. 7. Click Save at the bottom of the window. 8. After saving the settings, click Cancel to return to the Manage Portlets window. 9. Click My Portal and then My Workplace. 10.If single sign-on has been correctly configured, you should see something similar to the window shown in Figure 3-17. Figure 3-17 The Web Conferences portlet Chapter 3. Using existing portlets 115 Tip: A useful way to ensure that you have Instant Messaging connectivity in WebSphere Portal is to add the “Who Is Here” portlet to a page. In our test environment, we logged on as the WebSphere Portal administrator, clicked the Administration link, and added this portlet to the Welcome Page. We were then able to confirm that we had connectivity to the Instant Messaging and Web Conferencing server because we had awareness for the administrator logon name (see Figure 3-18). If there is a problem with Instant Messaging and Web Conferencing connectivity, this portlet will generate an appropriate error message. Check that the Instant Messaging and Web Conferencing server is up and running and that there are no network connectivity problems. You might also need to check that the values specified for Lotus Instant Messaging and Web Conferencing in the csenvironment.properties file on the WebSphere Portal are correct (see Chapter 8, “Domino 6.5.1 Extended Products with WebSphere Portal”, in the Domino 6.5.1 and Extended Products: Integration Guide, SG24-6357, found at: http://www.redbooks.ibm.com/abstracts/sg246357.html for more details about the csenvironment.properties file). Figure 3-18 Using Who Is Here portlet to confirm Lotus Instant Messaging connectivity Configuring the Instant Messaging Contact List There are no additional configuration steps for the Instant Messaging Contact List portlet. If Lotus Instant Messaging and Web Conferencing connectivity has been successfully confirmed, and single sign-on is working correctly, your Instant Messaging buddy list will appear in the portlet, as shown in Figure 3-19. Figure 3-19 Instant Messaging Contact List 116 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3.3.4 Configuring the Document Manager portlet To configure the Domino Document Manager portlet, complete the following steps: 1. Click the My Workplace. 2. Click the Document link. 3. Click the Edit portlet properties icon in the top-right area of the portlet window. 4. Specify the host name of the Domino Document Manager server and the database path and name for the library (see Figure 3-20). Figure 3-20 Specifying the Domino Document Manager server and library 5. If single sign-on has been correctly configured, you should see something similar to the window shown in Figure 3-82 on page 173. Chapter 3. Using existing portlets 117 Figure 3-21 The Document Manager portlet 3.3.5 Configuring the Domino Application portlet The Domino Application portlet enables you to integrate any Web-enabled Domino application into WebSphere Portal. This portlet is significant in that it allows you to render your Domino Web-enabled application within the context of portal. More importantly, it has been designed so that navigation within the Domino Web-enabled application will remain within the portal context (that is, it will not open new browser windows outside of the portal environment.) The Domino Application portlet acts like a tunnel, channelling all requests from the browser through WebSphere Portal and on to the Domino HTTP server at the back end. It manages cookies, caching, user authentication, and framing. Attention: This section provides basic details on how to configure this portlet. Please note that in 3.4, “Integration Option 2 - The Domino Application Portlet” on page 122, we provide greater detail. Finally, you may also find more in-depth information about this portlet in the Redpaper IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html To configure the Domino Application portlet, complete the following steps: 1. Click the My Workplace link. 2. Click the Domino Application link. 118 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3. Click the Configure portlet properties icon in the top-right area of the portlet window. This icon looks like a wrench. 4. Specify the host name of the Domino Web server, the database path, and port to use (the default port is 80), as shown in Figure 3-22. Figure 3-22 Configuring the Domino Application portlet 5. On the Authentication tab, select Single Sign-On (SSO), as shown in Figure 3-23. Figure 3-23 Configuring authentication in the Domino Application portlet 6. Click Done and then click Close to save your changes and exit. 7. If SSO has been configured correctly, and you have the necessary access rights to the Domino Application, you should see something similar to the window shown in Figure 3-24 on page 120, which shows our sample Sales Tracking Customer database. Chapter 3. Using existing portlets 119 Figure 3-24 A sample customer database in the Domino Application portlet 3.3.6 Configuring the Domino Databases (Notes View) portlet The Domino Databases portlet enables you to work with the documents from any view of any Domino database. In our test environment, we used the “People” view of the Domino Directory. To configure the Domino Databases portlet, complete the following steps: 1. Select the Edit portlet properties icon in the upper-right corner of the portlet. 2. In the Available Views section, select Add. 3. In the View Title section, enter the name of the view you want to access. In our case, this was $People (see Figure 3-25 on page 121). 4. In the Server section, specify the server name where the database is located Select the check box next to the Server section. 5. In the Database filename section, select the file path and database name. In our case, this was names.nsf. 120 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6. In the View section, select a name of the view that corresponds to the View Title entered earlier. Figure 3-25 Configuring the Notes View in the Domino Databases portlet 7. Add more views to the portlet (repeating steps 2-6) if wanted (see Figure 3-26). Figure 3-26 Adding additional views to the Domino Databases portlet Chapter 3. Using existing portlets 121 8. Click Save. You should then see the view or views you specified in the portlet window. For example, Figure 3-27 shows the Customer view of customer database (customer.nsf) the that we specified in our test environment. Figure 3-27 The customer view of customer.NSF in the Domino Databases portlet 3.4 Integration Option 2 - The Domino Application Portlet The Domino Application Portlet (DAP) integrates the content and technology of existing Domino Web Applications into the Portal environment. It allows customers to insert these existing applications into portlets and display them on a portal server with minimal development effort. Most importantly, it renders the portlets of the Domino Web application within the context of the portal, thereby keeping the user within the context and navigational scheme of the portal. Attention: While this section covers the basics of how to install and configure the Domino Application Portlet, you may also find more in-depth information in the Redpaper IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html The key features for the Domino Application Portlet include: Designed to allow Domino Web apps to be surfaced in a LWP/Portal environment. User experience remains within Portal. 122 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 No changes to the Domino application required. Reverse Proxy: The portlet uses a set of rules to map Domino generated URLs to Workplace/Portal such that all requests are channeled through Portal server. Default set of Domino Rules defined and configured (mail, discussion, and teamroom) Rules can be added for support of any Domino Web application. 3.4.1 Considerations The Domino Application Portlet acts like a reverse proxy, proxying the content from the back-end servers to the browser. It appears to the browser to be the real content server. DAP channels all requests from the user client (browser) through the portal and on to the Domino HTTP server in the back end. The portlet contains an iframe with an embedded servlet that is responsible for the actual connection and display of the Domino content. It manages cookies, caching, user authentication, and framing. Rules-based parsers rewrite the content produced by the Domino HTTP server. Figure 3-28 shows the Domino Application Portlets page before configuration. Figure 3-28 Domino Application Portlet 3.4.2 Implementation details for the Domino Application Portlet This section describes the setup and configuration of the Domino Application Portlet (DAP). It examines the basic setup and gives an overview of the configuration options available. It also contains examples that show how to set up DAP and write rules to tailor it for your own application. To fully explain this process, we provide complete details concerning: Initial setup Configuration options Edit options Results Chapter 3. Using existing portlets 123 Note: While this section covers the basics of how to install and configure the Domino Application Portlet, you may also find more in-depth information in the Redpaper IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html Initial setup DAP is set up like any other portlet, that is, the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog. However, if you install Extended Products Portlet (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), DAP is installed with all the other portlets. In this case, you would only need to click the My Workplace link and then click the Domino Application Portlet link. Otherwise, when installing as a stand-alone portlet from the portlet catalog, you complete the following tasks to deploy portlet: Install the portlet WAR file. The Domino Application portlet is provided by the portlet application, DAP50.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are outlined in 2.4, “Deploying the case study portlets” on page 83. Configuration options To configure the Domino Application Portlet, you must have administrator access rights. The configuration menu may be accessed by clicking the wrench icon (Figure 3-29) in the upper right hand corner of the portlet. It contains five main tabs; they are: Source and Display Authentication Caching Rules Debug Figure 3-29 DAP - Access to configuration menu 124 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Source and Display tab The Source and Display tab (Figure 3-30) allows the user to define which Domino server and database the portlet is to display (Domino Source Sever options). In addition to this, it also allows the user to direct DAP to look for the Domino content via a proxy server. This is a useful feature if the user wishes to see what requests are being made by the portlet to the Domino server. Finally, this tab also lets the user configure the iframe in which the DAP portlet displays the Domino content. The Show in edit mode check box permits some of these options to be made available to a normal portlet user in edit mode. So, for example, a normal user could configure a DAP portlet to point to his/her mail database without having to have administrator rights for the portlet. Figure 3-30 Source and Display UI Authentication The authentication settings may be modified on the Authentication tab (Figure 3-31 on page 126) of the configuration menu. These settings define the model DAP will use to authenticate with the Domino server and also where in the Credential Vault the user name and password may be found. Chapter 3. Using existing portlets 125 There are four different authentication models that the Domino Application Portlet (DAP) can use to authenticate with the target Domino server. They are none, basic, session, and Single Sign On (SSO). A number of options may be set, including storage in the Credential Vault or use of Single Sign On. A more in-depth description of authentication may be found in IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html Figure 3-31 Authentication UI Caching Within the Caching tab (Figure 3-32 on page 127), settings that affect the storage of cached objects from DAP may be set. While the browser has its own caching, a user may also define a number of caching mechanisms for the DAP portlet. Essentially, these mechanisms define where and how objects that are passed between Domino and DAP are stored. This caching takes place on the Portal server and use of caching here prevents unnecessary calls to the Domino server. A detailed description of the options here may be found in IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3917.html 126 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-32 Caching UI Rules The Rules tab (Figure 3-33 on page 128) defines the rules that are used to transform URLs and links in the Domino content so that they point to DAP instead of to the Domino server. These rules come in two forms that are mutually exclusive: Regular Expression Rules or HTML Rules. While there is too much detail to go into here, a detailed explanation is given in IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917; the essential difference between the two is that Regular Expression Rules are very flexible, but complicated, while HTML rules are simpler and faster, but less flexible. Chapter 3. Using existing portlets 127 Figure 3-33 Rules UI Debug Select the Debug tab (Figure 3-34) to view debugging information for the application specified in the Source and Display tab or in the Edit display. Click Start to turn on debugging mode. You will see a preview of the Domino database application that is specified in the Source and Display tab or Edit mode. Figure 3-34 Debug UI Note: Clicking Save has no effect on the state of debugging mode (on or off). If you close the configuration display with debugging switched on, it will remain on until you return to the configuration display and click Stop. 128 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Edit Options The Edit Options may be accessed by selecting the pencil icon in the top right hand corner on the DAP portlet page (Figure 3-35). Figure 3-35 DAP - Edit UI The edit page is where a user must enter their Domino user name and password if they are using Basic or Session based authentication. This page also contains any of the options that the Administrator decided to allow a normal user to configure. These may include the Domino Database settings and the display settings (see Figure 3-36). Figure 3-36 Edit Domino Source Server After editing the settings, click Save or Close to close the Edit display. Note: If you do not click Save before closing the display, you will lose any changes you have made. Results After configuring and editing the DAP portlet, you will be able to view the Web application within the portlet. Using our sample application, the result of the Domino Application Portlet page is shown in Figure 3-37 on page 130. Chapter 3. Using existing portlets 129 Figure 3-37 Domino application as seen through DAP 3.5 Integration Option 3 - using specific Portlets In the following sections, we discuss how to install and configure several of the most useful portlets provided with WebSphere portal, including the portlets that make up the Collaboration Center. The portlets that we will discuss include: Notes View portlet Domino Web Access (iNotes) portlet Lotus Web Conferencing (Sametime) portlet Lotus Instant Messaging Contact List (Sametime Contact List) portlet My Lotus Team Workplaces (QuickPlace) portlet People Finder portlet Document Manager (Domino.Doc) portlet 3.5.1 Integrate using Lotus Notes View Portlet Using the Lotus Notes portlets available in WebSphere Portal is an excellent example of the simplicity of using prepackaged portlets. This technique 130 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 configures a Web-enabled view in your Domino application to the portal environment through direct and efficient configuration screens. The view is displayed in your portal context and no external Web browser session will open. Considerations There are a number of prepackaged Lotus Notes portlets available in WebSphere Portal. The collaborative feature of Lotus Notes portlets is of particular use to quickly integrate existing Domino applications into the WebSphere Portal environment. Table 3-5 lists a number of useful views; it provides a good understanding of the use of these portlets. In this section, we describe the use of NotesViewPortlet, as it can be used to show any view from any Domino database. Table 3-5 Lotus Notes views Lotus Notes Description Notes Mail Displays any view (for example, Inbox, Calendar, or To Do) of a Notes Mail database to which a portal user has access. Notes View Displays any view of any Notes database to which a portal user has access. Users can add multiple views to a View menu. Notes TeamRoom Displays any view of a Notes TeamRoom to which a portal user has access. Notes Discussion Displays any view of a Notes Discussion to which a portal user has access. My Notes Mail Displays a portal user's own Notes Inbox, using the identity with which the user logs into WebSphere Portal. My Notes Calendar Displays a portal user's own Notes Calendar, using the identity with which the user logs into WebSphere Portal. My Notes To Do Displays a portal user's own Notes To Do (task) list, using the identity with which the user logs into WebSphere Portal. Implementation details for the Notes View Portlet This section describes how to use the Lotus Notes View portlet to display information from one of the example databases within the portal context view. To fully explain this implementation, we provide complete details concerning: Initial setup Edit options Results Chapter 3. Using existing portlets 131 Initial setup Lotus Notes View Portlet is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog. However, if you install the Extended Products Portlets (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), Lotus Notes View portlet is installed with all the other portlets. Click the My Workplace link and then click the Domino Databases link. Otherwise, you complete the following tasks to deploy the portlet: Install the portlet WAR file. The Lotus Notes View portlet is provided by the portlet application, notes2.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Figure 3-38 shows the Lotus Notes View portlets page before configuration. Figure 3-38 Lotus Notes Portlets before configuration Editing options 1. Select the Edit icon in the top right hand of the portlet window and click it, as shown in Figure 3-39. Figure 3-39 Editing a portlets’ properties 2. You see Available Views in your system. You can specify the source view and database. Click the Add icon. In the Available Views section, select Add (as shown in Figure 3-40 on page 133.) 132 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-40 Pointing to view in Notes database 3. You see the Notes View Source Form (Figure 3-41 on page 134). Chapter 3. Using existing portlets 133 Figure 3-41 Lotus Notes View portlet edit mode Edit the following information within the Notes Source View (Figure 3-41): Under View title, specify the text you want to display in the View menu for switching to this view in this database. Examples of useful items to display on the View menu are "By Customer Name". Under Server, specify the server name, for example, itso-dom.cam.itso.ibm.com. Under Database filename, specify the database file name and path, for example, mail\manderle.nsf or redbook\customer.nsf. Under View, specify the name or alias name of the view element in the source database, for example, "Customeres\By Customer Name”. Under View category (Optional), specify a category in the view to display in Notes and Domino (documents in the rest of the view are hidden). 134 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Under Protocol (Optional), change from the default to HTTPS (SSL), a secure protocol, if you know that the Domino server containing the database that is the source for the selected view uses that protocol. If you do not know, set this view to detect the server's protocol automatically. 4. Click Next. 5. Fill in the necessary information for Notes View Style Column (all are optional), as shown in Figure 3-42. Figure 3-42 Lotus Notes View portlet edit Style Edit the following information in the window shown in Figure 3-42: – Change the number of Rows per screen to display, for example, 30. – Turn on the Alternating row colors check box to help make the view easier to read. Chapter 3. Using existing portlets 135 – Turn on the Icon for creating new documents check box if you want to be able to create new documents in the selected view. This check box requires you to specify the name of the Notes form (part of source database design) to use, for example, “Sales Activity” – Under View documents in, select an option for launching documents. – Under Column for showing people awareness, drop down the list and select a column containing people's names to display as links you can click for instant messaging. For example, in a Customer database, the “Account Owner“. The column must be designed to contain names as data, and the portal must be configured to work with a Sametime server. – Under Column for launching documents, drop down the list and select the column to click when you want to open a document. – Under Columns to hide, click or Ctrl-click one or more columns. Some databases are designed to show many columns. You can hide ones you do not need. – Under Direction for default sort column, select an option for application. 6. When you have entered all of the necessary information, click Done to continue. 7. Click Save to keep or Cancel to discard changes to the selected view. Results of configuring the Notes View Portlet After editing the Lotus Notes View portlet, the result of the Domino portlets page is shown in Figure 3-43 on page 137. 136 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-43 Result of modifying the Lotus Notes View Portlet For column titles with a highlighted link, you can order the listing based on that column. The configured server and database name always shows below the portlet window’s (itso-dom.cam.itso.ibm.com). If the portlet allows for launching the Notes client or a Web browser, the launch rocket icon is present below the title region. If you have rights to create documents in the respective Domino database, which is “author” at minimum, then a “New document” icon also shows up next to the launch rocket icon. If you click a highlighted link inside the portlet (in our example, Customer Name), you are able to open a document (if access allows) into a new Web browser session and out of the portal context, as shown in Figure 3-44 on page 138. Chapter 3. Using existing portlets 137 Figure 3-44 Result of clicking the first highlighted link in the Lotus Notes View portlet If you click the second highlighted link inside the portlet (in our example, Account Owner), you are able to open a Sametime menu (assuming Sametime is configured), as shown in Figure 3-45. Figure 3-45 Sales Report - Sametime Detail For configuring a Notes View portlets for other Notes databases, repeat steps 1 to 7 for the Notes TeamRoom, Notes Discussion (Figure 3-46 on page 139), and other databases. 138 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-46 Discussion portlet 3.5.2 Integrate using the Domino Web Access (iNotes) portlet The Domino Web Access (iNotes) Version 5.0.2.2 portlet allows the user to view and work in a Notes mail database that has a Domino Web Access design, and is optimized for access using a Web browser. Considerations for deploying the Domino Web Access portlet The user can set up the portlet to display any or all of the following functional areas: Welcome (default) Mail Contacts Calendar To Do Notebook In the next section, we will show you how to install, configure, and deploy the iNotes on your server. As portal administrator, you can change the area that displays in the portlet. You can also pre-configure all the other settings users can modify in edit mode, such as setting up a reverse proxy server, and specifying an instance number for the portlet when the current portal page contains more than one instance of Domino Web Access. Chapter 3. Using existing portlets 139 Implementation details for the Domino Web Access portlet This section describes how to use the Domino Web Access (iNotes) portlet to display information from one of the mail databases within the portal context view. To fully explain this implementation, we provide complete details concerning: Initial setup Edit options Results Initial setup The Domino Web Access (iNotes) portlet is setup like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog. However, if you install the Extended Products Portlets (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), the Domino Web Access (iNotes) portlet is already installed with all the other portlets. Click the My Workplace link and then click the Mail link; otherwise, you complete the following tasks to deploy the portlet: Install the portlet WAR file. The Domino Web Access portlet is provided by the portlet application, dominowebaccess.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Edit options 1. In the title bar, select the Edit icon in the top right hand of the portlet window and click it, as shown in Figure 3-47. Figure 3-47 Editing a portlets’ properties 140 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 2. In this form (Figure 3-48), you can customize the following variables for Domino Web Access Portlet: Figure 3-48 Configuring the Domino Web Access portlet – Under Functional Area, select one of the following areas to display in this instance of Domino Web Access: All, Welcome, Mail, Calendar, To Do List, Contacts, or Notebook. • If you select All, under Start with, specify the functional area that displays when this instance of Domino Web Access opens. • You do not need to specify an Instance number unless you add more than one instance of Domino Web Access to a page, and both instances display All; in that case, give each instance a different number. – (Optional) Under Application title, change the title to whatever you want (for example, My Company's Domino Web Access), as long as you do not leave the field blank. – (Optional) Under Width, type a number of pixels for this instance of Domino Web Access to span regardless of column width. – (Optional) Under Height, type a number of pixels. Chapter 3. Using existing portlets 141 – Under Source, select one of the following: • Automatically find my mail database. This option uses the name and password under which you logged in. • Let me manually select my mail database. If you select this option, you must also specify a source database, as described in “Pointing Domino Web Access to a source mail database” on page 142. – (Optional) Specify a reverse proxy server. For more information, Specifying a reverse proxy server. – (Optional) Under Protocol, change from the default to HTTPS (SSL), a secure protocol, if you know the Domino server containing the database containing the selected view uses that protocol. If you do not know it, set this view to detect the server's protocol automatically. 3. Click Save to keep or Cancel to discard changes. Figure 3-49 Domino Web Access - Instance Tip: If you select All, under Start with, specify the functional area that displays when this instance opens.You do not need to specify an Instance number unless you add more than one instance of to a page, and both instances display All; in that case, give each instance a different number (Figure 3-49). Pointing Domino Web Access to a source mail database Under Source, select Let me manually select my mail database, as shown in Figure 3-50 on page 143. Under Server, specify the name of a Domino server, for example, itso-dom.cam.itso.ibm.com. – After typing a value, you can select the check box next to the field to fill in the Database filename field with available databases on the server. Then you can select one of the databases for the next step. 142 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Under Database filename, specify the path and file name for a Domino Web Access source mail database, for example, mail/manderle.nsf. Figure 3-50 Configuring the Domino Web Access portlet - Manually Repeat the steps for the Calendar, Address Book, and other links (Figure 3-51 and Figure 3-52 on page 144). Figure 3-51 Calendar Portlet Chapter 3. Using existing portlets 143 Figure 3-52 Contacts Portlet 3.5.3 Lotus Web Conferencing (Sametime) The Lotus Web Conferencing portlet (Figure 3-53) allows you to find, attend, and schedule e-meetings as well as view meeting details. This portlet can be integrated with People Finder as part of the Collaboration Center, or deployed independently. As with the other Collaboration Center portlets, people links are visible in the Web Conferencing portlet to make your interaction fast and easy, improving personal and organizational productivity. Figure 3-53 The Lotus Web Conferencing portlet Implementation details for the Lotus Web Conferencing Portlet The following topics explain how to change the properties of the IBM Lotus Web Conferencing (Sametime) application. The application is a component of the 144 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Collaboration Center. To fully explain this implementation, we provide complete details concerning: Initial setup Edit parameters Using Initial setup Lotus Web Conferencing (Sametime) is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog; however, if you install the Extended Products Portlets (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), the Lotus Web Conferencing (Sametime) portlet is installed with all the other portlets. Click the My Workplace link and then click the Web Conferences link; otherwise, complete the following tasks to deploy the portlet: Install the portlet WAR file. The Lotus Web Conferencing portlet is provided by the portlet application, LotusWebConferencing.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Editing parameters To change Web Conferencing properties, follow these steps: 1. Click the pencil icon in the title bar of any of the application views (Figure 3-54). Figure 3-54 Editing a portlets’ properties 2. Edit the Number of meetings to display on each page. Meetings are listed on one or more 'pages' within the Search and List view. This number specifies the maximum number of meetings that can be listed on a page. The default value is 15 (Figure 3-55 on page 146). Chapter 3. Using existing portlets 145 Figure 3-55 Web Conferences - Edit UI 3. Click OK to accept the changes or Cancel to abandon them. Using the Web Conferencing portlet To find an e-meeting, use the Search and List view, which can locate any e-meeting that is still available on the e-meeting server(s). It is the default view for the Web Conferencing application. 1. In the drop-down list (Figure 3-56), select the type of meeting you want to find: Figure 3-56 Web Conferences drop-down list – In Progress lists all meetings that are active now. – Scheduled lists all meetings that are scheduled for some future time. – Moderated by Me - In Progress lists all In Progress meetings for which you are named as moderator. – Moderated by Me - Scheduled lists all Scheduled meetings for which you are named as moderator. – Recorded lists all meetings that have been recorded. You can replay a recorded meeting after it is over. This allows you to see a meeting that, for example, you were unable to attend. 146 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Finished lists all meetings that have ended. Note: The options Moderated by Me - In Progress and Moderated by Me Scheduled are available only if you are logged in to the portal. If you are an anonymous (unauthenticated) portal user, you will not see this type of meeting in the list. 2. Select the scope of the search (Figure 3-57): Figure 3-57 Search options – Show all lists all meetings of the type selected in the previous step (Type of meeting), except confidential (unlisted) ones. – Search by meeting name or moderator limits the list to particular meetings within the type selected in the previous step. Enter the name (or part name) of the moderator or meeting. 3. Click Go. 4. You can see the results of a meeting search in the meeting list. If there are more meetings than can be listed at one time. To clear the search results and remove the list table, click Clear. 5. To create an e-meeting, use the New Meeting icon. This option opens the Schedule a New Meeting view (Figure 3-58 on page 148), where you can schedule or start an e-meeting. The New Meeting command does not appear if your administrator has disabled this option. Chapter 3. Using existing portlets 147 Figure 3-58 Schedule a New Meeting In the Essentials section, follow these steps: a. Enter a Name for the meeting, for example, “IBM WebSphere Portal”. b. Enter a Description for the meeting (Optional), for example, “Build Level”. c. Select Start Now if you want the meeting to start immediately or Schedule for if the meeting is to start at some future time. If you selected Schedule for, specify a Start Date, Start Time, and Duration for the meeting. d. Select the Record meeting check box (Optional) if you want the meeting to be recorded so that users can play it back at a later date. 148 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 In the Security section, follow these steps: a. Enter a password (Optional) for the meeting. Users will have to supply this password in order to attend the meeting. b. Select Secure this meeting by not listing... (Optional) if you want the meeting to be confidential (unlisted). Users wishing to attend an confidential meeting will need to know its full name in advance. c. Select Secure this meeting using encryption... (Optional) if you want the meeting to be encrypted. In the Tools section under General, select (or deselect) the check boxes to indicate the tools that you want to use during the meeting: a. Whiteboard allows you to present files, draw images, and enter text. b. Screen Sharing allows any attendee to share his or her screen display with the other meeting participants. c. Meeting Room Chat allows attendees to send messages to everyone in the meeting. d. Send Web Page allows you, as moderator, to simultaneously direct all participants' Web browsers to a specific Web page. e. Polling allows you, as moderator, to send questions to participants and to collect the responses. Under Audio/Video, select one of the following: a. None b. Computer Audio allows attendees to speak with other participants via the computer. c. Computer Audio and Video allows attendees to speak with other participants and if using video, to be seen by them Note: You will see only those tools that your administrator has enabled; you may not see all of the ones describe here. 6. Finally, when all of the settings are correct, you can click Save to finish scheduling a new meeting or click Cancel to close the form without scheduling the meeting. 7. At the next screen (Figure 3-59 on page 150), review the information you have entered. The name of the moderator for the meeting appears with an Instant Messaging icon that indicates the moderator's online status: – Active (green square) – Away (red circle) Chapter 3. Using existing portlets 149 – Do Not Disturb (yellow diamond) – Not logged on or Instant Messaging not available (gray dot) You can click the name to display the Person Name menu. Its options include for example, Chat, Send E-mail, Show Profile, Show Person Record, and Show in Organizational View. On a public page, people links do not appear. The names of people appear as plain text, without a menu. Figure 3-59 Review - Meeting Detail 8. Click Close Detail return to the meeting Search and List view. After editing the Web Conferencing, the result of the work is shown in Figure 3-60 on page 151. 150 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-60 New Web Conferences 3.5.4 Lotus Instant Messaging Contact List (Sametime Contact List) My Contacts allows you to use Sametime instant messaging, as shown in Figure 3-61. You can chat with people, display only online names in the list, modify your status message, or modify groups. Figure 3-61 My Contacts Implementation details for the Instant Messaging Contact List The following topics explain how to change the properties of the IBM Lotus Instant Messaging Contact List (Sametime Contact List) application. The application is a component of the Collaboration Center. To fully explain this implementation, we provide complete details concerning: Initial setup Chapter 3. Using existing portlets 151 Edit parameters Using Initial setup The Lotus Instant Messaging Contact List (Sametime Contact List) is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog; however, if you install the Extended Products Portlets (3.3, “Integration Option 1 Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), the Sametime Contact List portlet is installed with all the other portlets. Click the My Workplace link and then click the Web Conferences or Mail link. (the Contact List is available on both pages); otherwise, you complete the following tasks to deploy the portlet: Install the portlet WAR file. The My Contacts portlet is provided by the portlet application, SametimeContactList.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Editing and configuration parameters There are no edit and configuration parameters for this portlet. The Portlet works only if a Sametime server is installed and running. Using the Instant Messaging portlet If you want to chat with people, click the triangle for a group that contains a person with whom you want to chat. The names of people available for chatting appear with a green icon.Then click the name of any person with whom you want to chat. In the window that opens (Figure 3-62 on page 153), do one or more of the following: Type a chat message and press Enter or click Send. Click Invite Others to create and send an invitation for a multiple-person chat. You can select names from a directory and search the directory for names. Click Add Tools to enable screen sharing, whiteboard, audio, or video for your chat meeting. To complete the chat, click Close. 152 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-62 Chat Working with People and Groups 1. Click People and select Add Person or Group (Figure 3-63). You must know how to spell the Person or Group name (no directory lookup is available). 2. Type the person's name. 3. From the drop-down list, select the name of the personal group to which you want to add the person. 4. Click Add, then click Return to List. Figure 3-63 Add Person or Group Chapter 3. Using existing portlets 153 Working with a personal group You can create or rename a personal group. 1. Click People and select Create Personal Group or Rename Personal Group. 2. Type a new name for the group, click Create or Rename, and then click Return to List. Figure 3-64 My Contacts - New Group Options Displaying only online names in the contact list My Contacts can show names of anyone who uses Sametime in your organization, but you can chat only with names displayed as active (green). Click Options and select Show Online People Only. To return to the default of showing all names, click Options and select Show All People. Changing your online status message: Your online status message (Active, Away, and so on) appears when another user hovers the cursor over your name in their list. Click Options and select Change Online Status. 154 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Select one of the following messages: To show others you are available to chat (green icon), select I Am Active. To tell others you are temporarily unavailable (yellow icon), select I Am Away. To tell others you are online but do not want to chat at this time (double clock icon), select Do Not Disturb Me. Figure 3-65 My Contacts - Options 3.5.5 My Lotus Team Workplaces (QuickPlace) The IBM Lotus My Team Workplaces portlet lets users find, work in, and request new team workplaces as well as view workplace details. This portlet can be integrated with People Finder as part of the Collaboration Center, or deployed independently. As with the other Collaboration Center portlets, people links are visible in the My Team Workplaces portlet to make employee interaction fast and easy, improving personal and organizational productivity. Considerations With using the My Team Workplaces portlet, users have a central location from which to see and visit the online workplaces to which they belong. Users can quickly find workplaces to see summary views of activity and recent events, to get more detailed information about the workplace, and to work in the place. People links in team workplaces provide a way for place members to interact with each other. The My Team Workplaces portlet cannot be deployed in a public page in the portal. That is, the portlet is not available to anonymous (unauthenticated) portal users. Registered (authenticated) users - namely users who have logged in to the portal - can use My Team Workplaces in the pages to which they have access. Implementation details for the Team Workplaces portlet This part explains how to set up the properties of the IBM Lotus Team Workplaces application. The application is a component of the Collaboration Chapter 3. Using existing portlets 155 Center. To fully explain this implementation, we provide complete details concerning: Initial setup Edit parameters Using Initial setup Lotus Team Workplaces is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog. However, if you install the Extended Products Portlets (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), the Team Workplaces portlet is installed with all the other portlets. Click the My Workplace link and then click the Team Space link; otherwise, complete the following tasks to deploy the portlet: Install the portlet WAR file. The Team Workplaces portlet is provided by the portlet application, LotusMyTeamWorkplaces.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are shown in 2.4, “Deploying the case study portlets” on page 83. Figure 3-38 on page 132 shows the Lotus Notes View portlets page before configuration. Edit parameters 1. Click the pencil icon in the title bar, as shown in Figure 3-66. Figure 3-66 Editing a portlets’ properties 2. Edit the properties you want to modify. – My workplaces: Workplaces are listed in one or more screens within the List view. This number specifies the maximum number of workplaces that can be listed on a screen. – Details: Workplace pages are listed in one or more screens within the Details view. This number specifies the maximum number of pages that can be listed on a screen. 156 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Search results: Workplace pages that match entered search criteria are listed in one or more screens within the Search Results view. This number specifies the maximum number of pages that can be listed on a screen. Figure 3-67 gives some example parameters. Figure 3-67 Team Space - edit UI 3. Click OK to accept the changes or Cancel to abandon them. Using the My Team Workplaces Portlet To view team workplaces, use the List view. It is the default view for the My Team Workplaces application and it lists all workplaces that you are a member of. If you are not a member of any team workplace, or you are not logged on, the list table does not display. Click a team workplace name or the down-arrow next to it to display the Display Details menu.(Figure 3-68). Figure 3-68 Display Details menu Chapter 3. Using existing portlets 157 Open Workplace: Opens the workplace in a separate browser window. The same window is used for any workplace you open in the current session. What's New: Opens the Details view, listing the What's New pages for the workplace. My Tasks: Opens the Details view, listing the My Tasks pages for the workplace. My Pages: Opens the Details view, listing all pages in the workplace that include your name in the Author field. Search This Workplace: Opens the Advanced Search view with this workplace selected as the workplace to be searched. Details view Now we show you how to use the Details view in the IBM Lotus My Team Workplaces (QuickPlace) application.The Details view lists the pages in a workplace. You can access it in various ways, for example, from the Details menu on the List view by clicking My Tasks. In the Display Details view (Figure 3-69), you can perform the following actions: Display the pages of a particular category by selecting the category in the View drop-down list. The categories are What's New, My Tasks, and My Pages. Access a page by clicking its title. Search the workplace for pages that contain particular text. Enter your search text in the Search this workplace box and click Go or use more advanced searches within the current workplace by clicking Advanced Search. Open the current workplace by choosing Open Workplace from the menu. Update the list of displayed pages from the server by choosing Refresh from the menu. Figure 3-69 Team Space - What’s New 158 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 New workplace The following section explains how to add a new team workplace using the IBM Lotus My Team Workplaces (QuickPlace) application. 1. Click New Workplace on the default (List) view to open the Request a New Team Workplace view (Figure 3-70). Figure 3-70 New Team Workplace – In Workplace Type, select one of the available types in the drop-down list. – In Name for Address, enter a short name for the new workplace, for example, “RedbookTeam”. This will become the final part of the URL for the workplace. – In Title, enter a suitable title for the new workplace, for example, “Redbook Team Workplace”. – In Workplace Manager Name, enter the name of the person who is to be manager of the new workplace. – In E-mail Address, enter the e-mail address of the manager named in the previous step. Chapter 3. Using existing portlets 159 – (Optional) Enter data into the remaining fields. Your administrator may have tailored these to the particular needs of your organization. The default fields are the following: • Expiration Date: Enter a date after which the workplace will no longer be needed. • Cost Center: Enter the cost center for the department that will be using the workplace. • Department: Enter the name of the department that will be using the workplace. • Description: Enter a description for the workplace. 2. Click Submit Request to send the request to the team workplace administrator, or click Cancel to cancel your request. 3.5.6 People Finder Portlet The People Finder portlet provides both quick search and advanced search options for locating people and information about people. Once found, a person is visible to other users as a person link, which indicates an online presence, and displays a menu of instant messaging and other options. Clicking a person link displays the Person Record, including the person's business card information followed by administrator-defined fields organized in sections, for example, Contact Information, Current Job, and Background. The portlet also provides a view of the person's place in the organizational context. In the Organization View, users can display the person's reporting structure; that is, the employees the person manages, if any, and the person's management chain. Considerations Before you configure the People Finder portlet, familiarize yourself with the IBM WebSphere Member Manager attributes that correspond to the pre-configured fields in People Finder. General users work with the People Finder portlet using the following features, which appear in one or more views of the portlet: Quick Search and Quick Search Results, including Business Card fields Advanced Search and Advanced Search Results Person record, including Business Card fields Organization view, including Business Card fields 160 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Implementation details This section describes how to use the People finder portlet to find information about people. The application is a component of the Collaboration Center. To fully explain this implementation, we provide complete details concerning: Initial setup Configuration options Using Initial setup People finder is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog. However, if you install the Extended Products Portlets (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), the People finder portlet is installed with all the other portlets. Click the My Workplace link and then click the Team Space or Mail link. People finder is available on both pages; otherwise, complete the following tasks to deploy the portlet: Install the portlet WAR file. The Team Workplaces portlet is provided by the portlet application, lwppeoplefinder.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Configuration options The People Finder portlet is pre-configured for immediate use. In the Attributes and Display Formats table, review the default attributes and display formats that are selected to appear as fields of the People Finder portlet. The Member Manager attributes selected here are used as fields in the default configuration of the portlet's views and search queries. Tip: If you wish to use the portlet in its default configuration, do not change the selected fields. Consider testing the default configuration in a pilot deployment before changing portlet fields. In the title bar, select the Configuration icon in the top right hand of the portlet window and click as shown in Figure 3-71 on page 162. Chapter 3. Using existing portlets 161 Figure 3-71 Configuring a portlets’ properties Configuration Basics 1. You can see the Configuration Overview page as shown in Figure 3-72. Under Define Shared Elements, click Configuration Basics. Figure 3-72 People finder - Configuration Overview 2. On the Configuration Basics page, in the Search Results field, type the maximum number of items for Quick Search and Advanced Search to return (Figure 3-73 on page 163). The number that you specify here overwrites the Member Manager setting for the maximum number of items to return in a search results list. If you specify zero (0), People Finder uses the Member Manager default value for the maximum number of search results to return. 162 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-73 People finder - Basic Configuration 3. In the Attributes and Display Formats table, select the Include check box for each field to use in the People Finder portlet. The fields you select here are available for selection when you perform subsequent configuration tasks. For each selected field, click one of the following to specify the display format: – String: Plain text. Corresponds to Member Manager data type String. – Link: The address of an Internet or intranet site. Corresponds to Member Manager data type String. – Person Link: A person's name displayed as a link showing online status and, when clicked, an action menu. Corresponds to Member Manager attribute MemberIdentifier with data type String. – Member Link: A person related to the found person (for example, the found person's manager or administrative assistant), whose name is displayed as a link showing online status and, when clicked, an action menu. Corresponds to Member Manager data type String. – E-mail: An e-mail address displayed as a mailto: link. Corresponds to Member Manager data type String. – Numeric: Corresponds to Member Manager data types Integer, Long, and Double. Chapter 3. Using existing portlets 163 – Image: Corresponds to Member Manager data type ByteArray. – Object: Corresponds to Member Manager data type Object. 4. Click OK to save your changes and return to the Configuration Overview. Business Card The Business Card provides basic information about a person. You may choose to include a person's photograph on the business card. Tip: For best results, do not add more than six lines to the business card. 1. On the Configuration Overview page, under Define Shared Elements, click Business Card (Figure 3-74). Figure 3-74 People finder - Business Card 2. To include a photograph in the Person Record and the Organization View, select the check box Include photo, and then from the Attribute containing photo list, select the Member Manager attribute that contains photos. By default, the selected attribute is jpegPhoto. 164 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3. From the list of available fields, click displayName and then click Add. Then, one by one, select a field and then click Add until you finish adding fields. 4. In the table of Fields and Descriptions, click Up and Down to order the fields as you want them to appear on the business card. Click Delete to remove a field from the table. 5. Click OK to save your changes and return to the Configuration Overview. Sections The Person Record and Advanced Search views are pre-configured to include the sections Contact Information, Current Job, and Background. You can add sections to use when you define the layout of the Person Record and the Advanced Search views. Important: Sections that you add must already be defined in the language-specific properties file of the People Finder, PeopleFinderUI_language_code.properties. When you add a section, you enter the resource key for a section name. 1. On the Configuration Overview page, under Define Shared Elements, click Sections to display the task page (Figure 3-75). Figure 3-75 People Finder - sections Chapter 3. Using existing portlets 165 2. For each section that you want to add in the Section Name Resource Key field, type the resource key and then click Add. 3. In the table of Resource Keys and Display Labels, click Up and Down to order the sections as you want them to appear in the Person Record and Advanced Search views. Click Delete to remove a section from the table. Deleting a section also deletes the Person Record fields and the Advanced Search queries and results. 4. Click OK to save your changes and return to the Configuration Overview. Using Now you can use the People Finder to find information about people. These sections explain how to use the People Finder. Using quick search Quick search is the default view for People Finder. To search for a person, follow these steps: 1. In the Search by list, select the area of personal data to search. The list typically includes these items: – Name – User ID – E-mail – Phone – Department – Job Title 2. In the Search for field, enter the text you want to find. 3. Click Search. 4. Figure 3-76 on page 167 shows the results of a quick search. If only one name is found, you also see the business card information for that person. 166 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-76 People Finder - quick search Tip: Searching is not case-sensitive, so m and M are treated as the same letter. In most cases, a match is returned if an entry is found that begins with the text you entered. For example, the search text “ma” would find Martin or Mary Weng in a first name field. Using advanced search To carry out an advanced search, follow these steps: 1. Click Advanced Search to open the Advanced Search view (Figure 3-77 on page 168). Chapter 3. Using existing portlets 167 Figure 3-77 Advanced search 2. In one or more of the search text boxes, enter the text you want to find. – People finder compares the text you enter against the appropriate fields in the Person Records. – Matching is additive. In other words, if you enter search text in the First Name field and also in the Last Name field, only people who have a first name that contains the First Name search text and a last name that contains the Last Name search text will be returned. 3. Click Search or, to return to the main People Finder view at any time, click Cancel. 4. Figure 3-78 on page 169 shows the results of a advanced search. 168 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 3-78 People Finder - Detail Person Record 5. Figure 3-79 on page 170 shows the second part results of a advanced search. Your administrator determines whether or not the Organization view is available; by default, it includes these sections and fields. Chapter 3. Using existing portlets 169 Figure 3-79 People Finder - Organization 3.5.7 Domino.Doc (Document Manager) Portlet IBM Lotus Domino Document Manager is the document management solution for organizing, managing, and storing all of your critical business documents, and for making them accessible inside and outside your organization. Built on the common storage metaphor of file rooms, file cabinets, binder categories, binders (folders), and documents, Document Manager is familiar and, therefore, easy to learn and use directly from your browser with this WebSphere Portal instance of the Documents application. Implementation details for the Document Manager Portlet The following topics explain how to set up the Domino Document Manager. The application is a component of the Collaboration Center. To fully explain this implementation, we provide complete details concerning: Initial setup Edit parameters Result Initial setup Domino Document Manager (Domino.Doc) is set up like any other portlet; the WAR file is installed and then the portlet is added to a page. This is true for the stand-alone version available from the portlet catalog; however, if you install 170 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Extended Products Portlet (3.3, “Integration Option 1 - Using the Domino V6.5.1 and Extended Products Portlets: Collaboration the easy way” on page 100), Domino.Doc is installed with all the other portlets. Click the My Workplace link and then click the Documents link; otherwise, you complete the following tasks to deploy the portlet: Install the portlet WAR file. The Domino.Doc portlet is provided by the portlet application, domdoc.war. Create a place or pages for the portlets. Add the portlets to a page. The detailed steps for performing each of these tasks are in 2.4, “Deploying the case study portlets” on page 83. Edit parameters 1. In the title bar, click the Edit icon (Figure 3-80). Figure 3-80 Edit icon 2. You see Domino.Doc Source Form, as shown in Figure 3-81 on page 172. Chapter 3. Using existing portlets 171 Figure 3-81 Domino.Doc sources form – Under Title, edit the title, for example, to Documents. You can type any title, but do not leave the field blank. – Under Source, in the Server field, specify the name of the Domino server that contains the Document Manager source database, for example, itso-dom.cam.itso.ibm.com. You may select a name from the list under the Server field, or type a name. • When you select the check box next to the Server field with a server name selected, if the server has Document Manager source databases or directories with Document Manager databases, they will appear in the Database list. – Under Database filename, specify a Document Manager database name. You can select a name in the list under Database, or type a name, for example, redbooklib.nsf, in the Database filename field. If you select a database name, it will appear in the Database filename field. If you select a directory from the Database list, the directory will appear in the Database filename field and the names of the Document Manager databases in that directory will appear in the Database list. Select a database in the Database list and the name will be appended to the directory name in the Database filename field. 172 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tip: When you see two periods (..) appear in the Database list, you can click them to move to the next higher directory on the server. – Under Application width and Application height, type a number of pixels to determine the size of Documents within the column. – Select one of the following options for the Internet protocol of the server hosting Document Manager: • HTTP • HTTPS (for Secure Socket Layer) • Detect protocol automatically Tip: Select Detect protocol automatically if you do not know the server's protocol. 3. Click OK to keep or Cancel to discard changes to the source database. Results of using the Document Manager portlet If Single Sign-on has been correctly configured, you should see something similar to Figure 3-82. Figure 3-82 The Document Manager portlet Chapter 3. Using existing portlets 173 3.6 Reference material The following Web sites and Redbooks are helpful when exploring the integration of Lotus Domino and WebSphere: Domino and WebSphere Together, Second Edition, SG24-5955 IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917 IBM Lotus Domino Developer Domain http://www.lotus.com/ldd IBM WebSphere Developer Domain - Portal Zone http://www-106.ibm.com/developerworks/websphere/zones/portal/ Lotus Domino 6.5.1 and Extended Products Integration Guide, SG24-6357 174 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4 Chapter 4. Using custom Domino JSP Tag libraries This chapter describes how to integrate Lotus Domino applications into a WebSphere Portal using the custom Domino JSP Tag libraries, which were introduced in Release 6 of Domino. We begin the chapter by reviewing several pertinent technologies: J2EE, JSP, and Tag libraries. Next, we introduce the tools needed to accomplish a successful integration. As we describe how we integrated our sample application, we point out some key considerations, as well as some common pitfalls along the way, and how they can be overcome. © Copyright IBM Corp. 2005. All rights reserved. 175 4.1 Overview The Lotus Domino Toolkit for WebSphere Studio enables easy creation of integrated Domino and WebSphere applications by seamlessly connecting the Domino database to WebSphere Studio. Developers can build Java Server Pages in WebSphere Studio with virtually no coding as well as access elements in Domino databases — such as forms, views, and action buttons — using a visual drag-and-drop interface to build sophisticated pages for applications. The toolkit installs the Domino JSP tag libraries and configures the WebSphere Studio environment for their use. It also creates a Domino view to the Studio navigator from which one can drag and drop the Domino JSP tag onto the JSP being developed. 4.1.1 Skills and degree of customization - Domino JSP Tags Figure 4-1 on page 177 gives an overview of this integration option relative to all the available options open to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. 176 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 Bowstreet Portlet Factory / Conet Knowledge Director 2 1 IBM Portlet Builder for Domino limited Existing Portlets 4 Lotus Workplace Builder low Level of customization high Figure 4-1 Integration options The main message to take from this graphic is that the Domino custom JSP Tags approach represents an excellent option for a high degree of customization, while only requiring intermediate Java knowledge. Finally, keep in mind that, depending on the solution you need, a combination of several options may be required. For example, if portlets built by the IBM Portlet Builder for Domino need to be “fine-tuned”, it may be necessary to use Domino JSP tags or to use the Domino Java API. 4.2 Technologies involved The integration techniques described in this chapter rely on several technologies; this section is a brief introduction to them. It begins with a look at J2EE and a description of some of its components, then provides a closer look at JavaServer Pages (JSP) technology and custom JSP Tag libraries. Since there is a countless number of publications about J2EE, JSPs, and so on, we will concentrate on basic information. Chapter 4. Using custom Domino JSP Tag libraries 177 4.2.1 J2EE overview Java 2 Enterprise Edition (J2EE) is a specification for a standard platform for developing and hosting reusable components. The components can then be used to provide multi-tier client- and server-based enterprise applications. It is based on the Java 2 Standard Edition (J2SE, formerly called Java Runtime Environment or JRE), which has been complemented with enterprise standards that provide a scalable, robust, secure, and stable platform to build enterprise solutions. It enables developers to extend existing solutions by creating applications quickly, with reduced complexity, cost, and facilities. Technologies included in J2EE Some of the technologies in the J2EE platform are: JavaServer Pages (JSPs) Java Servlets Enterprise JavaBeans (EJBs) J2EE Connector Architecture CORBA JDBC data access API What’s different in J2EE versus Domino? One of the main advantages and strengths of J2EE is the separation of the tiers or layers that compose an e-business application. Unlike a Lotus Domino application, where all the data, business logic, and presentation objects are packed on a single .NSF file, in the J2EE design pattern there are several separate containers that represent different logical tiers, as depicted Figure 4-2 on page 179. 178 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-2 J2EE design Database tier Viewing the figure from right to left, the first tier is the Database tier. This tier is not part of the J2EE spec and is accessed directly by a technology called JDBC, which provides access to the application data stored on relational databases. From a J2EE developer point of view, this tier is basically a provider of data access and storage. EJB container tier Next is the EJB container tier, which is a J2EE run-time component. You would place business logic here by using Java components called Enterprise Java Beans (EJB), which actually are designed to provide seamless access to relational databases and enterprise information systems (EIS) with transactional integrity. Along with the data storage and access facilities, you can embed the business logic of your application in these components since they offer high performance and availability mechanisms that can be accessed from different channels of communication, not just through the Web. Chapter 4. Using custom Domino JSP Tag libraries 179 Web container tier The next tier is the Web container (also a J2EE runtime component), which is designed to construct presentation components and control presentation logic. It is based on technologies that offer a high performance, extendable presentation framework to build upon, like Servlets and JavaServer Pages. The Web container is also the host of other technologies, such as Web Services and XML-XSLT applications, that enable your applications to extend to other channels of interaction. Client tier The final layer is the client tier, which is represented by two types of client. The most commonly used is the thin client Web browser, which basically understands and renders the HTML or XHTML broadcast from the Web container into Web pages. Inside the browser, you can have a Java component called Applets, which as shown in the diagram can only access the J2SE basic services. Also, there is another type of client, called the J2EE Client container, because J2EE allows a client-server configuration. This fat client has access to several J2EE services; it is used when the use of external devices and usability issues arise that the Web Browser is unable to attend to. Additional thoughts on J2EE The Web container and the EJB container are the two main blocks that make up a J2EE application server. The WebSphere Portal allows the construction of Portlet applications that will reside on the Web container, so our focus remains on this container as we explore the JSP - Domino custom JSP tag libraries option of portalizing Lotus Domino applications. The Portlet components extend the Servlet component, and can present its information using JSP pages. And since JSP development is part of the Lotus Domino development environment, it seems natural to understand and unleash the power of JSPs in the portal environment. More information about J2EE can be found at the Sun Microsystems Web site: http://java.sun.com 4.2.2 JavaServer Pages A JavaServer Page (JSP) is a HTML Web page that contains code that executes application logic to generate dynamic content. The page is created at the time it is requested. JSPs are compiled into servlets; the code they contain is executed by the server. 180 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The power of a JSP page is in the tags that it contains. JSP tags are similar to HTML tags, except they contain a reference to Java implementation classes rather than to instructions on how to display the tag body. A JSP allows you to easily create content for Web applications while maintaining the ability to include information generated on the fly. That can be computed by Java code or extracted from other third-party systems such as, in our case, Lotus Domino applications. Definition of a JSP A JSP is a standard file that is written basically in HTML, which can include special tags to allow developers include dynamic content for Web applications. From a Java point of view, it extends the Servlet component used in most J2EE Web applications. The JSP files end with a .jsp extension. The following code snippet contains the code of a simple JSP file. Example 4-1 JSP sample snippet <html> <body> <% out.println(“Hello World !!”); %> </body> </html> As you can see, this snippet looks much like a standard HTML file, with some special tags that contain Java code inside. The output of this JSP will be a Hello World !! message on the Web browser. There are several elements in a JSP file, one of which will help us include JSP Tag libraries. The elements included in a JSP file are briefly described in the following section. Elements of a JSP The JSP files can embed Java code through the use of special tags. These tags can be grouped into four main categories. Directives The JSP Directives are elements that give the J2EE Application Server global information about the JSP file. The instructions are processed by the JSP engine on compilation time. Directives are used to set instruction on page level, insert data from external files, and to declare custom tag libraries. The syntax of the JSP Directive is: <%@ directive attribute=”value” %> Chapter 4. Using custom Domino JSP Tag libraries 181 The attribute and value pair are optional. Table 4-1 identifies some of the directives. Table 4-1 JSP Directives Directive Description Available attributes page Defines information that affects the global definition of the JSP file. The attributes are not required, since they are set by default. autoFlush buffer contentType errorPage extends info import isErrorPage isThreadSafe language session include This directive lets the developer include files in the JSP at compile time. file taglib Lets the JSP include custom tag libraries on the JSP. uri prefix We will use the taglib directive in our JSP examples to include the custom Domino JSP tags. For further information about the JSP directives and attributes, refer to the references at the end of this chapter. Declarations Declarations are used when a JSP developer wants to include methods or define variables on the Servlet class generated by the J2EE Web Container. Declared variables map to servlet instance variables and should not be modified during the request. Example 4-2 is a sample of a String variable declaration inside a JSP file. Example 4-2 Sample variable declaration inside a JSP file <html> <body> <%! String myString=new String(“My String”);%> </body> </html> Example 4-3 on page 183 shows the declaration of a method inside a JSP file. 182 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-3 Sample method declaration inside a JSP file <html> <body> <%! public getMyString() { return myString; )%> </body> </html> Expressions Expressions are used to display dynamic Java content on the Web browser. These are some of the most commonly used elements in JSP files. The expression tags are replaced by the evaluation of the Java code; this evaluation is performed at runtime. The syntax of an expression is: <%= expression%> The expression evaluated must successfully return a String class or a class that can be converted into a String. Example 4-4 is a sample of a JSP expression. Example 4-4 Sample JSP expression <html> <body> <%=this.getMyString()%> </body> </html> Scriptlets Scriptlets are general purpose Java tags within which a developer can embed normal Java code. The syntax of the scriptlets is: <% javaCode %> Example 4-5 is an example of a JSP Scriptlet. Example 4-5 Sample JSP scriptlet <html> <body> <% out.println(“Hello World !!”); %> </body> </html> Chapter 4. Using custom Domino JSP Tag libraries 183 Implicit objects in JSP files Working with JSP files, you will be able to reference—without declaring—several Java objects. These objects have exactly the same characteristics as though they where being called from a Servlet component. Table 4-2 outlines the most important objects. Table 4-2 Some important implicit objects in JSP files Object name Description session This object represents the javax.servlet.http.HttpSession object and is most commonly used to store data that is related to the user, through the user interaction with the application. One of the most important uses of this object is to replace the stateless nature of HTTP by providing a temporary stateful storage of the information the user generates though his interaction with the Web application. request This object represents the javax.servlet.http.HttpServletRequest interface and is primarily used to allow the user to access the request parameters through the getParameter(String) method. Also, this object is used frequently to pass attributes from one request to the target JSP file. It also exposes, through different methods, the requesting user and device information that is trying to access the JSP file. response This object represents the javax.servlet.http.HttpServletResponse and is responsible for passing information back to the requesting client. It is commonly used to write information to the output stream, although the out object takes care of that. out This object represents a JspWriter, which is derived from the java.io.Writer and provides the client the ability to stream information back to the requesting client. One of the most common methods used by this object is the out.println(String) method, which prints the String parameter directly on the output generated by the JSP file. For further information about JSP implicit objects, check the references at the end of this chapter. Providing a stateful interaction through a stateless protocol The nature of the HTTP protocol is stateless, meaning it basically accepts a request through a TCP/IP port and responds with a bytestream of characters that are rendered on the Web browser. To compensate for this shortcoming, the J2EE technology includes objects that can be used by our JSPs, which are implicit in their use and solve the stateless characteristics of the HTTP protocol. In the previous section, we discussed an implicit object called session. This object represents the javax.servlet.HttpSession class; its purpose is to maintain a temporary storage area that can be used by our applications to keep the context 184 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 of who is interacting with our application and with what characteristics this interaction is taking place. As shown in Figure 4-3, there are two techniques used to enable this interaction. The first is to maintain a Session ID on a cookie inside the browser. This cookie contains the ID code that the Web container can use to look up the session data in which the current user is working. The second approach is rewriting the URL, which appends the Session ID to the URL to maintain the session-browser relationship. This approach is not supported by our portal infrastructure since we could have a session for each portlet. Figure 4-3 Stateful interactions using Java components The use of the session object inside our JSPs will enable us to maintain portlet-specific information through the user interaction with the portal. To illustrate this, imagine you have a portlet that extracts user information, but then you change to another WebSphere Portal place or page to interact with other portlets. When you come back to the original portlet, it would be useful to still get the same information as you had before. This can be accomplished using the session object. JSP limitations The JSP technology has one main limitation that should be taken into account: the size of the Java bytestream is limited to 64 KB. Chapter 4. Using custom Domino JSP Tag libraries 185 For more information about JSPs, see the Sun Microsystems Web site: http://java.sun.com/products/jsp/ 4.3 Software and tools used As we discuss the examples, we refer to several tools available to developers. Some of them are: Lotus Domino Designer V6.5.3 WebSphere Studio Application Developer V5.1.2 WebSphere Portal Toolkit for WebSphere Studio V5.0.2.2 Lotus Domino Toolkit for WebSphere Studio V1.3 Since we discussed the Domino Designer in previous chapters, we will focus on reviewing the other tools available in this chapter. For further information about the Lotus Domino Designer, refer to the references at the end of this chapter. 4.3.1 WebSphere Studio Application Developer V5.1.2 WebSphere Studio Application Developer is one of the WebSphere Studio family of products that has been developed based on the Eclipse Workbench. The Eclipse Workbench is an open source development platform, designed by IBM and released to the open source community. It is an open, portable, universal tooling platform that provides frameworks, services, and tools for building tools. In essence the workbench provides the tool infrastructure. With this infrastructure in place, the tool builders are able to focus on the actual building of their tools. The workbench has been designed for maximum flexibility to support the development of tools for new technologies that may emerge in the future. Development tools written for the workbench should support a role-based development model, in which the outcomes of the developers’ work will be consistent. The developers should not have to be concerned with how different individual tools may be treating their files. The WebSphere Studio family of products is an integrated platform (IDE) for developing, testing, debugging, and deploying J2EE applications. It provides support for each phase of the application development life cycle. WebSphere Studio Application Developer V5 includes the following tools: Web development tools Jakarta Struts development tools 186 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Enterprise JavaBeans (EJB) development tools Portal development tools Java development tools Web services development tools XML development tools Relational database tools Team collaboration tools Integrated debugger for JSPs, Servlets, EJBs, and Java code Server tools for testing and development Tracing, monitoring, and performance analysis tools Debugger Log and Trace Analyzer Plug-in development tools Integration with automated build tools like ANT Unit test tools like JUnit The WebSphere Studio Application Developer has many features to assist the developer; some are illustrated in Figure 4-4 on page 188. Within the framework, there are development perspectives that let you invoke the tools without losing the reference to the working object. In addition, the framework is extendable, allowing you to plug in other tools like WebSphere Portal Toolkit for WebSphere Studio and Lotus Domino Toolkit for WebSphere Studio. Chapter 4. Using custom Domino JSP Tag libraries 187 Partner Products and Developer Specific Plug-ins Rational, Merant, Serena, Instantiations.... User Experience, Mobile Internet... Non-IBM Offerings & Extensions IBM Specialized Modular Extensions WebSphere Portal Server Plugin Business Integrator Plugin VoiceXML Server Plugin WS Studio Enterprise Developer IBM WebSphere AD Tools Portfolio WS Studio Appl. Dev. Integration Edition WS Studio Application Developer WS Studio Site Developer .....Many more to Come Commerce Sever Plugin Versata Logic Studio Business Logic Automation WebSphere Developer Studio for iSeries ... WebSphere Studio Workbench Common Services Open Tools Platform Services Resource management Project model Common Framework Team programming model Debugging Extensibility framework Widget toolkit UI Framework Editing Framework Builders, Markers, Help Infrastructure, Software Configuration Management, Windows/Linux Figure 4-4 WebSphere Studio internal structure As the figure shows, the WebSphere Studio tool is constructed of building blocks. The cornerstone of the structure is the Eclipse Framework, and on top of it IBM WebSphere Studio Workbench is the basic framework on which several flavors of the WebSphere Studio products are supported. The first item in the WebSphere Studio portfolio is WebSphere Studio Site Developer, which provides support for creating Web applications and Web services projects and utilizes the broad number of services provided by the WebSphere Studio Workbench. Next is WebSphere Studio Application Developer, which gives the developer a full J2EE environment for developing enterprise applications. On top of it, the WebSphere Studio Application Developer Integration Edition delivers a full environment for developing JCA adapters and enterprise services provided by the WebSphere Application Server Enterprise Edition. 188 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Finally, the top of the line tool is the WebSphere Studio Enterprise Developer, which gives the traditional Cobol CICS® developer an environment for developing legacy applications, along with the new EGL language, which helps develop enterprise applications on a 4GL environment. The WebSphere Studio family comes with excellent tools to visually build JSP interfaces and construct visually the logic of Web applications using the Jakarta Struts framework. The Struts framework and how it fits in the Portal environment is discussed in the next chapter. Figure 4-5 gives an overview of WebSphere Studio Application Developer. Figure 4-5 Snapshot of WebSphere Studio Application Developer For more information about WebSphere Studio Application Developer V5, refer to the references at the end of this chapter. 4.3.2 WebSphere Portal Toolkit for WebSphere Studio V5.0.2.2 The IBM Portal Toolkit Version 5.0.2.2 provides the capabilities to customize, create, test, debug, and deploy individual portlets and Web content. Portals provide a mechanism for aggregating information and accessing enterprise Chapter 4. Using custom Domino JSP Tag libraries 189 services via a single consolidated view for Web usage. A portlet (similar to a servlet) provides access to a specific application or function that is available to the user via the portal. Templates in the Portal Toolkit V5.0.2.2 enable developers to quickly and easily create their own portlets. Debugging and deployment tools shorten the development cycle. And the sample portlets provide best programming practices. The Portal Toolkit plugs into the IBM WebSphere Studio products and provides a comprehensive framework for the development of e-business applications. Portal Toolkit provides the following: Portlet project supporting: – IBM portlet API – JSR 168 portlet API Portlet perspective for developing portlets Portlet project wizard to create: – Basic portlet – Faces portlet – Struts portlet – Portlet examples Editing and validating of the portlet deployment descriptor (portlet.xml) Testing and debugging of portlets – WebSphere Portal Test Environment – WebSphere Portal Server Attach Previewing of portlets Visual tooling to insert portlet programming objects to JSP files in Page Designer Online help for portlet development Figure 4-6 on page 191 gives an overview of WebSphere Portal Toolkit for WebSphere Studio. 190 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-6 WebSphere Portal Toolkit for WebSphere Studio Development environment configurations You can set up your development environment to debug portlets that are running locally or remotely. Local debug configuration You can run and debug portlets on the local development machine. In this environment, you can run and debug your portlets without having to manually deploy them to the server (see Figure 4-7). Figure 4-7 Development Environment - Local debug configuration Chapter 4. Using custom Domino JSP Tag libraries 191 Remote debug configuration: You can run and debug portlets that are deployed to WebSphere Portal installed on a remote server from your local system (see Figure 4-8). Figure 4-8 Development Environment - Remote debug configuration For the latest information about the toolkit, and for downloadable upgrades and fixes, check the following Web site: http://www.ibm.com/websphere/portal/toolkit 4.3.3 Lotus Domino Toolkit for WebSphere Studio V1.3 The Lotus Domino Toolkit for WebSphere Studio is a plug-in for WebSphere Studio Application Developer and WebSphere Studio Site Developer. It allows you to add Domino 6 custom tags to Java server pages, providing a simple way to blend Domino and J2EE applications. JSP tags are XML tags embedded in a JSP providing data access, data input, and process control. The tags abstract the Domino objects for Java (Domino Java API) and provide a quick development turnaround for building J2EE applications that use Domino data and services. The toolkit provides a dedicated pane in WebSphere Studio where you open the Domino database you wish to work with. The pane displays the views, columns, forms, fields, and Domino server agents in the database, and provides two quick ways of putting Domino tags into your page: You can right-click an item and choose Add to Web Page from the Context menu You can drag and drop an item directly into the page. Either of these operations will paste a tag representation of the item into the editor at the current cursor position. Of course, if you prefer, you can add the tags manually in the editor. 192 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-9 Lotus Domino Toolkit for WebSphere Studio V1.3 How it fits into the Lotus technology strategy To understand the Lotus technology strategy, and how it applies to Domino applications and their development, envision a multi-lane superhighway with a Lotus Domino lane, a WebSphere lane, and a next generation lane. The Lotus Domino lane continues as far as the eye can see and runs parallel to the WebSphere lane, which also continues as far as the eye can see. The next generation lane merges with the other two lanes at a point in the future. In the Lotus Domino lane, the Domino collaborative application development and deployment environment enables you to develop applications quickly and to take them offline, bringing people, processes, and data together to facilitate both productivity in e-business and quick decision-making. Lotus will continue the current Domino application development model and data store (NSF) and in the future, will enhance it to meet customer and developer requirements. As in the IBM tradition, Lotus Notes and Domino customers will benefit from comprehensive support for the foreseeable future. Additionally, Lotus Domino will Chapter 4. Using custom Domino JSP Tag libraries 193 increase its support of the J2EE and infrastructure standards, such as JSP tags, Java APIs, LDAP, and RDB integration to assist developers interested in working in both the Domino and WebSphere lanes of the superhighway. In the WebSphere lane, the J2EE spec is leveraged as the application development platform. J2EE provides a specific architecture for building, deploying, and managing applications in multiple tiers, often broken into presentation, logic, and data. This architecture is designed to provide scalability, flexibility, and manageability. While J2EE is a rich application development platform, it has very few features to support collaboration, so it benefits from having Lotus Domino to provide rich collaborative capabilities. Applications designed to use the Lotus Domino and WebSphere lanes blend powerful collaborative features with significant transactional scalability to deliver end-to-end e-business solutions. Evolution of Lotus Domino Toolkit for WebSphere Studio The initial Version 1.0 of the toolkit shipped with Domino Designer V6.0.2 Version 1.1 shipped with Domino Designer V6.0.3 and V6.5 – Support for WebSphere Studio V5.0.1 and V5.1 – Categorization and drag-and-drop-enablement of all Domino Custom Tags in the Utilities menu – domino:session tag enhanced to allow sessions to be shared across JSPs – Support for Domino Custom Tags within WebSphere Portal deployments • Enhanced to work with Portal • New remote session optimization parameters for session tag Version 1.2 shipped with Domino Designer V6.5.1 – Includes Domino V6.5.1 JSP Custom Tags – Support for WebSphere Studio V5.1.1 – More SPR fixes – Ability to have more than one Domino JSP portlet per portal page doing updates – Keep the Domino files in your portal application in sync with the Domino server Version 1.3 ships with Domino Designer V6.5.2 – Includes Domino V6.5.2 JSP Custom Tags – Support for WebSphere Studio V5.1.2 – More SPR fixes 194 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Domino V6.5.2 tags support object pooling 4.4 Integration techniques In this section, we explain how to implement the four portlets that comprise the Sales Workplace described in 2.3, “Case study: A simple sales tracking application” on page 77. We show you how we constructed four portlets from scratch using the Portal Toolkit wizards. These portlets will include JSP pages where we will place the Domino custom JSP tags that allow us to access the Lotus Domino applications. Finally, when all four portlets are working on their own, we show you how we added some extended functionality: first, people awareness, so you will be able to collaborate with people on documents, and second, integrating our portlet at the portal level through Click-to-Action. The structure of the portlet page is shown in Figure 4-10. Figure 4-10 Domino custom JSP tags portlets Now lets take a closer look at what each of the portlets will do. Customer List The purpose of this portlet is to display the contents of the Customer By Name view from the customer.nsf Domino database. Later on, we will enable this portlet to handle people awareness and Click-to-Action functionality. Chapter 4. Using custom Domino JSP Tag libraries 195 When we finish the enablement of our portlet, it will look like the one displayed in Figure 4-11. Figure 4-11 Customer List portlet Customer Details The Customer Details portlet, when first invoked, will display a form with a drop-down list containing the customers from the database. After a customer is selected, the portlet will display the details about the customer. When we finish the enablement of our portlet, it will look like the one displayed in Figure 4-12. Figure 4-12 196 Customer Details portlet Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Customer Contacts The Customer Contacts portlet behaves similarly to the Customer Details portlet. When initially viewed, it will display a list of customers with radio buttons and pagination at the bottom of the page. After a selection is made the portlet will display all the contacts for the specified customer. The list of contacts is a view that is filtered by customer. When we finish the enablement of our portlet, it will look like the one displayed in Figure 4-13. Figure 4-13 Customer Contacts portlet Customer Sales Activities The Customer Sales Activities portlet initially displays a list of customers similar to the Customer Contracts portlet. After a customer is selected, a list of sales activities will be displayed. This list of activities is a view that is filtered by customer. When we finish the enablement of our portlet, it will look like the one displayed in Figure 4-14 on page 198. Chapter 4. Using custom Domino JSP Tag libraries 197 Figure 4-14 Customer Sales Activities portlet 4.5 Integration using Domino custom JSP Tag libraries We used the Domino custom JSP Tag libraries technology to create the core portlets that will integrate Domino components. The details of the implementation are in this section. 4.5.1 Overview This integration technique introduces the Portal toolkit’s ability to produce portlet projects easily and shows how, in conjunction with the Lotus Domino toolkit for WebSphere Studio, it incorporates the Domino custom JSP tags into standard JSP pages to extract Domino data. First, we review some basic required concepts on the portlet class and the abilities of the portlet to do event-based integration. Further information about the portlet class, APIs, and related objects is discussed in Chapter 5, “Portlet development using Java: Technology review” on page 313. 198 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4.5.2 Domino custom JSP tag libraries One of the JSP directives mentioned previously was the taglib directive. As explained, the JSP tag library is a collection of custom JSP tags that encapsulate Java code through the simple use of tags. The library defines declarative, modular functionality that can be reused by any JSP page. The tags are defined in an XML format file known as the Tag Library Descriptor file or TLD. This descriptor tells the JSP parser-compiler what Java classes and methods should be interpreted. Grouping these tags in libraries gives the JSP developer a simple but powerful tool to incorporate Java code in the application without getting into the details of Java. These JSP tag libraries can be used extensively on your JSP pages to include Lotus Domino elements into your J2EE/Portal applications. This option brings to the developer who is not a Java expert, or who is not knowledgeable on handling Lotus Domino Java back-end objects, the ability to enable a Web application to incorporate complex Lotus Domino interactions by simply adding a custom Domino JSP tag to the JSP. And since the WebSphere Portal framework is based on a J2EE environment that allows the inclusion of JSP files, the developer can expose Lotus Domino applications to the portal infrastructure with the use of custom Domino JSP tags. There are two Domino JSP tag libraries. Both comply with the standard specifications of JSP 1.1 and Java Servlet 2.2 developed by Sun Microsystems, which are supported by the WebSphere Portal infrastructure. The Lotus Domino tag libraries are: domtags.tld Collaboration tags for accessing standard, back-end objects in the Domino data repository domutil.tld Utility tags for performing tasks that are common to all J2EE Web containers The actual Java implementation that is invoked by the Domino JSP custom tags resides on three Java archive (JAR) files: domtags.jar NCSO.jar Notes.jar Notes.jar and NCSO.jar contains the core classes of the Java API for Lotus Domino. The classes within domtags.jar rely on the Java implementation that is provided by these two archives. Depending on the physical topology of the environment, one or both archives must be used. Chapter 4. Using custom Domino JSP Tag libraries 199 If your Domino server is on the same physical machine as your J2EE application server, you may either use Notes.jar or NCSO.jar (with DIIOP enabled). The classes in Notes.jar assume a local access environment. If the servers reside on different physical locations, you have to use NCSO.jar. This archive includes classes that allow remote access through the Domino Internet Inter-ORB Protocol (DIIOP). Alternatively, if you wish to have a testing or development environment which would include both the Domino Server and the J2EE Application server located on the same physical machine, you can include both the Notes.jar and NCSO.jar on the same physical machine. The reasons for doing this could be as follows: You want to perform certain testing/development tasks and wish to take advantage of performance improvements by accessing the Notes.jar archive locally and not using Remote Method Invocation (RMI) over IIOP. If you wish to test/develop in an environment which more closely mimics a distributed environment, you can run the Domino Server locally (with the DIIOP task running) and use RMI/ IIOP. Attention: WebSphere Portal 5.0.2.2 ships NCSOW.jar. - replace that file with NCSO.jar from Domino 6.x if going against a Domino 6.x server. Adding support for Domino JSP custom tags In order to use the Domino JSP custom tags in an application, you have to: 1. Copy domtags.jar from the Lotus/Domino/Data/domino/java directory to the WebContent/WEB-INF/lib directory for the application. 2. Depending on the environment topology: a. Using remote access, copy NSCO.jar from the Lotus/Domino/Data/domino/java directory to the WebContent/WEB-INF/lib directory for the application. b. Using local access, copy Notes.jar from the Lotus/Domino/ directory to the WebContent/WEB-INF/lib directory for the application. c. Alternatively, you can place the jar file in the <was_root>/AppServer/lib directory. 3. Create a new folder called tld in the WebContent/WEB-INF directory of your application. 4. Copy domtags.tld and domutil.tld from the Lotus/Domino/Data/domino/java directory to the WebContent/WEB-INF/tld directory of your application. 5. Verify that your WEB-INF folder hierarchy has a structure similar to Figure 4-15 on page 201. 200 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-15 Sample folder hierarchy 6. Create the necessary tag library XML tags in the Web Deployment Descriptor of the application. a. Switch to the J2EE Hierarchy View. b. Expand the folder Web Modules and open the relevantthe Web Deployment Descriptor. c. Switch to References and click the JSP tag libraries tab. d. Press Add, select WebContent/WEB-INF/tld/domtags.tld, and press Finish. e. Press Add, select WebContent/WEB-INF/tld/domutil.tld, and press Finish. f. Switch to Source. g. Verify that the XML tags have been added to your Web Deployment Descriptor, as described in Example 4-6. Example 4-6 Web Deployment Descriptor including XML tags <taglib> <taglib-uri>/WEB-INF/tld/domtags.tld</taglib-uri> <taglib-location>/WEB-INF/tld/domtags.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/tld/domutil.tld</taglib-uri> <taglib-location>/WEB-INF/tld/domutil.tld</taglib-location> </taglib> This approach is sufficient if the components that take advantage of the Domino JSP custom tag library Java archives are defined in the same Web application. If multiple Web applications use these Java archives, we recommend placing a single set of the JAR files into the <wp_root>/shared/app directory of the WebSphere Portal. This gives the components of all Web applications the possibility to access the set of JAR files. In this case, it is not necessary to package the archives in the several applications. Chapter 4. Using custom Domino JSP Tag libraries 201 4.5.3 The Lotus Domino Object architecture Domino objects are based on a conceptual containment model. The scope of each object is defined through this model. Container objects are used to obtain contained objects. Some of the key containment relationships are shown in Figure 4-16. Figure 4-16 The Domino Object containment hierarchy The Domino JSP custom tags take advantage of the containment hierarchy described above. Each Domino JSP custom tag may contain other specific tags. In order to access a low level tag, all tags wrapping the specific tag have to be implemented. The context of a Domino JSP custom tag is parameterized by its wrapping tag, that is, a single tag defines the context for all enclosed tags. Some of the tags are only valid in the context of the enclosing tag. In general the tags are divided into four major groups (Table 4-3). Table 4-3 Domino JSP custom tag types 202 Tag type Function Data Access tags Gain access to the most important objects of the Domino hierarchy. Data Input tags Allow information input from a JSP to the Lotus Domino application. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tag type Function Process control tags Modify or query the state or properties of the Lotus Domino application. Utility tags Flow control of presentation logic based on conditions and expressions. 4.5.4 Types of Domino JSP tags The Domino JSP tags can be grouped into the following types: Core tags Data access tags Data input tags Process control tags Utility tags Programmatic access to underlying Java Objects In this section, we describe some useful Domino JSP tags. They are the most pertinent for developing portlets that extract information from Lotus Domino applications, but they are just a subset of all the tags available. Refer to the Lotus Domino Designer online help for comprehensive information about all the available tags. Core tags The tags that are most commonly used when accessing Domino data are called core tags (Table 4-4). Table 4-4 Core tags Tag name Description document Represents a Domino document or database record. form Provides a schema for document creation. ftsearch Enables a full text search on a page. mailto Sends a mail message via Domino mail. runagent Runs a specified agent on the server. view Displays a list of documents to select from. Chapter 4. Using custom Domino JSP Tag libraries 203 Tip 1: If you are including more than one of these core tags in a page, use the session tag (see Example 4-8). This initializes and dismantles the Domino session only once, improving performance. Tip 2: The Domino Toolkit makes it easy to “drag and drop” Domino views/forms to a JSP. Therefore, all information necessary for gathering the data from Domino will be put into one tag. For every time when a database reference will be generated (even to the same database used previously (see Example 4-7)) the JSP creates a new connection to that (same!) database. In the worst case, your Domino server will crash - even when reading “only” simple views. Example 4-8 shows how to do it right. Example 4-7 Bad: All in one <domino:view viewname="by Name" dbserver="CN=itso-dom/O=ibm" dbname="test/mydb.nsf" user="*webuser" host="dom.acme.com"> <table> .... .... </table> </domino:view> <domino:view viewname="by Country" dbserver="CN=itso-dom/O=ibm" dbname="test/mydb.nsf" user="*webuser" host="dom.acme.com"> <table> .... .... </table> </domino:view> 204 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-8 Good: Structured <domino:session host="dom.acme.com" user="*webuser"> <domino:db id="id_name_01" dbname="test/mydb.nsf"> <domino:view viewname="by Name"> <table> .... .... </table> </domino:view> <domino:view viewname="by Country"> <table> .... .... </table> </domino:view> </domino:db> </domino:session> Data access tags The data access tags allow the user to gain access to several of the most important objects in the Lotus Domino object hierarchy. Table 4-5 gives a brief overview of the tags that were useful for our portalizing project. Table 4-5 Data access tags Tag name Description session Defines the environment that the core collaboration tags run in. Use the session tag when multiple core tags are included on the same JavaServer page. This initializes and tears down the Domino session one time only, providing improved performance. This tag is not required if there is only one core tag on the page; the user and password attributes of the core tag implement the session for you. However, if you are using a CORBA session, this tag must be used, since the host attribute cannot be specified on the top-level tags. If one or more of the core tags reside in the same database, you can further improve the efficiency of the page by using the db tag instead of this tag to wrap them. Chapter 4. Using custom Domino JSP Tag libraries 205 Tag name Description database Provides a database context for all enclosed tags. If you are including several core tags that are running off the same database in a page, you can wrap them in this tag to increase scalability. This tag is not required if there is only one core tag on the page; the dbserver and dbname attributes of that core tag implement the db tag for you. Do not use this tag to wrap two core tags that reside in different databases; use the session tag instead. To loop over all the documents in a database, use the docloop tag nested inside the db tag. If you do not supply values for the user and password attributes, the database identifies the user as an Anonymous user. The database's ACL must have an “Anonymous” entry with at least Reader level privileges to the database for the tag to access the database successfully. document Enables an author to create or edit a document. The body of this tag is always evaluated. You can use the item, setitem, and formula tags within the body of this tag. To display the document, use the item and formula tags within the body. To edit the document, use the setitem tag within the body. If you set the value of an item using the setitem tag within the body of this tag, you must save your changes also within the body of this tag. You can save your changes by either: - Specifying an ID attribute, and calling <id>.save() in a scriptlet - Using the savenow tag 206 view Displays the summary information of a subset of documents in a database. You can use the key and ftsearch attributes to further qualify the subset. ftsearch Performs a full text search of a database. The result is a list of documents that fit the search criteria. Use the docloop or page tags to sequence over the resulting documents and the item or formula tags to display the summary data. item In the context of a form, document, or docloop tag, displays the value of an item in the current document. You can set the tag's readonly format using the format attribute. The body of the item tag is not evaluated. To provide update access to an item, use the input tag in the context of a form tag. viewitem Displays the value of an item in the current row of a view. The body of this tag is not evaluated. unid Displays the unique ID of the current document. The body of this tag is not evaluated. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tag name Description viewloop Iterates over the results of a view, evaluating the body once per ViewEntry object in the result. If no results are returned, it displays nothing. To create custom text to display when no objects are returned, use the novalues tag. You can access the items of an object using the viewitem tag. docloop Iterates through the items returned by a view, ftsearch, db, responses, or page tag as documents. The body of this command is output once per iteration, which means once per document in the result set. When a result contains no objects, the body of this tag is not evaluated. Use the novalues tag to create custom text to display when a result contains no objects. Use the item tag to access the items in a document. Note: If you use this tag within the context of the view tag, there will be a performance hit. The viewloop tag is a good alternative to use for views; it evaluates the body once per entry in the view, instead of loading a document for each entry in the view. Data input tags Data input tags allow the input of information from a JSP file to the Domino application. There are constraints on the use of these tags because of restrictions of the WebSphere Portal on the management of URIs and JavaScript inside a portlet, so they are not covered in detail in this chapter. Let us take a look at why data input tags will not instantly work with our portlet infrastructure like the other tags do. When you create a JSP and insert the Data Input tags, for example, the <domino:form>, <domino:input>, and <domino:savedoc> tags, you will see a lot of JavaScript code generated on the HTML page that will basically generate action URLs that process the input form. Example 4-9 shows some JavaScript code generated by the Data Input tags. Example 4-9 JavaScript code generated by Data Input tags function selfNavigate() { var actionURL = location.pathname; var argName; var first = true; for (argName in DominoArgs) { var argValue = DominoArgs[argName]; if (argValue != null) { if (first) { actionURL += '?'; first = false; } else { actionURL += '&'; } Chapter 4. Using custom Domino JSP Tag libraries 207 if (typeof argValue == 'object') { for (index = 0; index < argValue.length; index++) { if( index > 0) actionURL += '&'; actionURL += argName + '=' + argValue[index]; } } else { actionURL += argName + '=' + argValue; } } } if (DominoForm != null) { DominoForm.action = actionURL; DominoForm.performSubmit(); } else { location.replace(actionURL); } } This code appends to the portal URL the command and arguments. That is not the usual way information will be passed on the portal. Also, if there are two portlets accessing these data input tags, then you would have conflicts. Be careful when adding data input tags since they can be tricky on a portlet infrastructure. We did not use any of these tags in our examples. Process control tags These tags allow the JSP to query the state or properties of the Domino application, and based on the result, modify the presentation of our portlet. Table 4-6 Process control tags 208 Tag name Description ifcategoryentry Conditional tag. In the context of a viewloop tag, if the current ViewEntry object is a category, meaning it displays in the category column of a hierarchical or categorized view, the body of this tag is displayed. This tag can be used to edit the indentation or display properties of category entries to distinguish them from the other entry types, represented by the ifdocumententry, iftotalentry, and ifconflictentry tags. ifdocumententry Conditional tag. In the context of a viewloop tag, if the current ViewEntry object represents a document in a hierarchical or categorized view, the body of this tag displays. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tag name Description ifdocauthor Conditional tag. Restricts generation of the JSP page to only those users who have author access to the current document. Users have author access to a document if they have: Editor, designer, or manager access to a database Author access to the database and their name is contained in an authors field on the form (or authors item in the document), if the form or document has one. Note: If the user attempting to access the JSP page does not have at least reader access to the database (if they have only depositor access, for example), an exception is thrown. To avoid this, if a user might have depositor level access, wrap the document or form tag with an ifreader tag. nodocument Displays an alternate message if there is no document associated with the unid attribute being passed to the form tag. If the requested document does not exist, it displays the body of this tag. To localize the text that displays, use the msg tag in the tag body. runagent Runs a specified back-end agent on the server. You can specify agents that run on the server, such as agents that send mail or create a folder. You cannot specify an agent that displays information in the browser to the user. For example, you cannot run an agent that contains a LotusScript print statement using this tag. If you want to capture data using this tag to run an agent, you must write the agent's results to a document and access the document to recover the data. To use this tag to run an agent, set up the basics tab of the Agent Properties box for the agent as follows: 1. In the Trigger section, select the On event radio button. 2. Choose the Action menu selection in the drop-down box. 3. In the Target drop-down box, choose None. ifdbrole Conditional tag. In the context of a db tag, restricts generation of the JSP page to only those users included in a custom ACL role. To allow for programmatic determination of access control, the standard access level names (author, editor, and so forth) can be used as role names. Chapter 4. Using custom Domino JSP Tag libraries 209 Utility tags The utility tags allow you to control the flow of the presentation logic on the portlet based on Domino conditions and expressions. Table 4-7 Utility tags Tag name Description if The body of this tag conditionally executes depending on a specified condition. One condition can be specified per tag and can be passed in by including a condition tag in the body of the if tag or as one of the if tag attributes. Note: Only one condition can be specified; if more than one is specified, an exception is thrown. Note: If you do include a condition tag in the body of this tag, the body of this tag must always be evaluated. If the condition fails, the evaluated body is discarded. You should not include code that has side-effects in an if tag that is being used in conjunction with a condition tag. else Used after an if or elseif tag; this tag executes only if none of the preceding if or elseif tags were executed. elseif Conditionally executes its body if the corresponding if tag did not execute and the condition for the elseif tag is true. Note: If you include a condition tag in the body of this tag, the body of this tag must always be evaluated. If the condition fails, the evaluated body is discarded. You should not include code with side-effects in this tag if it is being used in conjunction with a condition tag. condition Specifies the condition of an if or elseif tag. The body of the tag must be a string that represents a Boolean value, for example, true, false, 0, 1, yes, or no. This tag has no attributes. Note: If this tag is used in the context of the if tag, the body of the if tag must always be evaluated. If the condition fails, the evaluated body is discarded. You should not include code with side-effects in an if or elseif tag being used in conjunction with a condition tag. switch Enables the JSP author to incorporate control flow. Each case or default tag contained in the body of this tag is processed in turn and the first match that is found is evaluated. You cannot provide more than one value for this tag. If you supply a value attribute, do not include a switchvalue tag in the tag body. case 210 Provides processing instructions to a switch tag when a match is made. If the case tag's value attribute matches the switch tag's value attribute, the body of the case tag is evaluated. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tag name Description format Formats a value. You can pass in a value to format or format the tag body. You can also provide an ID name to save the formatted body or value as a variable. browsertag Identifies the capabilities associated with the current (or specified) browser. Either returns the value of the capability or conditionally evaluates the body of the tag based on whether or not the browser supports the passed capability. For capability variables consult the Lotus Domino 6 Designer documentation. Programmatic access to underlying Domino Java Objects Some of the tags allow access to the underlying Domino Java Objects. This can be useful in order to customize JSP representation or use of these objects in Java scriptlets. In order to get access to the Java object, the id attribute is available in many tags, as shown in Example 4-10. Example 4-10 Using the ID attribute to access Domino Java Objects <%-- open domino session --%> <domino:session id="session" host="<%= hostname %>" user="<%= username %>" password="<%= password %>" duration="<%= duration %>"> <%-- connect to domino database --%> <domino:db id="db" dbname="<%= dbname %>"> <%-- create table header --%> <div style="margin: 6px"> <table cellspacing="0" cellpadding="0" border="0"> <tr><td class="wpsTableHead">Views:</td></tr> <% // get views from database Vector allViews = db.getViews(); // check for existent view(s) if (allViews.size() > 0) { // view(s) exist String viewName = null; // iterate through view(s) Enumeration enum = allViews.elements(); while (enum.hasMoreElements()) { // get name of current view View currentView = (View)enum.nextElement(); Chapter 4. Using custom Domino JSP Tag libraries 211 viewName = currentView.getName(); %> <%-- create table body displaying the name of the views --%> <tr ><td><%= viewName %></td></tr> <% } } %> </table> </div> </domino:db> </domino:session> 4.5.5 Limitations and considerations There are some issues to consider when using Lotus Domino JSP tag libraries to expose Lotus Domino applications to the WebSphere Portal. The <jsp:include> tag – Incorporating a form into a page using the <jsp:include> tag renders any validatehref attributes on the form useless. You can define a validhref attribute for the following tags: • form • deletedoc • docnavimg • savedoc • saveclosedoc – There is currently a bug when using the <jsp:include> tag. It may happen that you receive the error: JSP tags exception: (4376) Object has been removed. This bug is under investigation. The work around is to set the session's duration="page". Further information about session management can be found in 4.5.6, “Session management” on page 213. Versions – Domino Toolkit for WebSphere Studio V1.3 contains the Domino V6.5.2 tags. Ideally, the V6.5.2 TLD files in the toolkit should be replaced with the ones from Domino V6.5.3, since there are fixes in V6.5.3 that you can benefit from. – You should also be aware that you always need to use the same version of JSP tags as the Domino server you are accessing. 212 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Rich Text – The Notes storage format of the rich text field will be MIME Part, because browsers do not understand the cd-record data types. WebSphere Portal has cross site scripting defenses, and to use the rich text editor, these defenses must be turned off. Set the parameter security.css.protection=false. You will find it in: • WebSphere Portal Server: WebSphere\PortalServer\shared\app\config\services\ConfigService.pr operties • WebSphere Studio: WSAD\runtimes\Portal_v50\shared\app\config\services\ConfigService. properties – Domino R5 does not support Rich Text editing. 4.5.6 Session management In this section, we will discuss the Domino JSP session tag, the Domino Session Manager, and the key attributes associated with managing sessions using the JSP tags. Overview Prior to V6.0.3/6.5.1 of Domino, one of the major issues that limited the use of the custom Domino JSP tags within the WebSphere Portal environment was the limited ability to manage sessions. Within more recent releases of Domino, however, namely V6.0.3/6.5.1 and continuing into V6.04/ 6.5.3, the session management capabilities for the Domino JSP custom tags have improved significantly. Domino Session In terms of Java, the Domino session class is the root of the Domino Objects containment hierarchy. The session provides access to the other Domino objects. It is created in Java programs and represents the Domino environment of the current program. The session is the location, where the Domino server stores user specific data. The custom Domino JSP tag libraries take advantage of the Domino Objects for Java. The session tag provided by the custom Domino JSP tag libraries can be used to gain programmatic access to the underlying Domino Object. Chapter 4. Using custom Domino JSP Tag libraries 213 Custom Domino JSP session tag The session tag <domino:session .../> defines the environment that the top level tags run in. Its use is recommended when several top level tags are used on the same JSP. Wrapping the top level tags using the session tag initializes the session only once, resulting in improved performance. The host attribute There are two different types of Domino sessions, that is, local and remote sessions. You can specify the type by using the host attribute within the session tag. Local sessions A local session manages the user data on the same machine the Domino server is running on. Using the local Domino classes requires the Java program to call the Domino back-end code. On local use you need to manage threads, that is, the thread that initialized the local Domino session must also be the one that terminates the session. Remote sessions Remote sessions manage user data on a different machine than the Domino server runs on. A remote session is initialized through the use of CORBA classes shipped with Domino and requires the DIIOP task running on the Domino server. Using the CORBA classes does not require special thread initialization or termination. The duration attribute To define the lifetime of a Domino session, the duration attribute was introduced. The use of this attribute can help to decrease the overhead of sessions that are created. The attribute can have the following values: page request session The default value, that is, the one that is used if the optional attribute is not specified, is page. Using this value on each JSP that uses the custom Domino JSP tags creates a different session connection. Using the value request creates a single Domino session that exists until the HTTP Request completes. This allows multiple JSPs to share a Domino session through the span of one HTTP Request. The last and remaining attribute value session keeps a remote Domino session open for the duration of the HTTP Session. This value can solely be used for remote sessions, as there is no restriction on thread initialization or termination. 214 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 In a local access environment, the value session is automatically downgraded to request. This would also happen if you do not supply your application with information about how many of lengthy remote connections are allowed on the Domino server. There is no mechanism that permits the server to create a message that tells you that you should stop establishing long lasting sessions. Once the resources are too limited, the server starts revoking and refusing connections. In order to prevent this, include a RemoteSessions.properties file to your application and declare a maxPersistentSessions attribute, whose value represents the number of lengthy sessions allowed on the server per user. Once the value is reached, the duration of any newly created session is downgraded to request. If you are using remote access and the duration value session, we also recommend that you decrease the time-out value for an idle DIIOP session on the Domino server. The custom Domino JSP tags are capable of re-establishing a timed-out DIIOP session and a minor time-out value helps to ensure that the Domino back end does not run out of resources, if there is a large number of concurrent user requests. DominoSessionManager Even though the session tag is used to create the Domino session from a designers point of view, the session tag passes the task to a Java class called DominoSessionManager. This factory object takes the host, duration, user, and password attributes and creates the Domino session. If the values of these attributes are not specified or the attributes are not present, the default values for the Web application are used. These can be specified as container-specific environment variables in the Web Deployment Descriptor (web.xml) of the Web application. The way to define a container parameter will be described in a later section of the chapter covering session sharing between multiple Web applications. If there are no predefined default values, the DominoSessionManager creates a default Domino session, that is, a local session for an anonymous user. The duration attribute is set to page. If the duration attribute value is different than page, the sessions are cached. The caching is performed by the DominoSessionManager. The identity of a cached session is defined by the provided host, user, password, and duration attributes. Chapter 4. Using custom Domino JSP Tag libraries 215 Sharing a session between tags on a JSP Each custom Domino JSP tag must execute in the context of a Domino session. A JSP tag runtime provides every tag with a reference to the enclosing tag. In addition, the runtime will try to bind the top level tags to the nearest Domino session containing it on the parse tree, that is, a top level tag searches the tree of its ancestors for a containing tag holding a valid Domino session. This creates an odd default behavior. If a top level tag without session tag attributes searches the parse tree and does not succeed in binding to a valid Domino session, it creates a default session, that is, a local session for the anonymous user. The process described is the default implementation that is applied if the duration attribute is set to page. Session sharing between components of a single Web application This section describes how to share a Domino session between the components of a single Web application, that is, a single portlet. To illustrate the dependencies, consider that a single Web application is composed of one or a collection of JSPs. Each JSP can invoke another through the use of the jsp:include directive, which allows including dynamic content into a JSP. Each JSP might derive its dynamic content from a Domino back end. Session sharing between JSPs can take place in two ways: 1. Domino sessions are created by the DominoSessionManager. Sessions lasting longer than a page are cached. The identity of a cached session is defined by the user, password, host, and duration attributes. If the value of the duration attribute within a session tag is not page and the user, password, host, and duration attributes match those of a cached session, the cached session will be reused instead of creating a new session. 2. If a JSP incorporates another JSP via the jsp:include directive and the include directive is nested in a custom Domino session tag, it is possible to share a session utilizing the mechanism described in “Sharing a session between tags on a JSP” on page 216. In order for the included JSP to share the session, it must include the parameters that match the existing one, namely, it must contain a session tag and use the same duration, host user, and password attributes in the top level tags. For example, consider A.jsp, which incorporates the code shown in Example 4-11 on page 217, that is, it creates a session that lasts for the length of the HTTP session, belongs to a specific user, and could be local or remote. A jsp:include statement is nested in the session tag. 216 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-11 Sample code fragment of A.jsp <domino:session id="exteriorSession" user="<%= username %>" password="<%= password %>" host="<%= hostname %>" duration="session"> <%-- Start:Session-specific code --%> . <jsp:include page="B.jsp" flush="true" /> . <%-- End:Session-specific code --%> </domino:session> B.jsp comprises the code shown in Example 4-12. Example 4-12 Sample code fragment of B.jsp <domino:session id="innerSession" user="<%= username %>" password="<%= password %>" host="<%= hostname %>" duration="session"> <%-- Start:Session-specific code --%> . <%-- End:Session-specific code --%> </domino:session> These JSPs can now share a session through the mechanism described in 1 on page 216. Using the session tag and the same session attributes in the top level tags in B.jsp, the custom Domino JSP tags search the parse tree to find a containing tag holding a valid session, that is, the session tag of A.jsp. Note: To share a session, the session must have the same attribute values specified for host, user name, password, and duration values. If these values are not the same, this will cause a new session to be created. Session sharing between multiple Web applications The processes described in the section above are sufficient to describe a single Web application, but within a portal environment the approach is not sufficient. Portlet applications are collections of related portlets, that is, a collection of Web applications that display page content. Deploying portlet applications, WebSphere Portal uses a number of Web applications to satisfy a single HTTP Request. In order to share Domino sessions between the different Web Chapter 4. Using custom Domino JSP Tag libraries 217 applications, that is, different portlets, it is necessary to share the DominoSessionManager between the portlets. This section discusses the steps that are necessary to enable the components of a portlet application to share the DominoSessionManager. Sharing Domino sessions between different portlets requires the explicit use of the session tag provided by the custom Domino JSP library. It is not possible to rely on implicit sessions that are established by the core top level tags in case the session tag is missing. In order to share Domino sessions, the session tags have to specify a duration attribute, and even more important, a sessionmgrkey attribute. The value of the sessionmgrkey attribute specifies the name of the HTTP Session attribute, which holds the DominoSessionManager. It is also possible to specify this value as a context-specific environment variable in the Web Deployment Descriptor (web.xml) of the portlet application. Context-specific variables can be used to provide general information to all components of a Web application. To define a context parameter for the sessionmgrkey attribute, add the code to the Web Deployment Descriptor of the portlet application, as described either in Example 4-13 or Example 4-14. Example 4-13 Context parameter for sessionmgrkey attribute <context-param> <param-name>lotus.domino.preset.sessionmgrkey</param-name> <param-value>dominoportalmgr</param-value> </context-param> Example 4-14 Context parameter for sessionmgrkey attribute <context-param> <param-name>lotus.domino.default.sessionmgrkey</param-name> <param-value>dominoportalmgr</param-value> </context-param> There are two key points that should be noted about context parameters: Adding a context parameter allows the JSP tag author to specify a centralized location for all JSPs in a Web application. If the sessionmgrkey attribute is provided, the tag runtime will not create or destroy DominoSessionManager. The portlet must do this. 218 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 To ensure that a DominoSessionManager is present at the time a user logs in, we recommend overriding the login() method of each portlet that needs to share the DominoSessionManager. A sample implementation is given in Example 4-15. Example 4-15 Sample login() method /** * @see org.apache.jetspeed.portlet.PortletSessionListener#login(PortletRequest) */ public void login(PortletRequest request) throws PortletException { super.login(request); PortletSession ps = request.getPortletSession(); HttpSession hs = ((PortletSessionImpl)ps).getServletSession(); DominoSessionManager dsm = (DominoSessionManager)hs.getAttribute("dominoportalmgr"); if (dsm == null) { dsm = new DominoSessionManager(false); hs.setAttribute("dominoportalmgr", dsm); } } The portlet looks for the DominoSessionManager as an attribute of the HTTP Session, not the PortalSession Object. The code implemented in the login() method retrieves the HTTP Session and checks for an existing DominoSessionManager. If no DominoSessionManager exists, a new one is created and placed as an attribute in the HTTP Session. This allows other portlets to find it in the HTTP Session. Therefore, it is possible to share a single Domino session associated with the particular portal user. It is not possible to define which particular portlet of the portlet application is called first and responsible for creating the DominoSessionManager (this is the reason why you have to turn parallel rendering off). In order to clean up, the portlet has to terminate the DominoSessionManager. This can be performed in the logout() method of the portlet. A sample implementation is given in Example 4-16. Example 4-16 Sample logout() method /** * @see org.apache.jetspeed.portlet.PortletSessionListener#logout(PortletSession) */ public void logout(PortletSession ps) throws PortletException { HttpSession hs = ((PortletSessionImpl)ps).getServletSession(); DominoSessionManager dsm = (DominoSessionManager)hs.getAttribute("dominoportalmgr"); Chapter 4. Using custom Domino JSP Tag libraries 219 if (dsm != null) { hs.removeAttribute("dominoportalmgr"); dsm.term(); } super.logout(ps); } 4.5.7 Object Pooling Most pages on a portal consist of portlet collections that access Lotus Domino data, that is, there might be multiple portlets accessing the same content. An object pool helps avoiding creating new Java objects repeatedly (create once, use, or reuse). Such an object pool is designed to pool and reuse instances of objects that are: Complex Frequently instantiated during run time An object pool can help reduce the needed memory of an application (also when cleaning up). Without efficient use of objects, in terms of both instantiation and cleaning up obsolete objects, this can increase the load on specific parts of the Lotus Domino back end and eventually lead to problems caused by resource limitations. Object pooling describes an advanced approach to overcoming resource limitations. It allows sharing of instantiated objects. Therefore, processes do not have to reinstantiate the same objects over and over again. Additionally, objects do not have to be destroyed and recycled by the processes, as these responsibilities are delegated to the object pool. Applying pooling for objects that require non-trivial amounts of time and memory to create and destroy increases the performance significantly. Object pooling and Domino JSP custom tags One of the most striking enhancements of the Domino JSP custom tags is their ability to use custom object pool implementations. The following Domino JSP custom tags support back end objects held in object pool implementations: session db view document 220 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The dojkey attribute Each of these tags introduced an new attribute called dojkey. The value of the dojkey attribute represents the name of an attribute either held in the HTTP Request or the HTTP Session, which holds the according Domino Object for Java. At first, the tags check for an existing object in the HTTP Request. If there is none, then the tags search the HTTP Session. In case neither HTTP Request or HTTP Session provides an object, the specific tag creates the according object and adds the object to an HTTP Request attribute. The name of this attribute is set to the value of the dojkey attribute. Object validation and error handling The object held by either the HTTP Request or HTTP Session attribute is assumed to be of the correct type. Furthermore, it is assumed to be valid. An invalid object causes an error. The way the error is handled is defined by the onfailure attribute. The use of this attribute is described in “Core tags” on page 203. In case the onfailure attribute is not specified, the tags delegate the error to the default error page. In general, the Domino JSP custom tags check the session before using it, and will try to reestablish their session in the case of an error. If the error was generated by a non-valid session, the session for the tag using the particular dojkey attribute cannot be recreated because other tag attributes are not required to be specified, that is, host, password, user, or duration. Using the dojkey attribute requires the object pool implementation to manage the life cycle of the objects. The Domino JSP custom tags will not destroy or terminate the Domino Objects for Java. Object pooling and MVC architecture The current implementation of the Domino JSP custom tags cannot be classified into the MVC paradigm. For more information, consult 4.5.5, “Limitations and considerations” on page 212. Using object pooling is an significant enhancement in order to implement the architecture of the MVC pattern. The JSP is not required to acquire the data from the Domino back end itself, but assumes that the objects are provided in the HTTP Request or HTTP Session attributes. This requires the developer to implement Java routines within the portlet code that places the required objects into the attributes, that is, to extend the application to use object pooling enforces the implementation of a controller part. Chapter 4. Using custom Domino JSP Tag libraries 221 4.5.8 Implementation example We start the implementation of this technique by creating a portlet project and creating the four basic portlets that expose the Lotus Domino application using custom Domino JSP tag libraries. Prior to the development, install all the necessary software and tools, as described in 4.3, “Software and tools used” on page 186. Building the portlet project with WebSphere Studio First, we build a portlet application structure fit that can handle the portlets that will communicate to our Lotus Domino application. To do this, we use several of the tools introduced in previous sections. We performed the following steps to build the portlet project: 1. Open WebSphere Studio Application Developer. 2. Switch to the Portlet perspective 3. Select File → New → Portlet Project. A New Portlet Project dialog is displayed, as shown in Figure 4-17. Figure 4-17 Creating a Portlet Project 222 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4. On the Portlet Project page, name the project DominoJspTags. 5. Select the Basic portlet option if it is not already checked. The Basic portlet will build all the structure needed to hold our portlet. 6. Select Configure Advance Options and click Next to continue. 7. On the J2EE Settings Page, click the New... button for the EAR Project. 8. Enter DominoJspTagsEAR as the project name and click Finish. 9. Select J2EE Level 1.3/WebSphere Portal 5.0 and click Next to continue. 10.On the Features Page, accept the defaults and click Next to continue. 11.On the Portlet Settings page, create the portlet application with parameters like those shown in Figure 4-18. Note that the wizard creates an initial portlet. This portlet will be the Customer List portlet. Figure 4-18 Parameters for creating the portlet project 12.On the Event Handling page, deselect Add form sample and click Next. 13.On the Single Sign-on page, accept the defaults and click Next. 14.On the Miscellaneous page, leave Additional markups and Additional modes unchecked and click Next. Chapter 4. Using custom Domino JSP Tag libraries 223 15.Click Finish. Now let us inspect what the creation wizard built. The newly created portlet project appears in the Project Navigator view in the left. Within the project are two important folders: Java Resources and WebContent. In the WebContent folder, there is a JSP directory, and inside it there is a JSP created for every state the portlet can acquire (that is, View.jsp, Help.jsp, Configure.jsp, and Edit.jsp prefixed with the class name). Since we did not select additional modes during the Miscellaneous dialog box, we only see the DominoJspTagsPortletCustomerListView.jsp file. Our portlet will only be accessed in the View mode. Now we take a look at the Java Resources folder. It contains a default generated portlet package. This package contains a Java file; DominoJspTagsPortletCustomerList.java, which is our portlet. Figure 4-19 Project Navigator view The DominoJspTagsPortletCustomerList.java file should look like the one illustrated in Example 4-17. Example 4-17 Displaying the DominoJspTagsPortletCustomerList.java file package dominojsptags; import java.io.IOException; import org.apache.jetspeed.portlet.*; import org.apache.jetspeed.portlet.event.*; 224 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 /** * * A sample portlet based on PortletAdapter * */ public class DominoJspTagsPortletCustomerList extends PortletAdapter implements ActionListener { public static final String VIEW_JSP = "/dominojsptags/jsp/DominoJspTagsPortletCustomerListView."; name to be rendered on the view mode // JSP file /** * @see org.apache.jetspeed.portlet.Portlet#init(PortletConfig) */ public void init(PortletConfig portletConfig) throws UnavailableException { super.init(portletConfig); } /** * @see org.apache.jetspeed.portlet.PortletAdapter#doView(PortletRequest, PortletResponse) */ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { // Invoke the JSP to render getPortletConfig().getContext().include(VIEW_JSP+getJspExtension(request), request, response); } /** * @see org.apache.jetspeed.portlet.event.ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent event) throws PortletException { if( getPortletLog().isDebugEnabled() ) getPortletLog().debug("ActionListener - actionPerformed called"); // ActionEvent handler String actionString = event.getActionString(); // Add action string handler here } /** * Returns the file extension for the JSP file * * @param request PortletRequest * @return JSP extension */ Chapter 4. Using custom Domino JSP Tag libraries 225 private static String getJspExtension(PortletRequest request) { String markupName = request.getClient().getMarkupName(); return "jsp"; } } This completes the creation of the skeleton for our portlet. Next, we are going to add the session sharing to our portlet. Adding session sharing parameters 1. Open the Web Deployment Descriptor (web.xml file). 2. Click on the Parameters tab. 3. Add the parameters shown in Table 4-8. Table 4-8 Session sharing parameters Attribute Value lotus.domino.preset.sessionduration session lotus.domino.preset.sessionmgrkey dominoportalmgr Note: The attribute named 'duration' with a value of 'session' keeps the Domino session open for the duration of the HTTP session. The value of the sessionmgrkey attribute specifies the name of the HTTP Session attribute, which holds the DominoSessionManager. 4. We will also need to create a file called RemoteSession.properties that contains the following string: maxPersistentSessions=10 (or the number you find your Domino server can handle). Note: There is no mechanism to permit the Domino server to say it would like you to stop opening long sessions - they do tie up resources, and after a while Domino will just start refusing connections. You might want to set the DIIOP time-out value fairly low. 5. Right-click the dominojsptags package within the Java Resources folder and create a Simple file by selecting New → Other... → Simple → File. 6. Enter RemoteSession.properties as the file name. 226 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 7. Insert maxPersistentSessions=10 or the number you find your Domino server can handle. This completes the modification of session sharing. Next, we are going to add a session bean to the project that holds user-specific data. Adding a SessionBean The use of a SessionBean allows you to store data that is related to the user, through the user interaction with the application. Even though the user might switch to another WebSphere Portal page or might interact with other portlets, you are still able to display the same information when the user returns to your application. 1. Switch to the Project Navigator. 2. Right-click the dominojsptags package contained in the Java Source folder of your application. 3. Select New → Class. 4. Name the class DominoJspTagsSessionBean. 5. Click Finish. 6. Open the file DominoJspTagsSessionBean.java. 7. Insert the following code (Example 4-18). Example 4-18 DominoJspTagsSessionBean.java file package dominojsptags; public class DominoJspTagsSessionBean { private String jspPage = null; private String username = null; private String password = null; private String hostname = null; private String dbname = null; private String selectedView = null; private String uidDoc = null; private String customerNameAttr = null; public DominoJspTagsSessionBean(){ this.jspPage = DominoJspTagsPortletCustomerList.VIEW_JSP_INDEX; //View. this.username = null; this.password = null; this.hostname = null; this.dbname = null; this.selectedView = null; this.uidDoc = null; this.customerNameAttr = null; Chapter 4. Using custom Domino JSP Tag libraries 227 } /** * @return */ public String getDbname() { return dbname; } /** * @return */ public String getHostname() { return hostname; } /** * @return */ public String getJspPage() { return jspPage; } /** * @return */ public String getPassword() { return password; } /** * @return */ public String getSelectedView() { return selectedView; } /** * @return */ public String getUidDoc() { return uidDoc; } /** * @return */ public String getUsername() { 228 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 return username; } /** * @param string */ public void setDbname(String string) { dbname = string; } /** * @param string */ public void setHostname(String string) { hostname = string; } /** * @param string */ public void setJspPage(String string) { jspPage = string; } /** * @param string */ public void setPassword(String string) { password = string; } /** * @param string */ public void setSelectedView(String string) { selectedView = string; } /** * @param string */ public void setUidDoc(String string) { uidDoc = string; } /** * @param string */ public void setUsername(String string) { Chapter 4. Using custom Domino JSP Tag libraries 229 username = string; } /** * @return */ public String getCustomerNameAttr() { return customerNameAttr; } /** * @param string */ public void setCustomerNameAttr(String string) { customerNameAttr = string; } } This completes the modification of a SessionBean. Next, we are going to extend the PortletAdapter class for creating and destroying a DominoSessionManager. Extending the PortletAdapter class Portlets are special Web applications, in that they share an HttpSession and, for good performance, will want to share a DominoSessionManager. The Web applications PortletAdapter class needs to be in charge of creating and destroying a DominoSessionManager. 1. Switch to the Project Navigator. 2. Right-click the dominojsptags package contained in the Java Source folder of your application. 3. Select New → Class. 4. Name the class PortletContainerAdapter. 5. Click Finish. 6. Open the file PortletContainerAdapter.java. 7. Insert the following code (Example 4-19). Example 4-19 PortletContainerAdapter.java package dominojsptags; import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; 230 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 import import import import import import import import import import javax.servlet.ServletInputStream; javax.servlet.ServletOutputStream; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletRequestWrapper; javax.servlet.http.HttpServletResponse; javax.servlet.http.HttpServletResponseWrapper; javax.servlet.jsp.PageContext; lotus.domino.taglib.*; org.apache.jetspeed.portlet.*; org.apache.jetspeed.portletcontainer.util.ThreadAttributesManager; public class PortletContainerAdapter extends ContainerAdapter { private static final String HEX = "0123456789ABCDEF"; public PortletContainerAdapter() { ContainerAdapterAccess.setInstance(this); } private static String hex2asc(String org) { if(org == null) return null; int k = org.length(); StringBuffer buf = new StringBuffer(k / 2); char crc = '\0'; char xxx = (char)(("0123456789ABCDEF".indexOf(org.charAt(0)) << 4) + "0123456789ABCDEF".indexOf(org.charAt(1))); for(int i = 2; i < k; i++) { int c = "0123456789ABCDEF".indexOf(org.charAt(i)) << 4; i++; c += "0123456789ABCDEF".indexOf(org.charAt(i)); buf.append((char)c); crc ^= (char)c; } if(crc == xxx) return buf.toString(); else return null; } private static String asc2hex(String org) { int k = org.length(); StringBuffer buf = new StringBuffer(k * 2); buf.append('0'); Chapter 4. Using custom Domino JSP Tag libraries 231 buf.append('0'); char crc = '\0'; for(int i = 0; i < k; i++) { char c = org.charAt(i); crc ^= c; buf.append("0123456789ABCDEF".charAt(c >> 4 & 0xf)); buf.append("0123456789ABCDEF".charAt(c & 0xf)); } buf.setCharAt(0, "0123456789ABCDEF".charAt(crc >> 4 & 0xf)); buf.setCharAt(1, "0123456789ABCDEF".charAt(crc & 0xf)); return buf.toString(); } public String encodeAction(String jsp, PageContext arg1) { if(jsp == null) { PortletRequest request = (PortletRequest)ThreadAttributesManager.getAttribute("org.apache.jetspeed.portl etcontainer.portlet.request"); PortletSession session = request.getPortletSession(); jsp = (String)session.getAttribute(DominoJspTagsPortletCustomerList.JSP); } return asc2hex(jsp); } public String decodeAction(String jsp, PageContext arg1) { return hex2asc(jsp); } public String createURI(String jsp, PageContext pc, Param param) { PortletResponse portletResponse = (PortletResponse)ThreadAttributesManager.getAttribute("org.apache.jetspeed.port letcontainer.portlet.response"); PortletURI uri = portletResponse.createURI(); if(jsp != null) uri.addAction(encodeAction(jsp, pc)); for(; param != null; param = param.getNext()) uri.addParameter(param.getName(), param.getValue()); // System.out.println("PortletContainerAdapter.createURI("+jsp+") produced "+uri.toString()); return uri.toString(); } 232 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 public String createURI(String jsp, PageContext pc) { PortletResponse portletResponse = (PortletResponse)ThreadAttributesManager.getAttribute("org.apache.jetspeed.port letcontainer.portlet.response"); PortletURI uri = portletResponse.createURI(); if(jsp != null) uri.addAction(encodeAction(jsp, pc)); // System.out.println("PortletContainerAdapter.createURI("+jsp+") produced "+uri.toString()); return uri.toString(); } public String encodeNS(String name, PageContext arg1) { PortletResponse portletResponse = (PortletResponse)ThreadAttributesManager.getAttribute("org.apache.jetspeed.port letcontainer.portlet.response"); return portletResponse.encodeNamespace(name); } public String encodeURL(String name, PageContext arg1) { // System.out.println("PortletContainerAdapter.encodeURL("+name+")"); PortletResponse portletResponse = (PortletResponse)ThreadAttributesManager.getAttribute("org.apache.jetspeed.port letcontainer.portlet.response"); return portletResponse.encodeURL(name); } public ServletInputStream getInputStream(HttpServletRequest request) throws IOException { ServletInputStream in = null; try { // might be servlet api 2.2 from Portal4 in = request.getInputStream(); } catch (IllegalStateException e) {// then again, might be servlet api 2.3 from Portal5 if (request instanceof javax.servlet.http.HttpServletRequestWrapper ) { in = ((HttpServletRequest) ((HttpServletRequestWrapper)request).getRequest()).getInputStream(); } } return in; } Chapter 4. Using custom Domino JSP Tag libraries 233 public BufferedReader getReader(HttpServletRequest request) throws IOException { BufferedReader buf = null; try { // might be servlet api 2.2 from Portal4 buf = request.getReader(); } catch (IllegalStateException e) {// then again, might be servlet api 2.3 from Portal5 if (request instanceof javax.servlet.http.HttpServletRequestWrapper ) { buf = ((HttpServletRequest) ((HttpServletRequestWrapper)request).getRequest()).getReader(); } } return buf; } public ServletOutputStream getOutputStream(HttpServletResponse response) throws IOException { ServletOutputStream sos = null; try { // might be servlet api 2.2 from Portal4 sos = response.getOutputStream(); } catch (IllegalStateException e) {// then again, might be servlet api 2.3 from Portal5 if (response instanceof javax.servlet.http.HttpServletResponseWrapper ) { sos = ((javax.servlet.http.HttpServletResponseWrapper)response).getResponse().getOutp utStream(); } } return sos; } public PrintWriter getWriter(HttpServletResponse response) throws IOException { PrintWriter pw = null; try { // might be servlet api 2.2 from Portal4 pw = response.getWriter(); } catch (IllegalStateException e) {// then again, might be servlet api 2.3 from Portal5 if (response instanceof javax.servlet.http.HttpServletResponseWrapper ) { pw = ((javax.servlet.http.HttpServletResponseWrapper)response).getResponse().getWrit er(); } } 234 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 return pw; } } Modifying the Customer List portlet Java source 1. Open the DominoJspTagsPortletCustomerList.java. 2. Insert the following code (Example 4-20). Example 4-20 CustomerList declaration public static final String VIEW_JSP = "/dominojsptags/jsp/DominoJspTagsPortletCustomerListView."; name to be rendered on the view mode public static final String DominoJSPPortlet ="dominojsptags.DominoJspTagsPortlet" ; public static String JSP = VIEW_JSP; // session data public static final String SESSION_BEAN= "dominojsptags.DominoJspTagsSessionBean"; public static final String SUBMIT "dominojsptags.DominoJspTagsPortletSubmit"; public static final String RESET= "dominojsptags.DominoJspTagsPortletReset"; public static final String USERNAME "dominojsptags.DominoJspTagsPortletUsername"; public static final String PASSWORD "dominojsptags.DominoJspTagsPortletPassword"; public static final String HOSTNAME "dominojsptags.DominoJspTagsPortletHostname"; public static final String DBNAME "dominojsptags.DominoJspTagsPortletDbName"; public static final String VIEWNAME= "dominojsptags.DominoJspTagsPortletViewName"; public static final String UIDDOC= "dominojsptags.DominoJspTagsPortletUidDoc"; // JSP file = = = = = // jsp root directory public static final String VIEW_JSP_ROOT = "/dominojsptags/jsp/DominoJspTagsPortlet"; // names of jsp files public static final String VIEW_JSP_INDEX = "View."; public static final String VIEW_JSP_CUSTOMER_LIST= "CustomerListView."; // actions Chapter 4. Using custom Domino JSP Tag libraries 235 public static final String ACTION_LOGIN= "dominojsptags.DominoJspTagsPortletActionLogin"; public static final String ACTION_LOGOUT= "dominojsptags.DominoJspTagsPortletActionLogout"; public static final String ACTION_SHOW_SGL_VIEW = "dominojsptags.DominoJspTagsPortletActionShowSingleView"; public static ContainerAdapter adapter = null; 3. Create the getSessionBean() method with the following code (Example 4-21). Example 4-21 Customer List getSessionBean() method /** * Create SessionBean * * @param request PortletRequest * @return SessionBean */ private DominoJspTagsSessionBean getSessionBean(PortletRequest request){ // get PortletSession PortletSession ps = request.getPortletSession(); if (ps == null) { // no existing PortletSession return null; } else { // get SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)ps.getAttribute(SESSION_BEAN); if (sessionBean == null) { // no existing SessionBean - create new SessionBean and set attribute in PortletSession sessionBean = new DominoJspTagsSessionBean(); ps.setAttribute(SESSION_BEAN, sessionBean); } // return SessionBean return sessionBean; } } 4. Modify the init() method, as in Example 4-22 on page 237. 236 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-22 Customer List init() method /** * @see org.apache.jetspeed.portlet.Portlet#init(PortletConfig) */ public void init(PortletConfig portletConfig) throws UnavailableException { System.out.println("DominoJSPPortlet " + this.toString() + " init"); super.init(portletConfig); if(adapter == null) adapter = new PortletContainerAdapter(); } 5. Modify the doView() method, as in Example 4-23. Example 4-23 Customer List doView() method /** * @see org.apache.jetspeed.portlet.PortletAdapter#doView(PortletRequest, PortletResponse) */ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> doView: Unable to get a handle of the session bean."); return; } // set properties in sessionBean sessionBean.setUsername("*webuser"); sessionBean.setHostname("itso-dom.cam.itso.ibm.com"); sessionBean.setDbname("redbook/customer.nsf"); // set name of JSP to render String jspName = VIEW_JSP_CUSTOMER_LIST; // Invoke the JSP to render getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } 6. Change the host name and dbname to reflect your Domino environment. 7. Modify the actionPerformed() method, as in Example 4-24 on page 238. Chapter 4. Using custom Domino JSP Tag libraries 237 Example 4-24 Customer List actionPerformed() method /** * @see org.apache.jetspeed.portlet.event.ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent event) throws PortletException { if( getPortletLog().isDebugEnabled() ) getPortletLog().debug("ActionListener - actionPerformed called"); // ActionEvent handler String actionString = event.getActionString(); // Add action string handler here // get PortletRequest PortletRequest request = event.getRequest(); // get SessionBean DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> actionPerformed: Unable to get a handle of the session bean."); return; } if (ACTION_SHOW_SGL_VIEW.equals(actionString)) { // handle display single database view action // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_LIST); } else { // set jsp file to be rendered next - initial view display sessionBean.setJspPage(VIEW_JSP_CUSTOMER_LIST); } } 8. To ensure that a DominoSessionManager is present at the time a user logs in, it is a good idea to override the login() and logout() methods of each portlet that needs to share the DominoSessionManager. a. Import into the portlet with the packages shown in Example 4-25 on page 239. b. Insert the constructor sample code in Example 4-26 on page 239. c. Insert the sample login() method given in Example 4-15 on page 219. 238 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 d. Insert the sample logout() method given in Example 4-16 on page 219. Example 4-25 Customer List import import import import import lotus.domino.taglib.ContainerAdapter; lotus.domino.taglib.DominoSessionManager; javax.servlet.http.HttpSession; com.ibm.wps.pe.pc.legacy.impl.PortletSessionImpl; Example 4-26 DominoJspTagsPortletCustomerList() constructor public DominoJspTagsPortletCustomerList(){ System.out.println("DominoJspPortlet " + this.toString() + " constructed");. } This completes the modification of the Customer List portlet java source. Next, we are going to add the Domino capabilities that are included in the Lotus Domino Toolkit for WebSphere Studio. Adding Lotus Domino JSP tags to our portlets To enable our project to include the JSP tag libraries, we performed the following steps: Create folder hierarchy 1. Import domtags.jar and NCSO.jar from the Notes/data/domino/java directory to the WebContent/WEB-INF/lib directory for the application, as shown in Figure 4-20 on page 240. Chapter 4. Using custom Domino JSP Tag libraries 239 Figure 4-20 Import jar files 2. Create a new folder named tld in the WebContent/WEB-INF directory of your application. 3. Import domtags.tld and domutil.tld from the Notes/data/domino/java directory to the WebContent/WEB-INF/tld directory of your application. 4. Verify that your folder hierarchy has the following structure: New files were added to our portlet project: two Domino custom tag libraries in the WEB-INF directory, and two JAR files in the WEB-INF/lib folder. This result is shown in Figure 4-21 on page 241. 240 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-21 Inserting Domino custom tag libraries Add libraries to web.xml Next, we need to create the necessary tag library XML tags in the Web Deployment Descriptor for the application: 1. From the Project Navigator, open the Web Deployment Descriptor. 2. Switch to References and click the JSP tag libraries tab, as shown in Figure 4-22. Figure 4-22 Web Deployment Descriptor - References/JSP tag libraries 3. Click Add, select WebContent/WEB-INF/tld/domtags.tld, and click Finish. 4. Click Add, select WebContent/WEB-INF/tld/domutil.tld, and click Finish (see Figure 4-24 on page 242). Chapter 4. Using custom Domino JSP Tag libraries 241 Figure 4-23 Web Deployment Descriptor - Adding JSP tag libraries 5. Switch to Source. 6. Verify that the following XML tags have been added to the Web Deployment Descriptor, as shown in Figure 4-24. Figure 4-24 Web Deployment Descriptor - Viewing JSP tag source 7. Save the changes and close the Web Deployment Descriptor. Connecting to the Domino database A navigator plug-in provides a view that lets you explore Domino application design and create tags within the editor to represent that design. To open the Domino view: 1. Choose Window → Show View → Other. 2. Select Domino from the Domino folder. This opens an empty Domino window. The window is in its own perspective. Clicking on the window title bar allows it to be dragged around like any other window. If you do not see the Domino view, you do not have the Lotus Domino Toolkit for WebSphere Studio installed. 242 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3. Right-click the white canvas and select New database connection, as shown in Figure 4-25. Figure 4-25 Connecting to the Domino database 4. When prompted for connectivity information, fill in the appropriate values for the Domino server and point to the customer.nsf database you are using in your project. Click Finish. You will be prompted for a password. Enter it and click OK. Figure 4-26 Connecting to Domino databases through Domino toolkit When the connection is complete, a list of all the forms and views that are on the database is displayed, as illustrated in Figure 4-27 on page 244. On this Chapter 4. Using custom Domino JSP Tag libraries 243 initial portlet, you will be including the Customers/By Customer Name view on your JSP. Figure 4-27 Reviewing the Customer database Modifying the Customer List portlet JSP file 1. Open the DominoJspTagsPortletCustomerListView.jsp file from the Project Navigator in Source mode. 2. Change the <%@ page session=”false”... to session=”true”. 3. Right below the <portletAPI:init /> tag, insert the following code (Example 4-27). Example 4-27 Access the SessionBean <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerList.SESSION_BEAN); // default to the Customers By Name view sessionBean.setSelectedView("CustomersByName"); %> 4. Delete the code within the <DIV> tag. 244 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5. Add the session tag by expanding the Customer database → Utilities → Tag Uses → Domino Custom Tags → DOMTAGS → Alphabetical → session. Right-click the session tag and choose Add tag to Web Page (see Figure 4-28). Tip: Adding the session tag this way would automatically generate the necessary code and error handling. Figure 4-28 Domino tags 6. Next, we want to retrieve the host and user from the SessionBean. Replace the code on the session tag with the code shown in Example 4-28. Example 4-28 <domino:session> tag <domino:session id="generalSession" host="<%=sessionBean.getHostname()%>" user="<%=sessionBean.getUsername()%>" duration="page"> Chapter 4. Using custom Domino JSP Tag libraries 245 Tip: Single sign-on (SSO) support allows Web users to authenticate once when accessing Web resources across multiple WebSphere Application Servers. The <Domino:session> tag currently has a *webuser as the user name from the SessionBean. This option lets the portlet establish the connection to the Lotus Domino database with the same identity as the one used to log into the portal. Also notice that when the *webuser is used, no password is specified. As a prerequisite to use the same identity, single sign-on (SSO) must be enabled. 7. Add a <domino:preserve> tag to the JSP file (Example 4-29). This preserves explicitly passed page arguments when a user self-navigates. If you do not use this tag, the initial arguments passed to the page will not be preserved during a self-navigation and the page may not work correctly. Example 4-29 <domino:preserve> tag <domino:preserve name="mycustomerlistview" /> 8. Add the db tag with the following code (Example 4-30). Example 4-30 <domino:db> tag <domino:db id="generalDb" dbname="<%=sessionBean.getDbname()%>"> 9. Next, add the view tag. Go back to the Domino view and drag the Customers/By Customer Name view within the db tags (see Figure 4-29). Figure 4-29 Adding the Customers/Customer By Name view to View.jsp 246 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Tip: When you drag/drop the Domino view into the JSP file, it would automatically generate all the attributes required to make a Domino session <domino:view> tag with many attributes: host, user, password, and dbname. Avoiding the database argument in the <domino:view> tag is more a “good practice” that will make it easier to start object sharing. The tags, in an attempt to make using JSPs easy and more like Visual Basic, support way too many attributes. Those attributes are not marked as required in the tld file in order to allow the tag to be contained in another tag that will supply the missing attribute, so you have a logical containment hierarchy of: <domino:session <domino:database <domino:view 10.Replace the <domino:view> tag with the following code (Example 4-31). Example 4-31 <domino:view> tag <domino:view id="generalView" viewname="<%=sessionBean.getSelectedView()%>"> 11.Delete the hidden (fourth) column, since this is a control column. 12.On the JSP file, select the top row of the table to be a header row. To do so, right-click the selected row and select Attributes, and in the Attributes view, change from Data to Head, as shown in Figure 4-30. Figure 4-30 Changing the table to include headers 13.Next, add pagination to the JSP so that the user may navigate the view. a. Add the following code below the <domino:view> tag: <domino:page id="plinfo" rows="7"> b. Add the following code above the </domino:view> tag: Chapter 4. Using custom Domino JSP Tag libraries 247 <%-- pagination --%> <domino:pagefirst/> <domino:pageprev/> <domino:pagenext/> <domino:pagelast/> <br>Page <%=plinfo.getPage()%> of <%=plinfo.getPageCount()%> </domino:page> 14.Include, at the beginning of the JSP, the following JSP Tag library definitions (Example 4-32 on page 249). 248 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-32 JSP Tag Library definitions <%@ taglib uri="/WEB-INF/tld/domutil.tld" prefix="domutil" %> <%@ taglib uri="/WEB-INF/tld/domtags.tld" prefix="domino" %> <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init/> These definitions include inserting the custom Domino libraries so that they can be referenced inside your code. The last line initializes the portlet tag library; there is not any need to initialize the Domino libraries. 15.Your new JSP file should look similar to Figure 4-31 in Design mode. Figure 4-31 Initial portlet JSP in Design mode 16.Save the jsp file. We have now a working portlet that displays basic information extracted from our Lotus Domino database. Deploying our initial application Use the following steps to deploy the application. 1. At the WebSphere Studio Application Developer tool, change to the J2EE Navigator view. 2. Right-click the DominoJspTagsPortlet project and select Export. A wizard comes up. Select the WAR file export and basically export the project to your hard disk. 3. Install the portlet into WebSphere Portal: a. Log into the WebSphere Portal with an administrative user, and select the Portal Administration place. Chapter 4. Using custom Domino JSP Tag libraries 249 b. It should open right away to the Install Portlets window. Select the newly created .WAR file from your hard disk. Figure 4-32 Installing the Customer List portlet c. Click Next. Once it recognizes your portlet, click Install. When the installation is finished, a “Portlets were successfully installed” message is displayed (see Figure 4-33). Figure 4-33 Successful installation of the portlet 4. Grant access to the portlet application. Now that the portlet is installed to the portal, grant access to the users. Go to the Access/Resource Permissions/Portlet applications in the Portal 250 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Administration place. Search for the DominoJspTags application that we have just installed. Click the Assign Access icon for the portlet application to which you want to assign access. Select the required users or groups and grant them at least View access. This is illustrated in Figure 4-34. Figure 4-34 Granting access to the DominoJspTags application 5. Add the portlet to the page. a. Go to the Portal User Interface/Manage Portlets in the Portal Administration place and select the page where you will install the portlet. b. Select the Edit Page Layout icon. c. Modify the number of columns to two, and in the first column click the Add Portlets button. This directs you to a portlet search page. d. Search by Customer List and your portlet should come up. Select it and click OK. e. Finally, click Done. Figure 4-35 on page 252 shows the result of adding the portlet into a page. Chapter 4. Using custom Domino JSP Tag libraries 251 Figure 4-35 Adding the Customer List portlet to the page 6. Preview the portlet. Log into the portal with a user name that has access to the Lotus Domino database and select the page where you added the portlet. You should be able to view the portlet running. Figure 4-36 Initial portlet with Domino functionality accessed through JSP tags Figure 4-36 shows an example of a basic view being displayed in a portlet. 252 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The Customer Details portlet We now describe how to construct the Customer Details portlet. This portlet initially displays a JSP with a drop-down list of the customers available. After a customer is selected, it reloads and displays the customer information details. Customer details portlet Java code 1. Open the Web Project from the Portlet perspective. 2. Copy the DominoJspTagsPortletCustomerList.java file and paste it to the same package. When prompted to rename the file, rename it DominoJspTagsPortletCustomerDetails.java. 3. Open the CustomerDetails java file and modify it to target the CustomerDetailsView.jsp. 4. Replace the declarations with the following code (Example 4-33): Example 4-33 Customer Details portlet declaration public static final String VIEW_JSP = "/dominojsptags/jsp/DominoJspTagsPortletCustomerDetails."; to be rendered on the view mode // JSP file name ... // names of jsp files public static final String VIEW_JSP_INDEX = "View."; public static final String VIEW_JSP_CUSTOMER_DETAILS= "CustomerDetailsView."; public static final String VIEW_JSP_CUSTOMER_DETAILS_ENTRY= "CustomerDetailsEntry."; 5. Replace the doView() method to include the code in Example 4-34. Example 4-34 Customer Details portlet doView() method /** * @see org.apache.jetspeed.portlet.PortletAdapter#doView(PortletRequest, PortletResponse) */ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> doView: Unable to get a handle of the session bean."); return; Chapter 4. Using custom Domino JSP Tag libraries 253 } // set properties in sessionBean sessionBean.setUsername("*webuser"); sessionBean.setHostname("itso-dom.cam.itso.ibm.com"); sessionBean.setDbname("redbook/customer.nsf"); // We are checking if the uidDoc attribute is on the session, initially it will // be null but once a customer is selected the uidDoc will be populated. if(request.getPortletSession().getAttribute("uidDoc") != null){ PortletURI detailURI = response.createURI(); detailURI.addAction("details"); request.setAttribute("details", detailURI.toString()); // Store the return URI in the request PortletURI returnURI = response.createReturnURI(); request.setAttribute("CD_back", returnURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); // Redirecting to the DominoJspTagsPortletCustomerDetails.jsp file getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } else { // If no customer is selected PortletURI detailURI = response.createURI(); detailURI.addAction("details"); request.setAttribute("details", detailURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); if (jspName.equals(VIEW_JSP_INDEX) || jspName.equals("")) { jspName = VIEW_JSP_CUSTOMER_DETAILS; sessionBean.setJspPage(jspName); } // Invoke the JSP to render getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } } This code selects whether you want to display the initial selection JSP or the customer details JSP, based on the uidDoc attribute stored in the session. Notice that we need a new JSP called CustomerDetailsEntry.jsp to display the customer details; we will do this later. In the code, before including the target JSP, actions are created. These will respond to users’ interactions through forms and buttons. 254 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 As we saw in the introduction to this integration technique, this portlet will start with a JSP that displays a drop-down list where the user selects the customer. When the user clicks the View Details button, it will activate an action called details. If you inspect the code, you will find that this action URI is going to be stored as an attribute on the request object. The inclusion of both JSP files will help make our portlet work as a stand-alone portlet if needed. (In the next section, we describe how to enable the Click-to-Action communication between portlets, but for now they will work independently.) 6. For the Customer Details portlet, we introduce a new option that is in the portlet structure, the actions. The actions let the presenting JSP send information to the portlet class to perform the required business logic. In our portlet, the View.jsp will send a details action to the CustomerDetails portlet and as a result the portlet will redirect the request to the CustomerDetailsEntry.jsp page, and pass to it the UI of the document. Figure 4-37 illustrates the action’s interactions in the Customer Details portlet. Customer Details portlet doView() actionPerformed() Details Action Figure 4-37 Action interaction in the Customer Details portlet Chapter 4. Using custom Domino JSP Tag libraries 255 7. Next, we have to implement the ActionPerformed() method. Add the following code in the ActionPerformed() method (Example 4-35): Example 4-35 actionPerformed() method of the Customer Details /** * @see org.apache.jetspeed.portlet.event.ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent event) throws PortletException { if( getPortletLog().isDebugEnabled() ) getPortletLog().debug("ActionListener - actionPerformed called"); // ActionEvent handler String actionString = event.getActionString(); // Add action string handler here // get PortletRequest PortletRequest request = event.getRequest(); // get SessionBean DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> actionPerformed: Unable to get a handle of the session bean."); return; } // retrieve uiddoc from request String uidDoc = request.getParameter("uid"); // Capture the uid parameter from the request and store it as an attribute called uidDoc in the session object. if(actionString.equals("details") && !(uidDoc.equals("-Select a customer-"))){ request.getPortletSession().setAttribute("uidDoc", uidDoc); // set property in sessionBean sessionBean.setUidDoc(uidDoc); // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_DETAILS_ENTRY); } else { // handle display single database view action // retrieve viewname from request String view = request.getParameter(VIEWNAME); // set properties in sessionBean sessionBean.setSelectedView(view); 256 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 sessionBean.setJspPage(VIEW_JSP_CUSTOMER_DETAILS); } } This code basically captures the uid parameter from the request and stores it as an attribute called uidDoc in the session object. Furthermore, it sets the properties in the sessionBean. Tip: Storing information about the Portlet session object will enable the user to switch between pages and places, and when the user comes back to this page, the portlet will still be displaying the information previously selected. If you store the information about the Portlet request object, the result of the portlet will only be available if the user changes pages and later comes back. Now let us take care of the JSPs. First, we copy and modify the existing View.jsp file, and after that, we create the new CustomerDetailsEntry.jsp View.jsp 1. Copy the DominoJspTagsPortletCustomerListView.jsp file and name it DominoJspTagsPortletCustomerDetailsView.jsp. 2. Open the newly copied View.jsp file in the Source view. 3. Replace the code for sessionBean to point to the Customer Details class as follows (Example 4-36): Example 4-36 Customer Details portlet view jsp sessionBean <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerDetails.SESSION_BEAN); // default to the Customers By Name view sessionBean.setSelectedView("CustomersByName"); %> 4. Delete the code inside the <Domino:view> tags. 5. Insert the following code in the JSP file (Example 4-37): Example 4-37 Customer Details portlet View.jsp fragment initial contents <!-- Creating a form with an encoded name for the portal, so if there --> <!-- are two forms with the same name, there won’t be any conflicts. --> <!-- Also notice that the details action is extracted from the request. --> <%-- Display the Customers By Name view --%> <DIV style="margin: 6px"> Chapter 4. Using custom Domino JSP Tag libraries 257 <P>Please select a customer: <formmethod="post" action="<%=(String)request.getAttribute("details")%>" name="<portletAPI:encodeNamespace value='CD_form'/>"> <SELECT size="1" name="uid"> <OPTION value="" selected>-Select a customer-</OPTION> <domino:viewloop id="loop"> <%-- filter documents --%> <domino:ifdocumententry> <OPTION value="<domino:unid/>"> <domino:viewitem col="1" /> </OPTION> </domino:ifdocumententry> </domino:viewloop> </SELECT> <%-- create submit and reset buttons --%> <table> <tr> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerDetails.SUBMIT%>'/>" value="Show Entry" type="submit"/> </td> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerDetails.RESET%>'/>" value="Reset" type="reset"/> </td> </tr> </table> </form> </DIV> This code will insert a text message instructing the user to select an available customer from the list. Followed by a <form> tag that will use the POST method to submit the information to WebSphere Portal, the action on this form will trigger the action event details. Next, a custom JSP tag for a Domino view is placed. This opens a session with the Lotus Domino server, and a select HTML field will loop using the <Domino:viewloop>. 258 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Inside the loop, we extract two pieces of information: the universal ID of the customer document using the <Domino:unid/>, and the column information corresponding to the Customer Name. CustomerDetailsEntry.jsp 1. Right-click the /jsp/html folder and select New → JSP File. 2. Name the new JSP file DominoJspTagsPortletCustomerDetailsEntry.jsp, and select the check box to specify this JSP is a fragment. Click Next. 3. Click on the Add Tag Library button. 4. Select all three tld libraries displayed. Add prefixes to the two libraries: Domino to the domtags.tld library and util to the domutil.tld library, as shown in Example 4-38. 5. The prefixes are needed so you can associate each tag with a JSP tag library. Figure 4-38 Insert Tag Libraries to the new CustomerDetails.jsp file 6. In the Source view, copy the following code beneath the Tag Library definitions (Example 4-38): Example 4-38 CustomerDetailsEntry.jsp fragment initial code <p> <%@ page language="java" contentType="text/html; charset=ISO-8859-1" Chapter 4. Using custom Domino JSP Tag libraries 259 pageEncoding="ISO-8859-1" import="dominojsptags.*" session="true" %> <portletAPI:init /> <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerDetails.SESSION_BEAN); %> <% try { %> <domino:session id="generalSession" host="<%=sessionBean.getHostname()%>" user="<%=sessionBean.getUsername()%>" duration="page"> <%-- Start:Session-specific code --%> <%-- connect to domino database --%> <domino:db id="generalDb" dbname="<%= sessionBean.getDbname()%>"> <%--Valid in <domino:db>and <domino:session>--%> <%-- open document --%> <domino:document id="CustomerDetailsDocument" unid="<%= sessionBean.getUidDoc()%>" schema="Customer"> <%-- display document properties --%> <TABLE border="0" cellspacing="2" cellpadding="2"> <TR align="left"> <TH>Customer Name</TH> <TD><domino:item name="customerName" /></TD> </TR> <TR align="left"> <TH>Customer Number</TH> <TD><domino:item name="customerNumber" /></TD> </TR> <TR align="left"> <TH>Customer Address</TH> <TD><domino:item name="customerAddress" /></TD> </TR> <TR align="left"> <TH>Account Owner</TH> <TD><domino:item name="ownerName" /></TD> </TR> <TR align="left"> <TH>Date Created</TH> 260 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <TD><domino:item name="DateCreated" format="DATE=SHORT" /></TD> </TR> <TR align="left"> <TH>Comments</TH> <TD><domino:item name="Comments" /></TD> </TR> </TABLE> <p> <form method="POST" action="<portletAPI:createReturnURI> <portletAPI:URIAction name='<%= DominoJspTagsPortletCustomerDetails.ACTION_SHOW_SGL_VIEW%>'/> <portletAPI:URIParameter name="<%= DominoJspTagsPortletCustomerDetails.VIEWNAME%>" value="<%= sessionBean.getSelectedView()%>"/> </portletAPI:createReturnURI>" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViewForm'/>"> <INPUT class="wpsButtonText" type="submit" name="Back" value="Back" onClick="window.location.href='<%=(String)request.getAttribute("CD_back")%>'"> </form> </p> </domino:document> </domino:db> <%-- End:Session-specific code --%> </domino:session> <% } catch (lotus.domino.taglib.DominoTagException e) { lotus.domino.NotesException ne = e.getNotesException(); %> <b>Tags Error:</b> <%= e.getMessage() %> <br> <b>Notes Error:</b> <%= ne.getMessage() %> <br> <% } catch(Exception e) { e.printStackTrace(new java.io.PrintWriter(out)); } %> This code opens a connection with the Lotus Domino server and extracts the document that has the UID corresponding to the uidDoc attribute we stored on the session object. Chapter 4. Using custom Domino JSP Tag libraries 261 To extract the field information from the Domino document, we use the <Domino:item> tag. 7. Save the file. Update the deployment descriptors The following section addresses how to update the deployment descriptors, namely web.xml and Portlet.xml. This is the final step prior to deploying the updated portlet. Update Web.xml 1. Open the web.xml file located in the /WEB-INF folder. 2. Go to the Servlets tab. 3. Click the Add button. 4. Select the DominoJspTagsPortletCustomerDetails class. 5. Update the servlet from DominoJspTagsPortletCustomerDetails to dominojsptags.DominoJspTagsPortletCustomerDetails. 6. Add a URL mapping; set it to /dominojsptags.DominoJspTagsPortletCustomerDetails/*, as shown in Figure 4-39. Figure 4-39 Customer Details Servlet 7. Save and close the web.xml file. Update Portlet.xml 1. Open the portlet.xml file located in the same folder. 2. Click the Add portlet button. 3. Select the CustomerDetails servlet, which is not used, and click OK. 4. Change the display name to DominoJspTagsCustomerDetails and its ID to dominojsptags.DominoJspTagsPortletCustomerDetails. 5. Click the Concrete Portlet Application folder. 262 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6. Click the Add Concrete Portlet button. 7. Click the CustomerDetails portlet, which is not used, and click OK. 8. Change its Display Name and Title to DominoJspTags Customer Details. 9. Add a description if needed. 10.Save the portlet.xml file. Deploy the portlet 1. Export the project from the J2EE Navigator view by right-clicking over the project and selecting Export. 2. Now we can test the new portlet we have just created. We follow the same steps as the deployment of the previous portlet, except instead of using the install wizard, we go to the Portlet Applications page and perform an update to the existing .WAR file. The resulting portlet will look similar to Figure 4-40. Figure 4-40 Customer Detail portlet Customer Contacts portlet Now we describe how to build the third portlet, which is the Customer Contacts portlet. This portlet displays an initial page with a list customers where the user can select to query. After a customer is selected, the portlet performs a full text search on the Contacts By Customer view in the customer.nsf database. Finally, it displays the result of the search in the portlet. Since the behavior of this portlet is similar to that of the Customer Detail, we will reuse some of the functionality already created. Chapter 4. Using custom Domino JSP Tag libraries 263 CustomerContacts.java file 1. Copy the DominoJspTagsPorletCustomerDetails.java portlet class and paste it in the same portlet package, but with a name of DominoJspTagsPorletCustomerContacts.java. 2. Open the newly copied CustomerContacts Java file. 3. Change the JSP files references from details to contacts as follows (Example 4-39): Example 4-39 CustomerContacts JSP files public static final String VIEW_JSP = "/dominojsptags/jsp/DominoJspTagsPortletCustomerContractsView."; file name to be rendered on the view mode // JSP ... // names of jsp files public static final String VIEW_JSP_INDEX = "View."; public static final String VIEW_JSP_CUSTOMER_CONTACTS= "CustomerContactsView."; public static final String VIEW_JSP_CUSTOMER_CONTACTS_ENTRY= "CustomerContactsEntry."; 4. In both the doView() and actionPerformed() methods: a. Change the name of the action from details to contacts. b. Change the attribute uidDoc to customerNameAttr. 5. In the doView() method: a. Modify the jspName reference from VIEW_JSP_CUSTOMER_DETAILS to VIEW_JSP_CUSTOMER_CONTACTS. b. Rename the reference from CD_back to CC_back. 6. In the actionPerformed() method, modify the sessionBean.setJspPage reference to the customer contacts as follow (Example 4-40): Example 4-40 CustomerContacts setJspPage // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_CONTACTS_ENTRY); ... // set properties in sessionBean ... sessionBean.setJspPage(VIEW_JSP_CUSTOMER_CONTACTS); 264 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 7. In the actionPerformed() method, modify the request.getParameter() parameter from uid to customerName. The doView() and actionPerformed() methods should look like Example 4-41. Example 4-41 Customer Contacts portlet initial doView() and actionPerformed() methods /** * @see org.apache.jetspeed.portlet.PortletAdapter#doView(PortletRequest, PortletResponse) */ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> doView: Unable to get a handle of the session bean."); return; } // set properties in sessionBean sessionBean.setUsername("*webuser"); sessionBean.setHostname("itso-dom.cam.itso.ibm.com"); sessionBean.setDbname("redbook/customer.nsf"); if(request.getPortletSession().getAttribute("customerNameAttr") != null){ PortletURI detailURI = response.createURI(); detailURI.addAction("contacts"); request.setAttribute("contacts", detailURI.toString()); // Store the return URI in the request PortletURI returnURI = response.createReturnURI(); request.setAttribute("CC_back", returnURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); // Redirecting to the DominoJspTagsPortletCustomerDetails.jsp file getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } else { // If no customer is selected PortletURI detailURI = response.createURI(); detailURI.addAction("contacts"); request.setAttribute("contacts", detailURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); Chapter 4. Using custom Domino JSP Tag libraries 265 if (jspName.equals(VIEW_JSP_INDEX) || jspName.equals("")) { jspName = VIEW_JSP_CUSTOMER_CONTACTS; sessionBean.setJspPage(jspName); } // Invoke the JSP to render getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } } /** * @see org.apache.jetspeed.portlet.event.ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent event) throws PortletException { if( getPortletLog().isDebugEnabled() ) getPortletLog().debug("ActionListener - actionPerformed called"); // ActionEvent handler String actionString = event.getActionString(); // Add action string handler here // get PortletRequest PortletRequest request = event.getRequest(); // get SessionBean DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> actionPerformed: Unable to get a handle of the session bean."); return; } // retrieve customer name from request String customerNameAttr = request.getParameter("customerName"); // Capture the customerName parameter from the request and store it as an attribute called customerNameAttr in the session object. if(actionString.equals("contacts") && !(customerNameAttr.equals("-Select a customer-"))){ request.getPortletSession().setAttribute("customerNameAttr", customerNameAttr); // set property in sessionBean sessionBean.setCustomerNameAttr(customerNameAttr); // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_CONTACTS_ENTRY); 266 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 } else { // handle display single database view action // retrieve viewname from request String view = request.getParameter(VIEWNAME); // set properties in sessionBean sessionBean.setSelectedView(view); sessionBean.setJspPage(VIEW_JSP_CUSTOMER_CONTACTS); } } The changes to the CustomerContacts java file are highlighted in bold in Example 4-41 on page 265. Now that the CustomerContacts java file is set, we will continue with the JSP files. View.jsp file 1. Copy the DominoJspTagsPortletCustomerDetailsView.jsp file and name it DominoJspTagsPortletCustomerContactsView.jsp. 2. Open the newly copied View.jsp file in Source mode. 3. Replace the code for sessionBean to point to the Customer Contact class and modify the selected view to point to the ContactsByCustomer view as follows (Example 4-42): Example 4-42 CustomerContacts ContactsByCustomer view JSP <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerContacts.SESSION_BEAN); // default to the Contacts by Customer Name view sessionBean.setSelectedView("ContactsByCustomer"); %> 4. Modify the form tag action attribute from details to contacts, which is the name of the action we created on our CustomerContacts portlet. 5. Modify the form name from CD_form to CC_form. 6. Create a table header with Customer Name. 7. Remove the <SELECT> and <OPTION> statements, since we will be using radio buttons instead. 8. Modify the <domino:ifdocumententry> tag to <domino:ifcategoryentry>. This will filter the view and present only the category entries. 9. Modify the Select HTML field name from uid to customerName. Chapter 4. Using custom Domino JSP Tag libraries 267 10.Modify the <domino:viewitem> tag, name attribute so that it extracts the Employer instead of the Customer Name. 11.Change the Select HTML field to radio button and its value from <domino:unid/> to <domino:viewitem name="Employer"/>, as shown in Example 4-43. Example 4-43 CustomerContacts radio button <tr> <td><input type="radio" name="customerName" value="<domino:viewitem name="Employer"/>"/></td> <td><font color="black" face="Arial" size="1"><domino:viewitem name="Employer"/></font></td> </tr> 12.Add pagination to the page as follows (Example 4-44): Example 4-44 CustomerContacts pagination <%-- add pagination --%> <domino:page id="plinfo" rows="10"> ... <%-- Display the Customers By Name view --%> ... <%-- filter documents --%> ... <%-- pagination --%> <domino:pagefirst/> <domino:pageprev/> <domino:pagenext/> <domino:pagelast/> <br>Page <%=plinfo.getPage()%> of <%=plinfo.getPageCount()%> </domino:page> 13.Modify the Submit and Reset buttons at the end to reference the CustomerContacts class instead of the CustomerDetails class, as shown in Example 4-45. Example 4-45 CustomerContacts submit & reset buttons <%-- create submit and reset buttons --%> <table> <tr> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerContacts.SUBMIT%>'/>" value="Show Entry" 268 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 type="submit"/> </td> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerContacts.RESET%>'/>" value="Reset" type="reset"/> </td> </tr> </table> 14.The modified View.jsp file looks like the following (Example 4-46): Example 4-46 CustomerContactsView.jsp fragment <domino:session id="generalSession" host="<%=sessionBean.getHostname()%>" user="<%=sessionBean.getUsername()%>" duration="page"> <%-- Start:Session-specific code --%> <domino:preserve name="mycustomercontactsview" /> <%-- connect to domino database --%> <domino:db id="db" dbname="<%= sessionBean.getDbname()%>"> <%-- open domino view --%> <domino:view id="view" viewname="<%= sessionBean.getSelectedView()%>"> <%-- add pagination --%> <domino:page id="plinfo" rows="10"> <%-- Display the Customers By Name view --%> <DIV style="margin: 6px"> <P>Please select a customer: <formmethod="post" action="<%=(String)request.getAttribute("contacts")%>" name="<portletAPI:encodeNamespace value='CC_form'/>"> <%-- create table header --%> <table> <tr> <th></th> <TH><FONT color="black" face="Arial" size="2">Customer Name</FONT></TH> </tr> <%-- create table body --%> <domino:viewloop id="loop"> <%-- filter documents --%> <domino:ifcategoryentry> Chapter 4. Using custom Domino JSP Tag libraries 269 <tr> <td><input type="radio" name="customerName" value="<domino:viewitem name="Employer"/>"/></td> <td><font color="black" face="Arial" size="1"><domino:viewitem name="Employer"/></font></td> </tr> </domino:ifcategoryentry> </domino:viewloop> </table> <%-- pagination --%> <domino:pagefirst/> <domino:pageprev/> <domino:pagenext/> <domino:pagelast/> <br>Page <%=plinfo.getPage()%> of <%=plinfo.getPageCount()%> </domino:page> <%-- create submit and reset buttons --%> <table> <tr> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerContacts.SUBMIT%>'/>" value="Show Entry" type="submit"/> </td> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerContacts.RESET%>'/>" value="Reset" type="reset"/> </td> </tr> </table> </form> </DIV> </domino:view> </domino:db> <%-- End:Session-specific code --%> </domino:session> 15.Save and close the View.jsp file. 270 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomerContactsEntry.jsp file 1. Copy the DominoJspTagsPortletCustomerDetailsEntry.jsp file and name it DominoJspTagsPortletCustomerContactsEntry.jsp. 2. Open the newly copied Entry.jsp file in Source view. 3. Erase the code in between and including the <Domino:document> tag, since we are going to display a view instead of a document. 4. Insert the JSP code shown in Example 4-47 where the <Domino:document> tag resided. Example 4-47 CustomerContactsEntry JSP fragment initial contents <%-- Construct the full text search string --%> <%!String SearchString="";%> <%SearchString="FIELD customerName contains "+sessionBean.getCustomerNameAttr();%> <domino:view id="generalView" viewname="<%=sessionBean.getSelectedView()%>" ftsearch='<%=SearchString%>'> <table> <tr> <th>Contact Name</th> <th>Phone Number</th> </tr> <domino:viewloop id="myviewloop"> <tr> <domino:ifdocumententry> <% if(myviewloop.getDocument().getItemValueString("customerName").equals(sessionBe an.getCustomerNameAttr())) {%> <td><domino:viewitem col="2"/></td> <td><domino:viewitem col="3"/></td> <% } %> </domino:ifdocumententry> </tr> </domino:viewloop> </table> </domino:view> <p> <form method="POST" action="<portletAPI:createReturnURI> <portletAPI:URIAction name='<%= DominoJspTagsPortletCustomerContacts.ACTION_SHOW_SGL_VIEW%>'/> <portletAPI:URIParameter name="<%= DominoJspTagsPortletCustomerContacts.VIEWNAME%>" Chapter 4. Using custom Domino JSP Tag libraries 271 value="<%= sessionBean.getSelectedView()%>"/> </portletAPI:createReturnURI>" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViewForm'/>"> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViews'/>" value="Back" type="submit"/> </form> </p> You will find that the <Domino:view> tag has a new attribute: ftsearch. This attribute lets us do a full text search based on a field, as displayed in the example, where we will search based on a field called CustomerName. Note: Use of the ftsearch attribute of the <Domino:view> tag requires that the referenced view be fully text indexed prior to the search request. Also, you will find that the <Domino:viewloop> tag has an attribute called name. This allows us to define a Domino Java object and use it inside our JSP code. In this JSP, we query each of the returned elements to make sure the full text search returned the exact documents that we were looking for. Other tags can have the ID attribute that will convert a JSP tag into a Domino Java object that can be referenced in the code. Information on the construction of portlets with these Domino Java objects is in the next chapter. Also, note that the <Domino:viewitem> tag is extracting information by the column number attribute; you can also use the name attribute to extract the column value by referencing the column name, like in the previous portlet’s View.jsp file. Finally, we introduced another JSP tag called <Domino:ifdocumententry>, which basically filters out the categorization entries from the view. Update the deployment descriptors The following section addresses how to update the deployment descriptors, namely Web.xml and Portlet.xml. This is the final step prior to deploying the updated portlet. Update Web.xml 1. Open the web.xml file located in the /WEB-INF folder. 2. Go to the Servlets tab. 3. Click the Add button. 272 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4. Select the DominoJspTagsPortletCustomerContacts class. 5. Update the servlet from DominoJspTagsPortletCustomerContacts to dominojsptags.DominoJspTagsPortletCustomerContacts. 6. Add a URL mapping; set it to /dominojsptags.DominoJspTagsPortletCustomerContacts/*, as shown in Figure 4-41. Figure 4-41 Customer Contacts Servlet 7. Save and close the web.xml file. Update Portlet.xml 1. Open the portlet.xml file located in the same folder. 2. Click the Add portlet button. 3. Select the CustomerContacts servlet, which is not used, and click OK. 4. Change the display name to DominoJspTagsCustomerContacts and its ID to dominojsptags.DominoJspTagsPortletCustomerContacts. 5. Click the Concrete Portlet Application folder. 6. Click the Add Concrete Portlet button. 7. Click the CustomerDetails portlet, which is not used, and click OK. 8. Change its Display Name and Title to DominoJspTags Customer Contacts. 9. Add a description if needed. 10.Save the portlet.xml file. Deploy the portlet Now we are all set with our third portlet; just deploy it as we did with our previous portlet and you should see something similar to Figure 4-42 on page 274. Chapter 4. Using custom Domino JSP Tag libraries 273 Figure 4-42 Customer Contacts initial portlet Customer Sales Activities portlet The Customer Sales Activities portlet displays information just like the two portlets already described, with a JSP file containing a list of the customers, but this time with sales activities. A difference from previous portlets is that it will access an independent sales database. After a customer is selected, the portlet loads a Domino view that will filter and display the documents and not the category entries. CustomerSalesActivities.java 1. Create the portlet class by copying the DominoJspTagsPortletCustomerContacts.java class that resides on the portlet package. 2. Paste the file in the same package and rename it DominoJspTagsPortletCustomerSalesActivities.java. 3. Open the newly pasted CustomerSalesActivities java file. 4. Change the JSP files references from contacts to sales activities as follows (Example 4-48 on page 275): 274 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-48 CustomerSalesActivities JSP files public static final String VIEW_JSP = "/dominojsptags/jsp/DominoJspTagsPortletCustomerSalesActivitiesView."; JSP file name to be rendered on the view mode // ... // names of jsp files public static final String VIEW_JSP_INDEX = "View."; public static final String VIEW_JSP_CUSTOMER_SALES_ACTIVITIES= "CustomerSalesActivitiesView."; public static final String VIEW_JSP_CUSTOMER_SALES_ACTIVITIES_ENTRY= "CustomerSalesActivitiesEntry."; 5. In both the doView() and actionPerformed() methods, change the name of the action from contacts to activities. 6. In the doView() method: a. Modify the database name to the Sales Activities database (sales.nsf). a. Modify the jspName reference from VIEW_JSP_CUSTOMER_CONTACTS to VIEW_JSP_CUSTOMER_SALES_ACTIVITIES. b. rename the reference from CC_back to CSA_back. c. rename the key that is used to store the action URI on the request object from contacts to activities. 7. In the actionPerformed() method, modify the sessionBean.setJspPage reference to the customer sales activities as follows (Example 4-49): Example 4-49 CustomerSalesActivities setJspPage // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_SALES_ACTIVITIES_ENTRY); ... // set properties in sessionBean ... sessionBean.setJspPage(VIEW_JSP_CUSTOMER_SALES_ACTIVITIES); 8. The doView() and actionPerformed() methods should look like Example 4-41 on page 265. Chapter 4. Using custom Domino JSP Tag libraries 275 Example 4-50 Customer Sales Activities portlet initial doView() and actionPerformed() methods /** * @see org.apache.jetspeed.portlet.PortletAdapter#doView(PortletRequest, PortletResponse) */ public void doView(PortletRequest request, PortletResponse response) throws PortletException, IOException { DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> doView: Unable to get a handle of the session bean."); return; } // set properties in sessionBean sessionBean.setUsername("*webuser"); sessionBean.setHostname("itso-dom.cam.itso.ibm.com"); sessionBean.setDbname("redbook/sales.nsf"); if(request.getPortletSession().getAttribute("customerNameAttr") != null){ PortletURI detailURI = response.createURI(); detailURI.addAction("activities"); request.setAttribute("activities", detailURI.toString()); // Store the return URI in the request PortletURI returnURI = response.createReturnURI(); request.setAttribute("CSA_back", returnURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); // Redirecting to the DominoJspTagsPortletCustomerDetails.jsp file getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } else { // If no customer is selected PortletURI detailURI = response.createURI(); detailURI.addAction("activities"); request.setAttribute("activities", detailURI.toString()); // get name of JSP to render String jspName = sessionBean.getJspPage(); if (jspName.equals(VIEW_JSP_INDEX) || jspName.equals("")) { jspName = VIEW_JSP_CUSTOMER_SALES_ACTIVITIES; sessionBean.setJspPage(jspName); 276 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 } // Invoke the JSP to render getPortletConfig().getContext().include(VIEW_JSP_ROOT+ jspName +getJspExtension(request), request, response); } } /** * @see org.apache.jetspeed.portlet.event.ActionListener#actionPerformed(ActionEvent) */ public void actionPerformed(ActionEvent event) throws PortletException { if( getPortletLog().isDebugEnabled() ) getPortletLog().debug("ActionListener - actionPerformed called"); // ActionEvent handler String actionString = event.getActionString(); // Add action string handler here // get PortletRequest PortletRequest request = event.getRequest(); // get SessionBean DominoJspTagsSessionBean sessionBean = getSessionBean(request); if (sessionBean == null) { // insert routine to handle non-existence of a portlet session System.out.println(">>>>>>>>>> actionPerformed: Unable to get a handle of the session bean."); return; } // retrieve customer name from request String customerNameAttr = request.getParameter("customerName"); // Capture the uid parameter from the request and store it as an attribute called uidDoc in the session object. if(actionString.equals("activities")){ request.getPortletSession().setAttribute("customerNameAttr", customerNameAttr); // set property in sessionBean sessionBean.setCustomerNameAttr(customerNameAttr); // set jsp file to be rendered next sessionBean.setJspPage(VIEW_JSP_CUSTOMER_SALES_ACTIVITIES_ENTRY); } else { // handle display single database view action // retrieve viewname from request String view = request.getParameter(VIEWNAME); Chapter 4. Using custom Domino JSP Tag libraries 277 // set properties in sessionBean sessionBean.setSelectedView(view); sessionBean.setJspPage(VIEW_JSP_CUSTOMER_SALES_ACTIVITIES); } } You can see the changes in bold in Example 4-50 on page 276. Also, notice that there is no change on the customerName parameter and customerNameAttr. This is because our search on the view will be done by the customer name. In addition, this will help the Click-to-Action broker to associate both actions as similar; this is explained in detail in 4.6, “Integration via Click-to-Action” on page 287. View.jsp file 1. Copy the DominoJspTagsPortletCustomerContactsView.jsp file and name it DominoJspTagsPortletCustomerSalesActivitiesView.jsp. 2. Open the file and inspect it in the source view. 3. Replace the code for sessionBean to point to the Customer Sales Activities class and change the view name to saByCustomer as follows (Example 4-51): Example 4-51 Customer Sales Activities view jsp sessionBean <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerSalesActivities.SESSION_BEAN); // default to the Sales Activity by Customer view sessionBean.setSelectedView("saByCustomer"); %> 4. In the form tag: a. Modify the action attribute to reference from contacts to activities. b. modify the form name from CC_back to CSA_back. 5. In the HTML input tag, modify the value and name so that the <Domino:viewitem> name attribute is Customer instead of Employer. 6. Modify the Submit and Reset buttons at the end to reference the CustomerSalesActivities class instead of the CustomerContacts class, as show in Example 4-52 on page 279. 278 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 4-52 CustomerSalesActivities submit and reset buttons <%-- create submit and reset buttons --%> <table> <tr> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerSalesActivities.SUBMIT%>'/>" value="Show Entry" type="submit"/> </td> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerSalesActivities.RESET%>'/>" value="Reset" type="reset"/> </td> </tr> </table> 7. The modified View.jsp file looks like the following (Example 4-53): Example 4-53 CustomerSalesActivitiesView JSP file <% // get access to the attributes saved in the SessionBean DominoJspTagsSessionBean sessionBean = (DominoJspTagsSessionBean)portletRequest.getPortletSession().getAttribute(Domin oJspTagsPortletCustomerSalesActivities.SESSION_BEAN); // default to the Sales Activity by Customer view sessionBean.setSelectedView("saByCustomer"); %> <% try { %> <domino:session id="generalSession" host="<%=sessionBean.getHostname()%>" user="<%=sessionBean.getUsername()%>" duration="page"> <%-- Start:Session-specific code --%> <domino:preserve name="mycustomercontactsview" /> Chapter 4. Using custom Domino JSP Tag libraries 279 <%-- connect to domino database --%> <domino:db id="db" dbname="<%= sessionBean.getDbname()%>"> <%-- open domino view --%> <domino:view id="view" viewname="<%= sessionBean.getSelectedView()%>"> <%-- add pagination --%> <domino:page id="plinfo" rows="10"> <%-- Display the Customers By Name view --%> <DIV style="margin: 6px"> <P>Please select a customer: <formmethod="post" action="<%=(String)request.getAttribute("activities")%>" name="<portletAPI:encodeNamespace value='CSA_form'/>"> <%-- create table header --%> <table> <tr> <th></th> <TH><FONT color="black" face="Arial" size="2">Customer Name</FONT></TH> </tr> <%-- create table body --%> <domino:viewloop id="loop"> <%-- filter documents --%> <domino:ifcategoryentry> <tr> <td><input type="radio" name="customerName" value="<domino:viewitem name="Customer"/>"/></td> <td><font color="black" face="Arial" size="1"><domino:viewitem name="Customer"/></font></td> </tr> </domino:ifcategoryentry> </domino:viewloop> </table> <%-- pagination --%> <domino:pagefirst/> <domino:pageprev/> <domino:pagenext/> <domino:pagelast/> <br>Page <%=plinfo.getPage()%> of <%=plinfo.getPageCount()%> </domino:page> <%-- create submit and reset buttons --%> <table> <tr> <td> 280 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerSalesActivities.SUBMIT%>'/>" value="Show Entry" type="submit"/> </td> <td> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='<%= DominoJspTagsPortletCustomerSalesActivities.RESET%>'/>" value="Reset" type="reset"/> </td> </tr> </table> </form> </DIV> </domino:view> </domino:db> <%-- End:Session-specific code --%> </domino:session> 8. Save and close the View.jsp file. CustomerSalesActivitiesEntry.jsp file 1. Copy the DominoJspTagsPortletCustomerContactsEntry.jsp file and name it DominoJspTagsPortletCustomerSalesActivitiesEntry.jsp. 2. Open the newly copied Entry.jsp file in the Source view. 3. Erase the code in between and including the <table> HTML tag. 4. Insert the JSP code shown in Example 4-54 to where the <table> tag resided. Example 4-54 CustomerSalesActivitiesEntry JSP fragment initial contents <TABLE border="0" cellspacing="2" cellpadding="2"> <tr> <th>Date</th> <th>Activity</th> <th>Sales Person</th> <th>Contact</th> <th>Made Sale?</th> </tr> <domino:viewloop id="myviewloop"> <domino:ifdocumententry> <% Chapter 4. Using custom Domino JSP Tag libraries 281 if(myviewloop.getDocument().getItemValueString("customerName").equals(sessionBe an.getCustomerNameAttr())) {%> <tr align="left"> <td><domino:viewitem col="2" format="DATE=SHORT"/></td> <td><domino:viewitem col="3"/></td> <td><domino:viewitem col="4"/></td> <td><domino:viewitem col="5"/></td> <td><domino:viewitem col="6"/></td> </tr> <% } %> </domino:ifdocumententry> </domino:viewloop> </table> 5. Modify the Submit and Reset buttons at the end to reference the CustomerSalesActivities class instead of the CustomerContacts class, as show in Example 4-55. Example 4-55 CustomerSalesActivities back button <form method="POST" action="<portletAPI:createReturnURI> <portletAPI:URIAction name='<%= DominoJspTagsPortletCustomerSalesActivities.ACTION_SHOW_SGL_VIEW%>'/> <portletAPI:URIParameter name="<%= DominoJspTagsPortletCustomerSalesActivities.VIEWNAME%>" value="<%= sessionBean.getSelectedView()%>"/> </portletAPI:createReturnURI>" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViewForm'/>"> <input class="wpsButtonText" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViews'/>" value="Back" type="submit"/> </form> 6. The modified Entry.jsp file looks like the following (Example 4-56): Example 4-56 CustomerSalesActivitiesEntry.jsp <domino:session id="generalSession" host="<%=sessionBean.getHostname()%>" user="<%=sessionBean.getUsername()%>" duration="page"> <%-- Start:Session-specific code --%> 282 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <%-- connect to domino database --%> <domino:db id="generalDb" dbname="<%= sessionBean.getDbname()%>"> <%-- Construct the full text search string --%> <%!String SearchString="";%> <%SearchString="FIELD customerName contains "+sessionBean.getCustomerNameAttr();%> <domino:view id="generalView" viewname="<%=sessionBean.getSelectedView()%>" ftsearch='<%=SearchString%>'> <TABLE border="0" cellspacing="2" cellpadding="2"> <tr> <th>Date</th> <th>Activity</th> <th>Sales Person</th> <th>Contact</th> <th>Made Sale?</th> </tr> <domino:viewloop id="myviewloop"> <domino:ifdocumententry> <% if(myviewloop.getDocument().getItemValueString("customerName").equals(sessionBe an.getCustomerNameAttr())) {%> <tr align="left"> <td><domino:viewitem col="2" format="DATE=SHORT"/></td> <td><domino:viewitem col="3"/></td> <td><domino:viewitem col="4"/></td> <td><domino:viewitem col="5"/></td> <td><domino:viewitem col="6"/></td> </tr> <% } %> </domino:ifdocumententry> </domino:viewloop> </table> </domino:view> <p> <form method="POST" action="<portletAPI:createReturnURI> <portletAPI:URIAction name='<%= DominoJspTagsPortletCustomerSalesActivities.ACTION_SHOW_SGL_VIEW%>'/> <portletAPI:URIParameter name="<%= DominoJspTagsPortletCustomerSalesActivities.VIEWNAME%>" value="<%= sessionBean.getSelectedView()%>"/> </portletAPI:createReturnURI>" name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViewForm'/>"> <input class="wpsButtonText" Chapter 4. Using custom Domino JSP Tag libraries 283 name="<portletAPI:encodeNamespace value='dominojsptags.DominoJspTagsPortletShowViews'/>" value="Back" type="submit"/> </form> </p> </domino:db> <%-- End:Session-specific code --%> </domino:session> This is a very interesting JSP, since first it points to and extracts information from the Sales database, which could be unrelated to the Customers database. But as we discuss in the Click-to-Action topic later in this chapter, we will connect these two applications at the portal level. Also, if you inspect the <Domino:viewloop> tag, you will see that there is a name attribute again. This name attribute represents a Domino Java object and is later used in the same JSP file in a scriptlet code to filter out activities not related to our customer. Update the deployment descriptors The following section addresses how to update the deployment descriptors, namely Web.xml and Portlet.xml. This is the final step prior to deploying the updated portlet. Update Web.xml 1. Open the web.xml file located in the /WEB-INF folder. 2. Go to the Servlets tab. 3. Click the Add button. 4. Select the DominoJspTagsPortletCustomerSalesActivities class. 5. Update the servlet from DominoJspTagsPortletCustomerSalesActivities to dominojsptags.DominoJspTagsPortletCustomerSalesActivities. 6. Add a URL mapping; set it to /dominojsptags.DominoJspTagsPortletCustomerSalesActivities/* as shown in Example 4-41 on page 273. 284 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-43 Customer Sales Activities Servlet 7. Save and close the web.xml file. Update Portlet.xml 1. Open the portlet.xml file located in the same folder. 2. Click the Add portlet button. 3. Select the CustomerSalesActivities servlet, which is not used, and click OK. 4. Change the display name to DominoJspTagsPortletCustomerSalesActivities and its ID to dominojsptags.DominoJspTagsPortletCustomerSalesActivities. 5. Click the Concrete Portlet Application folder. 6. Click the Add Concrete Portlet button. 7. Click the CustomerDetails portlet, which is not used, and click OK. 8. Change its Display Name and Title to DominoJspTags Customer Sales Activities. 9. Add a description if needed. 10.Save the portlet.xml file. Deploy the portlet Deploy the portlet in the same manner that you used for the previous ones. The new portlet should appear something like Figure 4-44 on page 286. Chapter 4. Using custom Domino JSP Tag libraries 285 Figure 4-44 Customer Sales Activities initial portlet We have now finished the first phase of our portlet building. We constructed four portlets from different Domino databases that extract information based on the user input. Next, we explore techniques to enhance this initial transformation. In 4.6, “Integration via Click-to-Action” on page 287, we describe a technique to enable our portlets to communicate between each other, even between heterogeneous Domino databases. 4.5.9 Conclusions to the custom Domino tags integration technique The inclusion of JSP tags from different services lets us add value to our portlets. We showed how to include custom Domino JSP tags. Some of the benefits of this option are: The developer does not have to know Java programming in depth to build portlets that extract information from Domino. The developer does not have to know the Domino object model in depth to access data in Domino. JavaServer Pages (JSP) are a J2EE technology that can offer simplicity as a programming model and the robust characteristics of Java. IBM has the tools necessary to develop portlets that integrate Domino applications, including collaboration features. 286 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4.6 Integration via Click-to-Action This important topic is included in the current chapter, since the invocation is done through JSP tags. But as we explain later in this section, Click-to-Action incorporates other technologies as well, including Web services, WSDL, portlet descriptors, and others. We explain these technologies as we go through the implementation of Click-to-Action. 4.6.1 Click-to-Action Click-to-Action (sometimes referred as Click2Action or C2A) provides a framework for inter-portlet communication that simplifies users’ interactions with portlets on a portal page. With a simple click, a user can transfer data from a source portlet to one or more target portlets, causing the target to react to the action and display a new view with the results. The Click-to-Action framework includes a runtime that automatically matches sources with compatible targets (based on type information) and inserts clickable icons associated with sources on portlet pages. When the user clicks an icon next to a particular source, they are presented with a pop-up menu containing the list of targets for the action. After the user selects a specific target, the Click-to-Action runtime delivers the data to the target in the form of the corresponding portlet action. The portlet does not need to distinguish between an action initiated by user interaction with its own page segment and action initiated using the Click-to-Action route. This keeps the programming effort to a minimum, allowing Click-to-Action portlets to follow the normal portlet programming model. Features of the Click-to-Action model Click-to-Action provides an easy, menu-driven method to transfer compatible data between portlets, eliminating manual data entry from one portlet to another and avoiding the learning normally necessary to discover actions on target portlets that are compatible with sources on the current page. Click-to-Action includes these additional benefits: Broadcast source data to all matching actions on the page. A user can specify the target of an action or broadcast the action to all portlets on the page. This feature is available in the source portlet when the broadcast attribute is specified for the <c2a:encodeProperty/> tag. Chained propagation of data transfer. Sending data to one portlet can cause that portlet to send data to another portlet, which can in turn transmit data. This feature supports the synchronization of multiple portlet views in a single request-response cycle. Chapter 4. Using custom Domino JSP Tag libraries 287 For example, transferring the order ID to the Order Details portlet also triggers the transfer of the tracking ID for the order to the tracking details portlet, which in turn triggers the transfer of the customer name associated with the order to the customer details portlet, causing all three to display information pertaining to the same order. This feature can be enabled by specifying output parameters in the target portlet's WSDL. When the target receives data from a source, this can cause the transfer of one or more output parameters declared in the WSDL file. As pictures in Figure 4-45, the propagation of information can chain a series of events leading to a complete flow of interactions. Figure 4-45 Click-to-Action chained propagation Scatter multiple related sources to targets on the page with a single click. In addition to directing the data transfer to a particular portlet, you can broadcast the information that is sent to all the listener portlets. As a result of this broadcast, all portlets on the page display information related to the transferred information. This scatter feature, combined with the chained data transfer feature, results in the synchronization of all the information about the page through a single user click. Simple enablement for portlet development. – For a portlet to be a source of data, programmers can use a custom JSP tag library to flag sharable data on their output pages. The tags require a data type to be specified, as well as a specific value corresponding to an instance of this type. – For a portlet to be a target, programmers describe a subset of their portlet actions, including type information for the action parameters. The format for the action description is WSDL, with some custom extensions. Concepts and design of Click-to-Action Click-to-Action allows end-user triggered information interchange between independently developed portlets. Each portlet needs to provide information about data objects that it could share with other portlets, either as a producer or a consumer. Each sharable data object is identified with an XML type. The Click-to-Action broker is a runtime entity that processes information about sharable data objects on a page and matches producers of the data with 288 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 consumers using type matching. Based on the match information, the broker generates a special icon next to sources of data, which is used to display the pop-up menu of matching actions. When the end user chooses an action from the menu, it is intercepted by the broker, which then transfers the data value to the chosen target. Source portlets (portlets that contribute data objects that can be shared with other portlets) use a set of custom JSP tags to specify the type and value of the data being contributed. At the point where such a tag occurs, the Click-to-Action broker inserts the markup that can display the pop-up menu of action choices for the user. Advanced options on the tags allow the programmer to indicate whether a broadcast action is to be added to the menu, and allow the scattering of a set of data values (rather than a single data value) to all portlets. Target portlets (portlets that accept data from other portlets) declare a set of actions that can be invoked on the portlet. The actions are implemented by the portlet as normal portlet actions. The actions are declared using WSDL, with a custom binding extension that specifies the mapping from the abstract action declaration to the actual action implementation. Associated with each action is a single input parameter described by an XML type and one or more output parameters, each described by an XML type. The input parameter's type is used for matching the action to sources, and its value is filled in when the end user triggers the action using Click-to-Action. The output parameters, if specified, are used to automatically trigger other compatible actions (ones which can consume the same type) on other portlets every time the action executes (this may be used to trigger chains of related actions). The choice of WSDL for declaring the actions was influenced by two considerations: The need for a standard format rather than a custom format The ability in WSDL to plug in descriptions of different types of implementing entities, providing a future growth path for the Click-to-Action technology Another interesting aspect of the design is the use of normal portlet actions to deliver data from other portlets. This approach allows the reuse of actions that are used to interact with the portlet directly, and in many cases allows pre-existing portlets to be made into Click-to-Action targets simply by declaring all or part of their actions using WSDL. Figure 4-46 on page 290 is a high-level diagram of the Click-to-Action sequence of events that takes place. Chapter 4. Using custom Domino JSP Tag libraries 289 Figure 4-46 Click-to-Action sequence diagram The Click-to-Action runtime is composed of a generic wrapper portlet, which is used to wrap each portlet enabled for Click-to-Action, and a broker component. These components also interface with the WebSphere Portal core runtime. The purpose of the wrapper is to intercept calls to the application portlet and interface with the broker appropriately to transparently register actions supported by the portlet, transfer data from source to target portlets, and so forth. The broker centrally maintains a repository of actions on each portlet along with the parameter type information, performs source and target matches at runtime using this information, and generates additional markup to allow users to trigger data transfers across portlets. The WebSphere Portal core runtime performs the functions of generating the portal pages, receiving browser requests, invoking callbacks on portlets, and so forth. Finally, JSPs associated with source portlets use custom tags to declare sharable sources of data, and target portlets provide a WSDL file declaring portlet actions that may be invoked by the Click-to-Action runtime. The Click-to-Action flow is designed to account for the portlet event processing model, which is described in Portlet events. The portal programming model involves an event phase and a render phase in each request-response cycle. During the event phase, an action may be delivered on one portlet. If Click-to-Action is used, this may result in other actions being triggered on other portlets. The event phase is followed by the render phase, in which each portlet is asked to return markup, which is then aggregated in a single page. The 290 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 markup may embed actions that can be invoked by the user. The page is then returned to the client (such as a browser). A typical request-response flow involving Click-to-Action is illustrated in Figure 4-46 on page 290. This consists of the following steps: 1. During portlet initialization, the wrapper processes any action WSDL file associated with the application portlet and registers the actions with the broker. 2. During the render phase of a request cycle, JSPs associated with Click-to-Action source portlets are processed. 3. The custom Click-to-Action tags result in calls to the Click-to-Action event broker, which determines matching actions on the page based on type information. 4. The Click-to-Action broker generates additional code to display the Click-to-Action icon used to invoke the pop-up menu. 5. After all render phase portlet callbacks have been completed, the portal assembles the response page and returns it to the client. 6. The end user can click the Click-to-Action icon for a source to view a menu of compatible actions on the page and select one. 7. A new request is generated, containing the chosen source and action information, and is sent to the portal. 8. The portal core runtime delivers the action to the target portlet. This is intercepted by the wrapper, which may interact with the broker to further process the request before delivering the action to the target. While all portlet actions are intercepted by the wrapper, actions which are invoked through direct interaction with the portlet (as opposed to interaction through Click-to-Action) are passed through transparently to the portlet. 4.6.2 Considerations We can integrate portlets that expose Domino data through the WebSphere Portal Click-to-Action Broker. 4.6.3 Implementation of the technique As we mentioned in the introduction to this topic, the Click-to-Action technology included on the WebSphere Portal enables communication between portlets. In our case, it was used to extract information from our example Sales and Customer Lotus Domino applications. Chapter 4. Using custom Domino JSP Tag libraries 291 In this section, we describe how to enable the portlets with Click-to-Action capabilities. We focus first on the Customer List portlet, which is the source portlet, and then on enabling the target portlets, which are the remaining portlets (Customer Details, Customer Contacts, and Customer Sales Activities) on the page. Enabling the source portlet (Customer List) The process of enabling the source portlet is very simple. First, you have to know what parameters are to be transmitted to the target portlets. The parameter transmitted should be the same one expected on the action of the target portlet. The target portlet parameters and actions expected are outlined in Table 4-9. Table 4-9 Click-to-Action target portlet parameters and actions Portlet name Parameter Action Customer Details uid details Customer Contacts customerName contacts Customer Sales Activities customerName activities Use the following steps to start working on the portlet: 1. Open the DominoJspTagsPortletCustomerListView.jsp file. 2. At the very beginning of the jsp file, insert the following tag library import statement: <%@ taglib uri="/WEB-INF/tld/c2a.tld" prefix="C2A" %> 3. On the table row displaying the resulting loop, before the <Domino:viewitem col="1"/> tag, drag and drop the Click-to-Action Output Property control from the Portlet drawer in the Palette view, as shown in Figure 4-47 on page 293. 292 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-47 Insert Click-to-Action Output Property control 4. In the Insert Click-to-Action Output property dialog, enter CustomerIDType for the data type and select DominoJspTagsPortletCustomerList from the Portlet drop-down menu. Name the WSDL file CustomerList (see Figure 4-48). Figure 4-48 Insert Click-to-Action Output Property A down-arrow button should now be displayed before the <Domino:viewitem col="1"/> tag in Design view. 5. Insert a value attribute to the CustomerID C2A tag as follows: value='<%=myviewloop.getDocument().getUniversalID()%>'/> 6. Repeat steps 3 on page 292 to 4 and enter CutomerNameType as the data type. 7. Insert a broadcast attribute to the CustomerName C2A tag as follows: broadcast=”true” Chapter 4. Using custom Domino JSP Tag libraries 293 8. Insert a value attribute to the CustomerName C2A tag as follows: value='<%=myviewloop.getDocument().getItemValueString("customerName")%>'/> 9. The modified C2A tags should look like Example 4-57. Example 4-57 Click-to-Action tags <C2A:encodeProperty type="CustomerIDType" namespace="http://dominojsptags" name="CustomerIDType" value='<%=myviewloop.getDocument().getUniversalID()%>'></C2A:encodeProperty> <C2A:encodeProperty type="CustomerNameType" namespace="http://dominojsptags" name="CustomerNameType" broadcast="true" value='<%=myviewloop.getDocument().getItemValueString("customerName")%>'></C2A: encodeProperty> There are several things to note about the two lines inserted. First, notice that both tags are Click-to-Action JSP custom tags, and they have several attributes. Table 4-10 is a description of the purpose of the available Click-to-Action encode property attributes. Table 4-10 Click-to-Action encode property JSP tag attributes 294 Attribute Description type Specifies the type of data sent by the source portlet. Required. The data type is defined in the WSDL, which will be defined when we enable the target portlets. The Click-to-Action runtime uses type and namespace attributes to match source data to actions on targets. namespace Specifies the namespace for the type. Required. This attribute is used to group related types in a single domain. value Specifies the data to be sent by the source portlet. Required. The Click-to-Action runtime sends the value of the user's selections to the target actions. broadcast Indicates whether the source data can be broadcast to all target portlets with matching actions. False is the default setting. Optional. If the value is true, the generated menu displays an additional item to broadcast the source to all matching targets. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Attribute Description generateMarkupWhen Nested Indicates that this tag should generate markup even when nested within the <c2a:encodeProperties/> tag. This attribute is optional; the default is false. If this tag is not nested, the attribute is ignored. For our initial example, this attribute was not used. Also, notice that inside the value attribute you are inserting a Java scriptlet, which will get the parameters required to feed the target portlets. Since there are two portlets that will require the same customerName parameter, just one tag is required. 10.Save and close the jsp file. At this point, when you look at the Project Navigator, you should see a source portlet icon on the Customer List portlet. A WSDL file for CustomerList is also created in the WebContent folder. You are now done enabling the source portlet. Enabling the target portlets Now that the source portlet has been enabled, it is now time to shift our focus to the target portlets. We begin with discussing the target Customer Details portlet. Enabling the Customer Details portlet You do not have to modify any Java code to enable the target portlets; the task is basically a definition process that comprises the creation of a WSDL descriptor file. 1. In the Project Navigator, right-click the Customer Details portlet and select Enable Click-to-Action Target, as shown in Figure 4-49 on page 296. Chapter 4. Using custom Domino JSP Tag libraries 295 Figure 4-49 Customer Details portlet Enable Click-to-Action Target 2. In the Enable Click-to-Action Target dialog, set the parameters as follows (Figure 4-50 on page 297): a. For Data Type, click the Browse button and select CustomerList.wsdl. b. Select CustomerIDType. c. Enter details as the Action. d. Enter uid as the Parameter. e. Enter Show Details... as the C2A caption. This text will be shown in the context menu when the user clicks on the portlet’s Click-to-Action button. f. Enter “Get details for the specified customer” as the C2A description. g. Enter CustomerDetails as the WSDL file and click the OK button. 296 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-50 Customer Details portlet Enable Click-to-Action Target Parameters At this point, when you look at the Project Navigator, you should see a target portlet icon on the Customer Details portlet. A WSDL file for CustomerDetails is also created in the WebContent folder (Example 4-58). Example 4-58 CustomerDetails.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="CustomerDetails_Service" targetNamespace="http://dominojsptags" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:portlet="http://www.ibm.com/wps/c2a" xmlns:tns="http://dominojsptags" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://dominojsptags"> <xsd:simpleType name="CustomerIDType"> <xsd:restriction base="xsd:string"></xsd:restriction> </xsd:simpleType> </xsd:schema> </types> <message name="CustomerIDType_Request"> <part name="CustomerIDType_Input" type="tns:CustomerIDType" /> </message> <portType name="CustomerDetails_Service"> <operation name="CustomerDetails"> <input message="tns:CustomerIDType_Request" /> </operation> </portType> <binding name="CustomerDetails_Binding" type="tns:CustomerDetails_Service"> <portlet:binding /> Chapter 4. Using custom Domino JSP Tag libraries 297 <operation name="CustomerDetails"> <portlet:action name="details" type="simple" caption="Show Details..." description="Get details for the specified customer" /> <input> <portlet:param name="uid" partname="CustomerIDType_Input" /> </input> </operation> </binding> </definitions> The WSDL file describes how the target portlet exposes its services. Note that in the definitions open tag we specify the namespace we are using as http://dominojsptags, which is the same as the one defined in the source portlet Click-to-Action <C2A:encodeProperty> JSP tag. We define a simple type called CustomerIDType, which is a simple xsd string type. Notice also that in the source portlet’s first Click-to-Action <C2A:encodeProperty> JSP tag we are referencing this type. Also notice in the binding area that we are referencing an action with the same name, "details" that our portlet uses. It will store the value in a parameter called "uid" that will feed the portlets actionPerformed() method. Enabling the Customer Contacts portlet Create the WSDL file using the following steps: 1. In the Project Navigator, right-click the Customer Contacts portlet and select Enable Click-to-Action Target. 2. In the Enable Click-to-Action Target dialog, set the parameters as follows: a. For Data Type, click the Browse button and select CustomerList.wsdl. b. Select CustomerNameType. c. Enter contacts as the Action. d. Enter customerName as the Parameter. e. Enter Show Contacts... as the C2A caption. This text will be shown in the context menu when the user clicks on the portlet’s Click-to-Action button. f. Enter “Get contacts for the specified customer” as the C2A description. g. Enter CustomerContacts as the WSDL file and click the OK button. 298 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-51 Customer Contacts portlet Enable Click-to-Action Target Parameters At this point, when you look at the Project Navigator, you should see a target portlet icon on the Customer Contacts portlet. A WSDL file for CustomerContacts is also created in the WebContent folder. Example 4-59 CustomerContacts.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="CustomerContacts_Service" targetNamespace="http://dominojsptags" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:portlet="http://www.ibm.com/wps/c2a" xmlns:tns="http://dominojsptags" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://dominojsptags"> <xsd:simpleType name="CustomerNameType"> <xsd:restriction base="xsd:string"></xsd:restriction> </xsd:simpleType> </xsd:schema> </types> <message name="CustomerNameType_Request"> <part name="CustomerNameType_Input" type="tns:CustomerNameType" /> </message> <portType name="CustomerContacts_Service"> <operation name="CustomerContacts"> <input message="tns:CustomerNameType_Request" /> </operation> </portType> <binding name="CustomerContacts_Binding" type="tns:CustomerContacts_Service"> Chapter 4. Using custom Domino JSP Tag libraries 299 <portlet:binding /> <operation name="CustomerContacts"> <portlet:action name="contacts" type="simple" caption="Show Contacts..." description="Get contacts for the specified customer" /> <input> <portlet:param name="customerName" partname="CustomerNameType_Input" /> </input> </operation> </binding> </definitions The WSDL file describes how the target portlet exposes its services. Note in the definitions open tag we are describing the same namespace (http://dominojsptags) that we defined in the source portlet Click-to-Action <C2A:encodeProperty> JSP tag. We are defining a simple type called CustomerNameType, which is a simple xsd string type. Notice also that in the source portlet, in the second Click-to-Action <C2A:encodeProperty> JSP tag, we are referencing this type. In the binding area, notice that we are referencing an action with the same name contacts that one our portlet uses. It will store the value in a parameter called customerName that will feed our CustomerContacts portlet’s actionPerformed() method. Enabling the Customer Sales Activities portlet Create the WSDL file using the following steps: 1. In the Project Navigator, right-click the Customer Sales Activities portlet and select Enable Click-to-Action Target. 2. In the Enable Click-to-Action Target dialog, set the parameters as follows: a. For Data Type, click the Browse button and select CustomerList.wsdl. b. Select CustomerNameType. c. Enter activities as the Action. d. Enter customerName as the Parameter. e. Enter Show Sales Activities... as the C2A caption. This text will be shown in the context menu when the user clicks on the portlet’s Click-to-Action button. f. Enter “Get sales activities for the specified customer” as the C2A description. g. Enter CustomerSalesActivities as the WSDL file and click the OK button. 300 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-52 Customer Sales Activities portlet Enable Click-to-Action Target Parameters At this point, when you look at the Project Navigator, you should see a target portlet icon on the Customer Sales Activities portlet. A WSDL file for CustomerSalesActivities is also created in the WebContent folder. Example 4-60 CustomerSalesActivities.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="CustomerSalesActivities_Service" targetNamespace="http://dominojsptags" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:portlet="http://www.ibm.com/wps/c2a" xmlns:tns="http://dominojsptags" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://dominojsptags"> <xsd:simpleType name="CustomerNameType"> <xsd:restriction base="xsd:string"></xsd:restriction> </xsd:simpleType> </xsd:schema> </types> <message name="CustomerNameType_Request"> <part name="CustomerNameType_Input" type="tns:CustomerNameType" /> </message> <portType name="CustomerSalesActivities_Service"> <operation name="CustomerSalesActivities"> <input message="tns:CustomerNameType_Request" /> </operation> </portType> <binding name="CustomerSalesActivities_Binding" type="tns:CustomerSalesActivities_Service"> Chapter 4. Using custom Domino JSP Tag libraries 301 <portlet:binding /> <operation name="CustomerSalesActivities"> <portlet:action name="activities" type="simple" caption="Show Sales Activities..." description="Get sales activities for the specified customer" /> <input> <portlet:param name="customerName" partname="CustomerNameType_Input" /> </input> </operation> </binding> </definitions> The WSDL file describes how the target portlet exposes its services. Note in the definitions opening tag we are describing the same namespace that we defined in the source portlet Click-to-Action <C2A:encodeProperty> JSP tag, "http://www.ibm.com/customer". We are defining the simple type CustomerNameType, which is a simple xsd string type. Notice also that in the source portlet, in the second Click-to-Action <C2A:encodeProperty> JSP tag, we are referencing this type. Also notice in the binding area that we are referencing an action with a name “activities" like the one our portlet uses. It will store the value on a parameter called customerName, which will feed our portlet’s actionPerformed() method. Deploy the portlet Now that all the settings are complete for your Click-to-Action portlets, deploy them just as you did in the previous exercises. You should see a page like the one depicted in Figure 4-53 on page 303. 302 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 4-53 Click-to-Action enabled JSP tags portlets The portlets are enabled with Click-to-Action, and the customers.nsf database with the sales.nsf database are integrated seamlessly at the portal interface level. In the next section, we describe how to add some finishing touches, specifically by adding people awareness to the portlets. But before we do that, let us take a look at some common pitfalls that developers run into when developing portlets that are Click-to-Action enabled. Common pitfalls Be aware of the Namespace definition of the WSDL file; your Namespace should be unique and match the one described on the <C2A:encodeProperty> tag. Your namespace should be inside the definitions tag of the WSDL file in the attributes targetNamespace and xmlns:tns. Do not modify any other namespace. In WebSphere Portal 5, Click-to-Action is limited to Portlets that reside on the same page. 4.7 Integration via people awareness This integration technique will add value to your portlets by exploiting the people awareness services provided by WebSphere Portal. This integration technique adds real-time collaboration among the people involved in the application. Chapter 4. Using custom Domino JSP Tag libraries 303 4.7.1 People awareness If you extend the portal to offer people awareness features, portal users will see references to people in collaborative portlets. These references to individuals and groups are links that let portal users see and contact others with whom they might want to work. Wherever people links appear, portal users can display a menu of actions for contacting and working with the individuals and groups named by the link. If you have enabled Lotus Sametime to work with the portal, people links include the online status indicator that shows whether a person is active, away, offline, or in a Do Not Disturb state. People links When portal users click the name of (or the icon for) a person or group, a menu appears that provides actions linking them to other portal users. The actions that are visible on people link menus depend on the following factors: Whether Lotus companion products for advanced collaboration are installed and enabled to work with your portal (for example, Lotus Sametime and Lotus Discovery Server). The online status (Active, Away, Do Not Disturb, or Offline) of the person or group. Whether the link applies to an individual person or to a public group. The complete set of actions that users might see from people links depends on which Lotus companion products for advanced collaboration are installed and enabled to work with the portal. See a person's online status Appearing only if Lotus Sametime is enabled, the Sametime status icon indicates whether a person is active, away, offline, or does not want to be disturbed. Chat Appearing only if Lotus Sametime is enabled; this action is not available if the person is offline. Send E-mail Show Profile Appearing only if Lotus Discovery Server is enabled, this action displays the person's profile of business card information, contact information, affinities, current job, and background. Find Documents Authored By Appearing only if Lotus Discovery Server is enabled, this action launches Knowledge Map Search of all documents that the person has authored. 304 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Add to Sametime List Appearing only if Lotus Sametime is enabled, this action displays a window in which you can add the person to your Sametime List, either as an individual entry or as a member of a new or existing personal group. Online presence If you have enabled Lotus Sametime to work with the portal, portal users can see each other's online presence in their person links according to the status options they have set in their Sametime client: I am active. I am away or not using the computer now. Do not disturb me. I am offline. Tip: Portal users can select Options → Preferences → Status in their Sametime Connect clients to customize the messages that appear for each online state and to control the period of time in which keyboard or mouse inactivity automatically switches their status from Active to Away. In this section, we describe how to use this integration technique to add some of the collaborative services included with WebSphere Portal. Before we begin, we first review what the Collaborative Components are. Collaborative Components Collaborative Components or Collaborative Services are a set of JSP tags and Java objects that enable the inclusion of Lotus collaborative functionality to new or existing portlets. These components allow the seamless interaction of the Lotus family of products with the Java-based portlets that run on WebSphere Portal. These methods of interaction do not replace the product-specific APIs, but facilitate the integration of such products within the portal infrastructure. The Collaborative Components provide standardized access to applications, through an easy to use API that is optimized for a collaborative portal, and a consistent security model across all Lotus Software family of products. This API is written in Java and is not platform-specific, so it provides a multiplatform solution, with no dependence on UI-specific implementation. Therefore, these components are very useful tools for writing pervasive portlets. Chapter 4. Using custom Domino JSP Tag libraries 305 The services are the following: Infrastructure objects – CSEnvironment. – CSCredentials. – CSFactory. Java Service objects – CSBaseService. This service is the base class for the other Java Service objects. – DominoService. – QuickplaceService. – PeopleService. – DiscoveryServerService. JSP custom tags – People tags. – Menu tags. Further information about usage and services is available from the WebSphere Portal Infocenter, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html Note: The Lotus Notes productivity portlets that are installed with Portal are not implemented with the DominoService object. Therefore, do not refer to those portlets as examples. Instead, refer to the samples that are installed with the Collaborative Components enterprise application (cs.ear). The Java Collaboration Components API is explained in the next chapter because it requires further Java knowledge. For now, our discussion concentrates on the People tags components, which work with JSP Tag libraries. PeopleService tags The PeopleService tag library contains the following necessary tags: people Displays person menu links according to the following factors: – Portlet context (that is, where the portlet resides) – The permission level of the specified user 306 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – The Lotus Software products for advanced collaboration that are installed and enabled in the portal environment Added to a person's name string returned by the PeopleService object, the person tag generates the HTML that renders the person link menu that provides the following basic action for collaborating with the named person: – Send e-mail If Sametime is installed and enabled to work with the Portal, then the person tag also provides online status for the person link and the following additional actions on the person menu: – Chat – Share – Available tools – Add to Sametime List If Discovery Server is installed and enabled to work with the Portal, then the person tag provides the following additional actions on the person menu: – Show expertise profile – Find documents authored by peopleinit Determines whether Sametime or Discovery Server, or both, are enabled to work with a portal and generates the correct HTML and JavaScript for initializing Sametime or enabling Discovery Server, or both. Establishes the server connections between the Portal, the Sametime server, and the Discovery Server, and provides automatic log-in to all servers. Both the people and peopleinit tags generate HTML and require Java and JavaScript on the client that are compatible with the WebSphere Portal. 4.7.2 Implementation of the technique Now that your portlets are Click-to-Action enabled, the next step is to implement people awareness by including one the PeopleService tags that are available on WebSphere Portal. People awareness services are available at the JSP level and are incredibly easy to use. The enablement consists basically of two steps on each JSP you want to enable: Insert a JSP taglib directive on the JSP. Place the people tag around the names in the JSP of which you want to be aware. Chapter 4. Using custom Domino JSP Tag libraries 307 Enabling the CustomerList portlet The CustomerList portlet consists only of one JSP file. Follow these steps to enable the portlet: 1. Open the DominoJspTagsPortletCustomerListView.jsp file. 2. Copy the following line at the beginning of the file: <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="peopleservice" %> 3. In the JSP file, in the results file of the display table, insert in the third column, surrounding the <Domino:viewitem col="3"/> tag, the peopleservice tags as follows: <peopleservice:person><Domino:viewitem col="3"/></peopleservice:person> Important: Be careful when inserting the peopleservice tags: do not include a line break or space between the tags and the name. 4. Save and close the file. Enabling the CustomerDetails portlet The CustomerDetails portlet is composed of two JSPs. The View.jsp file does not display any names, so you do not need to enable people awareness on this file. The CustomerDetailsEntry.jsp file displays people names, so you need to enable this JSP. 1. Open the DominoJspTagsPortletCustomerDetailsEntry.jsp file. 2. Copy the following line at the beginning of the file: <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="peopleservice" %> 3. In the JSP file on the results table, there is a row called Account Owner. Enable this field by including the following peopleservice tags: <peopleservice:person><Domino:item name="ownerName"/></peopleservice:person> Important: Be careful when inserting the peopleservice tags: do not include a line break or space between the tags and the name. 4. Save and close the file. 308 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Enabling the CustomerContacts portlet The CustomerContacts portlet is composed of two JSPs. The View.jsp file does not display any names, so there is no need to enable people awareness in this file. The CustomerContactsEntry.jsp file displays people names, so you need to enable this JSP using the following steps: 1. Open the DominoJspTagsPortletCustomerContactsEntry.jsp file. 2. Copy the following line at the beginning of the file: <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="peopleservice" %> 3. In the JSP file on the results table, there is a column called Contact Name. Enable this field by including the peopleservice tags as follows: <peopleservice:person><Domino:viewitem col=”2”/></peopleservice:person> Important: Be careful when inserting the peopleservice tags: do not include a line break or space between the tags and the name. 4. Save and close the file. Enabling our CustomerSalesActivities portlet The CustomerSalesActivities portlet is composed of two JSPs. The View.jsp file does not display any names, so there is no need to enable people awareness in this file. The CustomerSalesActivitiesEntry.jsp file displays people names, so you need to enable this JSP using the following steps: 1. Open the DominoJspTagsPortletCustomerSalesActivitiesEntry.jsp file. 2. Copy the following line at the beginning of the file <%@ taglib uri="/WEB-INF/tld/people.tld" prefix="peopleservice" %> 3. In the JSP file on the results table, there are two columns called Sales Person and Contact Name. Enable these fields by including the peopleservice tags as follows: ... <peopleservice:person><Domino:viewitem col=”4”/></peopleservice:person> </td> <td> <peopleservice:person><Domino:viewitem col=”5”/></peopleservice:person> ... Important: Be careful when inserting the peopleservice tags: do not include a line break or space between the tags and the name. 4. Save and close the file. Chapter 4. Using custom Domino JSP Tag libraries 309 All of your portlets are now enabled, and they can be deployed in the WebSphere Portal just as you did previously. You should see your portlets working, as shown in Figure 4-54. Figure 4-54 Customer Information portlets with people awareness 4.8 Reference Material The following references are helpful when exploring J2EE: Domino and WebSphere Together, Second Edition, SG24-5955, found at: http://www.redbooks.ibm.com/abstracts/sg245955.html?Open Introduction to JavaServer Pages technology - developerWorks, found at: http://www-106.ibm.com/developerworks/edu/j-dw-jsp-i.html Sun Microsystems J2EE Web site, found at: http://java.sun.com/j2ee/ Sun Microsystems JSP Web site, found at: http://java.sun.com/products/jsp WebSphere Studio Application Developer Version 5 Programming Guide, SG24-6957, found at: http://www.redbooks.ibm.com/abstracts/sg246957.html?Open 310 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 For WebSphere Portal information relevant to this chapter, consult the following: Access Integration Patterns using IBM WebSphere Portal, SG24-6267, found at: http://www.redbooks.ibm.com/abstracts/sg246267.html?Open Guide to WebSphere Portal 5.0, found at: ftp://ftp.software.ibm.com/software/websphere/portal/pdf/Guide_to_WebSphere _PortalV5.pdf IBM WebSphere Portal V5 A Guide for Portlet Application Development, SG24-6076, found at: http://www.redbooks.ibm.com/abstracts/sg246076.html?Open Portlet Best Practices Guide, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/portlet/portle tcodingguidelines.html WebSphere Portal 5.0.2 InfoCenter http://publib.boulder.ibm.com/pvc/wp/502/index.html WebSphere Portal for Multiplatforms - Library http://www-306.ibm.com/software/genservers/portal/library/ WebSphere Portal Product Documentation http://www7b.software.ibm.com/wsdd/zones/portal/proddoc.html When working with the Lotus Domino JSP tag libraries, the following references are helpful: Lotus Domino Designer 6.x Help There is a chapter on the JSP Tag libraries that has further explanations on the tags covered on this chapter. Lotus Domino Toolkit for WebSphere After installing the toolkit, the information is available within the WebSphere Studio Application Developer InfoCenter. Using the Domino JSP Custom Tags: An Approach to Portalizing Domino Applications, REDP-3902, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3902.html Chapter 4. Using custom Domino JSP Tag libraries 311 312 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5 Chapter 5. Portlet development using Java: Technology review This chapter introduces several Java technologies that are available for integrating Domino applications with WebSphere Portal. Developing applications in Java allows the most flexibility of all the integration techniques shown so far in this redbook. Java gives the developer total control of all aspects of the application. The target audience for this chapter is primarily Java developers who are integrating Domino applications with WebSphere Portal, business partners who want to offer portal interface to the existing Domino application, or anyone who wishes to know how to integrate Domino applications with WebSphere Portal Server. The developer does not have to know how to develop Domino applications or what tools Domino offers for Domino developers. The methods described here are applicable to WebSphere Portal integration in general and not necessarily specific to Domino integration. © Copyright IBM Corp. 2005. All rights reserved. 313 5.1 Overview WebSphere Portal offers several methods for portlet development. Developing portlets by coding against API is offered, and both IBM Portlet API and JSR 168 portlet API are supported. Tools are provided to use existing frameworks, such as Java Server Faces (JSF) and Struts, for portlet development. Using JSF or Struts allows you to develop portlets without learning portlet APIs and makes it possible to use almost any development environment for portlet development (but portal concepts must be kept in mind, of course). WebSphere Studio Application Developer (WSAD) is used in this redbook and it is a recommended tool to develop portal applications, but it is not necessary to use WSAD, so developers can concentrate on learning the API that Domino offers for Java language and building the actual application. The following sections illustrate the topics covered in detail in this chapter: 5.2, “Domino Java API” on page 315 introduces common classes and how Java API is used in applications. 5.3, “IBM Portlet API” on page 336 introduces basic concepts of IBM Portlet API and what capabilities are offered. 5.4, “JSR 168 Java Portlet Specification” on page 354 introduces the JSR 168 Portlet Specification and compares differences between the IBM Portlet API and JSR 168. 5.5, “Struts framework” on page 364 introduces the Struts framework. 5.6, “JSF framework” on page 371 introduces JSF framework. 5.7, “Other technologies” on page 374 describes useful technologies that are used, or could be used, in portlet development and in portalizing Domino applications. 5.8, “Portal application design guidelines” on page 381 has basic guidelines for portal application design and introduction to common design patterns. Note: 5.9, “Additional information” on page 388 provides links to material that provides more detailed information about the technologies described in this chapter. 5.1.1 Skills and degree of customization with API integration approach Figure 5-1 on page 315 gives an overview of this integration option relative to all the options available to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for 314 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 Bowstreet Portlet Factory / Conet Knowledge Director 2 1 IBM Portlet Builder for Domino Existing Portlets limited 4 Lotus Workplace Builder low Level of customization high Figure 5-1 Integration options The main message to take from Figure 5-1 is that using the Java API represents the option for the highest degree of customization possible. Accordingly, advanced Java programming knowledge will be required. 5.2 Domino Java API Data residing in a Domino server can be accessed from a portlet using the Java language, where CORBA serves as a middleware distributed environment for a Domino Object Model (DOM) back-end classes. 5.2.1 Overview The high level components of Domino - WebSphere Portal integration are illustrated in Figure 5-2 on page 316. Chapter 5. Portlet development using Java: Technology review 315 Figure 5-2 Overview of Domino - WebSphere Portal integration The Domino environment consists of Domino Object Models, such as session, database, views, and documents. DIIOP and HTTP protocols are used in implementing physical connections between Domino and the Portlet. In the WebSphere Portal, Domino Java API is used to access Domino data. Alternatively, Domino XML over HTTP or Web Services can be used to access Domino. To achieve a good user experience, single sign-on (SSO) may be enabled between Domino and WebSphere. Note: DIIOP and SSO may have to be configured before development. Consult your system administrator, the WebSphere Portal InfoCenter, and the Lotus Domino Administrator Help database. CORBA CORBA, or Common Object Request Broker Architecture, is an open standard defined by the Object Management Group (OMG). CORBA serves as middleware for a distributed computing environment whereby clients can invoke methods on remote APIs residing on other computers. CORBA uses Internet Inter-ORB Protocol (IIOP) for communication over a TCP/IP network. CORBA/IIOP support enables developers to create portlets that can be remotely invoked in Domino services. In addition, it enables information to be processed 316 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 efficiently over networks within an open standards-based framework and to distribute work effectively between clients and servers, ultimately lowering the cost of ownership. Advantages to using CORBA are: You can use Domino Object Model (DOM) back-end classes. The client does not have to deal with issues such as networking or security. CORBA allows many different portlets to use the same objects (not copies of the objects). The latest version of the object is always used. DIIOP DIIOP, or Domino Internet Inter-ORB, is the Domino task that allows external CORBA programs to attach to and manipulate Domino databases. Most notably, this allows Java programs or portlets to connect to Domino. The remote methods use CORBA classes included in the NCSO.jar file shipped with Domino and require that the DIIOP task is running on the server where the session object is to be obtained. Local/remote access to Domino Domino supports both local and remote access using virtually identical object models. Both options are available through the identical set of Java interfaces contained in the lotus.domino package. The only difference is the .jar file you put in your portlet development environment: notes.jar for local access or ncso.jar for remote access. Both of these files are shipped with Domino server. The coding is the same whether your objects are on the same machine (local) as your Portlet Java code (or JSP), or on some other machine in the network (remote). The only difference is the fetching of Session object and that also specifies whether to use local or remote call. Keep in mind the following issues related to thread management: When using the local Domino classes from any Java program, you are essentially calling through a thin layer of Java code into the Domino back-end code, which is implemented in C++. The Java wrapper classes use a standard Java-to-C calling mechanism, known as Java Native Interface (JNI), to access the real Domino classes in the product's .dlls (or whatever the platform-specific equivalent of a .dll is). The Domino code is loaded “in process” in the Java Virtual Machine (JVM), which is great from the point of view of performance: You are getting the best possible speed out of the hook-up between the Java and C code—everything is right there in the computer's memory. On local use, you need to manage threads, and initialize and terminate them properly. Chapter 5. Portlet development using Java: Technology review 317 If you use the remote object library for Domino (the CORBA classes), you are not accessing any Domino C/C++ code from within the JVM's process space, and there are not any special requirements for thread initialization or termination. You can instantiate a Session object (or any object in the Domino hierarchy) and keep it around for re-use later. This is a real advantage, although there is a performance hit by having all calls remote across a network. Even if you're using the CORBA classes to communicate with a Domino server on the same machine as your WebSphere program, you still pay for having all method invocations processed remotely. Extra time is used for: marshalling the arguments, formatting data according to the IIOP wire protocol specification, transmitting the call, de-marshalling the parameters, finding the remote object to invoke, and so on. The bytes may not actually go out over the network, but they have to travel through your network adapter card and be processed on both ends of the conversation as though there were a network cable in between. In a real-life production portal environment, you probably will never face an actual case where you have installed WebSphere Portal server together with Domino Server on the same machine. However, this may be the case in a very small production environment or in a testing and development environment. From a performance point of view, it is not ever recommended to install them on the same machine. To summarize: Local access has much faster access to Domino calls, but does things more repetitively. Local access loads Domino code in JVM. Remote access is a “cleaner” architecture, requiring fewer actual calls. Do not use local access when integrating WebSphere Portal and Domino. Mechanism of the CORBA sessions for Domino When CORBA is used to access the Domino server, the objects that are instantiated in your portlet code do not contain any functional methods in the same way as local objects do. The portlet is the client, and the CORBA objects are the Session, Database, View, and Documents that the portlet creates at various times. When CORBA objects are created, what you actually get is a stub to manipulate on the client. A second object—the real one if you like—is created on the server and linked with your stub. This stub contains all the same methods that the real object contains, but instead of the same functional code, they simply contain 318 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 code to serialize the method call over the network so that the actual method is executed on the server by the real object. Figure 5-3 gives an overview of the mechanism of CORBA. Figure 5-3 Mechanism of CORBA For example, the Session instance hangs around until you recycle it, or until the connection to Domino times out. All Domino objects created using this Session likewise resides on the remote Domino machine. Any method invocations you make are sent over the network to the server and executed there. What look like local Java object instances are really just instances of proxy objects, whose only job is to communicate with the real objects over on the Domino server. Recycling is a really important issue when you are using Domino Java API (see “Recycling Domino objects” on page 320). Domino objects architecture Java Domino classes are created by modifying some of the LotusScript Extension (LSX) architecture to include a Java “adapter” to compose the new Java Domino classes. The Java Domino classes have similar functions to some of the LotusScript Domino back-end objects. You can use these classes from any Java program. Internally, Java Notes classes execute the same C++ code as the LotusScript Domino back-end objects; only the language syntax is different. The Domino objects class architecture is based on a conceptual containment model, where the containment model defines an object's scope. A container object is always used to access objects it contains. For example, you use a Session object to get Database objects, and a Database object to create Document objects. In Java, you cannot create lotus.domino objects using the “new” modifier. All lotus.domino objects must be created with lotus.domino methods that flow from the root Session object (see Figure 5-4 on page 320). Chapter 5. Portlet development using Java: Technology review 319 Figure 5-4 Domino Object Model Tip: A full description of Domino Java classes can be found in Lotus Domino Designer V6.5.1 Help. This is a must read for developers. Designer help can be downloaded from the Internet. See the references at the end of this chapter for a link to Lotus Domino Designer V6.5.1 Help and other useful material. Recycling Domino objects Important: Recycling is good for the environment and good for the Domino objects. The recycle method unconditionally destroys an object and returns its memory to the system. All lotus.domino classes contain the following method: public void recycle() Session contains the following method, where the vector contains the Domino Objects to be recycled. This method effectively batches recycle operations and is especially efficient for remote (IIOP) calls: public void recycle(java.util.Vector objects) You recycle an object by calling the recycle method, for example, doc.recycle(); where doc is the object to be recycled. 320 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Important: Java has no knowledge of the heavyweight back-end Domino objects, only the lightweight Java objects representing them. Garbage collection has no effect on Domino objects unless you first explicitly recycle them. If your system appears to have memory problems, try to recycle, but adhere to the following guidelines: Recycle an object only if it is no longer needed. Recycle an object in the same thread in which it is created. Recycling a parent recycles all the children. In Session, call recycle only after all threads exit (local). Loops enumerating documents or items are good candidates for recycling. Important: In a remote (IIOP) environment, recycle releases resources on the server. Although a client-side cache exists, the Java object can no longer communicate with its remote counterpart. In a remote (IIOP) environment, recycle can be called from any thread on any object. Results are undefined if you attempt to use a recycled object. No error is guaranteed. If you create more than one object to represent the same Domino element, recycling one recycles all. For example: View v1 = db.getView("All"); View v2 = db.getView("All"); v1.recycle(); // also recycles v2 5.2.2 Domino Java classes This section introduces common tasks when accessing Domino and commonly used Domino Java classes. Tip: The Domino Java classes for remote connections are in the NCSO.jar file and for local connections in Notes.jar. The jar files are in the Domino installation directory, for example, c:\Lotus\Domino\Data\domino\data. Important: Remember the Lotus Domino Designer V6.5.1 Help. It includes detailed descriptions of all Domino Java classes. Chapter 5. Portlet development using Java: Technology review 321 Accessing Domino The Java program must import lotus.domino package and include NCSO.jar or Notes.jar in the Java classpath. Java SDK Version 1.3 or later is recommended. All Java programs that access Domino have at least one of the following tasks: Accessing Domino sessions Accessing databases Accessing views Accessing documents Accessing items and rich text items Accessing Domino sessions The Session class is the root of the Domino Objects containment hierarchy, providing access to the other Domino objects, and represents the Domino environment of the current program. Without a Session, Domino cannot be accessed. For local calls, the Domino environment is the local Domino directory, which can belong to a server or a user. For remote (IIOP) calls, the Domino environment is the server handling the remote requests. The Session class has several methods and some of the commonly used are getDatabase(), getUserName(), getServerName(), and getDbDirectory(). For a Java program, Session is created using methods in NotesFactory class. Put the code in Example 5-1 in a file called DominoExample.java in your development directory, for example, c:\development. Copy NCSO.jar to the development directory. Example 5-1 Accessing Domino server import lotus.domino.*; import java.util.*; public class DominoExample { public static void main(String[] args) { try { Session s=NotesFactory.createSession("domino651.swic.fi.ibm.com","test person","password"); System.out.print("[0] "); System.out.print(s.getServerName()); 322 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 System.out.print(" ("+s.getNotesVersion()+")"); System.out.print(" accessed by "); System.out.println(s.getUserName()); s.recycle(); } catch (NotesException ne) { ne.printStackTrace(); } } } Open a command prompt in the development directory and compile DominoExample.java: c:\development>javac -classpath NCSO.jar DominoExample.java Run the sample: c:\development>java -cp .;NCSO.jar DominoExample The output should be something as follows: [0] CN=DOMINO651/O=swic (Release 6.5.2|June 01, 2004 CN=Test Person/O=swic ) accessed by Accessing databases After a session has been established, a database can be opened for reading/writing. Session has the method getDatabase(), which opens a database in a server or in Session’s environment (see Example 5-2). Database has methods like getDocumentByUNID(), createDocument(), and search(). Example 5-2 Accessing Domino database //add before line s.recycle(); in DominoExample.java Database db=s.getDatabase(null,"redbook/customer.nsf"); System.out.print("[1] Opened database '"); System.out.print(db.getTitle()); System.out.println("' ("+db.getSize()+" bytes)"); db.recycle(); Compile and run DominoExample.java. The output of the program is something like: [1] Opened database 'Customers' (1198080.0 bytes) Chapter 5. Portlet development using Java: Technology review 323 Accessing views Views can be accessed using methods in Database, like getViews(). The view class has methods to navigate through a view and access documents in a view by using methods like getFirstDocument(), getLastDocument(), and others (see Example 5-3). Example 5-3 Accessing views //add before line db.recycle(); in DominoExample.java Vector views=db.getViews(); System.out.println("[2] Database has "+views.size()+" views: "); for (int i=0;i<views.size();i++) { View view=(View)views.elementAt(i); System.out.print(" "+view.getName()+" ("); Vector columnNames=view.getColumnNames(); for (int j=0;j<columnNames.size();j++ ) { System.out.print(columnNames.elementAt(j)+" "); } System.out.println(")"); view.recycle(); } The output of Example 5-3 is something like: [2] Database has 9 views: Customers\By Customer Name (Customer Name Customer # Account Owner hidden 4 ) Customers\By Account Owner (Account Owner Customer Name Customer # ) Customers\By Customer Number (Customer # Customer Name Account Owner ) Customer Contacts\By Name (Contact Name Phone # Employer ) Customer Contacts\By Customer Name (Employer Contact Name Phone # ) Customer Contacts\By Customer Number (Employer Contact Name Phone # hidden 4 ) CustomerPortletIntegrated (Customer Name Customer Name Customer # Account Owne r hidden 4 ) CustomerContactsPortletIntegrated (Employer Contact Name Phone # hidden 4 ) ContactsRSSbyName (Contact Name - hidden ) Accessing documents Documents can be created using the createDocument() method in Database class, accessed via View, or accessed via the search() method in Database class (see Example 5-4 on page 325). The document has methods to access and modify document fields. DocumentCollection is a class that holds many Documents. DocumentCollection is returned after searching the database. 324 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 5-4 Accessing document //add before line db.recycle(); in DominoExample.java View view=(View)db.getViews().elementAt(0); Document doc=view.getFirstDocument(); System.out.println("[3] Document with UNID "+doc.getUniversalID()+" has items: "); Vector items=doc.getItems(); for (int i=0;i<items.size();i++) { Item item=(Item)items.elementAt(i); System.out.println(" "+item.getName()+": "+item.getText()); item.recycle(); } doc.recycle(); view.recycle(); The output of Example 5-4 is something like: [3] Document with UNID 00397BCDE805B8B7C2256F1A002F982F has items: Comments: Form: Customer customerNumber: 22 ownerNumber: 12000 employeeTotal: 2 Owner: CN=Test Person/O=swic customerName: 83 838383 customerAddress: (modified) (modified) (modified) DateCreated: 25.09.2004 11:39:51 DateModified: $$Return: Thank you! This record has been saved. <br><a href=/apps/customer.n sf/all/00397BCDE805B8B7C2256F1A002F982F?OpenDocument>Open saved record</a> ownerNameFormat: Smith, John ownerName: John Smith $UpdatedBy: CN=Test Person/O=swic $Revisions: 25.09.2004 11:39:51;29.09.2004 16:17:28;29.09.2004 16:20:04 Accessing items and rich text items Items and rich text items are accessed via the Document class. RichTextItem is a subclass of Item and includes methods specific to RichTextItem, such as embedObject(). Document has methods to modify fields, and any modifications that need to be saved, Document’s save method must called (see Example 5-5 on page 326). Chapter 5. Portlet development using Java: Technology review 325 Example 5-5 Accessing and modifying document fields //add before line db.recycle(); in DominoExample.java System.out.println("[4] Modify Customer documents."); DocumentCollection dc=db.search("Form = \"Customer\""); doc = dc.getFirstDocument(); while(doc!=null) { doc.replaceItemValue("customerAddress",doc.getItemValueString("customerAddress" )+" (modified "+new Date()+")"); System.out.println(" "+doc.getUniversalID()+" updated and saved: "+doc.save(true)); doc.recycle(); doc = dc.getNextDocument(); } dc.recycle(); The output of Example 5-5 is something like: [4] Modify Customer documents. 8D7EB55B2C925B5685256D1F0076E9F2 462E6D6DE88ED7FB85256D1F007962A7 ECD7A80DD88F8AF485256D20006AAA74 151E292E28B0EC5685256D24007164E7 D16F77996F57D6C685256D2D00615B21 B9F7693FC101FA3885256D2D00615B22 55191B59F43AC6B685256D2D00615B23 709906972DFDC8B685256D2D00615B24 73FC562573236BBD85256D2D00615B25 updated updated updated updated updated updated updated updated updated and and and and and and and and and saved: saved: saved: saved: saved: saved: saved: saved: saved: true true true true true true true true true Accessing rich text items is a little different from other items. The RichTextItem class is created using createRichTextItem on Document and accessed using the getFirstItem() method. RichTextItems may contain several types of items, such as text, file attachments, and embedded objects. Tip: Lotus Domino Designer V6.5.1 Help has many examples of how to work with RichTextItems. See also 6.3, “Accessing Domino data” on page 400. 326 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Commonly used Domino Java classes The following section discusses several of the most frequently used classes within the Domino Java API. NotesFactory The applications call the NotesFactory createSession methods to create a Session object. For applications making remote (IIOP) calls based on the host server's Domino Directory, create an Internet Session object as follows, where hostString is the host name or IP address of the Domino server (not the Domino server name). The specification of a host name or IP address determines the use of the remote interface. A host name can be suffixed with the port number that the HTTP or DIIOP task uses to listen for TCP (non-SSL) connections using the syntax hostname:port (hostname-colon-port). createSession(hostString, "", ""): Anonymous Internet access is granted to the session if the host's Server record on the host's Domino Directory permits anonymous access. Parameter two must be an empty string, not null. createSession(hostString, userString, passwordString): Internet access is granted to the session if the password matches the Internet password in the user's Person record on the host's Domino Directory. To access a server using Single Sign-on, create an Internet Session object as follows. For remote (IIOP) calls, the first parameter is the host name or IP address of the Domino server. For local calls, the first parameter is null. createSession(hostString, tokenString): Internet access is granted to the session based on the token. The token must be a valid token for Single Sign-on obtained from Session.getSessionToken, the LtpaToken cookie used by WebSphere, or the HTTP cookie list in a servlet. createSession(hostString, Credentials): Internet access is granted to the session based on an org.omg.SecurityLevel2.Credentials object. This method works in a WebSphere environment where the Credentials object is created using loginHelper. createSession(hostString, null): Internet access is granted to the session based on the current Credentials object in the WebSphere environment. This method works from an Enterprise JavaBeans (EJB) application in WebSphere. createSession(hostString, HttpServletRequest): Internet access is granted to the session based on authentication by the Domino HTTP server. To enable SSL (Secure Sockets Layer), use the String args[] parameter and specify "-ORBEnableSSLSecurity" as an element of the args array. For remote Chapter 5. Portlet development using Java: Technology review 327 (IIOP) applications, the client must have access to the server's trusted root certificate, stored in TrustedCerts.class in domino/java in the server's data directory. This file is generated by the DIIOP task when it starts and is enabled to listen on the SSL port specified in the server document. The HTTP task delivers TrustedCerts.class to applets. For other applications, ensure that TrustedCerts.class is on the classpath. The createSession methods that include an org.omg.CORBA.ORB parameter create a session using an existing ORB, which you first create with one of the createORB methods. Using one ORB for multiple sessions (connection pooling) saves network overhead. However, make sure the connection can handle all the sessions you create, and be sure to recycle when you terminate a session. For applications making local calls based on the Notes user ID, create a Session object as follows. A Domino server or Notes client must be installed locally. createSession(): No password verification occurs; the user is prompted for a password as required. createSession(null, null, null): Same as above. createSession(null, null, passwordString): Access is granted if the password matches the Notes user ID password. Session The session is the root of the Domino Objects containment hierarchy, providing access to the other Domino objects, and represents the Domino environment of the current program. For a remote (IIOP) session, the Session object represents the Domino server handling the remote requests. A reference to the current server such as a null server parameter means that Domino server. You cannot access other servers. For a local session, the Session object represents the machine on which the code is running. A reference to the current server such as a null server parameter, means the local Notes/Domino environment. You can access servers connected to the local environment by specifying their names. Commonly used methods include: getDatabase() public Database getDatabase(String server, String db) throws NotesException public Database getDatabase(String server, String db, boolean createonfail) throws NotesException Creates a Database object that represents the database located at the server and file name you specify, and opens the database, if possible. 328 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Returns a Database object that can be used to access the database you have specified, or null if the database cannot be opened and createonfail is false. getDbDirectory() public DbDirectory getDbDirectory(String server) throws NotesException Creates a new DbDirectory object using the name of the server you want to access. Returns a DbDirectory object on the server you specified. Database Database represents a Notes database. A database must be open before you can use all the properties and methods in the corresponding Database object. In most cases, the class library automatically opens a database for you. Notes throws an exception when you attempt to perform an operation for which the user does not have appropriate access. The properties and methods that you can successfully use on a Database object are determined by these factors: The user's access level to the database, as determined by the database access control list. The ACL determines if the user can open a database, add documents to it, remove documents from it, modify the ACL, and so on. The user's access level to the server on which the database resides, as determined by the Server document in the Domino Directory. Commonly used methods: createDocument() public Document createDocument() throws NotesException Creates a document in a database and returns a Document object that represents the new document. getDocumentByUNID() public Document getDocumentByUNID(String unid) throws NotesException Finds a document in a database, given the document universal ID (UNID), and returns the document whose universal ID matches the parameter. FTSearch() public DocumentCollection FTSearch(String query) throws NotesException public DocumentCollection FTSearch(String query, int max) throws NotesException public DocumentCollection FTSearch(String query, int max, int sortopt, int otheropt) throws NotesException Conducts a full-text search of all the documents in a database. Chapter 5. Portlet development using Java: Technology review 329 Returns a DocumentCollection object of documents that match the full-text query, sorted by the selected option. If no matches are found, the collection has a count of 0. To search for a word or phrase, enter the word or phrase as is, except that search keywords must be enclosed in quotes. Remember to escape quotes if you are inside a literal. Wildcards, operators, and other syntax are permitted. For the complete syntax rules, see "Finding documents in a database" in Lotus Notes 6 Help. search() public DocumentCollection search(String formula) throws NotesException public DocumentCollection search(String formula, DateTime dt) throws NotesException public DocumentCollection search(String formula, DateTime dt, int max) throws NotesException Given the selection criteria (Notes formula) for a document, returns all documents in a database that meet the criteria. Returns an unsorted DocumentCollection object of documents that match the selection criteria. getViews() public java.util.Vector getViews() throws NotesException Read-only method. Returns a vector of views and folders in a database. Each element in a vector is a View object. View A View object represents a view or folder of a database and provides access to documents within it. A View object provides access to ViewEntry, ViewEntryCollection, ViewNavigator, and ViewColumn objects: A ViewEntry object represents a row in the view and can be a document, category, or total. A document entry provides a handle to the associated Document object. A ViewEntryCollection object provides access to selected or all document ViewEntry objects. (Excluded are category and total ViewEntry objects.) A ViewNavigator object provides methods for navigating through selected or all ViewEntry and Document objects. ViewColumn object, which contains information about a column in the view. 330 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Commonly used methods: getFirstDocument() public Document getFirstDocument() throws NotesException Returns the first document in the view. Returns null if there are no documents in the view. getNextDocument() public Document getNextDocument(Document doc) throws NotesException Returns the document in the view following the specified parameter regardless of what type of document it is (document, response, or response-to-response). Returns null if there are no more documents in the view. DocumentCollection A DocumentCollection represents a subset of all the documents in a database. The documents in the subset are determined by the method or property you use to search the database. DocumentCollection, ViewEntryCollection, and ViewNavigator objects provide access to documents in a database. Use a DocumentCollection object if: You want to act on a specific set of documents that meet certain criteria. There is no view in the database that contains every document you need to search. You do not need to navigate the documents' response hierarchies. Views are a more efficient means of accessing documents because they are already indexed by the database itself. However, they do not necessarily provide access to the documents that you want. ViewEntryCollection and ViewNavigator provide access to view entries, which contain ViewEntry as well as Document information. ViewNavigator provides access to categories and totals as well as documents. Commonly used methods: getCount() public int getCount() throws NotesException The number of documents in a collection. getFirstDocument() public Document getFirstDocument() throws NotesException Returns the first document in the view. Returns null if there are no documents in the view. Chapter 5. Portlet development using Java: Technology review 331 getNextDocument() public Document getNextDocument() throws NotesException public Document getNextDocument(Document doc) throws NotesException Gets the document immediately following the current document or a specified document in a collection. If there is no parameter, it returns the document following the current document. If there is a parameter, returns the document following the specified document. If there is no next document, returns null. In remote (IIOP) operations, getNextDocument(Document doc) invalidates the cache and is therefore discouraged. The preferred loop structure is getFirstDocument() followed by getNextDocument() until it returns null. For performance reasons, you should avoid using getNthDocument(int n) and getNextDocument(Document doc) in a loop. Document A Document represents a document in a database. Commonly used methods: getItems() public java.util.Vector getItems() throws NotesException Returns a Vector of all the items in a document. An item is any piece of data stored in a document. getUniversalID() public String getUniversalID() throws NotesException Returns the universal ID, which uniquely identifies a document across all replicas of a database. In character format, the universal ID is a 32-character combination of hexadecimal digits (0-9, A-F). The universal ID is also known as the unique ID or UNID. createRichTextItem() public RichTextItem createRichTextItem(String name) throws NotesException Creates and returns a new rich-text item in a document. The item’s name is specified by the name parameter. 332 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 getItemValueString() public String getItemValueString(String name) throws NotesException Returns the value of an item with a single text value. If multiple items have the same name, this method returns the value of the first item. If the item has no value or the value is numeric or date-time, this method returns null. If no item with the specified name exists, this method returns null. It does not throw an exception. This method returns a rich text item rendered to plain text. Formatting and embedded objects are lost. If the item has multiple values, this method returns the first value. replaceItemValue() public Item replaceItemValue(String name, Object value) Replaces all items of the specified name with one new item, which is assigned the specified value. If the document does not contain an item with the specified name, this method creates a new item and adds it to the document. The data type of the item depends upon the data type of value, and does not need to match the data type of the old item (see Table 5-1). Table 5-1 The value of the new item Data type of value Resulting item String Text Integer Number Double Number DateTime Date-time item java.util.Vector with String, Integer, Double, or DateTime elements Multi-value text, multi-value number or multi-value date-time item Item Same data type as the Item Returns the new item, which replaces all previous items with the same name. Chapter 5. Portlet development using Java: Technology review 333 Item An Item represents a discrete value or set of values in a document. The client interface displays items in a document through fields on a form. When a field on a form and an item in a document have the same name, the field displays the item (for example, the Subject field displays the Subject item). All items in a document are accessible programmatically, regardless of what form is used to display the document in the user interface. Commonly used methods: getName() public String getName() throws NotesException The name of an item. getText() public String getText() throws NotesException public String getText(int maxlen) throws NotesException A plain text representation of an item's value. Multiple values in a list are separated by semicolons in the returned string. If an item's value is large, the returned string may be truncated. For rich-text items, this property skips non-text data such as bitmaps and file attachments. For HTML items, this property returns null. getValues() public java.util.Vector getValues() throws NotesException Returns java.util.Vector. The data type of the value depends upon the type of the item (see Table 5-2). Table 5-2 Value data types in a Vector Item type Valid return type Rich text java.util.Vector with one String element rendered into plain text Text (includes Names, Authors, and Readers item types) java.util.Vector with String elements Number or number list java.util.Vector with Double elements Date-time or range of date-time values java.util.Vector with DateTime elements Each element corresponds to a value in the item. If the item contains a single value, the vector has just one element. 334 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 If the item has no value, this method returns null. RichTextItem RichTextItem inherits from Item and represents an item of type rich text. Commonly used methods: appendText() public void appendText(String text) throws NotesException Appends text to a rich text item. The text is rendered in the current style of the item. embedObject() public EmbeddedObject embedObject(int type, String class, String source, String name) throws NotesException Given the name (specified in parameter source) of a file or an application; it either: – Attaches the file you specify to a rich text item. – Embeds an OLE/1 object in a rich text item. The OLE/1 object is created using the file you specify. getEmbeddedObject() public EmbeddedObject getEmbeddedObject(String name) throws NotesException Given the name of a file attachment, embedded object, or object link in a rich text item, returns the corresponding EmbeddedObject. To find a file attachment, specify its file name. Specify just the file name not the full path. EmbeddedObject EmbeddedObject represents an embedded object, an object link, or a file attachment. Commonly used methods: extractFile() public void extractFile(String path) throws NotesException Writes a file attachment to storage. Parameter path specifies the path and file name where you want to store the extracted file. getFileSize() public int getFileSize() throws NotesException Returns the size of a file attachment, in bytes. Chapter 5. Portlet development using Java: Technology review 335 getSource() public String getSource() throws NotesException For a file attachment, returns the file name of the original file. For an object or object link, returns the internal name for the source document. Tip: See 6.7.1, “Adding functionality to DominoAccess” on page 575 for an example. NotesException and NotesError The NotesException class extends java.lang.Exception to include exception handling for Lotus Notes/Domino. The NotesError class defines constants for Domino error codes. The NotesException class contains the following public variables: NotesException.id, of type int, contains the error code. NotesException.text, of type String, contains the error text. If internal (see below) is not null, this variable also contains the error text of the internal exception. NotesException.internal, of type Exception, is the internal exception if an internal exception caused the Domino exception. Otherwise (and typically), this variable is null. To print the error code, the error text, and a stack trace, call printStackTrace in the catch clause for NotesException. 5.3 IBM Portlet API The following section provides an introduction to the IBM Portlet API, describing the portlet inheritance, the portlet deployment descriptor, and key portlet concepts relevant to the IBM Portlet API. 5.3.1 Overview The IBM Portlet API in WebSphere Portal Server V5.0.2.2 is an extension of servlet container. 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 336 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 executed inside a Web container managed by the application server. In the Portlet API, this container is referred to as the Portlet container. IBM Portlet API and the servlet API The abstract Portlet class is the central abstraction of the Portlet API. The Portlet class extends HTTPServlet, of the Servlet API. All portlets extend this abstract class indirectly, and inherit from HttpServlet, as shown in Figure 5-5. Figure 5-5 Portlet inheritance Portlets are a special type of servlet, with properties that allow them to easily plug into and run in the portal server. Unlike servlets, portlets cannot send redirects or errors to browsers directly, forward requests, or write arbitrary markup to the output stream. The portlet container relies on the J2EE architecture implemented by WebSphere Application Server. As a result, portlets are packaged similar to J2EE Web applications and are deployed like servlets. Like other servlets, a portlet is defined to the application server using the servlet deployment descriptor (web.xml). Generally, portlets are administered more dynamically than servlets. The following updates can be applied without having to start and restart the portal server: Portlet applications consisting of several portlets can be installed and removed using the portal administration user interface. The settings of a portlet can be changed by an administrator with appropriate access rights Portlets can be created and deleted dynamically by administration portlets. Figure 5-6 on page 338 shows a portlet after its WAR file is deployed. For each portlet deployed on the portal server, it creates a servlet, or portlet class instance, on the application server. Chapter 5. Portlet development using Java: Technology review 337 Figure 5-6 Portlet class instance The initialization parameters are set by the portlet developer and can be read by the portlet using the PortletConfig object. The servlet deployment descriptor can contain multiple Web applications, each defined by the <servlet> element. In addition, each servlet definition can point to the same portlet class file, thus creating different PortletConfig objects with different initialization parameters for each portlet class instance. Portlet deployment descriptor In addition to the servlet descriptor, portlets must also provide a portlet deployment descriptor (portlet.xml) to define the portlet's capabilities to the portal server (see Example 5-6 on page 339). This information includes configuration parameters specific to a particular portlet or portlet application as well as general information that all portlets provide, such as the type of markup that the portlet supports. The portal server uses this information to provide services for the portlet. For example, if a portlet registers its support for help and edit mode in the portlet deployment descriptor, the portal server will render icons to allow the user to invoke the portlet's help and edit pages. 338 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 5-6 Portlet 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="com.myCompany.myPortletApp.54321"> <portlet-app-name>My portlet application</portlet-app-name> <portlet id="Portlet_1" href="WEB-INF/web.xml#Servlet_1"> <portlet-name>My portlet</portlet-name> <supports> <markup name="html"> <view output="fragment"/> </markup> </supports> </portlet> </portlet-app> <concrete-portlet-app uid="com.myCompany.myConcretePortletApp.54321"> <portlet-app-name>My concrete portlet application</portlet-app-name> <concrete-portlet href="#Portlet_1"> <portlet-name>My concrete portlet</portlet-name> <default-locale>en</default-locale> <language locale="en_US"> <title>My portlet</title> </language> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> Portlet concepts Figure 5-7 on page 340 shows different variations of a portlet as it is created, placed on a page, and accessed by users. Notice that the first two steps involve the use of persistent data, but for the third step, the data is available only for the duration of the session. Chapter 5. Portlet development using Java: Technology review 339 Figure 5-7 Portlet concept 1. The portal administrator uses the administrative interface to deploy a new portlet application WAR file or install a copy of a portlet. Either action creates a concrete portlet, which is a portlet parameterized by a single PortletSettings object. There can be many concrete portlets for each portlet. PortletSettings are read/write accessible and persistent. The PortletSettings contains configuration parameters initially defined in the portlet deployment descriptor. The use of concrete portlets allows many instances of a portlet to run with different configurations, without creating extra portlet class instances. During the life cycle of a single portlet, many concrete portlets can be created and destroyed. There is no object that explicitly represents the concrete portlet. The same concrete portlet can be shared across many users. 2. The portlet is placed on a page by a user or an administrator. This creates a concrete portlet instance, which is a concrete portlet parameterized by a single PortletData object. There can be many concrete portlet instances per concrete portlet. PortletData stores persistent information for a portlet that has been added to a page. For example, a user can edit a stock quotes portlet and save a list of stock symbols for the companies to track. 340 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3. The scope of the PortletData depends on the scope of the page that the concrete portlet is on. – If an administrator puts a concrete portlet on a group page, then the PortletData object contains data stored for the group of users. This holds true for a group of users who have view access to the page. However, if users have edit access to the portlet on a group page, then a new concrete portlet instance is created for each user that edits the portlet. In this case, PortletData contains data for each user that edits the portlet. – If a concrete portlet is put on a user's page, the PortletData contains data for that user. When a user accesses a page that contains a portlet, that creates a user portlet instance. When a user logs into the portal, the portal server creates a PortletSession for each of the user's portlets. A concrete portlet instance parameterized by a PortletSession is known as a user portlet instance. There can be many user portlet instances per concrete portlet instance. A user portlet instance is a concrete portlet instance parameterized by a single PortletSession. There can be many user portlet instances per concrete portlet instance. The PortletSession stores transient information related to a single use of the portlet. Portlet applications Portlet applications provide the means to package a group of related portlets that share the same context. The context contains all resources, for example, images, properties files, and classes. All portlets must be packaged as part of a portlet application. Portlet applications provide no code on their own but form a logical group of portlets. Beside this more logical gain, portlets of the same portlet application can also exchange messages. Concrete portlet application A concrete portlet application is a portlet application parameterized with a single PortletApplicationSettings object. For each portlet application, there may be many concrete portlet applications. PortletApplicationSettings are read/write accessible and persistent. There is no object that explicitly represents the concrete portlet application. A concrete portlet application contains at least one concrete portlet from the portlet application, but it is not required to contain all of them. Chapter 5. Portlet development using Java: Technology review 341 5.3.2 Elements of the IBM Portlet API This section describes some of the main classes and interfaces of the IBM Portlet API. Tip: WebSphere Portal InfoCenter introduces basic elements of the API in more detail and WebSphere Portal API documentation has package and class descriptions of each class of IBM Portlet API. Portlet The abstract Portlet class is the central abstraction of the Portlet API. All portlets extend this abstract class by extending one of its subclasses, such as PortletAdapter, which provide methods helpful for the developer. Portlet life cycle 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 then 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. initConcrete() After constructing the portlet and before the portlet is accessed for the first time, the concrete portlet is initialized with the PortletSettings. service() The portal calls the service() method when the portlet is required to render its content. During the life cycle 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. 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. 342 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 PortletRequest The PortletRequest object is passed to the portlet through the login(), beginPage(), endPage(), and service() methods, providing the portlet with request-specific data and the opportunity to access further important information: Attributes Attributes are name/value pairs associated with a request. Attributes are available only for the scope of the request. The portlet can get, set, and remove attributes during one request. Parameters Parameters are name/value pairs sent by the client in the URI query string as part of a request. Often the parameters are posted from a form. Parameters are available for the scope of a specific request. The portlet can get but not set parameters from a request. Client The Client object encapsulates request-dependent information about the user agent of a specific request. User data The PortletData object represents data for a concrete portlet instance that is saved to persistent store. Session The PortletSession represents user-specific, transient data for more than one request. Portlet settings The PortletSettings object represents the configuration for a concrete portlet that is saved to persistent store. PortletResponse The response object encapsulates information to be returned from the server to the client. PortletResponse is passed via the beginPage(), endPage(), and service() methods and can be used by the portlet to return portlet output using a Java PrintWriter. The response also includes methods for creating the PortletURI object or qualifying portlet markup with the portlet's namespace. Use one of the following methods to create the PortletURI: createURI() Creates a PortletURI object pointing to the calling portlet with the current mode. Chapter 5. Portlet development using Java: Technology review 343 createURI(PortletWindow.State state) Creates a PortletURI object pointing to the calling portlet with the current mode and given portlet window state. createReturnURI() Creates a portletURI pointing at the caller of the portlet. For example, createReturnURI() can be used to create a back button in an edit mode. Each portlet runs in its own unique namespace. The encodeNamespace() method is used by portlets to bring attributes in the portlet output to avoid name clashes with other portlets. Attributes can include parameter names, global variables, or JavaScript function names. PortletSession The PortletSession holds user-specific data for the concrete portlet instance of the portlet, creating a portlet user instance. Concrete portlet instances differ from each other only by the data stored in their PortletData. Portlet user instances differ from each other only by the transient data stored in their PortletSession. Any persistent data must be stored using PortletData. Information stored in a portlet's instance variables is shared between all concrete portlet instances and even between all concrete portlets - with read and write access. Make sure you do not use instance attributes for user-specific data. During login, a PortletSession is automatically created for each portlet on a page. To get a PortletSession, the getSession() method (available from the PortletRequest) has to be used. The method returns the current session or, if there is no current session and the given parameter "create" is true, it creates one and returns it. A PortletSession is not available on an anonymous page. Portlet configuration Portlet configuration can be read-only or read-write depending on where the configuration is located and how it is used: PortletConfig PortletSettings PortletApplicationSettings PortletData PortletConfig The PortletConfig provides the non-concrete portlet with its initial configuration. The configuration holds information about the portlet class. This information is valid for every concrete portlet derived from the portlet. 344 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 A portlet's configuration is initially read from its servlet deployment descriptor. This information is set by the portlet developer. The configuration is read-only and cannot be changed by the portlet. PortletSettings The PortletSettings object provides the concrete portlet with its dynamic configuration. The configuration holds information about the concrete portlet. This information is valid for every instance of the concrete portlet. A concrete portlet's configuration is initially read from the portlet deployment descriptor. The configuration is read-only and can be written by the portlet only when the portlet is in configure mode. This information is normally maintained by the portal administrator and may be changed while the portal server is running. The portlet can get, set, and remove attributes during one request. To commit the changes, the store() method has to be called. PortletApplicationSettings The PortletApplicationSettings object provides the concrete portlet application with its dynamic configuration. The configuration holds information about the portlet application that is shared across all concrete portlets included in the application. A concrete portlet application's configuration is initially read from the portlet deployment descriptor. The configuration is read only and can be written by the portlet only when the portlet is in configure mode. This information is normally maintained by the portal administrator and may be changed while the portal server is running. A portlet in the application can get, set, and remove attributes during one request. To commit the changes, the store() method has to be called. PortletData The PortletData holds data for the concrete portlet instance. For each occurrence on a page there is a concrete portlet instance. The PortletData contains persistent information about the concrete portlet instance while the PortletSession contains only the transient data of the user portlet instance. There is one concrete portlet instance for each occurrence of a portlet on a page. A page can be owned by either a single user (personal page) or by a single group of users (group page). PortletData contains user-specific data on a personal page and group-specific data on a group page. Portlet events Portlet events contain information about an event to which a portlet might need to respond. To receive notification of the event, the portlet must have an event listener implemented within the portlet class. Chapter 5. Portlet development using Java: Technology review 345 Note: A portlet has a different processing and rendering sequence than a servlet. A servlet does all of its processing in the service() method. A portlet, on the other hand, uses a two phase processing that is split between an action processing and service. This split is necessary to accommodate communication between portlets before rendering output in the service stage. The action processing is guaranteed to complete before a portlet is called to render. Action events To receive action events, the portlet implements an ActionListener interface. The ActionListener interface provides the actionPerformed() method, to which an ActionEvent object is passed. When a user clicks on a link or a submit button, an ActionEvent can be generated. The portlet action can be obtained from the ActionEvent, which describes the triggering event. When the actionPerformed() method is invoked, a response object is not available, because this is not a rendering step. Important: All state changes should be handled during action processing. Portlets should use the methods in service phase only to render portlet output. Portlet action is a string passed to the actionPerformed() method via an ActionEvent object. Message events Message events can be sent from one portlet to others if the recipient portlets are members of the same portlet application and are placed on the same page as the sending portlet. Additionally, a DefaultPortletMessage can cross portlet application boundaries and may be sent to all portlets on a page. A MessageEvent can be actively sent to other portlets only when the portlet is in the event processing cycle of the portlet container; otherwise, an exception is thrown. There are two different types of messages: Single addressed messages: Messages sent to a specific portlet by specifying the portlet name on the send() method. Broadcast messages: Messages sent to all portlets on the page. The portlet receiving the message must implement the MessageListener interface and an object with the type PortletMessage. Tip: Message events are useful when changes in one portlet should be reflected in another one. 346 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Listeners The IBM Portlet API provides listeners, which can add more functionality for a portlet. To enable the listener's functionality, one of the following interfaces must be implemented by the portlet: PortletSessionListener PortletPageListener PortletTitleListener PortletSettingsAttributesListener PortletApplicationSettingsAttributesListener PortletSessionListener In addition to the concrete portlet instance, which exists for each portlet occurrence on a page, a portlet may have an even finer granularity. The PortletSessionListener allows a portlet to recognize the life cycle of a user portlet instance: login() After a user logs in to a portal, each portlet creates a session for the user. The combination of the concrete portlet instance and the user session creates the user portlet instance. The start of a user instance is signaled by the portal calling the login() method at the portlet. This method allows the portlet to initialize the user's session instance of the portlet, for example, to store attributes in the session. logout() When the user ends the session with the portal, the portal server calls the logout() method to inform the portlet that the user's session instance is terminating. The portlet should then clean up any resources for the portlet user instance. This could include cleaning up, if necessary, the authentication state of the user or cookies that might have been placed on the browser by the portlet. At a minimum, any state on the back-end application should be cleaned up or marked as terminated to prevent any remaining cookies on a subsequent request from being used. PortletPageListener A portlet has no control or awareness of the order in which the output from all of the portlets on the page is written. The PortletPageListener allows a portlet to insert markup at the beginning and ending of a page. beginPage() At the beginning of each page and before any service() method of any portlet on the page is called, the beginPage() method is called for each portlet residing on the page. Like the service() method, the beginPage() method for Chapter 5. Portlet development using Java: Technology review 347 each portlet on the page is not called in a guaranteed order and can even be called in a different order for each request. The output of beginPage() is inserted into the page aggregation area prior to the rendering of portlets on the page. This method allows a portlet to output JavaScript that is visible to all portlet's service() methods or even to set cookies or headers. endPage() At the end of each page, and after all service() methods of all portlets on the page are called, the endPage() method is called for each portlet residing on the page. Like the service() method, the endPage() method is not called in a guaranteed order and can even be called in a different order for each request. For example, the portlet can insert JavaScript to the end of the page that needs to occur after all other elements of the page have been written. Note: When implementing PortletSesssionListener and PortletPageListener, the following methods are called on the portlet during its life cycle: init(): The non-concrete portlet is initialized with PortletConfig. initConcrete(): The concrete portlet is initialized with PortletSettings. login(): The user portlet instance is initialized with PortletSession. beginPage(): The portlet may render output at the beginning of each page for each request. service(): The portlet may render output in the portlet window for each request. endPage(): The portlet may render output at the end of each page for each request. logout(): The user portlet instance is destroyed. destroyConcrete(): The concrete portlet is destroyed. destroy(): The non-concrete portlet is destroyed. PortletTitleListener The PortletTitleListener interface is used to allow the portlet title, as it is displayed in the title bar, to be changed based on a condition (for example, the type of device used to access the portal) or user input (for example, a preference that the user sets on the edit page). If the Listener is not implemented, the portlet displays the title specified on the <title> element (under <language>) of the portlet deployment descriptor. 348 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 PortletSettingsAttributesListener This interface listens for changes to the attributes of the PortletSettings, like when an administrator configures a concrete portlet. PortletApplicationSettingsAttributesListener This interface listens for changes to the attributes of the PortletApplicationSettings, like when an administrator configures a concrete portlet application. PortletService To enable portlets to use pluggable services via dynamic discovery, the Portlet API provides the PortletService interface. A PortletService is accessed from the PortletContext.getService() method that looks up the appropriate factory for the service, creates the service and returns it to the portlet. Tip: Various services may be implemented by different vendors, for example, a SearchService, LocationService, or a MailService. DominoAccessService may be implemented and it would provide portlets access to Domino databases. CredentialVaultService For resources protected by the portal, WebSphere Portal uses CORBA credentials and an encrypted LTPA cookie to authenticate users. However, for back-end systems that require their own authentication, portlets need to provide some form of authentication to access these remote applications. In order to provide a single sign-on user experience, portlets must be able to store and retrieve user credentials for their particular associated application and use those credentials to log in on behalf of the user. 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. WebSphere Portal provides a CredentialVaultService PortletService that portlets can use to store and retrieve credentials from the vault. The credential vault is a repository where credentials are stored. Examples of credentials include certificates, private keys, user IDs, and passwords. A vault adapter is a plug-in module between the credential vault and CredentialVaultService. WebSphere Portal provides a simple adapter using the portal database as a default vault. You can extend the VaultAdapter class, in the portal framework, to develop an adapter interface to your own repository. Chapter 5. Portlet development using Java: Technology review 349 A vault segment is a partition of a vault. There are two types of segments: user-managed and administrator-managed. Portal administrators can create administrator-managed segments. A vault slot is part of a vault segment; it is represented using CredentialSlotConfig class. Portlets use vault slots to store and retrieve credentials. You can create a vault slot programmatically, in a user-managed segment. An administrator can also create a slot in an administrator-managed segment, using the Credential Vault portlet. The portlet can set and get credentials in slots created either way. The CredentialSlotConfig object contains configuration information about the slot; for example, the slot ID, segment object ID, and other attributes. There are two types of credentials: active and passive. Passive credentials allow a portlet to extract the credential's secret but active credentials do not. If you need to get user’s password as a clear text, you have to use passive credentials. Active credentials, however, can submit credentials to back-end applications using standard authentications, such as HTTP form-based authentication or basic authentication. Refer to 6.4.2, “CredentialVaultManager” on page 431 for an example of how to use CredentialVault. Portlet menu Portlet menus allow a portlet to add menu entries to the navigation tree of the portal. Menu items are automatically positioned in the navigation tree after the page that contains the portlet instance. The root node of this tree represents the portlet and all child nodes represent portlet menu entries. Portlet menu entries do not belong to the internal portal model. For example, they cannot be modified or removed using the page customizer. Figure 5-8 on page 351 shows example of portlet menu. 350 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 5-8 Portlet menu To add menu entries to the portal navigation tree, portlets must implement the MenuProvider interface. A dynamic menu’s tree structure is defined in the portlet code. Menu items are added dynamically for each request; the portlet is queried for menu information for each request so that the portlet can return stateful information in the menu entry. A static menu’s tree structure is defined in an XMI-formatted deployment descriptor extension packaged with the portlet. The static method allows portlets to declare menu entries in the deployment descriptor that are fixed. Deployment descriptors The WAR file for a portlet application must contain two descriptor documents: the Web application deployment descriptor and the portlet deployment descriptor. The definition of the servlets in the Web application deployment descriptor must be in the same order as the definition of portlets in the portlet deployment descriptor. Chapter 5. Portlet development using Java: Technology review 351 Web application deployment descriptor: web.xml As with other servlets following the J2EE model, portlets are packaged as WAR or EAR files with a Web application deployment descriptor (web.xml). This descriptor defines each portlet as a servlet within the Web application, including unique identifiers for each portlet, the portlet class, and initialization parameters. For more information about the Web application deployment descriptor, see the Java Servlet Specification Version 2.3. Portlet deployment descriptor: portlet.xml This information includes configuration parameters specific to a particular portlet or portlet application as well as general information that all portlets provide, such as the type of markup that the portlet supports. The portal server uses this information to provide services for the portlet. See the sample portlet.xml in Example 5-6 on page 339. Linking the servlet, portlet, and concrete portlet The definition of the servlets in the web.xml must be in the same order as the definition of portlets in the portlet.xml. The servlet identifier must be referenced by the portlet deployment descriptor, using the href attribute of the <portlet> tag. As shown in Figure 5-9, the href attribute indicates the path of the Web application descriptor in the WAR file appended by the servlet ID as the anchor. Figure 5-9 Referencing portlet to servlet Each concrete portlet definition indicates its parent portlet using the href attribute of the <concrete-portlet> tag. As shown in Figure 5-10 on page 353, the href attribute indicates the portlet ID as an anchor. 352 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 5-10 Referencing concrete portlet to portlet Note: Take extra care in deployment descriptors if you are writing them by hand. Tools such as WebSphere Studio Application Developer creates deployment descriptors for you when creating portlets. The UIDs of portlet applications and concrete portlet applications must identify them unambiguously in the area of their usage and portlet IDs must be unique within the application. JSP tags The portlet container provides tags for use in portlet JSPs. Table 5-3 shows a list of common portlet tags. See WebSphere Portal InfoCenter for more detailed information about JSP tags. Table 5-3 IBM Portlet API tags Tag Description <portletAPI:init /> Provides access to the portletRequest, portletResponse, and portletConfig objects. <portletAPI:createURI /> Creates an URI that points to the current portlet with the given parameters. <portletAPI:CreateReturnURI /> Creates a URI that points to the caller of the portlet. <portletAPI:URIAction /> Adds a default action to the URI of the createURI and createReturnURI tags. <portletAPI:URIParameter /> Adds a parameter to the URI of the createURI and CreateReturnURI tags. <portletAPI:encodeNamespace /> Maps the given string value into this portlet's namespace. Chapter 5. Portlet development using Java: Technology review 353 5.4 JSR 168 Java Portlet Specification The Java Standardization Request 168 (JSR 168) defines a portlet specification, including a contract between the portlet container and the portlet. The purpose of the JSR 168 specification is to solve the problem of portlet compatibility between portal servers offered by different vendors. The fundamental concepts of JSR 168 and IBM Portlet API are the same. This section describes the following differences between the two APIs: Relationship to servlet API Comparing common portlet API concepts Comparing portlet packaging and descriptors Comparing elements of the API Concepts unique to JSR 168 Concepts unique to the IBM portlet API 5.4.1 Relationship to servlet API The IBM portlet API extends the servlet API and many of the main interfaces such as request, response, and session. JSR 168 API does not extend the servlet API, but shares many of the same characteristics. JSR 168 takes advantage of much of the functionality provided by the servlet specification, such as deployment, classloading, Web applications, Web application life cycle management, session management, and request dispatching. JSR 168 portlets can call servlets and package them in the same portlet application. Portlets, servlets, and JSPs within the same portlet application share the same classloader, application context, and session. 5.4.2 Comparing common portlet API concepts For both portlet APIs, there is one portlet object instance per portlet configuration in the Web deployment descriptor. The APIs differ in how each portlet object is represented in the portal. Logical representation of portlets in the IBM portlet API The PortletSettings object provides the portlet with its unique set of configuration parameters and values. Configuration parameters are initially defined in the portlet deployment descriptor, but can also be added or modified by the portal administrator. There can be many PortletSettings objects, parameterizing the 354 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 same portlet object, provided on a per-request basis. Each PortletSettings object along with the portlet object comprises a concrete portlet. Figure 5-11 Logical representation of portlets in the IBM portlet API When users edit the settings in a portlet according to their preferences, the settings are saved to persistence using the PortletData object. There can be many PortletData objects parameterizing the same concrete portlet. Each PortletData object along with the concrete portlet comprises a concrete portlet instance. When multiple users interact in different browser sessions with the same concrete portlet instance on a portal page, each user sees a particular user portlet instance, which is a concrete portlet instance parameterized with the session, a mode, and window state. Logical representation of portlets in JSR 168 JSR 168 portlets, like IBM portlets, can be configured on two levels, by an administrator and by individual users. However, JSR 168 has no concept of a concrete portlet application or concrete portlets. The number of configuration layers is opaque to the programming model; the portlet configuration is contained within a single PortletPreferences object, which aggregates these configuration layers. Chapter 5. Portlet development using Java: Technology review 355 Figure 5-12 Logical representation of portlets in JSR 168 Preferences can be marked in the portlet.xml as read-only so that they may be customized only by administrators using configure mode or through the administration portlets. Preferences that are not marked read-only can be modified by users in edit mode. The parameterized view of a portlet for an individual user interaction is called a portlet window in JSR 168. JSR 168 adds render parameters as a new way to hold an interaction state for a portlet window. A portal page can contain more than one portlet window for a single portlet; each portlet window is associated with a unique portlet mode, state, and render parameters. 5.4.3 Comparing portlet packaging and descriptors In both APIs, one or more portlets are packaged as a portlet application in a WAR file. The portlet.xml file describes the portlet application and its portlets. The web.xml file describes the Web application. In JSR 168, since the portlet is not a servlet, the portlet descriptor does not reference a corresponding servlet ID. The web.xml describes other Web application resources, such as servlets that are part of the portlet application. The portlet descriptor is in the format of an XML Schema instead of a DTD. The top level element is the <portlet-app>, which contains one or more <portlet> definitions. 356 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 In JSR 168, context-wide parameters are stored in the web.xml using the <init-param> element and are obtained using PortletContext.getInitParameter(). Portlet-specific initialization parameters are stored in the portlet.xml using the <init-param> element and are obtained from the PortletConfig object provided during initialization. Since the web.xml is a mandatory item in a J2EE Web archive, you should make sure your portlet application includes a web.xml in its WAR file. This ensures that the portlet application is compatible with other portal server implementations as well as subsequent versions of WebSphere Portal Server. The web.xml should contain, at a minimum, the <web-app/> and <display-name/> elements. Comparing elements of the API Table 5-4 compares elements of the API. Table 5-4 Comparing elements of the API Element IBM Portlet API JSR 168 Life cycle init(). initConcrete(). service(). destroyConcrete(). destroy(). init() render() processAction() destroy() No concept of a concrete portlet. The render() and processAction() calls are implemented in place of service() and actionPerformed(). Two-phase processing Action processing precedes the call for portlets to render output. The actionPerformed() and service () methods are involved. Objects can be set in the action and retrieved from the subsequent render phase. Also uses two-phase processing. The corresponding methods are processAction() and render(). Main difference is that the action request and response objects are different from render request and response object. The portlet can set parameters that are available in the render call, but for all other cases the session should be used. Portlet mode View mode (called by corresponding doView()). Same. Chapter 5. Portlet development using Java: Technology review 357 Element Portlet window state 358 IBM Portlet API JSR 168 Edit mode (called by corresponding doEdit()). Same. Help mode (called by corresponding doHelp()). Same. Configure mode (called by corresponding doConfigure()). Config mode supported as a custom mode. In config mode, the portlet's read-only preferences can be updated by the administrator. At runtime, portlets use PortalContext.getSupporte dPortletModes() to retrieve the modes supported by the portal and adapt accordingly. JSR 168 also suggests these custom portlet modes: about, config, edit_defaults, preview, and print. Vendors can also define other portlet modes. Maximized. Same. Minimized. Same, except that JSR 168 allows portlets to display a limited amount of output. Normal. Same. Solo. Supported only as a custom window state. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Element IBM Portlet API JSR 168 Finite number of supported states. Allows portlets and portal implementations to define custom window states. At deployment time, the portal can map custom portlet window states from the portlet descriptor to its own custom window states, or it can ignore them. At runtime, portlets use PortalContext.getSupporte dWindowStates() to retrieve the modes supported by the portal and adapt accordingly. Methods to create URI to the portlet PortletResponse.createU RI(). RenderResponse.createA ctionURL() and RenderResponse.createR enderURL(). Methods to create URIs to portlet resources PortletResponse.encodeU RL(). Same. Including JSPs PortletContext.include(). PortletRequestDispatcher.i nclude(). JSP tag library <portletAPI:init/> provides access to the PortletRequest, PortletResponse, and PortletConfig objects. <portlet:defineObjects/> provides access to the RenderRequest, RenderResponse, and PortletConfig objects. <portletAPI:createURI/> creates a URI that points to the portlet. To invoke an action in an IBM portlet, include the <portletAPI:URIAction/> tag and action parameters. <portlet:renderURL/> <portlet:actionURL/> creates a URI to the appropriate render() or processAction() method of the portlet. <portletAPI:encodeNames pace/>. <portlet:namespace/>. Other tags provided by the IBM portlet API tag library. Use JSTL tags. Chapter 5. Portlet development using Java: Technology review 359 Element IBM Portlet API JSR 168 Accessing images and other portlet resources from the JSP Use the encodeURL() method of the response and specify the path to the resource, for example, <%=portletResponse.enco deURL("images/photo01.j pg") %>. Use the encodeURL() method, just as you would with the IBM portlet, except that you also have to add the context path of the portlet from the request, as in <%= portletResponse.encodeU RL(renderRequest.getCon textPath() + "images/photo01.jpg") %>. PortletConfig Provides the initialization parameters defined in the web.xml. Provides the initialization parameters defined in the portlet.xml. Namespace encoding PortletResponse.encodeN amespace(). RenderResponse.getNam espace(). Note: There is no concept of a concrete portlet in JSR 168. Action request and response objects are different from render request and response objects. Concepts unique to JSR 168 Render parameters These are parameters attached to the render request that stay the same for every render request until a new action occurs. This allows storing the navigational state in the render parameters instead of the session. The portlet should put all state information it needs to redisplay itself correctly into render parameters (for example, which screen to render). This facilitates saving bookmarks and provides better support for the use of the browser's back button. When the portlet is the target of an action, render parameters are reset. In the action, the portlet can set new render parameters to represent the new navigational state after the action is completed. The developer can use render URLs (see RenderResponse.createRenderURL()) to set render parameters directly without having to go through an action. As render parameters may be bookmarked, portlets should be prepared to handle parameters that are not valid (for example, that could be the result of an outdated bookmark). Such parameter values should be handled gracefully and should not lead to exceptions. From the JSP, the portlet can set render parameters using the <portlet:renderURL/> tag. 360 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Portal context To allow portlets to adapt to the portal that is calling them, JSR 168 provides the PortalContext to be retrieved from the request. This portal context provides information such as the portal vendor, version, and specific portal properties. This allows the portlet to use specific vendor extensions when called by the portal of that vendor and fall back to some simpler default behavior when called by other portals. As the portal context is attached to the request, it may change from request to request. This can be the case in the remote scenario, where one portlet (WSRP provider) may be called from different portals (WSRP consumers). Access to the portal user profile In JSR 168, a portlet can define in the deployment descriptor which user profile information it wants to access. The specification proposes to use a list of standard P3P attributes; however, the portlet is free to request any additional user information that is not covered by this attribute list. At deployment time, the portal can map the requested user profile attributes to the supported profile attributes or the portal can ignore the requested attributes. At runtime, the portlet can use the USER_INFO constant of the PortletRequest to determine which of the requested user profile attributes are available. Request and response properties The portlet and portlet container can exchange vendor-specific information using request and response properties. These properties are available in the action request and response and the render request and response. Properties are propagated for includes, but not between the action and render phase. When including a servlet or JSP, the properties are mapped to headers in the servlet API. Web application session scope Note: JSR 168 API supports the Web application session scope, in which every component of the Web application can share information through the APPLICATION_SCOPE field of the portlet session. This can be used to share transient information between different components of the same Web application, for example, between portlets or between a portlet and a servlet. Reuse of the HttpSession listeners As JSR 168 reuses the HttpSession, it also allows reusing all the session and attribute listeners that the servlet 2.3 specification defines. JSR 168 provides a PortletSessionUtil class for decoding the attributes of the HttpSession, as these are namespaced in the private portlet session case. Chapter 5. Portlet development using Java: Technology review 361 Resource bundles Portlets can define a resource bundle in the deployment descriptor that can be accessed at runtime using PortletConfig.getResourceBundle(). This provides localizations of resources, such as the portlet title, search keywords, or preference names and descriptions. At deployment time, all settings in the portlet descriptor that are intended to be viewed or changed by the administrator (for example, portlet description, init parameters, or display name) can be localized by setting the xml:lang attribute on the associated tag (like the servlet 2.4 deployment descriptor). JSR 168 also recommends a notation for localizing the preference attribute display names, values, and descriptions. Multiple response content types For each response, portlets can retrieve a list of supported content types using the PortletRequest.getResponseContentTypes() method. This allows portals to indicate to portlets that they have transcoding capabilities. Portlets receive only content types that they have defined in the <supports> section of the deployment descriptor. If the portlet declares support for content types using wildcards (for example, "text/*" or "*/*") in the deployment descriptor, the portlet container may also set these content types as response content type. Therefore, portlets specifying wildcard content types in the deployment should handle wildcard content types as response content types accordingly. Redirect in action During the action phase, JSR 168 API enables portlets to redirect requests to other Web resources. This allows portlets to process the request from different resources (for example, an accounting servlet) in response to an action. Preference validator Portlets can provide a class that validates the set of preference values in the PortletPreferences object. The class is defined in the portlet.xml. The preference validator can incorporate logic to check cross-dependencies between different preference properties. The portlet container always calls the validator before storing a preference set to ensure that only consistent preference sets are stored. 362 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Concepts unique to the IBM portlet API Portlet events The IBM Portlet API has the concepts of events. This event concept is based on the JetSpeed event model, which is similar to the Java event model. The IBM Portlet API provides the following events: – ActionEvent – MessageEvent – PortletApplicationSettingsAttributeEvent – PortletSettingsAttributeEvent – WindowEvent Additional listeners The listener concept of the IBM Portlet API allows the portlet to get notifications not only for events as described in the section above, but also for events related to the session life cycle, event phase life cycle, or render phase life cycle. The IBM Portlet API provides the following listeners to implement this functionality: – PortletPageListener – PortletSessionListener – EventPhaseListener Portlet menus The portlet menu service allows the portlet to contribute content to the portal navigation menu, providing users easier navigation through portal pages. Invalidation-based caching The portlet can actively invalidate the cache using the invalidate method on the portlet request as result of an action. This allows for more fine-grained cache control as the portlet can determine, as a result of this action, whether to invalidate the cache content for only the current portlet mode and markup or for all of the portlet's modes and markups. In JSR 168, an action invalidates all cached markup. Note: As JSR 168 matures, many features currently specific to IBM Portlet API may be part of the JSR 168. Chapter 5. Portlet development using Java: Technology review 363 5.5 Struts framework Developers may also choose to implemented their portlets using the Struts framework. Struts is a Jakarta project providing a very popular open source framework for building Web applications. Using the Struts Portlet Framework provided with WebSphere Portal, portlets written using the Struts framework can be run in WebSphere Portal. Struts provides considerable Web application functionality beyond page navigation and is an excellent choice for portlet development. The Struts framework is intended to provide a portlet application developer with two main advantages, specifically: A controlled logic to your portlet applications The development of portlet applications requires the developer to coordinate several technologies to work together. Typically, requests are sent to the portlet class doView() method, and depending on the request and state of the portlets, it redirects to the appropriate JSP pages for rendering. This is accomplished with a redirection map embedded in the portlet class. Basically, it is a tightly coupled application, since any change in the control logic would require recompiling and making sure that your application does not lose its integrity. The Struts framework solves this problem, especially in big and complex portlet applications, since it takes out the control logic map from the portlet class and places it on a flexible deployment descriptor, giving you a loosely coupled structure. Also, this map can be edited with graphical tools like the ones included in WebSphere Studio, the Struts tools. So the developer should consider using the Struts Portal framework if he is placing control logic into the portlet applications and requires a flexible and manageable control logic for the portlet. A strong foundation for portlet development The Struts framework incorporates proven development patterns, like the MVC model 2, that will make your portlet application perform and scale appropriately. So if you are considering introducing a hybrid approach in the development of your portlets, and you want to provide a strong structure, Struts can give you exactly what you need. The Struts framework will add some development components that have to be well understood and properly used in order to exploit its full advantages. So if your portlet application will just expose the control logic of your applications, it would be appropriate to reconsider using this framework. Also bear in mind that the standard Struts framework is accommodated to work in the WebSphere Portal infrastructure through the Struts Portal framework, so in 364 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 this section, we discuss the considerations for incorporating the Struts technology into your portlet application. Struts defined Struts is a Jakarta open source project that provides a framework based on the Model-View-Controller (MVC) pattern, which allows developers to efficiently implement their Web applications by keeping the business logic and presentation aspects separate. The developer community has embraced Struts, and the initial release is continually being enhanced. In addition to enhancements to the base Struts functionality, there are numerous extensions and tools available, for example, the Struts editor in WebSphere Studio. In the Portal environment, the ability to use Struts is a logical extension. The portlets on a Portal page can be essentially thought of as servlet applications in their own right. Thus, for many of the same reasons one would use Struts to implement a Web application, one would also like to be able to use Struts in a portlet. 5.5.1 Basic elements of Struts A Struts application is basically made up of the following elements (see Figure 5-13 on page 366): Actions The Actions represent processing that occurs prior to going to another page. Pages These are usually JSPs, but sometimes are HTML pages. ActionForm Beans ActionForms are Beans associated with Actions, supplying the data to fill or collect various fields on a page. The application writer creates these objects and, in the configuration file struts-config.xml, defines the relationships between these objects and the transitions that occur. The configuration of an ActionMapping associates a path with an Action and with ActionForms, and can list one or more destination pages following execution of the Action. As a result of executing the Action, an ActionForward object is returned, which contains the path to the next request. Typically, the returned path is to a page, but it is also possible that the path is to another Action. Chapter 5. Portlet development using Java: Technology review 365 Figure 5-13 Struts structure 5.5.2 Struts support in WebSphere Portal A Struts application in Portal server is similar to the servlet-based Struts application. A WAR file that contains the Struts jars, the JSPs, actions, and configuration is built. The WAR file in Portal server has some additional requirements. There are some additional jar files, and a portlet descriptor file. There are also some necessary changes to the Web deployment descriptor and the Struts configuration. To support existing Struts applications and offer a migration path to the Portal server for existing Struts applications, several differences between Struts servlet-based applications and portlets exist, specifically: The portlet itself is a servlet and has its own processing and servlet mapping. The portlet servlet must be configured as the main servlet rather than the Struts Action Servlet. Portlet action processing (for example, handling of user events like selecting links or submitting forms) is done in a step prior to rendering the display view. During this processing, the response object is not available. Display view rendering is done separately from action processing, and may be done multiple times without intervening actions. This occurs because all portlets on a page are essentially asked to refresh or re-render themselves when the entire Portal server page is refreshed. URIs under Portal server have a special format. A special API is used to generate the URI and add the desired information to be passed to the portlet. 366 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 If portlet URIs were not used, control would not get passed to the correct portlet. Thus, the portlet URIs must be used to get control passed to the correct portlet, with the additional path information needed by the Struts application made available. The Struts tags have been modified to automatically provide this needed functionality. Portal server does not support forwards or redirects. The differences enumerated result in the following conclusions with regard to supporting Struts applications as portlets: The portlet’s servlet mapping has to be used. Routing of Struts actions back to the Struts application processing has to be done using portlet URIs. The way the Struts mapping is configured is described later in this section. The processing of Struts Actions must occur during portlet action processing, and the information necessary to render a display view must be stored away so it is available during the later view rendering phase, which may occur multiple times without intervening actions. The Struts application paths, both to Actions and to pages, must be sent and retrieved in a different way. Forwards to pages (for example, JSPs) are done with include operations rather than with forward operations. Forwards to other Actions can be handled by recursively executing the Struts Action processing. Redirects are treated in the same way as a forward. Two-phase processing A portlet has a different processing and rendering design than a servlet. A servlet does all of its processing in the service method. A portlet, on the other hand, uses two-phase processing that is split between an action processing and service. The reason that a Portal server needs this split is because portlets may need to communicate with other portlets before the rendering stage. The action processing is guaranteed to complete before a portlet is asked for a rendering. The processing of events by a portlet is handled in a separate, earlier step from the rendering step. The typical action handling is achieved by implementing the ActionListener interface. The ActionListener interface provides the actionPerformed method, to which an ActionEvent object is passed. When a user clicks on a link or a submit button, an ActionEvent can be generated. The PortletAction can be obtained from the ActionEvent, which describes the triggering event. When the actionPerformed method is invoked, a response object is not available because this is not a rendering step. The rendering step is handled in a separate method, the service method, which calls the doView method in the PortletAdapter. The doView method is not only called following the actionPerformed processing when a user clicks on a link or Chapter 5. Portlet development using Java: Technology review 367 button in a portlet, but is also called when the portal page is refreshed. Thus, given a page with two portlets, A and B, when the user clicks on a link in portlet A, actionPerformed and doView is called for portlet A, but only the doView method is called for portlet B. The two-phase processing causes some significant challenges as it relates to Struts applications: The methods called during Struts processing expect both a request and response to work with. The first issue of the lack of a response object during actionPerformed processing can be handled by creating a pseudo response. The response object used prior to actually invoking the JSP is not heavily used. However, during action processing within a Struts application, it is not unusual for an application to report an error using the sendError method. The Struts rendering of the page is usually immediately preceded by action processing; they are essentially parts of one step. The second issue is the fact that the rendering step is separate from the event handling step. Note that some of the information that was available during the processing of the actionPerformed method, namely the request parameters, is no longer available when the doView method is invoked. Additionally, since doView can be called when the portlet page is refreshed (without a new event occurring for that portlet), all information required to render the page must be available every time doView is called. Since normal Struts processing allows the updating of the response object during almost all steps, including during action processing, there are clearly situations where the two-phase model would cause problems in the application. However, a typical well-behaved Struts application does not write directly to the response object and instead forwards to a JSP. It is assumed that the JSPs do not themselves need access to the original event information, request parameters, which initially led to the current rendering. Instead, it is assumed that the Action processing stores information in a bean, from which the JSP extracts the information. As long as those beans are available during the rendering, the rendering can be repeated. Since those beans, most notably the ActionForm, are usually stored in the original request attributes, the request attributes from the original request processing must be saved and made available when doView is invoked. No response object The typical well-behaved Struts application has no need to access the response object during the Action processing. The lone exception encountered is the need to report an error through the sendError method. When an application checks and finds some state information invalid, it is common to use response.sendError to generate an error page. Failing to support this would break a large number of 368 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 legacy Struts applications. The Struts portlet framework intercepts the calls to sendError and saves the error information for display at a later time. During the later view rendering phase, this error information is found, and the error information is displayed instead of displaying other content for the portlet. The Struts URL paths Struts Action mappings are defined in terms of paths. The name and location of page objects (for example, JSPs) are defined via paths as well. Thus, although portlets have their own form of URI, it is still necessary to be able to associate the Struts path with an action sent to a portlet and to retrieve that Struts path when the portlet action is handled. It is not unusual to pass parameters on such a path via the query string on the HTTP URL. It is also important to realize that often the actions containing these paths are generated from tags provided by Struts. The most obvious examples of these are the tags for the HTML elements LINK and FORM. Obviously, in order to support such tags when the Struts Application is executed in a portlet, they have to be modified to create a portletURI with the required additional information. The Struts tags that create links have been modified to pass the created paths directly through to the Portal server as a parameter on the portlet URI. This allows a portlet URI to be created that will cause the interaction with the portlet. Forwards and redirects As mentioned earlier, the Struts Action objects return an ActionForward object, which contains a path to be either forwarded or redirected to. Portal server does not support forward operations because the response object has already been committed. If the path is not an action, the page is included instead. If the path is an action, then a forward to the Action is simulated. The include of a page uses the PortletContext include method. A forward for an Action is simulated by recursively sending the new Action URI through the Struts base processing of an Action. Note that not only can we have this issue of forwards in ActionForward objects returned from Action objects, but also in tag handlers. In tag handlers, it is possible to access the PageContext object and invoke the forward method as well. An alternative method to the PageContext.forward is available via the PortletApiUtils class, which provides a mechanism to emulate the forward functionality. It is important to understand that although you can write portlets using Struts, there are some things that you can do in a Struts servlet that you cannot do in a Struts portlet. For example, Struts provides support for things like redirects and forwards to other servlets. These are provided because they are functions generally available to servlets. However, these capabilities are not available in Chapter 5. Portlet development using Java: Technology review 369 portlets. What not to do in an action Here are two examples of what you should not do in an action: The typical use of the response object is to call sendError when an error condition is detected. Portal server does not support writing to the response object during the action processing. Therefore, a response object is not available, as discussed previously. A pseudo response object is made available during the processing in the Request Processor. If the Struts Action writes to this response object, that text will be lost. The Action should return an ActionForward object. This is important so the Request Processor goes through the normal processing. The ForwardAction and IncludeAction, normally shipped with Struts, are examples of what should not be done in a Struts application in Portal server. These actions create a RequestDispatcher and try to forward or include the path in the Action execute. The ForwardAction should return an ActionForward so the RequestProcessor can process the Action. The Struts portlet framework provides its own versions of ForwardAction and IncludeAction to deal with this problem. It is hoped that the issue will be corrected in the base Struts implementation sometime in the future. However, as mentioned previously, the use of the sendError function on the response object is supported by the Struts portlet framework because the function is so commonly used. Roles support Struts uses roles to determine access to an Action. Portal server does not support roles at this time. The Struts portlet can be configured to use group names as though they were role names, in addition to group names, to emulate role-based access control. The following init parameter in the Web deployment descriptor enables this support: <init-param> <param-name>UseGroupsForAccess</param-name> <param-value>true</param-value> </init-param> 370 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5.6 JSF framework JavaServer Faces (JSF) is a framework for developing Java Web applications. The JSF framework aims to unify techniques for solving a number of common problems in Web application design and development, such as: User interface development JSF allows direct binding of user interface (UI) components to model data. It abstracts request processing into an event-driven model. Developers can use extensive libraries of prebuilt UI components that provide both basic and advanced Web functionality. Navigation JSF introduces a layer of separation between business logic and the resulting UI pages; stand-alone flexible rules drive the flow of pages. Session and object management JSF manages designated model data objects by handling their initialization, persistence over the request cycle, and cleanup. Validation and error feedback JSF allows direct binding of reusable validators to UI components. The framework also provides a queue mechanism to simplify error and message feedback to the application user. These messages can be associated with specific UI components. Internationalization JSF provides tools for internationalizing Web applications, supporting number, currency, time, and date formatting, and externalizing of UI strings. Applications built with JavaServer Faces are intended to follow the model-view-controller (MVC) architectural pattern. Note: JSF is commonly viewed as a rapid application development (RAD) framework. RAD is the idea that the application development process can be made more efficient through: Rapid prototyping Early, iterative functional testing of designs Re-using standard software components Using visual design tools Chapter 5. Portlet development using Java: Technology review 371 The advantages of using a RAD framework, such as JSF, are that overall development costs are reduced, that a customer gets to see immediate results and approve designs, and that the application does not become an anachronism due to changing business conditions during development. JSF qualifies as a RAD framework due to the standardization it provides, the tooling built on its specification, and its extensive libraries of off-the-shelf components. 5.6.1 JSF application concept A JSF application is a J2EE Web application, so a JSF application meets all the basic requirements of a Web application as defined in the J2EE specification (see Figure 5-14). Figure 5-14 JSF application structure The main pieces of a JSF application are: JSF pages JSPs built from JSF components, where each component is represented by a server-side class. 372 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Faces Servlet One servlet (FacesServlet) controls the execution flow. Configuration file An XML file (faces-config.xml) that contains the navigation rules between the JSPs, validators, and managed beans. Tag libraries The JSF components are implemented in tag libraries. Validators Java classes to validate the content of JSF components, for example, to validate user input. Managed beans JavaBeans defined in the configuration file to hold the data from JSF components. Managed beans represent the data model and are passed between business logic and user interface. JSF moves the data between managed beans and user interface components. Events Java code executed in the server for events (for example, a push button). Event handling is used to pass managed beans to business logic. 5.6.2 JSF support in WPS You can develop portlet applications using JSF in much the same way as you develop Web applications. The Faces support in Portal Toolkit V5.0.2.2 simplifies the process of writing Faces portlet applications and eliminates the need to manage many of the underlying requirements of portlet applications. WebSphere Portal Toolkit V5.0.2.2 provides a set of wizards that help you create Faces portal-related artifacts. In many cases, these wizards are identical to the wizards used to create standard Faces artifacts. Navigation The navigation model is exactly the same model as we have in JSF Web applications. This model is a set of rules written in the faces-config.xml file, located in the WebContent\WEB-INF subfolder of the portlet application. Command button and hyperlink actions Actions in JSF pages are managed the same way as in other Web applications. The code for the action is added to the page code Java class and the code is executed when you click the button or the hyperlink. Chapter 5. Portlet development using Java: Technology review 373 Portlet modes and JSF In JSF portlets, the following modes are available: View The view mode must be implemented. The expected functionality in this mode is to generate markup language (HTML in a Web application) to show the state of the portlet. Edit The edit mode should provide content and logic to let the user customize the behavior of the portlet for that user. Help When a portlet is in this mode, it should provide help information about itself. Configuration The configuration mode displays one or more configuration views that let administrators configure portlet settings that are valid for all users. Each portlet mode has a first page defined that is shown when the portlet switches to that mode. If you navigate or link to that page directly, this does not mean that the portlet changes its mode. The portlet mode should be changed only with the buttons available for this operation. You should take care to avoid navigation that could lead into an incorrect application state. 5.7 Other technologies This section has brief descriptions of technologies that can be and are used in portal application development and in portalizing Domino applications. 5.7.1 JSTL Java Server Pages Standard Tag Library (JSTL) encapsulates, as simple tags, core functionality common to many JSP applications. JSTL includes core tags to support the following features: Iteration The core iteration tag is <forEach>, which iterates over most collections and similar objects you want to iterate over. <forTokens> lets you iterate over tokens in a String object; it lets you specify the String and the delimiters. 374 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Conditionals JSTL supports a simple conditional <if> tag along with a collection of tags (<choose>, <when>, and <otherwise>) that support mutually exclusive conditionals. Expression languages JSTL provides a few tags to facilitate use of expression languages. <out> prints out the value of a particular expression in the current EL, similar to the way that the scriptlet expression (<%= ... %>) syntax prints out the value of a expression in the scripting language (typically Java). <set> lets you set a scoped attribute (for example, a value in the request, page, session, or application scopes) with the value of an expression. Text inclusion JSP supports the jsp:include tag, but this standard action is limited in that it only supports relative URLs. JSTL introduces the c:import tag, which lets you retrieve absolute URLs. For example, you can use c:import to retrieve information from the Web using HTTP URLs, or from a file server using an FTP URL. The tag also has some advanced support for performance optimizations, avoiding unnecessary buffering of data that is retrieved. I18N-capable text formatting Formatting data is one of the key tasks in many JSP pages. JSTL introduces tags to support data formatting and parsing. These tags rely on convenient machinery to support internationalized applications. XML manipulation JSTL gives you support for manipulating XML from JSP pages. Parse documents, use XPath to select content, and perform XSLT transformations from within your JSP pages. Database access Easily access relational databases using the SQL actions. You can perform database queries, easily access results, perform updates, and group several operations into a transaction. 5.7.2 Object pooling Pooling objects, like Domino session objects and views, can help to significantly improve performance in a Portal environment. With object pooling, many Portlets can share a limited resource such as a session, using it only when they need it. In this way, the performance cost of creating and destroying the session is reduced. Chapter 5. Portlet development using Java: Technology review 375 An object pool is a set of limited resources, such as sessions, that can be reserved for use by clients and then returned to the pool (for probable reuse) when the object is no longer needed. Reserving and returning pooled objects avoids the overhead of separately creating and destroying an object each time a client requests it. Multiple object pools can be used. For example, one object pool might contain session connection objects, and another pool might contain database or view objects. Object pools are relatively easy to implement and the Jakarta Commons project provides a generic object pooling interface, a toolkit for creating modular object pools, and several general purpose pool implementations. 5.7.3 Logging Logging equips the developer with detailed context for application failures. Logging and testing should not be confused; they are complementary techniques. When logging is wisely used, it can prove to be a valuable tool, and it is one of the key issues to consider in portlet development work. Inserting log statements into your portlet code is a low-tech method for debugging it and sometimes is the only available method for debugging. WebSphere Portal Server offers PortletLog and methods to log in portal’s log files. Logging can also be implemented by using a simple System.out.println() or using a logging package, such as Apache Logging Services’ log4j-project. With log4j, it is possible to enable logging at runtime without modifying the application binary. The log4j package is designed so that these statements can remain in shipped code without incurring a heavy performance cost. Logging behavior can be controlled by editing a configuration file, without touching the application binary. 5.7.4 Domino XML Lotus Domino provides support for Extensible Markup Language (XML). XML enables you to tag data in order to delimit it, leaving the interpretation of the data to the applications that read it. The XML representation of Domino data is known as DXL. DXL describes Domino-specific data and design elements, such as embedded views, forms, and documents. As XML becomes the standard basis for exchanging information, DXL provides a basis for importing or exporting XML representations of data to and from a Domino application. Domino Java API offers methods and classes to work with Domino XML. 376 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The sample in Example 5-7 would output a document in Domino XML (Example 5-8). Example 5-7 Generating XML from Domino document import lotus.domino.*; public class DominoExample2 { public static void main(String[] args) { try { Session s=NotesFactory.createSession("domino651.swic.fi.ibm.com","test person","password"); Database db=s.getDatabase(null,"redbook/customer.nsf"); DocumentCollection dc=db.search("Form = \"Customer\""); DxlExporter dxlExporter=s.createDxlExporter(); Document doc = dc.getFirstDocument(); String xmlData=dxlExporter.exportDxl(doc); System.out.println(xmlData); } catch (NotesException ne) { ne.printStackTrace(); } } } Example 5-8 Sample Domino Document XML <?xml version='1.0'?> <!DOCTYPE document SYSTEM 'xmlschemas/domino_6_5_2.dtd'> <document xmlns='http://www.lotus.com/dxl' version='6.5' maintenanceversion='2.0' replicaid='85256D81004AF39D' form='Customer'> <noteinfo noteid='8fe' unid='462E6D6DE88ED7FB85256D1F007962A7' sequence='11'> <created><datetime dst='true'>20030507T180551,11-04</datetime></created> <modified><datetime dst='true'>20040929T162245,19+03</datetime></modified> <revised><datetime dst='true'>20040929T162245,18+03</datetime></revised> <lastaccessed><datetime dst='true'>20040929T162245,18+03</datetime></lastaccessed> <addedtofile><datetime dst='true'>20030813T093841,28-04</datetime></addedtofile></noteinfo> <updatedby><name>Anonymous</name><name>CN=Michael Ticknor/OU=Cincinnati/O=IBM</name><name >CN=Christopher Heltzel/OU=Cambridge/O=IBM</name><name>CN=Camilo Esteban Rojas Lopez/OU=Colombia/O=IBM</name><name >CN=Test Person/O=swic</name></updatedby> Chapter 5. Portlet development using Java: Technology review 377 <revisions><datetime dst='true'>20030507T180551,11-04</datetime><datetime dst='true'>20030507T180610,91-04</datetime><datetime dst='true'>20030507T223631,46-04</datetime><datetime dst='true'>20030512T095205,41-04</datetime><datetime dst='true'>20030512T101228,85-04</datetime><datetime dst='true'>20030521T134711,05-04</datetime><datetime dst='true'>20030521T134718,79-04</datetime><datetime dst='true'>20040929T161727,56+03</datetime><datetime dst='true'>20040929T162003,12+03</datetime><datetime dst='true'>20040929T162105,66+03</datetime></revisions> <item name='customerNumber'><text>3</text></item> <item name='employeeTotal'><number>51</number></item> <item name='ownerNumber'><text>21</text></item> <item name='Comments'><richtext> <pardef id='1' leftmargin='1in' tabs='L0.5000in L1in L1.5000in L2in L2.5000in L3in L3.5000in L4in'/> <par def='1'/></richtext></item> <item name='Owner' authors='true' names='true'><text>Anonymous</text></item> <item name='customerName'><text>Doe Inc.</text></item> <item name='customerAddress'><text>55 Cambridge Parkway (modified) (modified) (modified) (modified Wed Sep 29 16:23:09 EEST 2004)</text></item> <item name='DateCreated'><datetime dst='true'>20030507T180551,11-04</datetime></item> <item name='DateModified'><datetime>20030521T124559,07-05</datetime></item> <item name='$$Return'><text>Thank you! This record has been saved. <br><a href=/apps/CUSTOMER.NSF/all/462E6D6DE88ED7FB85256D1F007962A7?OpenDocument>Op en saved record</a></text></item> <item name='ownerNameFormat'><text>Salkosuo, Sami</text></item> <item name='ownerName'><text>Sami Salkosuo</text></item></document> Java programs can use XML with any XML parser or just extract one piece of data from the XML document. Note: Domino XML supports file attachments in Rich Text fields. A file attachment would be presented as Base64 encoded String in <filedata> element. It is also possible to read Domino views using the command ReadViewEntries in URL. This allows applications to access Domino view data using HTTP without any Domino specific APIs. For example: http://domino651.swic.fi.ibm.com/redbook/customer.nsf/CustomersByName?ReadViewE ntries would give view data as XML, as in Example 5-9 on page 379. 378 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 5-9 Domino View as XML <?xml version="1.0" encoding="UTF-8"?> <viewentries toplevelentries="27"> <viewentry position="1" unid="00397BCDE805B8B7C2256F1A002F982F" noteid="A72" siblings="27"> <entrydata columnnumber="0" name="customerName"> <text>83 838383</text></entrydata> <entrydata columnnumber="1" name="customerNumber"> <text>22</text></entrydata> <entrydata columnnumber="2" name="ownerName"> <text>John Smith</text></entrydata> </viewentry> <viewentry position="2" unid="53C06EA9F3AAE5D085256D2D00615C36" noteid="956" siblings="27"> <entrydata columnnumber="0" name="customerName"> <text>After portal</text></entrydata> <entrydata columnnumber="1" name="customerNumber"> <text>7</text></entrydata> <entrydata columnnumber="2" name="ownerName"> <text>Bob Smith</text></entrydata> </viewentry> . . . <viewentry position="27" unid="8D7EB55B2C925B5685256D1F0076E9F2" noteid="8FA" siblings="27"> <entrydata columnnumber="0" name="customerName"> <text>WP Experts</text></entrydata> <entrydata columnnumber="1" name="customerNumber"> <text>16</text></entrydata> <entrydata columnnumber="2" name="ownerName"> <text>Gary Someone</text></entrydata> </viewentry> </viewentries> 5.7.5 Collaborative Services API Collaborative Services are a set of methods and JSP tags that allow developers who are writing portlets for WebSphere Portal or other application servers to add Lotus collaborative functionality to their portlets. Collaborative Services may be used to develop new custom portlets or to add collaborative functionality (menus or people links indicating online status, for example) to existing portlets. Collaborative Services are designed to provide access to the functionality of Domino and Extended products that are enabled to work as companion products to WebSphere Portal. As such, the methods provided by Collaborative Services Chapter 5. Portlet development using Java: Technology review 379 complement - not replace - the APIs of the individual Domino and Extended products, such as the Domino Java API and the Discovery Server KDSAPI. Benefits of Collaborative Services Collaborative Services provide standardized access to applications, easy-to-use APIs that are optimized for a collaborative portal, and a consistent security model across all Domino and Extended products. All of the Collaborative Services, except the people and menu tags, are user interface-neutral; that is, the portlet developer can design the user interface for the collaborative features they are implementing. The goal of Collaborative Services is to provide the data necessary for rendering the user interface and to allow the developer to execute actions on the Domino and Extended products that have been installed and enabled in the portal environment. The Java APIs in Collaborative Services contain no platform-specific code. Consequently, the components are UI-neutral and are not dependent on implementation details. Because they are UI-neutral, the Collaborative Services can be used to implement pervasive applications for mobile and wireless devices. Because Collaborative Services hide the configuration details of the Domino and Extended products that are installed within an enterprise, collaborative functionality can be easily added to a portlet in a generic way - regardless of the physical requirements and machine-dependent details of portal configuration. See WebSphere Portal InfoCenter for more information, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html 5.7.6 Web services A Domino application can have a Web service interface that allows it to be accessed as a Web Service by remote users, Web server clients or applications. Providing a Web service interface for Domino application is out of scope of this redbook but for the curious readers here's what you need to include in your Domino application: A LotusScript Web agent. The Web agent is written to accept a SOAP request, parse it, call the requested method (function), and return the result as a SOAP response to the requester. Any standard LotusScript function stored in a script library. A page containing the WSDL definition of the service. 380 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5.7.7 WSRP Web Services for Remote Portlets (WSRP) is a standard for content and application providers to provide their services to organizations that are running portals in an easily consumable form. By virtue of the common, well-defined WSRP interfaces, all Web services that implement WSRP plug in to all WSRP-compliant portals without requiring any service-specific adapters. A single, service-independent adapter on the portal side is sufficient to integrate any WSRP services. With WSRP, integrating content and applications into portals is made easier. No custom programming effort using a variety of different interfaces and protocols is required. Portal administrators no longer have to write interface code to adapt the WSRP services for their portal. Services deliver content to the client portal along with the presentation information so that the WSRP services appear and operate to portal users exactly like local portlets. 5.8 Portal application design guidelines Portlets and pages are the basic building blocks of portal applications. They provide the sub-units of user experience that are aggregated by the portal application to provide the final user experience. Portlets are packaged into portlet applications, which are similar to J2EE Web applications, except they make use of additional interfaces that make it easier to aggregate portlets onto a single page. The packaging format of portlet applications is the Web Archive (WAR) format, which, in addition to the web.xml, includes the portlet.xml deployment descriptor, which defines the portlet relevant parts of the Web application. A single portlet produces the content of one portlet window. In order to leverage the flexibility where portlets can be used as building blocks, portlet application developers should strive for small portlets that contain a specific function instead of one large portlet that includes all functions. Using small, specific portlets has several advantages: The portal end user can decide to only put the needed parts on the page and save space that otherwise would be occupied by parts that are not needed. The different functions can be split across portal pages to suit the working behavior of the user, and can adapt to limited device display capabilities. Additional functions can be added later as new portlets, without touching the existing running portlet. Chapter 5. Portlet development using Java: Technology review 381 Portlets that belong to the same logical application should be bundled together in a portlet application, providing several advantages over the approach of one portlet per portlet application. The advantages include the ability to share configuration data and session data, and the ease of deployment and administration. 5.8.1 Introduction to object-oriented design patterns Design patterns are common strategies for developing reusable object-oriented components. Each pattern describes a problem that occurs over and over again in a particular environment, and then describes the core of the solution to that problem in such a way that this solution can be used a million times over, without ever doing it the same way twice. This definition, from Christopher Alexander, shows perfectly the idea of the patterns. We now consider patterns for components design. The patterns that we show in this section can be used in other solutions and in other programming languages. Design patterns can exist at many levels—from a very low level, to specific solutions, to broadly generalized system issues. There are now hundreds of patterns in the literature; they have been discussed in articles and in conferences at all levels of granularity. Design patterns began to be recognized more formally in the early 1990s by Helm (1990) and Erich Gamma (1992), who described patterns incorporated in the GUI application framework and published the book Design Patterns Elements of Reusable Software, by Gamma, et al. This book, commonly referred to as the Gang of Four or “GoF” book, has had a powerful impact on those seeking to understand how to use Design patterns and has become an all-time best seller. The authors divided the patterns into three categories: creational, structural, and behavioral. Creational patterns are those that create objects for you, rather than having you instantiate objects directly. This gives your program more flexibility in deciding which objects need to be created for a given case. Structural patterns help you compose groups of objects into larger structures, such as complex user interfaces or accounting data. Behavioral patterns help you define the communication between objects in your system and how the flow is controlled in a complex program. 382 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The patterns described here provide the main concepts of the most common patterns that we can use in portal application development: Singleton Factory Abstract Factory Proxy Decorator Command Facade Model-View-Controller Singleton This is a creational pattern that is used to ensure that a class has only one instance, and to provide a global point of access to it. This pattern is interesting when you want to keep track of a sole instance. You can use this in many ways, for example, when you want to load application variables from a file or control the access to components. The easiest way to make a class that can have only one instance is to embed a static variable inside the class that we set on the first instance and check each time we enter the constructor. A static variable is one for which there is only one instance, no matter how many instances there are of the class. For example: static boolean instance_flag =false; The problem is how to discover whether or not creating an instance was successful, since constructors do not return values. One way would be to call a method that checks for the success of creation, and which simply returns some value derived from the static variable. Another approach, suggested by Design Patterns, is to create Singletons using a static method to issue and keep track of instances. To prevent instantiating the class more than once, we make the constructor private so an instance can only be created from within the static method of the class. Factory This is a creational pattern that is used to define an interface for creating an object, but lets subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses. This approach can be found in EJB technology for home and remote classes. Chapter 5. Portlet development using Java: Technology review 383 A Factory pattern is one that returns an instance of one of several possible classes depending on the data provided to it. Usually, all of the classes it returns have a common parent class and common methods, but each of them performs a task differently and is optimized for different kinds of data. Abstract Factory This is a creational pattern that provides an interface for creating families of related or dependent objects without specifying their concrete classes. This approach can be found in EJB technology for home and remote classes. The Abstract Factory pattern is one level of abstraction higher than the Factory pattern. You can use this pattern when you want to return one of several related classes of objects, each of which can return several different objects upon request. In other words, the Abstract Factory is a factory object that returns one of several Factories. Proxy This is a structural pattern that provides a surrogate or placeholder for another object to control access to it. The Proxy pattern is used when you need to represent a complex object with a simpler one. If creating an object is expensive in terms of time or computer resources, Proxy allows you to postpone this creation until you need the actual object. A Proxy usually has the same methods as the object it represents, and once the object is loaded, it passes on the method calls from the Proxy to the actual object. This approach can be found in remote implementation of EJB technology. Decorator This is a structural pattern that attaches additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality. The Decorator pattern provides a way to modify the behavior of individual objects without having to create a new derived class. Suppose we have a program that uses eight objects, but three of them need an additional feature. You could create a derived class for each of these objects, and in many cases this would be a perfectly acceptable solution. However, if each of these three objects requires different modifications, this would mean creating three derived classes. Further, if one of the classes has features of both of the other classes, you begin to create a complexity that is both confusing and unnecessary. 384 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 We can see this applicability in the portlet API. We have one skin for each portlet and the skin has some functionality, such as resizing the portlet, call edit mode for personalization issues, and so on. In a portlet development, you extend the AbstractPortlet and do not care how the engine implements this class. In other words, it is totally transparent for portlet developers. Command This is a behavioral pattern that encapsulates a request as an object, thereby letting you parameterize clients with different queue or log requests. The Command pattern forwards a request to a specific module. It encloses a request for a specific action inside an object and gives it a known public interface. It lets you give the client the ability to make requests without knowing anything about the actual action that will be performed, and allows you to change that action without affecting the client program in any way. Facade This is a structural pattern that provides a unified interface to a set of interfaces in a subsystem. Facade defines a higher-level interface that makes the subsystem easier to use. Usually, as programs are developed, they grow in complexity. In fact, for all the excitement about using Design patterns, these patterns sometimes generate so many classes that it is difficult to understand the program’s flow. Furthermore, there may be a number of complicated subsystems, each of which has its own complex interface. The Facade pattern allows you to reduce this complexity by providing a simplified interface to these subsystems. This simplification may in some cases reduce the flexibility of the underlying classes. Model-View-Controller A design pattern particularly useful for Portlet applications is the Model-View-Controller or MVC pattern (see Figure 5-15 on page 387). A number of different types of skills and tools are required to implement various parts of a Web application. For example, the skills and tools required to design an HTML page are vastly different from those required to design and develop the business logic part of the application. In order to effectively leverage these scarce resources and to promote reuse, we recommend structuring Web applications to follow the Model-View-Controller design pattern. Chapter 5. Portlet development using Java: Technology review 385 Model represents the application object that implements the application data and business logic. The View is responsible for formatting the application results and dynamic page construction. The Controller is responsible for receiving the client request, invoking the appropriate business logic, and based on the results, selecting the appropriate view to be presented to the user. The Model represents enterprise data and the business rules that govern access to and updates to this data. Often the Model serves as a software approximation to a real-world process, so simple real-world modeling techniques apply when defining the Model. A View renders the contents of a Model. It accesses enterprise data through the Model and specifies how that data should be presented. It is the View's responsibility to maintain consistency in its presentation when the Model changes. This can be achieved by using a push Model, where the View registers itself with the Model for change notifications, or a pull Model, where the View is responsible for calling the Model when it needs to retrieve the most current data. A Controller translates interactions with the View into actions to be performed by the Model. In a stand-alone GUI client, user interactions could be button clicks or menu selections, while in a Web application, they appear as GET and POST HTTP requests. The actions performed by the Model include activating business processes or changing the state of the Model. Based on the user interactions and the outcome of the Model actions, the Controller responds by selecting an appropriate View. 386 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 5-15 The Model-View-Controller design pattern 5.8.2 Design principles The correct portlet design is broken down into three distinct parts: the model, the view, and the controller (MVC). This design follows classical object oriented design patterns where each part is self-contained and modular, easing maintenance, extensions, and advancements. The model is the data to which the portlet provides an interface. Common data models are XML documents, database tables, and even other Web applications. The Java classes accessing the data model should have no knowledge of the form that the data is in, the idea being that the model can be changed without affecting the rest of the portlet application. The view is the interface to the data model, presenting it in some usable format. The view accesses the data to be rendered through the model interfaces, and therefore, does not care what format the model takes. It should also not understand the relationships between data models or represent any of the business logic for manipulating the data. Like the data model, the view should be independent and interchangeable, allowing other views to be substituted without Chapter 5. Portlet development using Java: Technology review 387 affecting the business logic or the model. The typical embodiment of the view is through series of Java Server Pages (JSPs), but it can also render using other techniques such as using XSL stylesheets to format XML documents. The controller is the glue that ties the model to the view and defines the interaction pattern in the portlet. The controller handles user requests from the view and passes control to the appropriate model objects to complete the requested action. The results of the action are then rendered back to the user by the controller using appropriate view objects and, perhaps, model objects which represent the data results of the completed action. The controller resides in the portlet Java classes. It knows the data model only through the model interfaces and it knows the view only in that it dispatches the view to render the data. Therefore, the controller logic can be just as easily replaced as the view and the model. As you design your portlets, it is extremely important to hold true to the MVC design principles. Portlets typically evolve over time and are largely reused as basis for new portlets. The ability to adapt a portlet to a new back-end data provider, or add markup support for mobile devices, or enhance the portlet to include user personalization, requires that each part of the portlet be self-contained and extensible. For portlet development guidelines, consult Appendix A, “General portlet development guidelines” on page 723. 5.9 Additional information Internet links Apache Logging http://logging.apache.org Jakarta Commons Pool http://jakarta.apache.org/commons/pool/ JSR 52: A Standard Tag Library for JavaServer Pages http://www.jcp.org/en/jsr/detail?id=52 JSR 127: JavaServer Faces http://www.jcp.org/en/jsr/detail?id=127 JSR 168: Portlet specification http://www.jcp.org/en/jsr/detail?id=168 388 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Lotus Domino Designer Help by versions http://www-10.lotus.com/ldd/notesua.nsf/find/designer New to WebSphere Portal http://www-106.ibm.com/developerworks/websphere/zones/portal/newto/ Struts home page http://struts.apache.org/ Technical resources for Lotus software http://www-136.ibm.com/developerworks/lotus/ Web Service for Remote Portlets specification http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp Web services introduction http://www-106.ibm.com/developerworks/webservices/newto/websvc.html WebSphere Portal Product Documentation; has InfoCenters for various Portal versions http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html WebSphere Portal Zone in IBM developerWorks http://www-106.ibm.com/developerworks/websphere/zones/portal/ Redbooks Domino Designer 6: A Developer's Handbook, SG24-6854 IBM WebSphere Portal V5 A Guide for Portlet Application Development, SG24-6076 A Portal Composite Pattern Using WebSphere Portal V5, SG24-6087IBM WebSphere Portal for Multiplatforms V5 Handbook, SG24-6098 WebSphere Studio 5.1.2 JavaServer Faces and Service Data Objects, SG24-6361 Redpaper Portal Application Design and Development Guidelines, REDP-3829 Chapter 5. Portlet development using Java: Technology review 389 390 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6 Chapter 6. Portlet development using Java: Integration examples In this chapter, we show how to portalize a Domino application using methods described in Chapter 5, “Portlet development using Java: Technology review” on page 313. We develop portlets using the IBM Portlet API, Struts, JSF, and JSR 168. We access Domino using our own DominoAccess class and we use object pooling, logging, Click-to-Action (introduced in 4.6, “Integration via Click-to-Action” on page 287), awareness (introduced in 4.7, “Integration via people awareness” on page 303), Credential Vault, and single sign-on capabilities in WebSphere Portal and Domino integration. WebSphere Studio Application Developer is briefly introduced before we move to integration examples. The goals of this chapter are to: Give an understanding of different methods available for portlet development Show how to develop portlets using WebSphere Studio Application Developer Give a functional example as a starting point for developing portlet applications © Copyright IBM Corp. 2005. All rights reserved. 391 This chapter does not give you inside details on how portlets, Struts, or JSF work behind the scenes. You will learn the basics of how they work while developing the samples and a curious reader will find enough information about Struts, JSF, and other technologies from the Internet and from other publications. 392 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.1 WebSphere Studio Application Developer At the time of the writing of this redbook, the current version of WebSphere Studio Application Developer (WSAD) is 5.1.2 and that is the tool we use in this chapter. WebSphere Studio Application Developer provides the tools you need to create, develop, test, and manage all of the resources involved with building Web and enterprise-scale J2EE and Web services applications. Customizable perspectives (views of the development resources and an organization of the desktop) let Web developers, Java programmers, EJB developers, and administrators share the same development tool. At the heart of Application Developer are creation tools, editors, wizards, templates, and code generators that help you rapidly develop J2EE resources such as HTML files, JSP pages, Java classes and servlets, EJB beans, and XML deployment descriptors. You organize these resources into projects that correspond to modules defined in the J2EE specification. Once the resources have been created, you can easily test and debug them within the development environment, or export and test them on a remote server. Some features: Built on Eclipse, an open, industry-supported platform for development tools, WebSphere Studio Application Developer enables you to adapt and extend your development environment with best-of-breed plug-in tools from IBM, IBM Business Partners, and the Eclipse community, to match your needs and to maximize developer productivity. Rapidly develop portal applications using visual portlet tools that support JavaServer Faces components for rich user interfaces and the Struts framework for visualizing application flows and ensuring maintainability. Quickly test portal applications using the IBM WebSphere Portal unit test environment. Accelerate Web development and make your applications easier to maintain using Struts tools for visually mapping and constructing applications. Streamline application testing with visual debuggers and built-in unit test environments for IBM WebSphere Application Server, WebSphere Portal, and Apache Tomcat. WSAD also includes Portal Toolkit, which provides the capabilities to customize, create, test, debug, and deploy individual portlets and Web content. Chapter 6. Portlet development using Java: Integration examples 393 Some Portal Toolkit features: Portlet development and debugging support for WebSphere Portal V5.0.2.1. Portlet project supporting IBM portlet API and JSR 168 portlet API Portlet project wizard to create basic portlets, Faces portlets, and Struts portlets Figure 6-1 shows WSAD and Struts tool in action. Figure 6-1 WSAD and Struts tool in action See also “Technologies involved” on page 177 for introduction to J2EE and JSP and 4.3, “Software and tools used” on page 186 for additional introduction to the tools used in this chapter. 394 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.2 Portalization project This chapter presents a sample portalization project. We have an existing Sales Tracking Domino application and our task is to develop a portal application for it. The portalization project consists of two parts: the first part is to develop a simple but functional portal application for the Customers database. The other part of the project is technology evaluation. Developing with IBM Portlet API is basically the first part, while the technology evaluation is done with Struts, JSF, and JSR 168. 6.2.1 Sales Tracking Domino application The Sales Tracking Domino application was introduced in 2.3, “Case study: A simple sales tracking application” on page 77 and forms and fields of the application are described in Appendix B, “Data dictionary for case study” on page 735. However, in some cases, the data dictionary may not be available and even application documentation may not be available. The Domino Designer can be used to get information about forms and fields in the Domino application (see Figure 6-2 on page 396). Chapter 6. Portlet development using Java: Integration examples 395 Figure 6-2 Domino Designer Domino Designer is not a difficult tool to use, and even if your Domino knowledge is limited, the basics of the Domino Designer can be learned quickly. Developing Domino applications is a different matter and out of the scope of this redbook. For this topic, we recommend reviewing the redbook Domino Designer 6, A Developer’s Handbook, SG24-6854, found at: http://www.redbooks.ibm.com/abstracts/sg246854.html In some situations, it may be the case that Domino Designer is not even available and all we have is a customer who has a Domino application and they want it available in the WebSphere Portal. For this task, we need to have a Notes client and access to an application we want to portalize. The Notes client can be used to view application documents, views, and fields. Fields in a document can be viewed by right-clicking any document and selecting Document properties (see Figure 6-3 on page 397). 396 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-3 Document properties 6.2.2 Portal application functionality The following section describes the portlets which were created using each of the different Java based API approaches to achieve the overall desired Portal functionality. IBM Portlet API We developed three portlets using the IBM Portlet API (see Figure 6-4 on page 398). Chapter 6. Portlet development using Java: Integration examples 397 Figure 6-4 IBM Portlet API portlets basic and simplified functionality CustomersPortlet lists customers from Domino database. Five customers per page are listed using a paging feature. Customers can be listed using a search. Clicking the customer name sends a portlet message to CustomerDetailsPortlet. CustomerDetailsPortlet is used to add, edit, and delete customers. Saving and deleting a customer sends a message to CustomersPortlet to update a customer list. CustomerDetailsPortlet can receive messages and it uses them to open a company for editing. CustomerContactsPortlet lists all customer contacts five contacts per page. Clicking a customer contact’s company name sends a message to CustomerDetailsPortlet. Portal application authenticates with Domino in one of two ways: single sign-on or user name/password. Credential Vault is used to store user names and passwords. CustomersPortlet has a configure mode for setting Domino host and database locations. Awareness is enabled for CustomersPortlet. 398 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Struts We developed one portlet with Struts. The Struts portlet example is a combination of CustomersPortlet and CustomerDetailsPortlet in the IBM Portlet API application (see Figure 6-5). Figure 6-5 Struts portlet: basic and simplified functionality The purpose of the Struts section is to show how to develop portlets using WSAD and the Struts framework. JSF We developed one portlet with JSF. The functionality of the portlet is the same as in the Struts portlet. This section will show how to develop portlets with JSF and tools provided by WSAD. JSR 168 We developed one simple JSR 168 portlet. The functionality of the portlet is limited to searching a customer from database. JSR 168 portlet is also an example of how to view a image from a RichTextItem in a Domino document (see Figure 6-6 on page 400). Chapter 6. Portlet development using Java: Integration examples 399 Figure 6-6 JSR 168 portlet, basic and simplified functionality 6.3 Accessing Domino data The first thing we want is to have means to access data in a Domino database. For that, we decided to write a custom class for accessing Domino database and beans to represent the data. 6.3.1 DominoAccess project The first thing we do is to create a WSAD project for our project. 1. Start WebSphere Studio Application Developer. 2. Click File → New → Project and the New project wizard opens 3. Select Java → Java Project (as shown in Figure 6-7 on page 401). 400 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-7 New project wizard 4. Click Next. 5. Enter DominoAccess for the project name. 6. Click Finish. If a dialog box asks to change to the Java perspective, click Yes. WSAD creates a new Java project in the workspace (see Figure 6-8 on page 402). Chapter 6. Portlet development using Java: Integration examples 401 Figure 6-8 DominoAccess project in WSAD workspace Before starting to write code for the DominoAccess classes, we need additional classes for our project: NCSO.jar has all the Java classes for accessing Domino server. This jar file is located on the Domino server in the Domino installation directory. In order to find it, search the file system for NCSO.jar. Important: Make sure that NCSO.jar file is copied from Domino Server Version 6.5.2 or later. Domino V6.5 introduced new classes and methods to Java API that we need in this project. commons-pool-1.1.jar has an implementation of Jakarta Commons Pool. This can be downloaded from the Jakarta Commons Pool site (http://jakarta.apache.org/commons/pool/); download Version 1.1 or later. commons-collections-3.0.jar has classes that are used by Jakarta Commons Pool. Download commons collections from the Jakarta Commons Collections site (http://jakarta.apache.org/commons/collections/); download Version 3.0 or later. 402 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 7. In WSAD, select DominoAccess project and right-click. Select Properties → Java Build Path. 8. Select the Libraries tab and click Add External JARs. Select NCSO.jar, commons-pool-1.1.jar, and commons-collections-3.0.jar, and add them to build path (see Figure 6-9). Figure 6-9 External jars in Java build path 6.3.2 DominoSessionFactory Next, we develop a DominoSessionFactory for our session pool. It uses and extends classes from Jakarta Commons Pool, which are documented in the Commons Pool documentation. The documentation also describes how the pool works. 1. In the WSAD, right-click DominoAccess project and select New → Class (see Figure 6-10 on page 404). Chapter 6. Portlet development using Java: Integration examples 403 Figure 6-10 Create new class in WSAD 2. Enter com.ibm.itso.cam.redbooks.sg246466.domino as the package name and DominoSessionFactory as the class name (Figure 6-11 on page 405). 404 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-11 Create DominoSessionFactory class 3. Click Finish. WSAD creates the class file and opens it. We see that the class was generated using a predefined template (Figure 6-12 on page 406). Chapter 6. Portlet development using Java: Integration examples 405 Figure 6-12 DominoSessionFactory class template 4. We do not worry about the template and we write our DominoSessionFactory using the built-in editor or some other text editor (see Example 6-1). Example 6-1 DominoSessionFactory.java package com.ibm.itso.cam.redbooks.sg246466.domino; import lotus.domino.*; import org.apache.commons.pool.*; import java.util.*; public class DominoSessionFactory extends BaseKeyedPoolableObjectFactory { public Object makeObject(Object key) throws Exception { Session s; StringTokenizer keyString = new StringTokenizer((String) key, ":"); String host = keyString.nextToken(); String userNameOrLTPAToken = keyString.nextToken(); try { String password = keyString.nextToken(); 406 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 s = NotesFactory.createSession(host, userNameOrLTPAToken, password); } catch (NoSuchElementException e) { s = NotesFactory.createSession(host, userNameOrLTPAToken); } return s; } public void destroyObject(Object key, Object obj) throws Exception { Session s = (Session) obj; s.recycle(); super.destroyObject(key, obj); } } DominoSessionFactory explained DominoSessionFactory extends BaseKeyedPoolableObjectFactory from the Commons Pool. BaseKeyedPoolableObjectFactory is implementation of the interface KeyedPoolableObjectFactory and that is an interface defining life-cycle methods for instances to be served by a KeyedObjectPool. Refer to the Commons Pool API documentation for details, found at: http://jakarta.apache.org/commons/pool/ DominoSessionFactory implements two methods: public Object makeObject(Object key) throws Exception public void destroyObject(Object key, Object obj) throws Exception makeObject() creates an instance that can be served by the pool. It takes a key as a parameter, which is used when constructing the object. In the DominoSessionFactory implementation, a key is a string in one of two formats: dominoHost:userName:password dominoHost:LTPATokenString Implementation extracts a Domino host address and username/password or LTPA token string and uses them to create a session to Domino with NotesFactory class. A Session object is returned. destroyObject() destroys an instance that is no longer needed by the pool. It takes two parameters: key, which is the key used when selecting the instance, and obj, which is the instance to be destroyed. As seen in the implementation, Chapter 6. Portlet development using Java: Integration examples 407 a Domino Session object is received and its recycle() method is called in order to release resources in the Domino server. This implementation creates a pool for every user and it uses a user’s credentials to access Domino databases. When opening a Domino database, access may or may not be allowed, depending on the access control of each user. 6.3.3 CustomerBean The next class we develop is CustomerBean. This JavaBean represents one customer in a database. Its fields are populated with values from the Customer form in the Sales Tracking Domino application. 1. Using WSAD, create a new class in the DominoAccess project. Use the package com.ibm.itso.cam.redbooks.sg246466.domino and the class name CustomerBean. 2. Replace the template code with the code in Example 6-2. Example 6-2 CustomerBean.java package com.ibm.itso.cam.redbooks.sg246466.domino; public class CustomerBean { String name = ""; String customerNumber = ""; String accountOwner = ""; String address = ""; int employeeTotal = 0; String additionalInformation = ""; String noteId = null; public String getNoteId() { return noteId; } public void setNoteId(String newNoteId) { this.noteId = newNoteId; } public String getAdditionalInformation() { return additionalInformation; } public void setAdditionalInformation(String newAdditionalInformation) 408 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 { this.additionalInformation = newAdditionalInformation; } public int getEmployeeTotal() { return employeeTotal; } public void setEmployeeTotal(int newEmployeeTotal) { this.employeeTotal = newEmployeeTotal; } public String getAddress() { return address; } public void setAddress(String newAddress) { this.address = newAddress; } public String getAccountOwner() { return accountOwner; } public void setAccountOwner(String newAccountOwner) { this.accountOwner = newAccountOwner; } public String getCustomerNumber() { return customerNumber; } public void setCustomerNumber(String newCustomerNumber) { this.customerNumber = newCustomerNumber; } public String getName() { return name; } public void setName(String newName) Chapter 6. Portlet development using Java: Integration examples 409 { this.name = newName; } } 6.3.4 CustomerContactBean The next class is CustomerContactBean, and its values are populated with values from the Customer Contact form in the Sales Tracking Domino application. 1. Using WSAD, create a new class in the DominoAccess project. Use the package com.ibm.itso.cam.redbooks.sg246466.domino and the class name CustomerContactBean (Example 6-3). Example 6-3 CustomerContactBean.java package com.ibm.itso.cam.redbooks.sg246466.domino; public class CustomerContactBean { String name = ""; String employerNumber = ""; String phone = ""; String address = ""; String title = ""; String additionalInformation = ""; String noteId = null; public String getNoteId() { return noteId; } public void setNoteId(String newNoteId) { this.noteId = newNoteId; } public String getAdditionalInformation() { return additionalInformation; } public void setAdditionalInformation(String newAdditionalInformation) { this.additionalInformation = newAdditionalInformation; } 410 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 public String getTitle() { return title; } public void setTitle(String newTitle) { this.title = newTitle; } public String getAddress() { return address; } public void setAddress(String newAddress) { this.address = newAddress; } public String getPhone() { return phone; } public void setPhone(String newPhone) { this.phone = newPhone; } public String getEmployerNumber() { return employerNumber; } public void setEmployerNumber(String newEmployerNumber) { this.employerNumber = newEmployerNumber; } public String getName() { return name; } public void setName(String newName) { this.name = newName; } Chapter 6. Portlet development using Java: Integration examples 411 } 6.3.5 SalesPersonBean This class is populated with values from the Sales Person Form. The sales persons are used as account owners for customers. 1. Create a SalesPersonBean class (Example 6-4). Example 6-4 SalesPersonBean.java package com.ibm.itso.cam.redbooks.sg246466.domino; public class SalesPersonBean { String name = ""; String employeeNumber = ""; String phone = ""; String region = ""; String title = ""; String additionalInformation = ""; String noteId = null; public String getNoteId() { return noteId; } public void setNoteId(String newNoteId) { this.noteId = newNoteId; } public String getAdditionalInformation() { return additionalInformation; } public void setAdditionalInformation(String newAdditionalInformation) { this.additionalInformation = newAdditionalInformation; } public String getTitle() { return title; } 412 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 public void setTitle(String newTitle) { this.title = newTitle; } public String getRegion() { return region; } public void setRegion(String newRegion) { this.region = newRegion; } public String getPhone() { return phone; } public void setPhone(String newPhone) { this.phone = newPhone; } public String getEmployeeNumber() { return employeeNumber; } public void setEmployeeNumber(String newEmployeeNumber) { this.employeeNumber = newEmployeeNumber; } public String getName() { return name; } public void setName(String newName) { this.name = newName; } } Chapter 6. Portlet development using Java: Integration examples 413 6.3.6 BeanUtils BeanUtils is a class that has utility methods related to the JavaBeans we use in this project, such as getting a sales person’s name based on a sales person’s employee number. 1. Create a BeanUtils class (Example 6-5). Example 6-5 BeanUtils.java package com.ibm.itso.cam.redbooks.sg246466.domino; public class BeanUtils { public static String getAccountOwnerName( String accountOwnerNumber, SalesPersonBean[] salesPersons) { for (int i = 0; i < salesPersons.length; i++) { if (salesPersons[i].getEmployeeNumber().equals(accountOwnerNumber)) { return salesPersons[i].getName(); } } return ""; } public static String getSalesPersonName( String salesPersonNumber, SalesPersonBean[] salesPersons) { return getAccountOwnerName(salesPersonNumber, salesPersons); } public static String getSalesPersonNoteId( String salesPersonNumber, SalesPersonBean[] salesPersons) { for (int i = 0; i < salesPersons.length; i++) { if (salesPersons[i].getEmployeeNumber().equals(salesPersonNumber)) { return salesPersons[i].getNoteId(); } } return ""; } 414 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 public static int nextCustomerNumber(CustomerBean[] customerBeans) { int maxCustomerNumber = 0; for (int i = 0; i < customerBeans.length; i++) { maxCustomerNumber = Math.max( maxCustomerNumber, Integer.parseInt(customerBeans[i].getCustomerNumber())); } return maxCustomerNumber + 1; } public static String getCustomerNumber( String customerName, CustomerBean[] customerBeans) { int maxCustomerNumber = 0; for (int i = 0; i < customerBeans.length; i++) { if (customerBeans[i].getName().equals(customerName)) { return customerBeans[i].getCustomerNumber(); } } return ""; } public static int nextEmployeeNumber(SalesPersonBean[] salesPersonBeans) { int maxSalesPersonNumber = 0; for (int i = 0; i < salesPersonBeans.length; i++) { maxSalesPersonNumber = Math.max( maxSalesPersonNumber, Integer.parseInt(salesPersonBeans[i].getEmployeeNumber())); } return maxSalesPersonNumber + 1; } public static String getCustomerName( String employerNumber, CustomerBean[] customerBeans) { for (int i = 0; i < customerBeans.length; i++) { if (customerBeans[i].getCustomerNumber().equals(employerNumber)) Chapter 6. Portlet development using Java: Integration examples 415 { return customerBeans[i].getName(); } } return ""; } public static String getCustomerNoteId( String employerNumber, CustomerBean[] customerBeans) { for (int i = 0; i < customerBeans.length; i++) { if (customerBeans[i].getCustomerNumber().equals(employerNumber)) { return customerBeans[i].getNoteId(); } } return ""; } public static String getAccountOwnerNumber( String accountOwnerName, SalesPersonBean[] salesPersonBeans) { for (int i = 0; i < salesPersonBeans.length; i++) { if (salesPersonBeans[i].getName().equals(accountOwnerName)) { return salesPersonBeans[i].getEmployeeNumber(); } } return ""; } public static String getSalesPersonNumber( String salesPersonName, SalesPersonBean[] salesPersonBeans) { return getAccountOwnerNumber(salesPersonName, salesPersonBeans); } } 416 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.3.7 DominoAccess Now that we have the beans we need, its time to implement the code that accesses the Domino server and generates CustomerBeans and CustomerContactBeans for us. We also want our DominoAccess class to add, edit, and delete customers in the Domino database. 1. Create a new class in the DominoAccess project. Use the package name com.ibm.itso.cam.redbooks.sg246466.domino and the class name DominoAccess (Example 6-6). Example 6-6 DominoAccess.java package com.ibm.itso.cam.redbooks.sg246466.domino; import import import import java.util.*; lotus.domino.*; org.apache.commons.pool.*; org.apache.commons.pool.impl.*; public class DominoAccess { private static DominoAccess dominoAccess = null; private KeyedObjectPool pool; public static String SALES_DB = "redbook/sales.nsf"; public static String CUSTOMER_DB = "redbook/customer.nsf"; public static String PRODUCTS_DB = "redbook/products.nsf"; private DominoAccess() { KeyedPoolableObjectFactory factory = new DominoSessionFactory(); pool = new GenericKeyedObjectPool(factory, 5); } public void destroy() { try { pool.close(); } catch (Exception e) { e.printStackTrace(); } } public static DominoAccess getInstance() { Chapter 6. Portlet development using Java: Integration examples 417 if (dominoAccess == null) { dominoAccess = new DominoAccess(); } return dominoAccess; } public CustomerBean[] getCustomersByName(String key, String name) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); DocumentCollection dc = customerDb.FTSearch( "(![Form]=\"Customer Contact\") AND ([Form]=\"Customer\") AND ([CustomerName] CONTAINS " + name + ")"); CustomerBean[] customers = getCustomers(dc); customerDb.recycle(); pool.returnObject(key, session); return customers; } public CustomerBean getCustomerByNoteId(String key, String noteId) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); Document doc = customerDb.getDocumentByID(noteId); CustomerBean customerBean = generateCustomerBean(doc); customerDb.recycle(); pool.returnObject(key, session); return customerBean; } public CustomerBean[] getCustomers(String key, String searchFormula) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); DocumentCollection dc = customerDb.search(searchFormula); CustomerBean[] customers = getCustomers(dc); customerDb.recycle(); 418 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 pool.returnObject(key, session); return customers; } public CustomerBean[] getCustomers(String key) throws Exception { return getCustomers(key, "Form = \"Customer\""); } private CustomerBean[] getCustomers(DocumentCollection dc) throws Exception { Vector customerBeans = new Vector(); Document doc = dc.getFirstDocument(); while (doc != null) { customerBeans.addElement(generateCustomerBean(doc)); doc = dc.getNextDocument(); } CustomerBean[] customers = new CustomerBean[customerBeans.size()]; customerBeans.copyInto(customers); return customers; } private CustomerBean generateCustomerBean(Document doc) throws Exception { CustomerBean customerBean = new CustomerBean(); customerBean.setName(doc.getItemValueString("CustomerName")); customerBean.setCustomerNumber(doc.getItemValueString("CustomerNumber")); customerBean.setAccountOwner(doc.getItemValueString("OwnerNumber")); customerBean.setAddress(doc.getItemValueString("CustomerAddress")); customerBean.setEmployeeTotal(doc.getItemValueInteger("EmployeeTotal")); customerBean.setAdditionalInformation(doc.getItemValueString("Comments")); customerBean.setNoteId(doc.getNoteID()); return customerBean; } public void deleteCustomer(String key, String noteId) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); Document doc = customerDb.getDocumentByID(noteId); doc.remove(true); customerDb.recycle(); pool.returnObject(key, session); Chapter 6. Portlet development using Java: Integration examples 419 } public void addNewCustomer(String key, CustomerBean customer) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); String noteId = customer.getNoteId(); Document doc = noteId != null ? customerDb.getDocumentByID(noteId) : customerDb.createDocument(); doc.replaceItemValue("Form", "Customer"); doc.replaceItemValue("CustomerName", customer.getName()); doc.replaceItemValue("CustomerNumber", customer.getCustomerNumber()); doc.replaceItemValue("OwnerNumber", customer.getAccountOwner()); doc.replaceItemValue("CustomerAddress", customer.getAddress()); doc.replaceItemValue( "EmployeeTotal", new Integer(customer.getEmployeeTotal())); RichTextItem additionalInformation = noteId != null ? (RichTextItem) doc.getFirstItem("Comments") : doc.createRichTextItem("Comments"); updateRichTextItem( additionalInformation, customer.getAdditionalInformation(), noteId == null); doc.computeWithForm(false, false); doc.save(true); customerDb.recycle(); pool.returnObject(key, session); } public CustomerContactBean[] getCustomerContacts(String key) throws Exception { return getCustomerContacts(key, "Form = \"Customer Contact\""); } public CustomerContactBean[] getCustomerContacts( String key, String searchFormula) throws Exception { 420 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); DocumentCollection dc = customerDb.search(searchFormula); CustomerContactBean[] customerContacts = getCustomerContacts(dc); customerDb.recycle(); pool.returnObject(key, session); return customerContacts; } private CustomerContactBean[] getCustomerContacts(DocumentCollection dc) throws Exception { Vector customerContactBeans = new Vector(); Document doc = dc.getFirstDocument(); while (doc != null) { customerContactBeans.addElement(generateCustomerContactBean(doc)); doc = dc.getNextDocument(); } CustomerContactBean[] customerContacts = new CustomerContactBean[customerContactBeans.size()]; customerContactBeans.copyInto(customerContacts); return customerContacts; } private CustomerContactBean generateCustomerContactBean(Document doc) throws Exception { CustomerContactBean customerContactBean = new CustomerContactBean(); customerContactBean.setName(doc.getItemValueString("ContactName")); customerContactBean.setEmployerNumber( doc.getItemValueString("CustomerNumber")); customerContactBean.setPhone(doc.getItemValueString("ContactPhone")); customerContactBean.setAddress(doc.getItemValueString("ContactAddress")); customerContactBean.setTitle(doc.getItemValueString("ContactJobTitle")); customerContactBean.setAdditionalInformation( doc.getItemValueString("Comments")); customerContactBean.setNoteId(doc.getNoteID()); return customerContactBean; } public SalesPersonBean[] getSalesPersons(String key) throws Exception Chapter 6. Portlet development using Java: Integration examples 421 { return getSalesPersons(key, "Form = \"Sales Person\""); } public SalesPersonBean[] getSalesPersons(String key, String searchFormula) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Vector salesPersonBeans = new Vector(); Database salesPersonDb = session.getDatabase(null, SALES_DB); DocumentCollection dc = salesPersonDb.search(searchFormula); Document doc = dc.getFirstDocument(); while (doc != null) { salesPersonBeans.addElement(generateSalesPersonBean(doc)); doc = dc.getNextDocument(); } salesPersonDb.recycle(); pool.returnObject(key, session); SalesPersonBean[] salesPersons = new SalesPersonBean[salesPersonBeans.size()]; salesPersonBeans.copyInto(salesPersons); return salesPersons; } private SalesPersonBean generateSalesPersonBean(Document doc) throws Exception { SalesPersonBean salesPersonBean = new SalesPersonBean(); salesPersonBean.setName(doc.getItemValueString("SName")); salesPersonBean.setEmployeeNumber(doc.getItemValueString("SNumber")); salesPersonBean.setPhone(doc.getItemValueString("SPhone")); salesPersonBean.setRegion(doc.getItemValueString("SRegion")); salesPersonBean.setTitle(doc.getItemValueString("STitle")); salesPersonBean.setAdditionalInformation( doc.getItemValueString("Comments")); salesPersonBean.setNoteId(doc.getNoteID()); return salesPersonBean; } private void updateRichTextItem( RichTextItem rtItem, String newText, boolean newItem) { try 422 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 { if (newItem) { rtItem.appendText(newText); } else { RichTextNavigator rtnav = rtItem.createNavigator(); //remove old text in rich text item while (rtnav.findFirstElement(RichTextItem.RTELEM_TYPE_TEXTRUN)) { RichTextRange rtRange = rtItem.createRange(); rtRange.setBegin(rtnav); String textRun = rtRange.getTextRun(); int replaced = rtRange.findandReplace( textRun, "", RichTextItem.RT_FIND_CASEINSENSITIVE + RichTextItem.RT_REPL_ALL + RichTextItem.RT_REPL_PRESERVECASE); rtnav = rtItem.createNavigator(); } //append new text rtItem.appendText(newText); } } catch (NotesException ne) { ne.printStackTrace(); } } //main-method for testing public static void main(String[] args) { try { DominoAccess dominoAccess = DominoAccess.getInstance(); String key = "domino651.swic.fi.ibm.com:test person:password"; CustomerBean[] customerBeans = dominoAccess.getCustomers(key); System.out.println("Total customers: " + customerBeans.length); for (int i = 0; i < customerBeans.length; i++) { System.out.print("[" + (i + 1) + "] " + customerBeans[i].getName()); System.out.print(" " + customerBeans[i].getCustomerNumber()); System.out.print(" " + customerBeans[i].getAccountOwner()); System.out.print(" " + customerBeans[i].getAddress()); Chapter 6. Portlet development using Java: Integration examples 423 System.out.print(" " + customerBeans[i].getEmployeeTotal()); System.out.println(" " + customerBeans[i].getAdditionalInformation()); } System.out.println(); CustomerContactBean[] customerContactBeans = dominoAccess.getCustomerContacts(key); System.out.println( "Total customer contacts: " + customerContactBeans.length); for (int i = 0; i < customerContactBeans.length; i++) { System.out.print( "[" + (i + 1) + "] " + customerContactBeans[i].getName()); System.out.print(" " + customerContactBeans[i].getEmployerNumber()); System.out.print(" " + customerContactBeans[i].getPhone()); System.out.print(" " + customerContactBeans[i].getAddress()); System.out.print(" " + customerContactBeans[i].getTitle()); System.out.println( " " + customerContactBeans[i].getAdditionalInformation()); } System.out.println(); dominoAccess.destroy(); } catch (Exception e) { e.printStackTrace(); } } } DominoAccess explained DominoAccess class is a singleton. We get an instance of this class using the getInstance() method. As we can see, the constructor creates a new pool using the DominoSessionFactory class. Domino databases are hardcoded in this class, but luckily we implemented them as public static variables so we can set them later during runtime. And that is exactly what we use in the portlets. 424 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Many methods are quite clear in their functionality, but we will go through a couple of methods: public CustomerBean[] getCustomers(String key, String searchFormula) throws Exception getCustomers() methods accepts two parameters: key and searchFormula. Key is used to get and create a Session pool, as we saw in DominoSessionFactory. searchFormula is a Notes @function formula that specifies the selection criteria. Method borrows a Session object from the pool and gets a customer database from the session. searchFormula is used to get matching documents from the database as a DocumentCollection. DocumentCollection is a parameter for private CustomerBean[] getCustomers(DocumentCollection dc) throws Exception, which loops through Documents in DocumentCollection and creates CustomerBean for each customer/Document and returns an array of CustomerBeans. Before returning the CustomerBean array to the application, the database is recycled and the session returned to pool. public void addNewCustomer(String key, CustomerBean customer) throws Exception The method addNewCustomer is used to edit customers in the database. As we implemented, we check whether CustomerBean’s noteId is null or not. If it is null, then we add a new document to the Domino database and fill in the fields in the Domino Customer form with values from the bean’s fields. If noteId was not null, it means that we are editing an existing document in Domino database and so we use the getDocumentbyID() method in the database. New values are added or replaced. If a document is new, we create a Rich Text field using the method createRichTextItem() in the Document object. Otherwise, we get an existing Rich Text field using getFirstItem(). Important: When getting an existing RichTextItem in a Document, it must be explicitly cast to RichTextItem: RichTextItem additionalInformation = (RichTextItem) doc.getFirstItem("Comments") Using either a new or existing RichTextItem, we call the method updateRichTextItem(). Notice that updateRichTextItem() has a boolean parameter of newitem. Adding text in a new item is simple and straightforward using the appendText() method in RichTextItem. Chapter 6. Portlet development using Java: Integration examples 425 Replacing the old text needs a little more coding. We basically replace the old text with an empty string and then append new text to RichTextItem. 6.3.8 Exporting DominoAccess We export DominoAccess classes to a JAR file that can be used in our portlet projects. 1. Right-click the DominoAccess project and select Export (Figure 6-13). Figure 6-13 Export project 2. The Export dialog opens. Select JAR File and click Next. 3. Select DominoAccess project and enter a destination and name for the file, for example, c:\temp\DominoAccess.jar (Figure 6-14 on page 427). 426 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-14 Export JAR 4. Click Finish. DominoAccess.jar is now exported and we import it to our portlet projects later. When we change classes in DominoAccess, we have to export jar file and import it again to our portlet projects. Note: The DominoAccess_Project.zip file has the DominoAccess project ready for importing to WSAD. See Appendix C, “Additional material” on page 741 for download instructions. Chapter 6. Portlet development using Java: Integration examples 427 6.4 Sales Tracking application using IBM Portlet API Now that we have classes to access Domino data, we can start developing the portal application. 6.4.1 SalesTrackingIBMAPI project First, we create a portlet project. 1. In WSAD, select File → New → Project → Portlet Project. Figure 6-15 should appear. 2. Enter the project name SalesTrackingIBMAPI. 3. Check the Configure advanced options check box. Figure 6-15 New portlet project wizard 4. Click Next to go to the J2EE settings page. 5. Enter DefaultEAR as the EAR project and select J2EE level 1.3. 6. Click Next. 7. Click Next in the Features Page. 428 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 8. In the Portlet Settings page: – Enter SalesTrackingIBMAPICustomers portlet as the Portlet name. – Enter SalesTrackingIBMAPICustomers portlet as the Portlet title. – Check Change code generation options. – Enter com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi as the Package prefix. – Enter CustomersPortlet as the Class prefix. 9. Click Next. 10.Uncheck Add action listener and click Next. 11.Click Next in the Single Sign-On page. 12.In the Miscellaneous page, check Add edit mode and Add configure mode. 13.Click Finish. WSAD generates a new portlet project (Figure 6-16). If you are asked to confirm the perspective switch, answer Yes. Figure 6-16 New portlet project Chapter 6. Portlet development using Java: Integration examples 429 We can see in the Project Navigator view that WSAD created several files in our project. The directory JavaResources has three Java files, one for the portlet and two beans. Under WebContent, there are three JSP files in the directory com_ibm_itso_cam_redbooks_sg246466_portlets_ibmapi/jsp/html. However, we do not need these (except CustomersPortlet, which we replace with our own code a little later), so we delete them. 14.Select directory com_ibm_itso_cam_redbooks_sg246466_portlets_ibmapi and right-click. Select Delete and click Yes confirm that we really want to delete. 15.Also, delete the files CustomersPortletConfigBean.java and CustomersPortletEditBean.java. We will get errors from CustomersPortlet.java, but it is nothing to worry about since we replace the code anyway. 16.We deleted JSP files, but we also deleted the JSP directory. So, we create a new directory by right-clicking WebContent and selecting New → Folder. Enter jsp as the folder name and click Finish. 17.Create the directory html under the jsp directory that we created in previous step. 18.Next, we add DominoAccess.jar, NCSO.jar, commons-pool-1.1.jar, and commons-collections-3.0.jar to the project. The easiest way to do this is to copy the jar files to the WEB-INF/lib directory and refresh the project. – Copy the jar files to the WEB-INF/lib directory located in <WSAD_workspace>/SalesTrackingIBMAPI/WebContent. – Right-click the SalesTrackingIBMAPI project and select Refresh. Refresh instructs WSAD to look for any changes to the project that have been made in the local file system by external tools. 19.We need also Jakarta Log4j classes. Download the latest release from http://logging.apache.org/log4j. In this project, we use Log4j Version 1.2.8, so we copy log4j-1.2.8.jar to WEB-INF/lib and refresh the project. WSAD wizards create a basic structure that we need in portlet development. It creates directories where we put source code and it creates web.xml and portlet.xml deployment descriptors in the WebContent/WEB-INF directory. It provides also templates for portlets, but we do not need them in this case. 430 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.4.2 CredentialVaultManager We start by writing a class that handles Credential Vault. 1. Select the SalesTrackingIBMAPI project and create a class named CredentialVaultManager with a package name of com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi. 2. WSAD creates the code from a template and opens it. Replace the template code with the code in Example 6-7. Example 6-7 CredentialVaultManager.java package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi; import org.apache.jetspeed.portlet.*; import import import import com.ibm.wps.portletservice.credentialvault.*; com.ibm.wps.portletservice.credentialvault.credentials.*; com.ibm.wps.util.ObjectID; java.util.*; public class CredentialVaultManager { public static void saveCredentials( CredentialVaultService credentialVaultService, String resourceName, PortletRequest portletRequest, String userName, char[] password) throws Exception { PortletData data = portletRequest.getData(); resourceName = resourceName + portletRequest.getUser().getID(); String slotId = (String) data.getAttribute(resourceName + "SlotID"); if (slotId == null) { slotId = slotExists(credentialVaultService, resourceName, portletRequest); } if (slotId == null) { ObjectID segmentID = credentialVaultService.getDefaultUserVaultSegmentId(); Map descripMap = new Hashtable(); Map keywordMap = new Hashtable(); int secretType = CredentialVaultService.SECRET_TYPE_USERID_STRING_PASSWORD_STRING; Chapter 6. Portlet development using Java: Integration examples 431 boolean active = false; //false=both active and passive credentials boolean portletPrivate = false; //false=shared between users portlets //create the slot CredentialSlotConfig slot = credentialVaultService.createSlot( resourceName, segmentID, descripMap, keywordMap, secretType, active, portletPrivate, portletRequest); slotId = slot.getSlotId(); } Portlet.Mode portletMode = portletRequest.getMode(); if (portletMode.equals(Portlet.Mode.EDIT)) { data.setAttribute("userName", userName); data.setAttribute(resourceName + "SlotID", slotId); data.store(); } // store credentials in vault credentialVaultService.setCredentialSecretUserPassword( slotId, userName, password, portletRequest); } public static String getUserNameAndPassword( CredentialVaultService credentialVaultService, String resourceName, PortletRequest portletRequest) throws Exception { PortletData data = portletRequest.getData(); resourceName=resourceName+portletRequest.getUser().getID(); String slotId = (String) data.getAttribute(resourceName + "SlotID"); if (slotId == null) { slotId = slotExists(credentialVaultService, resourceName, portletRequest); } 432 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 if (slotId == null) { return "noCredentials"; } UserPasswordPassiveCredential credential = (UserPasswordPassiveCredential) credentialVaultService.getCredential( slotId, "UserPasswordPassive", new Hashtable(), portletRequest); String userName = credential.getUserId(); String password = new String(credential.getPassword()); return userName + ":" + password; } private static String slotExists( CredentialVaultService credentialVaultService, String resourceName, PortletRequest portletRequest) throws Exception { Iterator iter = credentialVaultService.getAccessibleSlots(portletRequest); while (iter.hasNext()) { CredentialSlotConfig slot = (CredentialSlotConfig) iter.next(); String slotResourceName = slot.getResourceName(); if (slotResourceName.indexOf(resourceName) > -1) { return slot.getSlotId(); } } return null; } } Chapter 6. Portlet development using Java: Integration examples 433 CredentialVaultManager explained This class handles storing and retrieving user names and passwords using the Credential Vault portlet service. public static void saveCredentials(CredentialVaultService credentialVaultService, String resourceName, PortletRequest portletRequest, String userName, char[] password) throws Exception This method saves a user name and password to an existing slot or, if a slot does not exist, creates a new slot based on the parameter resourceName and the user’s ID. CredentialVaultService class has a method to create new slots in a WPS database. If the portlet is in edit-mode, the slot ID and user name are saved to the persistent PortletData. public static String getUserNameAndPassword(CredentialVaultService credentialVaultService, String resourceName, PortletRequest portletRequest) throws Exception This method is used to retrieve a user name and password for a specified resource. If a slot does not exist, the string “NoCredentials” is returned; otherwise, a user name and password are returned in the format “username:password”. 6.4.3 CustomersPortlet Now we write CustomersPortlet as follows: 1. Replace the template code of CustomersPortlet.java with the code in Example 6-8. Example 6-8 CustomersPortlet.java package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi; import java.io.IOException; import java.util.Iterator; import java.util.Set; import javax.security.auth.Subject; import import import import import import import import import 434 org.apache.jetspeed.portlet.DefaultPortletMessage; org.apache.jetspeed.portlet.Portlet; org.apache.jetspeed.portlet.PortletAdapter; org.apache.jetspeed.portlet.PortletApplicationSettings; org.apache.jetspeed.portlet.PortletConfig; org.apache.jetspeed.portlet.PortletContext; org.apache.jetspeed.portlet.PortletException; org.apache.jetspeed.portlet.PortletRequest; org.apache.jetspeed.portlet.PortletResponse; Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 import import import import import import import import import import org.apache.jetspeed.portlet.PortletSession; org.apache.jetspeed.portlet.UnavailableException; org.apache.jetspeed.portlet.event.ActionEvent; org.apache.jetspeed.portlet.event.ActionListener; org.apache.jetspeed.portlet.event.MessageEvent; org.apache.jetspeed.portlet.event.MessageListener; org.apache.log4j.DailyRollingFileAppender; org.apache.log4j.Level; org.apache.log4j.Logger; org.apache.log4j.PatternLayout; import com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean; import com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccess; import com.ibm.wps.portletservice.credentialvault.CredentialVaultService; public class CustomersPortlet extends PortletAdapter implements ActionListener, MessageListener { public static Logger LOGGER = null; public final static int ENTRIES_PER_PAGE = 5; private final static String RESOURCE_NAME = "SG246466SalesTrackingApplication"; private static CredentialVaultService CREDENTIAL_VAULT_SERVICE = null; public void init(PortletConfig portletConfig) throws UnavailableException { super.init(portletConfig); if (LOGGER == null) { String loggerName = portletConfig.getInitParameter("log4j.logger.name"); LOGGER = Logger.getLogger(getClass()); PatternLayout layout = new PatternLayout("%d %-6r [%15.15t] %-5p %30.30c %x - %m\n "); DailyRollingFileAppender appender = null; try { String logFile = portletConfig.getInitParameter("log.file"); appender = new DailyRollingFileAppender(layout, logFile, "'.'dd-MM-yyyy"); } catch (Exception e) { } LOGGER.addAppender(appender); LOGGER.setLevel((Level) Level.DEBUG); } } Chapter 6. Portlet development using Java: Integration examples 435 public void login(PortletRequest portletRequest) { PortletApplicationSettings applicationSettings = portletRequest.getPortletSettings().getApplicationSettings(); DominoAccess.CUSTOMER_DB = applicationSettings.getAttribute("customer.db"); DominoAccess.SALES_DB = applicationSettings.getAttribute("sales.db"); DominoAccess.PRODUCTS_DB = applicationSettings.getAttribute("product.db"); PortletSession portletSession = portletRequest.getPortletSession(); portletSession.setAttribute("pageIndex", new Integer(0)); accessDomino(portletRequest); } public void destroy(PortletConfig config) { DominoAccess.getInstance().destroy(); } public void doView( PortletRequest portletRequest, PortletResponse portletResponse) throws PortletException, IOException { if (portletRequest.getPortletSession().getAttribute("noCredentials") != null) { getPortletConfig().getContext().include( "/jsp/NoCredentials.jsp", portletRequest, portletResponse); return; } getPortletConfig().getContext().include( "/jsp/CustomersPortletView.jsp", portletRequest, portletResponse); } public void doEdit( PortletRequest portletRequest, PortletResponse portletResponse) throws PortletException, IOException { getPortletConfig().getContext().include( "/jsp/CustomersPortletEdit.jsp", portletRequest, 436 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 portletResponse); } public void doConfigure( PortletRequest portletRequest, PortletResponse portletResponse) throws PortletException, IOException { getPortletConfig().getContext().include( "/jsp/CustomersPortletConfig.jsp", portletRequest, portletResponse); } public void actionPerformed(ActionEvent event) throws PortletException { String action = event.getActionString(); PortletRequest portletRequest = event.getRequest(); PortletSession portletSession = portletRequest.getPortletSession(); if (action.equals("next")) { int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); pageIndex = pageIndex + ENTRIES_PER_PAGE >= ((CustomerBean[]) portletSession.getAttribute("customers")).length ? pageIndex : pageIndex + ENTRIES_PER_PAGE; portletSession.setAttribute("pageIndex", new Integer(pageIndex)); } if (action.equals("previous")) { int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); pageIndex = pageIndex - ENTRIES_PER_PAGE < 0 ? 0 : pageIndex - ENTRIES_PER_PAGE; portletSession.setAttribute("pageIndex", new Integer(pageIndex)); } if (action.equals("showDetails")) { DefaultPortletMessage dpm = new DefaultPortletMessage(portletRequest.getParameter("noteId")); getPortletConfig().getContext().send( Chapter 6. Portlet development using Java: Integration examples 437 "SalesTrackingIBMAPICustomerDetails portlet", dpm); } if (action.equals("searchCustomer")) { accessDomino(portletRequest); } if (portletRequest.getParameter("cancel") != null) { return; } if (action.equals("saveCredentials")) { try { CredentialVaultManager.saveCredentials( CREDENTIAL_VAULT_SERVICE, RESOURCE_NAME, portletRequest, portletRequest.getParameter("userName"), portletRequest.getParameter("password").toCharArray()); portletRequest.setAttribute("saveCredentialsResult", "Success"); portletRequest.setModeModifier(Portlet.ModeModifier.CURRENT); } catch (Exception e) { LOGGER.error(e.toString(), e); portletRequest.setAttribute("saveCredentialsResult", e.toString()); } } if (action.equals("saveConfiguration")) { String salesDb = portletRequest.getParameter("sales.db"); String customerDb = portletRequest.getParameter("customer.db"); String productDb = portletRequest.getParameter("product.db"); PortletApplicationSettings applicationSettings = portletRequest.getPortletSettings().getApplicationSettings(); applicationSettings.setAttribute( "domino.host.address", portletRequest.getParameter("domino.host.address")); applicationSettings.setAttribute("sales.db", salesDb); applicationSettings.setAttribute("customer.db", customerDb); applicationSettings.setAttribute("product.db", productDb); 438 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 applicationSettings.setAttribute( "use.single.signon", portletRequest.getParameter("use.single.signon")); DominoAccess.CUSTOMER_DB = customerDb; DominoAccess.SALES_DB = salesDb; DominoAccess.PRODUCTS_DB = productDb; try { applicationSettings.store(); } catch (Exception e) { LOGGER.error(e.toString(), e); } } } public void messageReceived(MessageEvent event) { PortletRequest portletRequest = event.getRequest(); PortletSession portletSession = portletRequest.getPortletSession(); DefaultPortletMessage message = (DefaultPortletMessage) event.getMessage(); if (message.getMessage().equals("reset")) { accessDomino(portletRequest); } } public static String getDominoSessionPoolKey( PortletContext portletContext, PortletRequest portletRequest) throws Exception { String dominoHost = portletRequest .getPortletSettings() .getApplicationSettings() .getAttribute( "domino.host.address"); boolean useSSO = Boolean .valueOf( portletRequest .getPortletSettings() .getApplicationSettings() .getAttribute( "use.single.signon")) Chapter 6. Portlet development using Java: Integration examples 439 .booleanValue(); String uidPwdOrLTPAToken = ""; if (CREDENTIAL_VAULT_SERVICE == null) { CREDENTIAL_VAULT_SERVICE = (CredentialVaultService) portletContext.getService( CredentialVaultService.class); } if (useSSO) { Subject subject = CREDENTIAL_VAULT_SERVICE.getUserSubject(portletRequest); LOGGER.debug("Subject.toString(): " + subject.toString()); LOGGER.debug("Private credentials:"); Set privateCredentials = subject.getPrivateCredentials(); Iterator iterator = privateCredentials.iterator(); com.ibm.wps.sso.LTPATokenCredential ltpaToken = (com.ibm.wps.sso.LTPATokenCredential) iterator.next(); LOGGER.debug("LTPA Token string: " + ltpaToken.getTokenString()); uidPwdOrLTPAToken = ltpaToken.getTokenString(); } else { uidPwdOrLTPAToken = CredentialVaultManager.getUserNameAndPassword( CREDENTIAL_VAULT_SERVICE, RESOURCE_NAME, portletRequest); } if (uidPwdOrLTPAToken.equals("noCredentials")) { portletRequest.getPortletSession().setAttribute("noCredentials", ""); throw new Exception("No credentials. Set credendtial using Edit-mode of CustomersPortlet."); } return dominoHost + ":" + uidPwdOrLTPAToken; } private void accessDomino(PortletRequest portletRequest) { try { PortletSession portletSession = portletRequest.getPortletSession(); String key = getDominoSessionPoolKey( getPortletConfig().getContext(), 440 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 portletRequest); DominoAccess dominoAccess = DominoAccess.getInstance(); String searchString = portletRequest.getParameter("searchString"); CustomerBean[] customerBeans; if (portletRequest.getParameter("reset") != null || searchString == null) { customerBeans = dominoAccess.getCustomers(key); } else { customerBeans = dominoAccess.getCustomersByName(key, searchString); } portletSession.setAttribute("customers", customerBeans); portletSession.setAttribute( "accountOwners", dominoAccess.getSalesPersons(key)); } catch (Exception e) { LOGGER.error(e.toString(), e); } } } CustomersPortlet explained This class has lot of functionality and we go through the class method by method. Class variables We have here four static variables and two of those are public variables, which can be used from other classes. LOGGER is log4j logger, ENTRIES_PER_PAGE is the maximum customer entries per portlet page, RESOURCE_NAME is used in Credential Vault, and CREDENTIAL_VAULT_SERVICE is WebSphere Portal’s CredentialVaultService implementation. init(PortletConfig portletConfig) This initializes LOGGER. See the log4j documentation for details about logger classes. login(PortletRequest portletRequest) login() is called when a user has logged into portal and views CustomersPortlet for the first time after logging in. Method sets variables in DominoAccess class with values from PortletApplicationSettings. Chapter 6. Portlet development using Java: Integration examples 441 This also retrieves CustomerBeans and SalesPersonBean from Domino and saves them in the PortletSession. This is done in the accessDomino() method. destroy(PortletConfig config) Destroys the Domino session pool when portal is shut down. doView() This renders the portlet output using either NoCredential.jsp or CustomersPortletView.jsp, depending on whether credentials are set or not. doEdit() Includes CustomersPortletEdit.jsp. doConfigure() Includes CustomersPortletConfig.jsp. actionPerformed(ActionEvent event) Handles the actions of CustomersPortlet. Several actions are possible: – “next”: Shows the next page of customers. – “previous”: Shows the previous page of customers. – “showDetails”: Sends a message to CustomerDetailsPortlet. The message is the note ID of the customer document. – “searchCustomer“: Searches the Domino database for a customer. The search string is specified as a request parameter. – “cancel”: Returns from edit or configure mode to view mode. – “saveCredentials”: Saves credentials to CredentialVault using the CredentialVaultManager class. – “saveConfiguration”: Saves the configuration to PortletApplicationSettings and sets variables in DominoAccess class. messageReceived(MessageEvent event) Receives the “reset” message and resets session variables. getDominoSessionPoolKey(PortletContext portletContext, PortletRequest portletRequest) This method is used also by other portlets. It returns a pool key for use in a Domino session pool. A pool key can be either “dominoHost:userName:password” or “dominoHost:LTPATokenString”. The latter is used when SSO is enabled. An LTPA token is retrieved using CredentialVault.getUserSubject(portletRequest). It returns a JAAS Subject object and the LTPA token is stored as PrivateCredentials in the Subject object. If SSO is disabled, the user name and password are retrieved from 442 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Credential Vault and they have to be set using the edit mode of CustomersPortlet. accessDomino(PortletRequest portletRequest) This method uses the DominoAccess class to access Domino and retrieve data. The main purpose of this method is to store CustomerBeans and SalesPersonBeans to portlet session. Configuration parameters CustomersPortlet uses several parameters that are read from deployment descriptors. 1. Open portlet.xml (see Figure 6-17 on page 444) and add the following values to Context Parameters in Concrete Portlet Application (Table 6-1): Table 6-1 SalesTracking portal application context parameters Name Value domino.host.address domino651.swic.fi.ibm.com use.single.sign.on false customer.db redbook/customer.nsf sales.db redbook/sales.nsf product.db redbook/products.nsf user.name test person password password Chapter 6. Portlet development using Java: Integration examples 443 Figure 6-17 Sales Tracking portal application context parameters 2. Open web.xml (see Figure 6-18 on page 445) and add the parameters for log4j (Table 6-2). Table 6-2 SalesTracking CustomersPortlet servlet parameters 444 Name Value log.file c:/salestrackingportletibmapi.log log4j.logger.name SalesTrackingPortletIBMAPILog Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-18 SalesTracking servlet init parameters 6.4.4 CustomersPortlet JSP files Next, we develop the JSPs. We added configure and edit modes during the project creation process, so we need three JSP files, plus one JSP for showing that the credentials are not set. NoCredentials.jsp The first JSP is a simple JSP that displays a message that credentials are not set. 1. Right-click the SalesTrackingIBMAPI/WebContent/jsp/html directory and select New → JSP File. Enter NoCredentials.jsp as file name (Figure 6-19 on page 446). Chapter 6. Portlet development using Java: Integration examples 445 Figure 6-19 New JSP file: NoCredentials.jsp 2. Click Finish. 3. WSAD creates NoCredentials.jsp and opens it. The JSP has code from the template, which we replace with the code in Example 6-9. Example 6-9 NoCredentials.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> <table cellspacing="1" cellpadding="1"> <tr> <td colspan="2"><span class="wpsPortletText">Authentication credentials not set. Use Edit-mode of CustomersPortlet to set them. </span></td> </tr> </table> 446 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomersPortletView.jsp 1. Create a new JSP file CustomersPortletView.jsp in the directory SalesTrackingIBMAPI/jsp/html (Example 6-10). Example 6-10 CustomersPortletView.jsp <%@ page import="org.apache.jetspeed.portlet.*"%> <%@ page import="java.util.*"%> <%@ page import="com.ibm.itso.cam.redbooks.sg246466.domino.*"%> <%@ page import="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.*"%> <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@taglib uri="/WEB-INF/tld/people.tld" prefix="pa"%> <portletAPI:init /> <table cellspacing="1" cellpadding="1"> <tr> <form method="post" action="<portletAPI:createURI><portletAPI:URIAction name="searchCustomer"/></portletAPI:createURI>"> <td align="left"><span class="wpsLabelText">Name</span></td> <td align="left"><input name="searchString" type="text" value="" size="20"></td> <td align="left"><input class="wpsButtonText" type="submit" value="Search"></td> <td align="left"><input class="wpsButtonText" name="reset" type="submit" value="Reset"></td> </form> </tr> <tr> <td </tr> <tr> <th <th <th <th </tr> colspan="3"> </td> class="wpsTableHead"> </th> class="wpsTableHead">Name</th> class="wpsTableHead">Customer number</th> class="wpsTableHead">Account owner</th> <%PortletSession portletSession = portletRequest.getPortletSession(); SalesPersonBean[] salesPersons = (SalesPersonBean[]) portletSession.getAttribute("accountOwners"); CustomerBean[] customerBeans = (CustomerBean[]) portletSession.getAttribute("customers"); if (customerBeans != null) { int entriesPerPage = CustomersPortlet.ENTRIES_PER_PAGE; Chapter 6. Portlet development using Java: Integration examples 447 int totalCustomers = customerBeans.length; int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); int endIndex = Math.min(totalCustomers, pageIndex + entriesPerPage); for (int i = pageIndex; i < endIndex; i++) {%> <tr> <td class="wpsTableText"><%=String.valueOf(i + 1)%></td> <td class="wpsTableText"><a href="<portletAPI:createURI><portletAPI:URIAction name="showDetails"/><portletAPI:URIParameter name="noteId" value="<%=customerBeans[i].getNoteId()%>"/></portletAPI:createURI>"><span class="wpsLink"><%=customerBeans[i].getName()%></span></a></td> <td class="wpsTableText"><%=customerBeans[i].getCustomerNumber()%></td> <td class="wpsTableText"><pa:person> <%=BeanUtils.getAccountOwnerName(customerBeans[i].getAccountOwner(), salesPersons)%></pa:person></td> </tr> <%} %> <td align="left" class="wpsTableText">Total: <%=String.valueOf(totalCustomers)%></td> <td> </td> <td align="right" class="wpsTableText"><a href="<portletAPI:createURI><portletAPI:URIAction name="previous"/></portletAPI:createURI>"><span class="wpsLink">Previous</span></a></td> <td align="right" class="wpsTableText"><a href="<portletAPI:createURI><portletAPI:URIAction name="next"/></portletAPI:createURI>"><span class="wpsLink">Next</span></a> <%} %> </table> The JSP is quite straightforward. We import required classes and reference a couple of tag libraries, portlet.tld and people.tld. At the beginning of the page, there is a form for searching customers and after it there is a table of customers. Links for the next and previous page are at the bottom of the JSP. We use the style classes from the WPS stylesheet in our JSP. This is recommended, since the portlets may run in a variety of Portals where look and feel varies. We also use some of the portlet JSP tags that are available. 448 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Note: Awareness is enabled in this JSP. Functionality is provided by <person> tag from people.tld. Simply include a name within <person> tag and portal server handles awareness during runtime: <pa:person>John Smith</pa:person> Important: There must be no line breaks in the person tag. For example: <pa:person> John Smith</pa:person> Line breaks cause errors during runtime. Also, avoid beginning and trailing spaces in the person tag. CustomersPortletEdit.jsp 1. Create CustomerPortletEdit.jsp (Example 6-11). Example 6-11 CustomersPortletEdit.jsp <%@ page import="org.apache.jetspeed.portlet.*"%> <%@ page import="java.util.*"%> <%@ page import="java.text.*"%> <%@ page import="com.ibm.itso.cam.redbooks.sg246466.domino.*"%> <%@ page import="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.*"%> <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> <h3 class="portlet-section-header">Set user name and password for Sales Tracking Domino application</h3> <%if (portletRequest.getAttribute("saveCredentialsResult") != null) { %> Result: <%=(String) portletRequest.getAttribute("saveCredentialsResult")%> . <br /> If result was success, you must logout and login again. <%} %> <%if (Boolean .valueOf( portletRequest.getPortletSettings().getApplicationSettings().getAttribute( "use.single.signon")) .booleanValue()) { Chapter 6. Portlet development using Java: Integration examples 449 %> Single signon enabled. <%} else { %> <form method="post" action="<portletAPI:createReturnURI><portletAPI:URIAction name="saveCredentials"/></portletAPI:createReturnURI>"> <table border="0" cellspacing="1" cellpadding="1"> <tr> <td colspan="2"><span class="wpsLabelText"><label>Domino host</label></span> </td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label><%=portletRequest.getPortletSettings().getApplicati onSettings().getAttribute( "domino.host.address")%></label></span></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Customer DB</label></span> </td> </tr> <tr> <td colspan="2"><%=portletRequest.getPortletSettings().getApplicationSettings().get Attribute( "customer.db")%></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Sales DB</label></span> </td> </tr> <tr> <td colspan="2"><%=portletRequest.getPortletSettings().getApplicationSettings().get Attribute( "sales.db")%></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Product DB</label></span> </td> </tr> <tr> 450 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <td colspan="2"><%=portletRequest.getPortletSettings().getApplicationSettings().get Attribute( "product.db")%></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>User name:</label></span></td> </tr> <tr> <td colspan="2"><input name="userName" type="text" value="<%=portletRequest.getData().getAttribute("userName") != null ? (String) portletRequest.getData().getAttribute("userName") : ""%>" size="45"></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Password:</label></span></td> </tr> <tr> <td colspan="2"><input name="password" type="password" value="" size="45"></td> </tr> <tr> <td><input class="wpsButtonText" type="submit" value="Save"></td> <td><input class="wpsButtonText" name="cancel" type="submit" value="Cancel"></td> </tr> </table> </form> <%} %> CustomersPortletEdit.jsp is presented when in edit mode and asks the user for a user name and password. If single sign-on is enabled, the user cannot edit the user name and password. CustomersPortletConfig.jsp 1. Create CustomersPortletConfig.jsp (Example 6-12). Example 6-12 CustomersPortletConfig.jsp <%@ page import="org.apache.jetspeed.portlet.*"%> <%@ page import="java.util.*"%> <%@ page import="java.text.*"%> Chapter 6. Portlet development using Java: Integration examples 451 <%@ page import="com.ibm.itso.cam.redbooks.sg246466.domino.*"%> <%@ page import="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.*"%> <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> <h3 class="portlet-section-header">Set Domino host address for Sales Tracking Domino application</h3> <form method="post" action="<portletAPI:createReturnURI><portletAPI:URIAction name="saveConfiguration"/></portletAPI:createReturnURI>"> <table border="0" cellspacing="1" cellpadding="1"> <tr> <td colspan="2"><span class="wpsLabelText"><label>Domino host</label></span> </td> </tr> <tr> <td colspan="2"><input name="domino.host.address" type="text" value="<%=portletRequest.getPortletSettings().getApplicationSettings().getAttri bute( "domino.host.address")%>" size="45"></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Customer DB</label></span> </td> </tr> <tr> <td colspan="2"><input name="customer.db" type="text" value="<%=portletRequest.getPortletSettings().getApplicationSettings().getAttri bute( "customer.db")%>" size="45"></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Sales DB</label></span> </td> </tr> <tr> <td colspan="2"><input name="sales.db" type="text" value="<%=portletRequest.getPortletSettings().getApplicationSettings().getAttri bute( "sales.db")%>" size="45"></td> 452 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Product DB</label></span> </td> </tr> <tr> <td colspan="2"><input name="product.db" type="text" value="<%=portletRequest.getPortletSettings().getApplicationSettings().getAttri bute( "product.db")%>" size="45"></td> </tr> <tr> <td colspan="2"><span class="wpsLabelText"><label>Use single sign on</label></span> </td> </tr> <tr> <td colspan="2"><input name="use.single.signon" type="text" value="<%=portletRequest.getPortletSettings().getApplicationSettings().getAttri bute( "use.single.signon")%>" size="45"></td> </tr> <tr> <td><input class="wpsButtonText" type="submit" value="Save"></td> <td><input class="wpsButtonText" type="submit" name="cancel" value="Cancel"></td> </tr> </table> </form> CustomersPortletConfig.jsp is displayed for the administrator in configure mode and only an administrator can use configure mode. The Domino host address and Domino database locations can be changed here. Enabling/disabling single sign-on is also done here. 6.4.5 Testing the application Now that we have written our CustomersPortlet, we are going to test it. WSAD includes a WPS test environment that is helpful in our development. 1. Right-click the SalesTrackingIBMAPI project and select Run on server. Chapter 6. Portlet development using Java: Integration examples 453 2. The server selection dialog opens (Figure 6-20). Figure 6-20 Server selection 3. Select WebSphere Portal V5.0 Test Environment and check Set server as project default. Click Finish. 4. WSAD starts the test environment and after it has started, we see a browser page with our portlet (Figure 6-21 on page 455). 454 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-21 Portlet running in test environment. 5. Credentials are not set, so they have to be set. Use the configure mode to set the Domino host address and database directories. Edit mode is used to set the user name and password (after saving the user name and password, we have to log in again to the server. This is because we set the session variables during the login() method). Single sign on is not enabled in the test environment, so it cannot be used. 6. After we have configured Domino host, user name, and other parameters, we see our portlet in action (Figure 6-22 on page 456). Chapter 6. Portlet development using Java: Integration examples 455 Figure 6-22 CustomersPortlet and a list of five customers 7. We have the awareness capability in the Account owner fields and when we deploy our application to WebSphere Portal, which has collaboration enabled, we see the online status of our account owners. 8. If we click customer name, nothing happens. As we implemented in CustomersPortlet.java, clicking the customer name sends a message to CustomerDetailsPortlet and that portlet is not yet implemented. 6.4.6 CustomerDetailsPortlet Before we start developing a new portlet, it is a good idea to stop the test environment. 1. Stop the test environment by selecting Servers. Right-click the test environment and select Stop (Figure 6-23 on page 457). 456 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-23 Stopping the test environment 2. Now we create a new portlet by selecting File → New → Other. 3. Select Portlet Development → Portlet (Figure 6-24 on page 458). Chapter 6. Portlet development using Java: Integration examples 457 Figure 6-24 New portlet 4. Click Next. 5. Select the SalesTrackingIBMAPI project, choose Basic portlet, and check the Configure advanced options check box. Click Next. 6. Click Next. 7. In the portlet settings, add the following values (Figure 6-25 on page 459): – Application name: SalesTrackingIBMAPI application – Portlet name: SalesTrackingIBMAPICustomerDetails portlet – Portlet title: SalesTrackingIBMAPICustomerDetails portlet – Check Change code generation check box – Package prefix: com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi – Class prefix: CustomerDetailsPortlet 458 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-25 CustomerDetailsPortlet portlet settings 8. We notice that we cannot continue because of the error com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi already exists. However, we want CustomerDetailsPortlet to have the same package as CustomersPortlet. So we have to go around this message. 9. Change the package prefix to com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi2. 10.Click Next. 11.Uncheck the Add action listener check box. 12.Click Finish. 13.WSAD creates a new portlet Java file for us (but in the wrong package) and it modifies web.xml and portlet.xml. We want our new portlet to have the same package as CustomersPortlet, so we do the following steps to change the generated code and deployment descriptors: 14.Right-click package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi2 under Java Resources. Select Delete. Chapter 6. Portlet development using Java: Integration examples 459 15.Right-click the com_ibm_itso_cam_redbooks_sg246466_portlets_ibmapi2 directory under Web Content and select Delete. 16.Double-click Web Deployment Descriptor under SalesTrackingIBMAPI. Click Source to view the web.xml source. 17.Select Edit → Find/Replace. 18.In the Find/Replace dialog, enter ibmapi2 as the find string and ibmapi as the Replace With string. Click Replace all. 19.Save changes and double-click Portlet Deployment Descriptor under SalesTrackingIBMAPI. 20.View source and replace all ibmapi2 strings with ibmapi and save the changes. Now we can write our portlet. 21.Create a class with the name CustomerDetailsPortlet in the package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi. 22.WSAD generates template code for the class. Replace it with the code in Example 6-13. Example 6-13 CustomerDetailsPortlet.java package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi; import import import import import import java.io.*; org.apache.jetspeed.portlets.*; org.apache.jetspeed.portlet.*; org.apache.jetspeed.portlet.event.*; com.ibm.itso.cam.redbooks.sg246466.domino.*; org.apache.log4j.*; public class CustomerDetailsPortlet extends PortletAdapter implements ActionListener, MessageListener { public void init(PortletConfig portletConfig) throws UnavailableException { super.init(portletConfig); } public void login(PortletRequest portletRequest) { try { //check authentication credentials 460 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomersPortlet.getDominoSessionPoolKey( getPortletConfig().getContext(), portletRequest); } catch (Exception e) { } } public void doView( PortletRequest portletRequest, PortletResponse portletResponse) throws PortletException, IOException { if (portletRequest.getPortletSession().getAttribute("noCredentials") != null) { getPortletConfig().getContext().include( "/jsp/NoCredentials.jsp", portletRequest, portletResponse); return; } PortletSession portletSession = portletRequest.getPortletSession(); if (portletSession.getAttribute("addCustomer") != null || portletSession.getAttribute("customerBean") != null) { getPortletConfig().getContext().include( "/jsp/CustomerDetailsPortletAddCustomerView.jsp", portletRequest, portletResponse); } else { getPortletConfig().getContext().include( "/jsp/CustomerDetailsPortletView.jsp", portletRequest, portletResponse); } } public void actionPerformed(ActionEvent event) throws PortletException { String action = event.getActionString(); PortletRequest portletRequest = event.getRequest(); PortletSession portletSession = portletRequest.getPortletSession(); Chapter 6. Portlet development using Java: Integration examples 461 if (action.equals("addNewCustomer")) { portletSession.removeAttribute("customerBean"); portletSession.setAttribute("addCustomer", ""); accessDomino(portletRequest); int newCustomerNumber = BeanUtils.nextCustomerNumber( (CustomerBean[]) portletSession.getAttribute("customers")); portletSession.setAttribute( "newCustomerNumber", String.valueOf(newCustomerNumber)); } if (action.equals("editCustomer")) { String noteId = portletRequest.getParameter("noteId"); accessDomino(portletRequest, noteId); } if (action.equals("saveCustomer")) { portletSession.removeAttribute("addCustomer"); portletSession.removeAttribute("customerBean"); if (portletRequest.getParameter("cancel") != null) { return; } DefaultPortletMessage dpm = new DefaultPortletMessage("reset"); getPortletConfig().getContext().send( "SalesTrackingIBMAPICustomers portlet", dpm); if (portletRequest.getParameter("delete") != null) { accessDomino(portletRequest); return; } CustomerBean customerBean = new CustomerBean(); customerBean.setName(portletRequest.getParameter("name")); customerBean.setCustomerNumber( portletRequest.getParameter("customerNumber")); customerBean.setAccountOwner(portletRequest.getParameter("accountOwner")); 462 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 int employeeTotal = 0; try { employeeTotal = Integer.parseInt(portletRequest.getParameter("employeeTotal")); } catch (NumberFormatException e) { } customerBean.setEmployeeTotal(employeeTotal); customerBean.setAddress(portletRequest.getParameter("address")); customerBean.setAdditionalInformation( portletRequest.getParameter("additionalInformation")); String noteId = portletRequest.getParameter("noteId"); customerBean.setNoteId(noteId); accessDomino(portletRequest, customerBean); } } public void messageReceived(MessageEvent event) { PortletRequest portletRequest = event.getRequest(); PortletSession portletSession = portletRequest.getPortletSession(); DefaultPortletMessage message = (DefaultPortletMessage) event.getMessage(); String noteId = message.getMessage(); accessDomino(portletRequest, noteId); } private void accessDomino(PortletRequest portletRequest) { accessDomino(portletRequest, null, portletRequest.getParameter("noteId")); } private void accessDomino(PortletRequest portletRequest, String noteId) { accessDomino(portletRequest, null, noteId); } private void accessDomino( PortletRequest portletRequest, CustomerBean customerBean) { accessDomino( portletRequest, customerBean, portletRequest.getParameter("noteId")); } Chapter 6. Portlet development using Java: Integration examples 463 private void accessDomino( PortletRequest portletRequest, CustomerBean customerBean, String noteId) { try { PortletSession portletSession = portletRequest.getPortletSession(); String key = CustomersPortlet.getDominoSessionPoolKey( getPortletConfig().getContext(), portletRequest); DominoAccess dominoAccess = DominoAccess.getInstance(); if (portletRequest.getParameter("delete") != null) { dominoAccess.deleteCustomer(key, noteId); } if (customerBean != null) { dominoAccess.addNewCustomer(key, customerBean); } if (noteId != null) { portletSession.setAttribute( "customerBean", dominoAccess.getCustomerByNoteId(key, noteId)); } portletSession.setAttribute("customers", dominoAccess.getCustomers(key)); portletSession.setAttribute( "salesPersons", dominoAccess.getSalesPersons(key)); } catch (Exception e) { e.printStackTrace(); } } } 464 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomerDetailsPortlet explained The purpose of the CustomerDetailsPortlet is to add new customers to the database and to show/edit customer details when receiving a message from other portlets. Some methods are described here: login(PortletRequest portletRequest) The purpose of this method is to check if authentication credentials are set. If they are not, then an attribute (noCredentials) is set in the portlet session. doView(PortletRequest portletRequest, PortletResponse portletResponse) doView() renders an output using a JSP file. If the noCredentials attributes is set in the portlet session, then noCredentials.jsp is included. If a user has clicked Add new customer or a message that shows that the details have been received, then CustomerDetailsPortletAddCustomerView.jsp is included. Otherwise, the main page is included. actionPerformed(ActionEvent event) Handles CustomerDetailsPortlet actions: – “addNewCustomer”: Initializes a session for adding a new customer. doView() includes a page for adding a new customer based on values in session. – “editCustomer”: Receives noteId as a parameter and accesses Domino to set CustomerBean in a session. CustomerBean is initialized with a document whose note ID is equal to parameter noteId. – “saveCustomer”: Saves new customer, modifies existing customer, or deletes customer. Also sends a message to CustomersPortlet to reset the customer list. accessDomino() method is called to access Domino server in all of the above actions. messageReceived(MessageEvent event) Receives a message from CustomersPortlet. The message is a note ID that is used to get a customer from Domino. accessDomino() accessDomino() methods are used to access Domino and performs actions based on the parameters in PortletRequest. Chapter 6. Portlet development using Java: Integration examples 465 6.4.7 CustomerDetailsPortlet JSP files This section describes how to create the JSP files required for finalizing the CustomerDetails Portlet. CustomerDetailsPortletView.jsp 1. Create CustomerDetailsPortletView.jsp in the SalesTrackingIBMAPI/WebContent/jsp/html directory. 2. Replace the template code with the code in Example 6-14. Example 6-14 CustomerDetailsPortletView.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init/> <table cellspacing="1" cellpadding="1"> <tr> <td align="left"> <a href="<portletAPI:createURI><portletAPI:URIAction name="addNewCustomer"/></portletAPI:createURI>"> <span class=".wpsLink">Add new customer</span> </a> </td> </tr> </table> This JSP has only a link to add a new customer. CustomerDetailsPortletAddCustomerView.jsp 1. Create CustomerDetailsPortletAddCustomerView.jsp in the SalesTrackingIBMAPI/WebContent/jsp/html directory. 2. Replace the template code with the code in Example 6-15. Example 6-15 CustomerDetailsPortletAddCustomerView.jsp <%@ <%@ <%@ <%@ <%@ page import="org.apache.jetspeed.portlet.*"%> page import="java.util.*"%> page import="com.ibm.itso.cam.redbooks.sg246466.domino.*"%> page import="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.*"%> taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> 466 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <%PortletSession portletSession = portletRequest.getPortletSession(); SalesPersonBean[] salesPersons = (SalesPersonBean[]) portletSession.getAttribute("salesPersons"); CustomerBean customerBean = (CustomerBean) portletSession.getAttribute("customerBean"); String name = ""; String customerNumber = (String) portletSession.getAttribute("newCustomerNumber"); String accountOwner = ""; String address = ""; int employeeTotal = 0; String additionalInformation = ""; String noteId = null; if (customerBean != null) { name = customerBean.getName(); customerNumber = customerBean.getCustomerNumber(); accountOwner = customerBean.getAccountOwner(); address = customerBean.getAddress(); employeeTotal = customerBean.getEmployeeTotal(); additionalInformation = customerBean.getAdditionalInformation(); noteId = customerBean.getNoteId(); } %> <h3 class="portlet-section-header">Add new customer</h3> <table cellspacing="1" cellpadding="1"> <form method="post" action="<portletAPI:createURI><portletAPI:URIAction name="saveCustomer"/></portletAPI:createURI>"> <%if (noteId != null) { %> <input name="noteId" type="hidden" value="<%=noteId%>"> <%} %> <tr> <td align="left"><span class="wpsLabelText">Name</span></td> <td align="left"><span class="wpsLabelText">Customer number</span></td> </tr> <tr> <td align="left"><input name="name" type="text" value="<%=name%>" size="20"></td> <td align="left"><input name="customerNumber" type="hidden" value="<%=customerNumber%>"> <span class="wpsLabelText"><%=customerNumber%></span> </td> </tr> <tr> <td align="left"><span class="wpsLabelText">Total employees</span></td> Chapter 6. Portlet development using Java: Integration examples 467 <td align="left"><span class="wpsLabelText">Account owner</span></td> </tr> <tr> <td align="left"><input name="employeeTotal" value="<%=String.valueOf(employeeTotal)%>" <td align="left"><select name="accountOwner" <%for (int i = 0; i < salesPersons.length; type="text" size="20"></td> size="1"> i++) { %> <option <%=(salesPersons[i].getEmployeeNumber().equals(accountOwner) ? "selected" : "")%> value="<%=salesPersons[i].getEmployeeNumber()%>"><%=salesPersons[i].getName()%> <%} %> </select></td> </tr> <tr> <td align="left"><span class="wpsLabelText">Address</span></td> <td align="left"><span class="wpsLabelText">Additional information</span> </td> </tr> <tr> <td align="left"><textarea name="address" cols="20" rows="4"><%=address%></textarea> </td> <td align="left"><textarea name="additionalInformation" cols="20" rows="4"><%=additionalInformation%></textarea></td> </tr> <tr> <td colspan="2" align="left"><input class="wpsButtonText" name="save" type="submit" value="Save"> <%if (noteId != null) { %> <input class="wpsButtonText" name="delete" type="submit" value="Delete"> <%} %> <input class="wpsButtonText" name="cancel" type="submit" value="Cancel"></td> </tr> </form> </table> 468 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomerDetailsPortletAddCustomerView.jsp presents an editable form of customer details. The fields are populated with existing customer values if CustomerDetailsPortlet received a message to show customer details. 6.4.8 Testing the application, part two Our portal application now has two portlets and they communicate with each other using portlet messaging. So let us verify this situation: 1. Select the SalesTrackingIBMAPI project and run it on the test environment. 2. After the server has been started, we see two portlets, as in Figure 6-26. Figure 6-26 CustomerDetailsPortlet in the test environment 3. When we click Add new customer, a page where we can add a customer opens (Figure 6-27 on page 470). Chapter 6. Portlet development using Java: Integration examples 469 Figure 6-27 CustomerDetailsPortlet: add new customer 4. We add some values and then save the customer. We see that CustomersPortlet now has 27 entries and at the end of the customer list we see the 27th customer entry (Figure 6-28 on page 471). 470 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-28 CustomerDetailsPortlet: new customer added 5. Now we want to edit the new 27th customer. By clicking on the customer name in CustomersPortlet, a message is sent to CustomerDetailsPortlet and it shows the customer details (Figure 6-29 on page 472). Chapter 6. Portlet development using Java: Integration examples 471 Figure 6-29 CustomerDetailsPortlet: edit a customer 6. We can edit values and save the edited document to the database or we can delete the customer. 6.4.9 CustomerContactsPortlet The last portlet in the SalesTrackingIBMAPI portal application is CustomerContactsPortlet, which lists customer contacts. 1. We add a new portlet to our application. Recall the steps we took in 6.4.6, “CustomerDetailsPortlet” on page 456. 2. In the Portlet settings, use the following values: – Application name: SalesTrackingIBMAPI application. – Portlet name: SalesTrackingIBMAPICustomerContacts portlet. – Portlet title: SalesTrackingIBMAPICustomerContacts portlet. – Check the Change code generation check box. – Package prefix: com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi. – Class prefix: CustomerContactsPortlet. 472 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 3. Again, recall the steps in 6.4.6, “CustomerDetailsPortlet” on page 456 in order to proceed. 4. After we have our template code for CustomerContactsPortlet, we replace it with the code in Example 6-16. Example 6-16 CustomerContactsPortlet.java package com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi; import import import import import import java.io.*; org.apache.jetspeed.portlets.*; org.apache.jetspeed.portlet.*; org.apache.jetspeed.portlet.event.*; com.ibm.itso.cam.redbooks.sg246466.domino.*; org.apache.log4j.*; public class CustomerContactsPortlet extends PortletAdapter implements ActionListener { public void init(PortletConfig portletConfig) throws UnavailableException { super.init(portletConfig); } public void login(PortletRequest portletRequest) { PortletSession portletSession = portletRequest.getPortletSession(); PortletSettings settings = portletRequest.getPortletSettings(); portletSession.setAttribute("pageIndex", new Integer(0)); accessDomino(portletRequest); } public void doView( PortletRequest portletRequest, PortletResponse portletResponse) throws PortletException, IOException { if (portletRequest.getPortletSession().getAttribute("noCredentials") != null) { getPortletConfig().getContext().include( "/jsp/NoCredentials.jsp", portletRequest, portletResponse); return; } getPortletConfig().getContext().include( Chapter 6. Portlet development using Java: Integration examples 473 "/jsp/CustomerContactsPortletView.jsp", portletRequest, portletResponse); } public void actionPerformed(ActionEvent event) throws PortletException { String action = event.getActionString(); PortletRequest portletRequest = event.getRequest(); PortletSession portletSession = portletRequest.getPortletSession(); if (action.equals("next")) { int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); pageIndex = pageIndex + CustomersPortlet.ENTRIES_PER_PAGE >= ( (CustomerContactBean[]) portletSession.getAttribute( "customerContacts")).length ? pageIndex : pageIndex + CustomersPortlet.ENTRIES_PER_PAGE; portletSession.setAttribute("pageIndex", new Integer(pageIndex)); } if (action.equals("previous")) { int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); pageIndex = pageIndex - CustomersPortlet.ENTRIES_PER_PAGE < 0 ? 0 : pageIndex - CustomersPortlet.ENTRIES_PER_PAGE; portletSession.setAttribute("pageIndex", new Integer(pageIndex)); } } private void accessDomino(PortletRequest portletRequest) { try { PortletSession portletSession = portletRequest.getPortletSession(); String key = CustomersPortlet.getDominoSessionPoolKey( getPortletConfig().getContext(), portletRequest); DominoAccess dominoAccess = DominoAccess.getInstance(); 474 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CustomerContactBean[] customerContactBeans = dominoAccess.getCustomerContacts(key); portletSession.setAttribute("customerContacts", customerContactBeans); portletSession.setAttribute("customers", dominoAccess.getCustomers(key)); } catch (Exception e) { e.printStackTrace(); } } } 6.4.10 CustomerContactsPortletView.jsp 1. Create CustomerContactsPortletView.jsp under SalesTrackingIBMAPI/WebContent/jsp/html. 2. Replace the template code with the code in Example 6-17. Example 6-17 CustomerContactsPortletView.jsp <%@ <%@ <%@ <%@ <%@ page import="org.apache.jetspeed.portlet.*"%> page import="java.util.*"%> page import="com.ibm.itso.cam.redbooks.sg246466.domino.*"%> page import="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.*"%> taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <portletAPI:init /> <html> <body> <table cellspacing="1" cellpadding="1"> <tbody> <tr> <td </tr> <tr> <th <th <th <th </tr> colspan="3"> </td> class="wpsTableHead"> </th> class="wpsTableHead">Name</th> class="wpsTableHead">Company</th> class="wpsTableHead">Phone number</th> <%PortletSession portletSession = portletRequest.getPortletSession(); Chapter 6. Portlet development using Java: Integration examples 475 CustomerBean[] customerBeans = (CustomerBean[]) portletSession.getAttribute("customers"); CustomerContactBean[] customerContactBeans = (CustomerContactBean[]) portletSession.getAttribute("customerContacts"); if (customerContactBeans != null) { int entriesPerPage = CustomersPortlet.ENTRIES_PER_PAGE; int totalCustomers = customerContactBeans.length; int pageIndex = ((Integer) portletSession.getAttribute("pageIndex")).intValue(); int endIndex = Math.min(totalCustomers, pageIndex + entriesPerPage); for (int i = pageIndex; i < endIndex; i++) {%> <tr> <td class="wpsTableText"><%=String.valueOf(i + 1)%></td> <td class="wpsTableText"><%=customerContactBeans[i].getName()%></td> <td class="wpsTableText"><%=BeanUtils.getCustomerName( customerContactBeans[i].getEmployerNumber(), customerBeans)%></td> <td class="wpsTableText"><%=customerContactBeans[i].getPhone()%></td> </tr> <%} %> <td align="left" class="wpsTableText">Total: <%=String.valueOf(totalCustomers)%></td> <td> </td> <td align="right" class="wpsTableText"><a href='<portletAPI:createURI><portletAPI:URIAction name="previous"/></portletAPI:createURI>'><span class="wpsLink">Previous</span></a></td> <td align="right" class="wpsTableText"><a href='<portletAPI:createURI><portletAPI:URIAction name="next"/></portletAPI:createURI>'><span class="wpsLink">Next</span></a> <%} %></td> </tbody> </table> </body> </html> 476 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.4.11 Testing the application, part three 1. We test our portlet application, and after the test environment is running, we see that the CustomerContactsPortlet listing is available under the customer contacts (Figure 6-30). Figure 6-30 CustomerContactsPortlet: contact listing There is a feature missing (see 6.2.2, “Portal application functionality” on page 397). We need to have messaging between CustomerContactsPortlet and CustomerDetailsPortlet. We do this by using Click-to-Action. 6.4.12 Enabling Click-to-Action We want to enable Click-to-Action between CustomerContactsPortlet and CustomerDetailsPortlet. 1. First, we enable CustomerContactsPortlet as a Click-to-Action source. Right-click Portlet Deployment Descriptor under SalesTrackingIBMAPI and select Enable Click-to-Action Source. Chapter 6. Portlet development using Java: Integration examples 477 2. Enter the following values (Figure 6-31): – Data type: NoteId. – Namespace: http://salestrackingibmapi. – Select SalesTrackingIBMAPICustomerContacts portlet as the source portlet. – WSDL file: CustomerNoteId. Figure 6-31 Enable Click-to-Action source 3. Click OK. WSAD generates the CustomerNoteId.wsdl file and modifies the web.xml to wrap our CustomerContactsPortlet in PortletWrapper. WSAD also includes the C2A parameter in portlet.xml. See Example 6-18 for the contents of the WSDL file. Example 6-18 CustomerNoteId.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="CustomerNoteId_Service" targetNamespace="http://salestrackingibmapi" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:portlet="http://www.ibm.com/wps/c2a" xmlns:tns="http://salestrackingibmapi" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://salestrackingibmapi"> <xsd:simpleType name="noteId"> <xsd:restriction base="xsd:string"></xsd:restriction> </xsd:simpleType> </xsd:schema> </types> <message name="noteId_Response"> <part name="noteId_Output" type="tns:noteId" /> </message> 478 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <portType name="CustomerNoteId_Service"> <operation name="CustomerNoteId"> <output message="tns:noteId_Response" /> </operation> </portType> <binding name="CustomerNoteId_Binding" type="tns:CustomerNoteId_Service"> <portlet:binding /> <operation name="CustomerNoteId"> <portlet:action /> <output> <portlet:param name="noteId" partname="noteId_Output" /> </output> </operation> </binding> </definitions> 4. Next, we modify the JSP file to include the Click-to-Action output. Open CustomerContactsPortletView.jsp and add a reference to the C2A tag library. Add the following line after portlet.tld in CustomerContactsPortletView.jsp: <%@ taglib uri="/WEB-INF/tld/c2a.tld" prefix="c2a"%> 5. Next, find a table data element in JSP where we print a customer name. Add the following tag next to the customer name: <c2a:encodeProperty type="noteId" namespace="http://salestrackingibmapi" name="noteId" value="<%=BeanUtils.getCustomerNoteId(customerContactBeans[i].getEmployerNu mber(),customerBeans)%>"></c2a:encodeProperty> Type-attribute is the data type that was specified when we enabled the Click-to-Action source. Namespace-attribute was also specified when enabling the Click-to-Action source. Name-attribute is sent to the target portlet and the target portlet uses PortletRequest.getParameter() method to get the value of the parameter called noteId. After the source has been enabled, we enable the target for the Click-to-Action. 6. Right-click Portlet Deployment Descriptor and select Enable Click-to-Action Target. 7. In the Enable Click-to-Action Target dialog box, enter the following values (Figure 6-32 on page 480): – Data type: noteId (or click Browse and select CustomerNoteId.wsdl). – Namespace: http://salestrackingibmapi. – Action: editCustomer (remember the editCustomer action in CustomerDetailsPortlet). – Parameter: noteId. Chapter 6. Portlet development using Java: Integration examples 479 – C2A caption: Show details. – Portlet: SalesTrackingIBMAPICustomerDetails portlet. – WSDL file: CustomerDetails. Figure 6-32 Enable Click-to-Action target 8. Click OK. WSAD generates the CustomerDetails.wsdl file and modifies the web.xml to wrap CustomerDetailsPortlet in PortletWrapper. WSAD also includes the C2A parameter in portlet.xml. See Example 6-19 for the contents of the WSDL file. Example 6-19 CustomerDetails.wsdl <?xml version="1.0" encoding="UTF-8"?> <definitions name="CustomerDetails_Service" targetNamespace="http://salestrackingibmapi" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:portlet="http://www.ibm.com/wps/c2a" xmlns:tns="http://salestrackingibmapi" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <types> <xsd:schema targetNamespace="http://salestrackingibmapi"> <xsd:simpleType name="noteId"> <xsd:restriction base="xsd:string"></xsd:restriction> </xsd:simpleType> </xsd:schema> </types> <message name="noteId_Request"> 480 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <part name="noteId_Input" type="tns:noteId" /> </message> <portType name="CustomerDetails_Service"> <operation name="CustomerDetails"> <input message="tns:noteId_Request" /> </operation> </portType> <binding name="CustomerDetails_Binding" type="tns:CustomerDetails_Service"> <portlet:binding /> <operation name="CustomerDetails"> <portlet:action name="editCustomer" type="simple" caption="Show details" description="" /> <input> <portlet:param name="noteId" partname="noteId_Input" /> </input> </operation> </binding> </definitions> Name-attribute in the <portlet:action> tag specifies the action name in the target portlet. The target portlet must understand what to do when it receives an action with specified name. Name-attribute in <portlet:param> the tag is sent to the portlet as a request parameter. There is no need to do any changes in the code, so we can test and see Click-to-Action in action. 6.4.13 Testing the application, part four 1. Run SalesTrackingIBMAPI on the server. 2. After the test environment has been started, we see CustomerContactsPortlet with Click-to-Action enabled (Figure 6-33 on page 482). Chapter 6. Portlet development using Java: Integration examples 481 Figure 6-33 CustomerContactsPortlet with Click-to-Action 3. Test Click-to-Action by clicking the arrow icon beside the customer name (Figure 6-34 on page 483). 482 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-34 CustomerContactsPortlet: testing Click-to-Action 4. Clicking Show details sends a message to CustomerDetailsPortlet (Figure 6-35 on page 484). Chapter 6. Portlet development using Java: Integration examples 483 Figure 6-35 CustomerContactsPortlet: editing customer 6.4.14 Deployment descriptors Now the portal application is ready for deployment. Before deploying the application to the production server, let us take a look at the deployment descriptors. While working with WSAD and Portal Toolkit, we do not have to write descriptors. They are presented here as an example (Example 6-20 and Example 6-21 on page 486). Example 6-20 web.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <display-name>SalesTrackingIBMAPI</display-name> <servlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortlet"> <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortl et</servlet-name> <display-name>CustomersPortlet</display-name> 484 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <servlet-class>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPort let</servlet-class> <init-param> <param-name>log.file</param-name> <param-value>c:/salestrackingportletibmapi.log</param-value> </init-param> <init-param> <param-name>log4j.logger.name</param-name> <param-value>SalesTrackingPortletIBMAPILog</param-value> </init-param> </servlet> <servlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.SalesTrackingIBMAPICusto merDetailsPortlet"> <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerDetail sPortlet</servlet-name> <display-name>CustomerDetailsPortlet</display-name> <servlet-class>com.ibm.wps.pb.wrapper.PortletWrapper</servlet-class> <init-param> <param-name>c2a-application-portlet-class</param-name> <param-value>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerDetails Portlet</param-value> </init-param> </servlet> <servlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerContactsPortlet" > <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerContac tsPortlet</servlet-name> <display-name>CustomerContactsPortlet</display-name> <servlet-class>com.ibm.wps.pb.wrapper.PortletWrapper</servlet-class> <init-param> <param-name>c2a-application-portlet-class</param-name> <param-value>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerContact sPortlet</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortl et</servlet-name> <url-pattern>/com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortl et/*</url-pattern> Chapter 6. Portlet development using Java: Integration examples 485 </servlet-mapping> <servlet-mapping> <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerDetail sPortlet</servlet-name> <url-pattern>/com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerDetail sPortlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerContac tsPortlet</servlet-name> <url-pattern>/com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomerContac tsPortlet/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> Example 6-21 portlet.xml <?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="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortlet.6cab44 56ff" major-version="1" minor-version="0"> <portlet-app-name>SalesTrackingIBMAPI application</portlet-app-name> <portlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Cus7cab4456ff" href="WEB-INF/web.xml#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Custom ersPortlet" major-version="1" minor-version="0"> <portlet-name>SalesTrackingIBMAPICustomers portlet</portlet-name> <cache> <expires>0</expires> <shared>no</shared> </cache> <allows> <maximized /> <minimized /> 486 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 </allows> <supports> <markup name="html"> <view /> <configure /> <edit /> </markup> </supports> </portlet> <portlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Sa9ce7ab96ff" href="WEB-INF/web.xml#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.SalesT rackingIBMAPICustomerDetailsPortlet" major-version="1" minor-version="0"> <portlet-name>SalesTrackingIBMAPICustomerDetails portlet</portlet-name> <cache> <expires>0</expires> <shared>no</shared> </cache> <allows> <maximized /> <minimized /> </allows> <supports> <markup name="html"> <view /> </markup> </supports> </portlet> <portlet id="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Cu107735a6ff" href="WEB-INF/web.xml#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Custom erContactsPortlet" major-version="1" minor-version="0"> <portlet-name>SalesTrackingIBMAPICustomerContacts portlet</portlet-name> <cache> <expires>0</expires> <shared>no</shared> </cache> <allows> <maximized /> <minimized /> </allows> <supports> <markup name="html"> <view /> </markup> </supports> </portlet> </portlet-app> Chapter 6. Portlet development using Java: Integration examples 487 <concrete-portlet-app uid="com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.CustomersPortlet.6cab44 56ff.1"> <portlet-app-name>SalesTrackingIBMAPI application</portlet-app-name> <context-param> <param-name>domino.host.address</param-name> <param-value>domino651.swic.fi.ibm.com</param-value> </context-param> <context-param> <param-name>use.single.signon</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>customer.db</param-name> <param-value>redbook/customer.nsf</param-value> </context-param> <context-param> <param-name>sales.db</param-name> <param-value>redbook/sales.nsf</param-value> </context-param> <context-param> <param-name>product.db</param-name> <param-value>redbook/products.nsf</param-value> </context-param> <concrete-portlet href="#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Cus7cab4456ff"> <portlet-name>SalesTrackingIBMAPICustomers portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>SalesTrackingIBMAPICustomers portlet</title> <title-short></title-short> <description></description> <keywords></keywords> </language> </concrete-portlet> <concrete-portlet href="#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Sa9ce7ab96ff"> <portlet-name>SalesTrackingIBMAPICustomerDetails portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>SalesTrackingIBMAPICustomerDetails portlet</title> <title-short></title-short> <description></description> <keywords></keywords> </language> <config-param> <param-name>c2a-action-descriptor</param-name> <param-value>/CustomerDetails.wsdl</param-value> 488 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 </config-param> </concrete-portlet> <concrete-portlet href="#com.ibm.itso.cam.redbooks.sg246466.portlets.ibmapi.Cu107735a6ff"> <portlet-name>SalesTrackingIBMAPICustomerContacts portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>SalesTrackingIBMAPICustomerContacts portlet</title> <title-short></title-short> <description></description> <keywords></keywords> </language> <config-param> <param-name>c2a-action-descriptor</param-name> <param-value>/CustomerNoteId.wsdl</param-value> </config-param> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> 6.4.15 Deployment 1. The first thing we do is to export our application. Right-click SalesTrackingIBMAPI and select Export (Figure 6-36 on page 490). Chapter 6. Portlet development using Java: Integration examples 489 Figure 6-36 Export SalesTrackingIBMAPI portlet application 2. In the Export dialog, select WAR File and click Next. 3. Enter the destination, including the directory, for example, C:\temp\SalesTrackingIBMAPIRedbookSample.war. 4. Click Finish. WSAD creates a WAR file ready for deployment and we can use WebSphere Portal’s administrator portlets to deploy it to the server. The structure of the WAR file follows the J2EE specification (Example 6-22 on page 491). 490 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 6-22 Contents of SalesTrackingIBMAPIRedbookSample.war | CustomerDetails.wsdl | CustomerNoteId.wsdl | tree.txt | +---jsp | \---html | CustomerContactsPortletView.jsp | CustomerDetailsPortletAddCustomerView.jsp | CustomerDetailsPortletView.jsp | CustomersPortletConfig.jsp | CustomersPortletEdit.jsp | CustomersPortletView.jsp | NoCredentials.jsp | +---META-INF | MANIFEST.MF | \---WEB-INF | ibm-web-bnd.xmi | ibm-web-ext.xmi | portlet.xml | web.xml | +---classes | \---com | \---ibm | \---itso | \---cam | \---redbooks | \---sg246466 | \---portlets | \---ibmapi | CredentialVaultManager.class | CustomerContactsPortlet.class | CustomerDetailsPortlet.class | CustomersPortlet.class | \---lib commons-collections-3.0.jar commons-pool-1.1.jar DominoAccess.jar log4j-1.2.8.jar NCSO.jar pbportlet.jar In the lib-directory, we have a pbportlet.jar file. The jar file includes the PortletWrapper class that is used in Click-to-Action portlets. This jar file is Chapter 6. Portlet development using Java: Integration examples 491 added automatically by WSAD when we enabled portlets for Click-to-Action. Note also that in the web.xml (Example 6-20 on page 484), the servlet class for Click-to-Action enabled portlets is PortletWrapper and its init parameter refers to the portlet class we wrote. 5. Open a browser and log in as the administrator to the WebSphere Portal production server. The administrator user name and password are usually wpsadmin:wpsadmin. 6. When logged in, select Administration → Portlets → Install (see Figure 6-37). Figure 6-37 Install portlet I 7. Browse for our portlet war file and click Next. 8. We see that following portlets will be installed (Figure 6-38 on page 493). 492 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-38 Install portlet II 9. Click Install. 10.If the installation was successful, we get the message APIN0005I: Portlets were successfully installed. 11.Now we can add a new page for displaying our portlets. Create a label named RedbookChapter6Samples, as seen in Figure 6-39. Figure 6-39 Create Redbook samples label 12.Create a page named SalesTrackingIBMAPI under RedbookChapter6Samples (Figure 6-40 on page 494). Chapter 6. Portlet development using Java: Integration examples 493 Figure 6-40 Create page SalesTrackingIBMAPI 13.Click Edit Page Layout (Figure 6-41). Figure 6-41 Edit page layout 14.Add SalesTrackingIBMAPI portlets to a page (Figure 6-42 on page 495). 494 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-42 Add portlets to a page 15.Click Done. 16.Now we have our portlets on a page and we see our application in action (Figure 6-43 on page 496). With awareness! Chapter 6. Portlet development using Java: Integration examples 495 Figure 6-43 SalesTrackingIBMAPI application 17.But of course we have to set authentication. Because this environment has single sign-on enabled, we use SSO to access the Domino server. Go to the configure mode of the SalesTrackingIBMAPICustomers portlet, configure parameters for the environment, and enable SSO (Figure 6-44). Figure 6-44 Configure SalesTrackingIBMAPI portal application 496 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 18.Click Save. 19.After relogin, we see the portlet application with awareness (Figure 6-45). Figure 6-45 SalesTrackingIBMAPI application with awareness 6.4.16 Summary We developed the portal application using IBM Portlet API. As we discovered, WebSphere Studio Application Developer offers many helpful features for portlet developer, for example, integrated test environment and generation of deployment descriptors. In the portal application we used portlet messaging, Click-to-Action, awareness, and different portlet modes. From the portlet perspective, the Domino application is just another back end where we need to connect and connection in this sample is done using a custom DominoAccess class. Simple JavaBeans are used to represent documents in the Domino database. Now we have an understanding of IBM Portlet API and its basic features, and we know how to develop portlets with it. The code presented in this section can be used as a starting point for other projects. Chapter 6. Portlet development using Java: Integration examples 497 Note: The SalesTrackingIBMAPI_Project.zip file has the SalesTrackingIBMAPI project ready for importing to WSAD. See Appendix C, “Additional material” on page 741 for download instructions. 6.5 Sales Tracking application using Struts This section shows how to develop a Struts based portlet. 6.5.1 Adding classes to DominoAccess Before we start to develop the Struts application, we add some classes to the DominoAccess project that will be helpful in our development. 1. We need portal classes in the DominoAccess project, so we add portal classes to the project build path. 2. Right-click the DominoAccess project and select Properties. 3. Select the Java Build Path and Libraries. Figure 6-46 Add library to Java build path 498 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 4. Use Add external JAR to add the following JAR files to the build path: – jaas.jar in <wsad_install_dir>/runtimes/base_v5/java/jre/lib/ext – j2ee.jar in <wsad_install_dir>/runtimes/base_v5/lib – wps.jar in <wsad_install_dir>/runtimes/portal_v50/shared/app – portlet-api.jar in <wsad_install_dir>/runtimes/portal_v50/shared/app 5. After jar files have been added, click OK. 6. Right-click the DominoAccess project and select Rebuild Project. 7. Add the class com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccessProxy to the DominoAccess project. 8. DominoAccessProxy is a proxy to DominoAccess that handles authentication details and exceptions so we do not have to write so much code in our portlet (Example 6-23). Example 6-23 DominoAccessProxy.java package com.ibm.itso.cam.redbooks.sg246466.domino; import java.util.Iterator; import java.util.Set; import javax.security.auth.Subject; import org.apache.jetspeed.portlet.PortletApplicationSettings; import org.apache.jetspeed.portlet.PortletContext; import org.apache.jetspeed.portlet.PortletRequest; import com.ibm.wps.portletservice.credentialvault.CredentialVaultService; public class DominoAccessProxy { public static String KEY = "domino651.swic.fi.ibm.com:test person:password"; public static void init( PortletRequest portletRequest, PortletContext portletContext) { String key = ""; PortletApplicationSettings applicationSettings = portletRequest.getPortletSettings().getApplicationSettings(); String dominoHost = applicationSettings.getAttribute("domino.host.address"); key = dominoHost + ":" Chapter 6. Portlet development using Java: Integration examples 499 + applicationSettings.getAttribute("user.name") + ":" + applicationSettings.getAttribute("password"); DominoAccess.CUSTOMER_DB = applicationSettings.getAttribute("customer.db"); DominoAccess.SALES_DB = applicationSettings.getAttribute("sales.db"); DominoAccess.PRODUCTS_DB = applicationSettings.getAttribute("product.db"); if (Boolean .valueOf(applicationSettings.getAttribute("use.single.signon")) .booleanValue()) { try { CredentialVaultService credentialVaultService = (CredentialVaultService) portletContext.getService( CredentialVaultService.class); Subject subject = credentialVaultService.getUserSubject(portletRequest); Set privateCredentials = subject.getPrivateCredentials(); Iterator iterator = privateCredentials.iterator(); com.ibm.wps.sso.LTPATokenCredential ltpaToken = (com.ibm.wps.sso.LTPATokenCredential) iterator.next(); key = dominoHost + ":" + ltpaToken.getTokenString(); } catch (Exception e) { e.printStackTrace(); } } KEY = key; } public static CustomerBean[] getCustomers() { try { DominoAccess dominoAccess = DominoAccess.getInstance(); return dominoAccess.getCustomers(KEY); } catch (Exception e) { e.printStackTrace(); } return null; } public static SalesPersonBean[] getSalesPersons() { 500 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 try { DominoAccess dominoAccess = DominoAccess.getInstance(); return dominoAccess.getSalesPersons(KEY); } catch (Exception e) { e.printStackTrace(); } return null; } public static boolean addCustomer(CustomerBean customerBean) { try { DominoAccess dominoAccess = DominoAccess.getInstance(); dominoAccess.addNewCustomer(KEY, customerBean); return true; } catch (Exception e) { e.printStackTrace(); } return false; } public static boolean deleteCustomer(CustomerBean customerBean) { try { if (customerBean.getNoteId() != null) { DominoAccess dominoAccess = DominoAccess.getInstance(); dominoAccess.deleteCustomer(KEY, customerBean.getNoteId()); return true; } } catch (Exception e) { e.printStackTrace(); } Chapter 6. Portlet development using Java: Integration examples 501 return false; } public static CustomerBean getCustomer(String noteId) { try { DominoAccess dominoAccess = DominoAccess.getInstance(); return dominoAccess.getCustomerByNoteId(KEY, noteId); } catch (Exception e) { e.printStackTrace(); } return null; } public static CustomerBean getCustomerByName(String name) { try { DominoAccess dominoAccess = DominoAccess.getInstance(); return dominoAccess.getCustomersByName(KEY, name)[0]; } catch (Exception e) { e.printStackTrace(); } return null; } } 9. Add the class com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection to the DominoAccess project (Example 6-24 on page 503). 502 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 6-24 CustomerBeanCollection package com.ibm.itso.cam.redbooks.sg246466.domino; public class CustomerBeanCollection { private CustomerBean[] customerBeans = null; public CustomerBean[] getCustomerBeans() { if (customerBeans == null) { customerBeans = DominoAccessProxy.getCustomers(); } return customerBeans; } public void setCustomerBeans(CustomerBean[] customerBeans) { this.customerBeans = customerBeans; } } 10.Add the class com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCollection to the DominoAccess project (Example 6-25). Example 6-25 SalesPersonBeanCollection.java package com.ibm.itso.cam.redbooks.sg246466.domino; public class SalesPersonBeanCollection { private SalesPersonBean[] salesPersonBeans = null; public SalesPersonBean[] getSalesPersonBeans() { if (salesPersonBeans == null) { salesPersonBeans = DominoAccessProxy.getSalesPersons(); } return salesPersonBeans; } public void setSalesPersonBeans(SalesPersonBean[] salesPersonBeans) { this.salesPersonBeans = salesPersonBeans; } Chapter 6. Portlet development using Java: Integration examples 503 } 11.Export the DominoAccess project to DominoAccess.jar. 6.5.2 SalesTrackingStruts project Next, we create a new portlet project for Struts. 1. We create a new portlet project. Instead of choosing the Basic portlet, we choose the Struts portlet (Figure 6-47). Figure 6-47 Create Struts portlet project 2. We can use the default features of the Struts project, so click Finish. 3. If you get a Repair Server Configuration dialog, click OK. 4. WSAD creates a Struts project and when it is finished, copy DominoAccess.jar, NCSO.jar, commons-pool-1.1.jar, and commons-collections-3.0.jar to the WEB-INF/lib directory and open a Web diagram file diagram.gph (if it is not open already). 504 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.5.3 Drawing a Struts application The Web diagram (Figure 6-48) allows us to model our Struts application before generating any code. This makes it easy to describe the relationships and the flow within the portal prior to coding. We define the relationship among the portal elements and the wizards generate the code based on certain assumptions we describe in the diagram and we do not have to write so much code. Figure 6-48 New Struts portlet project As we recall from 6.2.2, “Portal application functionality” on page 397, we remember that the Struts application should list customers and have the ability to add, edit, and delete customers. With this in mind, we start visualizing our application using the Web diagram. On the right side of WSAD, there is a Palette of Struts tools. The tools include Web page, JavaBeans, and Actions. We use these to model our application. 1. First, we need a starting page for our application. Select Web page from the Palette and drop it into the Web diagram. Name the page /index.jsp (Figure 6-49 on page 506). Chapter 6. Portlet development using Java: Integration examples 505 Figure 6-49 Web diagram with index.jsp 2. We need two other JSPs: Customers.jsp and CustomerDetails.jsp, so add them to the Web diagram. 3. We want to initialize DominoAccess to use SSO in this application and we decide to initialize it when displaying the Customers.jsp. So we add an action that sets SSO for our Struts application. Select Action mapping from the palette and place the action between index.jsp and Customers.jsp. Name the action /setSingleSignOn (Figure 6-50 on page 507). 506 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-50 Set single sign on action We notice that all our components are grey and unrealized. We realize them later. 4. Next, we want to have connections between components. We decide that from index.jsp we want to go to Customers.jsp and also set SSO before displaying customers. From Customer.jsp, a link back to index.jsp would be helpful. We do this by selecting Connection from the Palette and then clicking index.jsp. Move the mouse cursor on top of the setSingleSignon action and press the left mouse button. A dashed connection appears between the components. We also want a connection between setSingleSignOn action and Customers.jsp. Add a connection by clicking on top of the action and then move over the top of Customers.jsp. When editable text appears, write /showCustomers as the name of the connection. We add also a connection between Customers.jsp and index.jsp (Figure 6-51 on page 508). Chapter 6. Portlet development using Java: Integration examples 507 Figure 6-51 Connections between index.jsp and Customers.jsp We want to list customers in Customers.jsp in a fashion similar to what was shown in 6.4.3, “CustomersPortlet” on page 434. So we need couple of JavaBeans: one for customers and the other for sales persons. We use the two collection beans that we created in 6.5.1, “Adding classes to DominoAccess” on page 498. 5. Select Java Bean from the Palette and drop it somewhere in the Web diagram. A dialog box opens; add the following values: – Type: com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection – ID: customers – Scope: session 6. Add the JavaBean SalesPersonBeanCollection with the ID salesPersons and scope session (Figure 6-52 on page 509). 508 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-52 CustomerBeanCollection and SalesPersonBeanCollection in Web diagram 7. We want paging for our customer list, so we add the actions nextPage and previousPage and a JavaBean called PageIndex to hold the page index. Name the connections from the next and previous actions to Customers.jsp as showCustomers. Also add a JavaBean with session scope and class type salestrackingstruts.PageIndex and ID customersPageIndex (Figure 6-53 on page 510). Chapter 6. Portlet development using Java: Integration examples 509 Figure 6-53 Struts application with paging We want to add a new customer using the CustomerDetails page that is also used to edit an existing customer. For this, we need a form bean. 8. Select Form Bean from Palette and place it in the diagram. The dialog opens; add the following values: – Name: customerFormBean – Scope: session 9. Add the actions called /showCustomerDetails and /editCustomer. Also, add a JavaBean with the following values: – Type: salestrackingstruts.MessageBean – ID: messageBean – Scope: request 10.Add the following connections: – Customers.jsp -> /showCustomerDetails – /showCustomerDetails -> CustomerDetails.jsp (name: showCustomerDetails) 510 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – CustomerDetails.jsp -> Customers.jsp – CustomerDetails.jsp -> /editCustomer – /editCustomer -> CustomerDetails.jsp (name: saveFailure) – /editCustomer -> Customers.jsp (name: saveSuccess) We have now designed our Struts application (Figure 6-54). The next task is to start realizing JSPs, JavaBeans, and actions. We come back to the diagram to specify relations between JavaBeans and JSPs/actions. Figure 6-54 SalesTrackingStruts application (unrealized) 6.5.4 Realizing JSPs and JavaBeans We start realizing our application from index.jsp. 1. Double-click the index.jsp component. A dialog New JSP file opens, but we do not change anything and just accept the defaults. Click Finish. 2. index.jsp opens and it includes code from the template. We write our own JSP (Example 6-26 on page 512). Chapter 6. Portlet development using Java: Integration examples 511 Example 6-26 index.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <portletAPI:init /> <h4>Sales Tracking Struts application</h4> <html:link action="/setSingleSignOn">Customers</html:link> This JSP references the Struts tag libraries and they include Struts HTML tags, like <html:link>, which is used in index.jsp. The Palette in WSAD has a list of Struts HTML tags and we will use many of them in this application. 3. Right-click the SalesTrackingStruts project and select Properties. Select Web Project Features, check JSP Tag Libraries, and click OK. 4. Next, we write Customers.jsp and CustomerDetails.jsp (Example 6-27 and Example 6-28 on page 514). Example 6-27 Customers.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@taglib uri="/WEB-INF/tld/people.tld" prefix="pa"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <jsp:useBean id="customers" class="com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection" scope="session"></jsp:useBean> <jsp:useBean id="customersPageIndex" class="salestrackingstruts.PageIndex" scope="session"></jsp:useBean> <jsp:useBean id="salesPersons" class="com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCollection" scope="session"></jsp:useBean> <jsp:useBean id="messageBean" scope="request" class="salestrackingstruts.MessageBean"></jsp:useBean> 512 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <portletAPI:init /> <h3>Customers</h3> <c:if test="${not empty messageBean.message}"> <bean:write name="messageBean" property="message" scope="request" /> </c:if> <table> <thead> <tr> <th>Name</th> <th>CustomerNumber</th> <th>AccountOwner</th> </tr> </thead> <tbody> <c:forEach var="varCustomerBeans" items="${customers.customerBeans}" begin="${customersPageIndex.startPageIndex}" end="${customersPageIndex.endPageIndex}" step="1" varStatus="status"> <tr> <td><html:link action="/showCustomerDetails" paramId="noteId" paramName="varCustomerBeans" paramProperty="noteId"> <c:out value="${varCustomerBeans.name}" /> </html:link></td> <td><c:out value="${varCustomerBeans.customerNumber}" /></td> <td><c:forEach var="varSalesPerson" items="${salesPersons.salesPersonBeans}"> <c:if test="${varCustomerBeans.accountOwner == varSalesPerson.employeeNumber}"> <pa:person><c:out value="${varSalesPerson.name}"/></pa:person> </c:if> </c:forEach></td> </tr> </c:forEach> <tr> <td>Total: <%=String.valueOf(customers.getCustomerBeans().length)%></td> <td><html:link action="/previousPage">Previous</html:link></td> <td><html:link action="/nextPage">Next</html:link></td><tr> </tbody> </table> <br /> <html:link action="/showCustomerDetails">Add new customer</html:link> <br /> <html:link forward="/main">Main</html:link> In this JSP, we introduce our JavaBeans for the page and have a simple table for displaying customers. Note how we use JSTL tags, such as <forEach>, in Chapter 6. Portlet development using Java: Integration examples 513 this JSP. This also uses <html:link> tags with either an action or forward attribute. For now, we do not worry about any errors that we get. Example 6-28 CustomerDetails.jsp <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <jsp:useBean id="salesPersons" scope="session" class="com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCollection"></j sp:useBean> <c:set value="${salesPersons.salesPersonBeans}" var="salesPersonBeans" scope="session" /> <portletAPI:init /> <html> <body> <h3>Customer details</h3> <html:errors /> <html:form action="/editCustomer" scope="session"> <table border="0" cellpadding="1" cellspacing="1"> <tbody> <tr> <td>Name</td> <td><html:text property="name" /></td> </tr> <tr> <td>Customer number</td> <td><html:text property="customerNumber" /></td> </tr> <tr> <td>Account owner</td> <td><html:select property="accountOwner"> <html:options collection="salesPersonBeans" property="employeeNumber" labelProperty="name" /> </html:select></td> </tr> <tr> 514 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <td>Employee total</td> <td><html:text property="employeeTotal" /></td> </tr> <tr> <td>Address</td> <td><html:textarea property="address" /></td> </tr> <tr> <td>Additional information</td> <td><html:textarea property="additionalInformation" /></td> </tr> <tr> <td><html:submit property="action" value="Save" /></td> <td><html:submit property="action" value="Delete" /></td> </tr> </tbody> </table> </html:form> <br> <html:link forward="/customers">Back</html:link> <br /> <html:link forward="/main">Main</html:link> </body> </html> 5. Next, we realize MessageBean and PageIndexBean. Double-click JavaBean in the Web diagram. In the New Java class dialog, click Finish. The source for the bean is opened and we write our beans as shown in Example 6-29 and Example 6-30 on page 516. Example 6-29 PageIndex.java package salestrackingstruts; public class PageIndex { private int startPageIndex = 0; private int endPageIndex = 4; public void setStartPageIndex(int newStartPageIndex) { this.startPageIndex = newStartPageIndex; } public int getStartPageIndex() { return startPageIndex; } Chapter 6. Portlet development using Java: Integration examples 515 public void setEndPageIndex(int newEndPageIndex) { this.endPageIndex = newEndPageIndex; } public int getEndPageIndex() { return endPageIndex; } } Example 6-30 MessageBean.java package salestrackingstruts; public class MessageBean { private String message = ""; public void setMessage(String newMessage) { this.message = newMessage; } public String getMessage() { return message; } } 6. The rebuild project and error messages in Customers.jsp disappear. There are still many warnings, but they are corrected as we continue development. 7. Recall what beans we are using in the JSP files. Open the Web diagram and connect beans to JSP files. Now our Web diagram looks like Figure 6-55 on page 517. 516 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-55 SalesTrackingStruts Web diagram Some elements are now realized, but many are not, so we still have work ahead. Next, we realize customerFormBean. 8. Double-click customerFormBean. The New Form-Bean dialog opens (Figure 6-56 on page 518). Chapter 6. Portlet development using Java: Integration examples 517 Figure 6-56 New Form Bean 9. Click Next. Go to the SalesTrackingStruts project and find the editCustomer action in CustomerDetails.jsp. Choose all except the submit fields (Figure 6-57 on page 519). 518 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-57 Choose form fields 10.Click Next. 11.Now we choose which fields to create in our form bean. Recall that in our CustomerBean, we use the same field names and types as are in the CustomerBean (see Figure 6-58 on page 520). Chapter 6. Portlet development using Java: Integration examples 519 Figure 6-58 Create fields for form bean 12.Click Next. 13.Uncheck the Reset and Validate Method stubs. Click Finish. 14.WSAD generates CustomerFormBean and opens it. Go to the Web diagram and connect customerFormBean to CustomerDetails.jsp and /showCustomerDetails action. 6.5.5 Realizing actions 1. Double-click the /setSingleSignOn action. The New Action Mapping dialog box opens (Figure 6-59 on page 521). 520 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-59 Add new action mapping Note the configuration file name, action mapping path, and forwards fields. 2. Click Finish. 3. WSAD creates the SetSingleSignOnAction.java class and uses the Struts action template. The template is very useful and we have to add three lines (and import statements) to it. The complete Java source for the action is presented in Example 6-31. Example 6-31 SetSingleSignOnAction.java package salestrackingstruts.actions; import import import import import import import org.apache.jetspeed.portlet.PortletContext; org.apache.jetspeed.portlet.PortletRequest; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; Chapter 6. Portlet development using Java: Integration examples 521 import com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccessProxy; import com.ibm.wps.portlets.struts.WpsActionServlet; import com.ibm.wps.struts.action.StrutsAction; /** * @version 1.0 * @author */ public class SetSingleSignOnAction extends StrutsAction { public ActionForward execute( ActionMapping mapping, ActionForm form, PortletRequest request) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); // return value try { // do something here WpsActionServlet strutsServlet = (WpsActionServlet) request.getAttribute("spf_wpsActionServlet"); PortletContext portletContext = strutsServlet.getPortletContext(); DominoAccessProxy.init(request, portletContext); } catch (Exception e) { // Report the error using the appropriate name and ID. errors.add("name", new ActionError("id")); } // If a message is required, save the specified key(s) // into the request for use by the <struts:errors> tag. if (!errors.isEmpty()) { } // Write logic determining how the user should be forwarded. forward = mapping.findForward("/showCustomers"); // Finish with 522 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 return (forward); } } PortletContext is retrieved using the WpsActionServlet.getPortletContext() method, which is an undocumented feature. Action calls the DominoAccessProxy.init() method and sets the Domino server and other parameters. Parameters are read from PortletApplicationSettings, so we have to add them to the portlet.xml (see Example 6-38 on page 539). 4. Add actions for /previousPage and /nextPage (Example 6-32 and Example 6-33 on page 525). Example 6-32 PreviousPageAction.java package salestrackingstruts.actions; import import import import import import import org.apache.jetspeed.portlet.PortletRequest; org.apache.jetspeed.portlet.PortletSession; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; import salestrackingstruts.PageIndex; import com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection; import com.ibm.wps.struts.action.StrutsAction; /** * @version 1.0 * @author */ public class PreviousPageAction extends StrutsAction { public ActionForward execute( ActionMapping mapping, ActionForm form, PortletRequest request) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); // return value try Chapter 6. Portlet development using Java: Integration examples 523 { // do something here PortletSession session = request.getPortletSession(); PageIndex pageIndex = (PageIndex) session.getAttribute("customersPageIndex"); CustomerBeanCollection customers = (CustomerBeanCollection) session.getAttribute("customers"); int customersLength = customers.getCustomerBeans().length; int startIndex = pageIndex.getStartPageIndex(); int endIndex = pageIndex.getEndPageIndex(); if ((startIndex - 5) < 0) { pageIndex.setStartPageIndex(0); } else { pageIndex.setStartPageIndex((startIndex - 5)); } endIndex = startIndex + 4; if ((endIndex - 5) < 4) { pageIndex.setEndPageIndex(4); } else { pageIndex.setEndPageIndex(endIndex - 5); } session.setAttribute("customersPageIndex", pageIndex); } catch (Exception e) { // Report the error using the appropriate name and ID. errors.add("name", new ActionError("id")); } // If a message is required, save the specified key(s) // into the request for use by the <struts:errors> tag. if (!errors.isEmpty()) { } else { 524 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 // Write logic determining how the user should be forwarded. forward = mapping.findForward("showCustomersPage"); } // Finish with return (forward); } } Example 6-33 NextPageAction.java package salestrackingstruts.actions; import import import import import import import org.apache.jetspeed.portlet.PortletRequest; org.apache.jetspeed.portlet.PortletSession; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; import salestrackingstruts.PageIndex; import com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection; import com.ibm.wps.struts.action.StrutsAction; /** * @version 1.0 * @author */ public class NextPageAction extends StrutsAction { public ActionForward execute( ActionMapping mapping, ActionForm form, PortletRequest request) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); // return value try { // do something here PortletSession session = request.getPortletSession(); Chapter 6. Portlet development using Java: Integration examples 525 PageIndex pageIndex = (PageIndex) session.getAttribute("customersPageIndex"); CustomerBeanCollection customers = (CustomerBeanCollection) session.getAttribute("customers"); int customersLength = customers.getCustomerBeans().length; int startIndex = pageIndex.getStartPageIndex(); int endIndex = pageIndex.getEndPageIndex(); if ((startIndex + 5) < customersLength) { pageIndex.setStartPageIndex(startIndex + 5); } if ((endIndex + 5) >= customersLength) { pageIndex.setEndPageIndex(customersLength); } else { pageIndex.setEndPageIndex(endIndex + 5); } session.setAttribute("customersPageIndex", pageIndex); } catch (Exception e) { // Report the error using the appropriate name and ID. errors.add("name", new ActionError("id")); } // If a message is required, save the specified key(s) // into the request for use by the <struts:errors> tag. if (!errors.isEmpty()) { // Forward control to the appropriate 'failure' URI (change name as desired) //forward = mapping.findForward("failure"); } else { // Forward control to the appropriate 'success' URI (change name as desired) forward = mapping.findForward("showCustomersPage"); } 526 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 // Finish with return (forward); } } 5. Add the action for /showCustomerDetails (Example 6-34). Example 6-34 ShowCustomerDetailsAction.java package salestrackingstruts.actions; import import import import import import org.apache.jetspeed.portlet.PortletRequest; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; import salestrackingstruts.forms.CustomerFormBean; import com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean; import com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccessProxy; import com.ibm.wps.struts.action.StrutsAction; /** * @version 1.0 * @author */ public class ShowCustomerDetailsAction extends StrutsAction { public ActionForward execute( ActionMapping mapping, ActionForm form, PortletRequest request) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); // return value try { // do something here String noteId = request.getParameter("noteId"); if (noteId != null) { Chapter 6. Portlet development using Java: Integration examples 527 CustomerBean customerBean = DominoAccessProxy.getCustomer(noteId); //populate form bean CustomerFormBean formBean = (CustomerFormBean) form; formBean.setName(customerBean.getName()); formBean.setNoteId(customerBean.getNoteId()); formBean.setAddress(customerBean.getAddress()); formBean.setAdditionalInformation( customerBean.getAdditionalInformation()); formBean.setAccountOwner(customerBean.getAccountOwner()); formBean.setCustomerNumber(customerBean.getCustomerNumber()); formBean.setEmployeeTotal(customerBean.getEmployeeTotal()); } else { request.getPortletSession().removeAttribute("customerFormBean"); } } catch (Exception e) { // Report the error using the appropriate name and ID. errors.add("name", new ActionError("id")); } // If a message is required, save the specified key(s) // into the request for use by the <struts:errors> tag. if (!errors.isEmpty()) { } else { // Write logic determining how the user should be forwarded. forward = mapping.findForward("showCustomerDetails"); } // Finish with return (forward); } } 6. The last action we realize is the /editCustomer (Example 6-35 on page 529). 528 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 6-35 EditCustomerAction.java package salestrackingstruts.actions; import import import import import import import org.apache.jetspeed.portlet.PortletRequest; org.apache.jetspeed.portlet.PortletSession; org.apache.struts.action.ActionError; org.apache.struts.action.ActionErrors; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping; import salestrackingstruts.MessageBean; import salestrackingstruts.forms.CustomerFormBean; import com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean; import com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccessProxy; import com.ibm.wps.struts.action.StrutsAction; /** * @version 1.0 * @author */ public class EditCustomerAction extends StrutsAction { public ActionForward execute( ActionMapping mapping, ActionForm form, PortletRequest request) throws Exception { ActionErrors errors = new ActionErrors(); ActionForward forward = new ActionForward(); // return value try { // do something here PortletSession session = request.getPortletSession(); MessageBean msg = new MessageBean(); request.setAttribute("messageBean", msg); CustomerBean customerBean = new CustomerBean(); CustomerFormBean customerFormBean = (CustomerFormBean) form; customerBean.setName(customerFormBean.getName()); customerBean.setNoteId(customerFormBean.getNoteId()); customerBean.setAddress(customerFormBean.getAddress()); customerBean.setAdditionalInformation( customerFormBean.getAdditionalInformation()); Chapter 6. Portlet development using Java: Integration examples 529 customerBean.setAccountOwner(customerFormBean.getAccountOwner()); customerBean.setCustomerNumber(customerFormBean.getCustomerNumber()); customerBean.setEmployeeTotal(customerFormBean.getEmployeeTotal()); boolean delete = request.getParameter("action").equals("Delete"); if (delete) { if (!DominoAccessProxy.deleteCustomer(customerBean)) { errors.add( "deleteFailure", new ActionError("error.editcustomer.delete.failure")); } else { msg.setMessage("Delete successful."); session.removeAttribute("customers"); } } else { if (!DominoAccessProxy.addCustomer(customerBean)) { errors.add( "saveFailure", new ActionError("error.editcustomer.save.failure")); } else { msg.setMessage("Save successful."); session.removeAttribute("customers"); } } } catch (Exception e) { // Report the error using the appropriate name and ID. if (e instanceof NumberFormatException) { errors.add( "saveFailure", new ActionError("error.savecustomer.employee.total")); } else { errors.add("name", new ActionError("id")); 530 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 } } // If a message is required, save the specified key(s) // into the request for use by the <struts:errors> tag. if (!errors.isEmpty()) { saveErrors(request, errors); forward = mapping.findForward("saveFailure"); } else { // Write logic determining how the user should be forwarded. forward = mapping.findForward("saveSuccess"); } // Finish with return (forward); } } MessageBean is used in this action to provide a message about the action result. 6.5.6 Adding global forwards We notice that we have warnings about broken links. To correct them, we have to change the Struts configuration file. Locate struts-config.xml under WEB-INF directory and double-click. Go to Global Forwards and add the following forwards (Figure 6-60 on page 532): /main: Path attribute is index.jsp. /customers: Path attribute is Customers.jsp Chapter 6. Portlet development using Java: Integration examples 531 Figure 6-60 Add Global Forwards Now our Struts application is ready and the Web diagram looks like Figure 6-61 on page 533. 532 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-61 Completed SalesTrackingStruts application If the connection between customerFormBean and CustomerDetails.jsp is not solid, then do the following Double-click the /showCustomerDetails action. Under Form Bean Specification, select session for scope. Close and save. There may be still some dashed lines in the diagram between JSPs and actions, but since we know for a fact that the links are realized, we conclude that the diagram is not updated correctly. 6.5.7 Testing the application Run SalesTrackingStruts on the test environment (see Figure 6-62 on page 534, Figure 6-63 on page 534, and Figure 6-64 on page 534). Chapter 6. Portlet development using Java: Integration examples 533 Figure 6-62 SalesTrackingStruts, page 1 Figure 6-63 SalesTrackingStruts, page 2 Figure 6-64 SalesTrackingStruts, page 3 534 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.5.8 Deployment descriptors Before deploying the application to our production server, let us take a look at deployment descriptors. In addition to web.xml and portlet.xml, the Struts portlet application also includes struts-config.xml. Struts-config.xml The file struts-config.xml (Example 6-36) holds all the specific mapping information and is consulted at each request. This file specifies details of the action being invoked: who is supposed to be calling the action, the form beans associated with the initiating form or JSP, action targets and forwards, and so on. For the most part, the WSAD wizards add the necessary information but we need to update that manually from time to time, as we did in 6.5.6, “Adding global forwards” on page 531. Example 6-36 struts-config.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> <struts-config> <!-- Data Sources --> <data-sources></data-sources> <!-- Form Beans --> <form-beans> <form-bean name="customerFormBean" type="salestrackingstruts.forms.CustomerFormBean"></form-bean> </form-beans> <!-- Global Exceptions --> <global-exceptions></global-exceptions> <!-- Global Forwards --> <global-forwards> <forward name="/main" path="index.jsp"></forward> <forward name="/customers" path="Customers.jsp"></forward> </global-forwards> <!-- Action Mappings --> <action-mappings> Chapter 6. Portlet development using Java: Integration examples 535 <action path="/setSingleSignOn" type="salestrackingstruts.actions.SetSingleSignOnAction"> <forward name="/showCustomers" path="/Customers.jsp"></forward> </action> <action path="/previousPage" type="salestrackingstruts.actions.PreviousPageAction"> <forward name="showCustomersPage" path="/Customers.jsp"></forward> </action> <action path="/nextPage" type="salestrackingstruts.actions.NextPageAction"> <forward name="showCustomersPage" path="/Customers.jsp"></forward> </action> <action name="customerFormBean" path="/showCustomerDetails" scope="session" type="salestrackingstruts.actions.ShowCustomerDetailsAction"> <forward name="showCustomerDetails" path="/CustomerDetails.jsp"></forward> </action> <action name="customerFormBean" path="/editCustomer" type="salestrackingstruts.actions.EditCustomerAction" scope="session"> <forward name="saveSuccess" path="/Customers.jsp"></forward> <forward name="saveFailure" path="/CustomerDetails.jsp"></forward> </action> </action-mappings> <!--Controller--> <controller processorClass="com.ibm.wps.portlets.struts.WpsRequestProcessor"></controller> <!-- Message Resources --> <message-resources parameter="salestrackingstruts.resources.ApplicationResources" /> </struts-config> Struts-config.xml includes global forwards, actions, form beans, and other information about the application. What we did in the Web diagram is referenced here. For example, notice the action with the path /editCustomer. It has two forwards and recall how we specified them in the Web diagram and in the action class. Web.xml and portlet.xml Web.xml (Example 6-37 on page 537) and portlet.xml (Example 6-38 on page 539) has much Struts specific configuration. Web.xml includes references to Struts tag libraries, parameters for WpsStrutsPortlet, and mappings. While we developed our Struts portlet application, we did not write any portlet specific code, except that we used classes from IBM Portlet API like PortletRequest. All portlet specific code is done in WpsStrutsPortlet class and it allows us to develop portlets without coding against IBM Portlet API. 536 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Portlet.xml has the configuration parameters that we need to configure when we deploy an application to the server. Example 6-37 web.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <display-name>SalesTrackingStruts</display-name> <servlet id="Servlet_1097070551889"> <servlet-name>salestrackingstruts.SalesTrackingStrutsPortlet</servlet-name> <display-name>salestrackingstruts.SalesTrackingStrutsPortlet</display-name> <servlet-class>com.ibm.wps.portlets.struts.WpsStrutsPortlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>WEB-INF/struts-config.xml</param-value> </init-param> <init-param> <param-name>struts-servlet-mapping</param-name> <param-value>*.do</param-value> </init-param> <init-param> <param-name>ModuleSearchPath</param-name> <param-value>markupName, mode, locale</param-value> </init-param> <init-param> <param-name>IncludesSearchPath</param-name> <param-value>manufacturer, model, version</param-value> </init-param> <init-param> <param-name>EditModeLabel</param-name> <param-value>edit</param-value> </init-param> <init-param> <param-name>ConfigureModeLabel</param-name> <param-value>configure</param-value> </init-param> <init-param> <param-name>HelpModeLabel</param-name> <param-value>help</param-value> </init-param> <init-param> <param-name>ViewModeLabel</param-name> <param-value>view</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>salestrackingstruts.SalesTrackingStrutsPortlet</servlet-name> Chapter 6. Portlet development using Java: Integration examples 537 <url-pattern>/salestrackingstruts.SalesTrackingStrutsPortlet/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-chtml.tld</taglib-uri> <taglib-location>/WEB-INF/struts-chtml.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri> <taglib-location>/WEB-INF/struts-logic.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri> <taglib-location>/WEB-INF/struts-nested.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-portal-html.tld</taglib-uri> <taglib-location>/WEB-INF/struts-portal-html.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-portal-wml.tld</taglib-uri> <taglib-location>/WEB-INF/struts-portal-wml.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-template.tld</taglib-uri> <taglib-location>/WEB-INF/struts-template.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri> <taglib-location>/WEB-INF/struts-tiles.tld</taglib-location> </taglib> <taglib> <taglib-uri>/WEB-INF/struts-wml.tld</taglib-uri> 538 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <taglib-location>/WEB-INF/struts-wml.tld</taglib-location> </taglib> </web-app> Example 6-38 portlet.xml <?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="salestrackingstruts.SalesTrackingStrutsPortlet.9a7008e6ff" major-version="1" minor-version="0"> <portlet-app-name>SalesTrackingStruts application</portlet-app-name> <portlet id="salestrackingstruts.SalesTrackingStrutsPortlet" href="WEB-INF/web.xml#Servlet_1097070551889" major-version="1" minor-version="0"> <portlet-name>SalesTrackingStruts portlet</portlet-name> <cache> <expires>0</expires> <shared>no</shared> </cache> <allows> <maximized /> <minimized /> </allows> <supports> <markup name="html"> <view /> </markup> </supports> </portlet> </portlet-app> <concrete-portlet-app uid="salestrackingstruts.SalesTrackingStrutsPortlet.1409c7e6ff.1"> <portlet-app-name>SalesTrackingStruts application</portlet-app-name> <context-param> <param-name>domino.host.address</param-name> <param-value>domino651.swic.fi.ibm.com</param-value> </context-param> <context-param> <param-name>use.single.signon</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>customer.db</param-name> <param-value>redbook/customer.nsf</param-value> </context-param> <context-param> <param-name>sales.db</param-name> Chapter 6. Portlet development using Java: Integration examples 539 <param-value>redbook/sales.nsf</param-value> </context-param> <context-param> <param-name>product.db</param-name> <param-value>redbook/products.nsf</param-value> </context-param> <context-param> <param-name>user.name</param-name> <param-value>test person</param-value> </context-param> <context-param> <param-name>password</param-name> <param-value>password</param-value> </context-param> <concrete-portlet href="#salestrackingstruts.SalesTrackingStrutsPortlet"> <portlet-name>SalesTrackingStruts portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>SalesTrackingStruts portlet</title> <title-short></title-short> <description></description> <keywords>WPS, Struts</keywords> </language> <config-param> <param-name>FilterChain</param-name> <param-value>StrutsTranscoding</param-value> </config-param> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> 6.5.9 Deployment 1. Export the SalesTrackingStruts application to the SalesTrackingStrutsRedbookSample.war file. The contents of the war file are shown in Example 6-39. Example 6-39 Contents of SalesTrackingStrutsRedbookSample.war | CustomerDetails.jsp | Customers.jsp | index.jsp | +---META-INF | MANIFEST.MF | \---WEB-INF 540 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 | ibm-web-bnd.xmi | ibm-web-ext.xmi | portlet.xml | struts-bean.tld | struts-chtml.tld | struts-config.xml | struts-html.tld | struts-logic.tld | struts-nested.tld | struts-portal-html.tld | struts-portal-wml.tld | struts-template.tld | struts-tiles.tld | struts-wml.tld | web.xml | +---classes | \---salestrackingstruts | | MessageBean.class | | PageIndex.class | | | +---actions | | EditCustomerAction.class | | NextPageAction.class | | PreviousPageAction.class | | SetSingleSignOnAction.class | | ShowCustomerDetailsAction.class | | | +---forms | | CustomerFormBean.class | | | \---resources | ApplicationResources.properties | \---lib commons-beanutils.jar commons-collections-3.0.jar commons-collections.jar commons-digester.jar commons-fileupload.jar commons-lang.jar commons-logging.jar commons-pool-1.1.jar commons-validator.jar DominoAccess.jar jakarta-oro.jar jaxen-full.jar jstl.jar NCSO.jar Chapter 6. Portlet development using Java: Integration examples 541 PortalStruts.jar PortalStrutsCommon.jar PortalStrutsTags.jar saxpath.jar standard.jar struts.jar StrutsUpdateForPortal.jar There are many Struts specific jar files in the lib directory. The Struts tag library descriptor files are in the Web-inf directory. In the classes/resources directory, there is a file called ApplicationResources.properties that abstracts textual data from an application. Resource files maintain a set of name/value pairs which can be accessed easily from JSPs. For example, we might want submit buttons be labeled "Submit." This is defined in the resource file, and the label is referenced from all the JSPs by its assigned name only. This means that if we decide to change the buttons to "Submit Query" across the board, there is only one location to edit. The resource file has many other more interesting uses, such as header or footer text, titles of sections of the application or Web site, and so forth. A value in the properties file can be accessed from JSP using the <bean:message key=”some.key”/> tag, where key “some.key” is in ApplicatiotionResources.properties with a value of some.key=some text. 2. Install the SalesTrackingStruts application on the server. Since we did not implement a configure mode for the portlet, we have to modify parameters using WPS administration portlets. 3. After installing the portlet, go to the Manage applications portlet and select the SalesTrackingStruts application (Figure 6-65 on page 543). 542 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-65 Manage SalesTrackingStruts application 4. Click Modify parameters (Figure 6-66 on page 544). Chapter 6. Portlet development using Java: Integration examples 543 Figure 6-66 Manage SalesTrackingStruts application parameters 5. Configure the parameters to match your environment and enable single sign-on. Click Save at the bottom of the page. 6. Add the SalesTrackingStruts portlet to a new or existing page (see Figure 6-67 on page 545). 544 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-67 SalesTrackingStruts application with awareness 6.5.10 Summary The Struts development process described in this section gives a good starting point for developing portlets using the Struts framework. WSAD offers valuable tools for developing portlets with Struts. We can use a graphical tool to design and re-designing our application before we have to do any coding. It is also simple to add new functionality later to the Struts application; just modify the Web diagram and realize necessary actions, beans, and pages. The actual coding is simplified compared to coding using IBM Portlet API. All actions are separated from other actions, so there is no need to code everything in the actionPerformed() method. We did not need to code using IBM Portlet API, but we do need to know about the API and what it offers, especially in JSPs and actions where we can use API classes directly. Chapter 6. Portlet development using Java: Integration examples 545 Note: The SalesTrackingStruts_Project.zip file has the SalesTrackingStruts project ready for importing to WSAD. See Appendix C, “Additional material” on page 741 for download instructions. 6.6 Sales Tracking application using JSF This section shows how to develop a portal application based on Java Server Faces. 6.6.1 SalesTrackingJSF project 1. Create a new portlet project. Enter the project name SalesTrackingJSF and make sure to select the option Faces portlet. Click Next. 2. Click Next. 3. In the Feature pages, check the Web Project feature: JSP Tag Libraries. Click Finish. WSAD creates a new project and opens a JSP page SalesTrackingJSFView.jsp for editing, displaying either source or design, as in Figure 6-68 on page 547. 546 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-68 SalesTrackingJSF project Tip: If you do not see the string Place content here or it looks strange, there may be a problem with the fonts. Go to the WSAD menu and select Window → Preferences. Select Web Tools → Page Design → Fonts and change to the preferred fonts. Notice on the Palette that we have many Faces Components. We use these components to design our JSP pages. 4. Copy DominoAccess.jar, NCSO.jar, commons-pool-1.1.jar, and commons-collections-3.0.jar to the SalesTrackingJSF/WebContent/WEB-INF/lib directory. Chapter 6. Portlet development using Java: Integration examples 547 6.6.2 index.jsp The first JSP we create is index.jsp, which acts as a starting point for our application. WSAD created the SalesTrackingJSFView.jsp for us, and we use it to display the customer list. 1. Right-click the SalesTrackingJSF project and select New → Faces JSP File. Enter index.jsp as the File name. 2. Click Finish. WSAD creates and opens index.jsp for editing. 3. Open portlet.xml and find the parameter com.ibm.faces.portlet.page.view. Change its value to /index.jsp and save and close the file. 4. Change the text Place context here to SalesTrackingJSF application. In the lower left corner, there is an Attributes section for the selected component. Change the paragraph to Heading 3 (Figure 6-69). Figure 6-69 Index.jsp attributes 5. Click Command - Hyperlink from the Palette to select it and drop it under the heading. You will see a link called link label. In the Attributes, you see attributes for the link command. The command is a JSF element 548 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <h:commandLink> included in a <h:form> element. Curious readers will consult the JSP source to see what kind of JSP our visual programming is creating. We will come back to the attributes later. 6. Click the text link label in the JSP page. The Attributes section now changes to show attributes for <h:outputText>, an element which is included within <h:commandLink>. Enter the text Customers as the value for the output text element. We have now designed the user interface for index.jsp. The next thing we do is to add functionality. As we did with the Struts portlet, clicking the Customers link initializes DominoAccess to use either SSO or predefined user name and password. The JSF portlet uses the same parameters as the Struts application, so remember to add them in the portlet.xml. After initializing DominoAccess, the portlet displays a customer list. This is done by adding code to the hyperlink command and adding a navigation rule. 7. Select <h:commandLink> in the index.jsp. You have to click the icon immediately on the left side of text Customers (Figure 6-70). Figure 6-70 Select <h:commandLink> Chapter 6. Portlet development using Java: Integration examples 549 You will see that below the JSP page there is a Quick Edit window. This can be used to add code to actions. It can be also used to add JavaScript to different events in HTML, such as onBlur, onClick, and so on. 8. Click on the window that says Insert a code snippet or write your script here. It is now an editable window and it has the Java code that handles the command event. Note that you must return a String object or null. The returned string is used when we add navigation. 9. The following code snippet (Example 6-40) initializes the DominoAccess class. Write it in the QuickEdit window. Example 6-40 Code for Customers action Object request=getFacesContext().getExternalContext().getRequest(); Object context=getFacesContext().getExternalContext().getContext(); PortletRequest portletRequest=(PortletRequest)request; PortletContext portletContext=(PortletContext)context; DominoAccessProxy.init(portletRequest,portletContext); return "showCustomers"; We implemented the DominoAccessProxy.init() method so that it accepts PortletContext and PortletRequest as parameters. They are used to get application parameters from portlet.xml and to initialize SSO. Notice how we use the Faces API to get PortletRequest and PortletResponse objects. 10.But as we write the snippet, we get errors that our classes cannot be resolved. To correct this fault, open Index.java in the SalesTrackingJSF/Java Resources/pagecode directory. Right-click somewhere in the editor and select Source → Organize Imports. You get a dialog where you have to choose the type for PortletRequest and PortletContext. Choose the interfaces with the org.apache.jetspeed.portlet package and save the file. Index.java and its PageCodeBase.java super class are generated by WSAD while we design our JSP page. We may add code there if we want to and we use methods in PageCodeBase, such as getRequestScope(), getSessionScope(), and so on, as we will see later. Refer to the JavaServer Faces Technology 1.1_01 Reference Documentation at http://java.sun.com/j2ee/javaserverfaces/reference/api/ to learn how JSF works beneath the surface 11.Next, we add navigation to the link. Select the command link in the JSP design and select the Navigation tab on the Attributes. Click Add. 12.The Add navigation rule dialog opens. Enter the following values: – Page to go to: SalesTrackingJSFView.jsp – Alias: showCustomers, this is the string that we returned from the action. 550 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 There is no need to apply the rule only to a specific action, and we want to make the rule available globally, so select the Globally radio button (Figure 6-71). Figure 6-71 Add navigation to index.jsp 13.Click OK. The first page is now ready and you may test it if you want to. 6.6.3 SalesTrackingJSFView.jsp We use the SalesTrackingJSFView.jsp for listing customers. 1. Change the string Place content here to Customers. 2. We need a customer list for this page. In the Page data section, right-click JSP scripting and select New → JavaBean (Figure 6-72 on page 552). Chapter 6. Portlet development using Java: Integration examples 551 Figure 6-72 Add new JavaBean 3. Enter the following values for the new JavaBean: – Name: customers. – Class: com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection. – Check Make this JavaBean reusable. – Scope: session. Click Finish. In the Page Data, we now have the customer’s JavaBean (Figure 6-73 on page 553). 552 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-73 PageData with CustomerBeanCollection 4. Select customerBeans and drag and drop it in the SalesTrackingJSFVIew below the Customers heading. An Insert JavaBean dialog opens. Choose the following columns for display: name, customerNumber, and accountOwner (see Figure 6-74). Figure 6-74 Insert JavaBean dialog 5. Click Finish. Chapter 6. Portlet development using Java: Integration examples 553 WSAD creates a new output control for customer beans. Because we selected an array of CustomerBeans for output, the output control is a table (Figure 6-75 on page 554). Figure 6-75 SalesTrackingJSFView with CustomerBeans control 6. Save the file. 7. After we run SalesTrackingJSF on the server, we see our customer list displayed (Figure 6-76 on page 555). 554 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-76 SalesTrackingJSF customers list All the customers in the Domino database are displayed in the table. The next thing we want is to have paging, a link back to the main page, and a link to add new customers and each customer name should be a link to customer details. Notice that the account owner displayed here is a number. That is because CustomerBean stores the account owner as a sales person number. In IBM, the API and Struts portlets account owner name is extracted from SalesPersonBeans using the BeanUtils class and the account owner number. But we do not do that here because the main purpose of this section is to show how to build the JSF portlet and that can be done without displaying names in account the owner column. Link to main page 1. Select Link from the Faces Components and drop it below the table. A dialog Configure URL opens. Enter the value /index.jsp for the URL and Main for the label. Chapter 6. Portlet development using Java: Integration examples 555 Figure 6-77 Configure URL 2. Click OK. The JSP page now has a link back to the index page. You may test it if you want to. Paging 1. In the JSP design view, select the <h:dataTable> element (Figure 6-78). Figure 6-78 Select data table 2. Select the Paging tab. 3. Enter 5 as the Items/Page (Figure 6-79 on page 557). 556 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-79 Add deluxe pager 4. Click Add deluxe pager. WSAD adds a custom JSF component for paging a table (Figure 6-80). Figure 6-80 SalesTrackingJSF with deluxe pager 5. Save the file and test the paging functionality. Chapter 6. Portlet development using Java: Integration examples 557 Add new customer action and show details action Next, we add links to customer details page. The customer details page is also used when adding a new customer. 1. Create a new Faces JSP file named CustomerDetails.jsp. We will add functionality to it later. 2. Add a new command link with the name Add new customer above the Main link in the SalesTrackingJSFView.jsp. 3. Type in the following code snippet for the Add new customer action (Example 6-41). Example 6-41 Code for Add new customer action getSessionScope().remove("customerBean"); return "showCustomerDetails"; We remove CustomerBean from the session because we will add a CustomerBean in the session when we want to view customer details. And when we want to add customer details, we remove the existing CustomerBean so that fields in the customer form are not prefilled. To see how it works without removing the CustomerBean, you may comment it out. We return the string “showCustomerDetails” that we will use in navigation. 4. Clicking Add new customer link opens the CustomerDetails.jsp page, so add a navigation rule for it. The rule may be only for the SalesTrackingJSFView page. Save the file. 5. Add a command link to a customer name by selecting Command HyperLink and dropping it on top of the name in the name column (Figure 6-81 on page 559). 558 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-81 Add link to table 6. Save SalesTrackingJSFView.jsp. 7. If you get the following warning: Figure 6-82 Nested tag warning in SalesTrackingJSFView.jsp Double-click the warning and you will see the tag causing the problem (<h:outputText> tag is within another <h:outputText> tag). This was generated when we dropped the command link to the table. Delete the tag, save the file, and the warning disappears. 8. Next, we add a request parameter to the name link. We take the noteId parameter from CustomerBean that we want to use to get the CustomerBean from Domino. Do this by selecting the command link and select the Parameters tab in the Attributes window (Figure 6-83 on page 560). Chapter 6. Portlet development using Java: Integration examples 559 Figure 6-83 Select Parameter tab in SalesTrackingJSFView.jsp Click Add. 9. Enter noteId as the parameter name, and for value, select the noteId field in CustomerBean (see Figure 6-84 on page 561). 560 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-84 Add parameter to link 10.Click OK and save the file. 11.Now we add the action code for the name link. Add the following code snippet (Example 6-42) to the action and save the file. Example 6-42 Code snippet for the show details action String noteId=(String)getRequestParam().get("noteId"); if(noteId!=null) { getSessionScope().put("customerBean",DominoAccessProxy.getCustomer(noteId)); } return "showCustomerDetails"; Here we take the noteId parameter from the request, get CustomerBean from Domino, and add it to the session. SalesTrackingJSFView.jsp is now finished and we have one more JSP to go. Chapter 6. Portlet development using Java: Integration examples 561 6.6.4 CustomerDetails.jsp We created CustomerDetails.jsp in the previous section and now we add functionality to it. This JSP is used to add new customers and edit existing customers. 1. Change Place content here to Customer Details. 2. Add a new JavaBean to the CustomerDetails.jsp page. In the Page Data section, right-click JSP scripting and select New → JavaBean. 3. Enter the following values: – Name: customerBean. – Class: com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean. – Check Make this JavaBean reusable. – Scope: session. Click Finish. 4. Add another JavaBean with the following values: – Name: salesPersons. – Class: com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCollectio n. – Scope: session. 5. Insert new controls for the customer. Select the customerBean JavaBean in Page Data and drag and drop it below the Customer Details header. A dialog box opens. 6. Create controls for updating fields (Figure 6-85 on page 563). – Select the Updating fields radio button. – Uncheck the noteId field. – Select Combo box as the control type for the accountOwner field. – Modify the order of the fields. 562 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-85 Insert JavaBean for updating fields 7. Click Finish. WSAD creates a form to update or edit CustomerBean (Figure 6-86 on page 564). Chapter 6. Portlet development using Java: Integration examples 563 Figure 6-86 CustomerDetails.jsp: updating CustomerBean 8. We add choices to the account owner menu. Select the menu item in the customer form and right-click the employeeNumber field in the salesPersons JavaBean. Select Bind to ‘menu1’ (Figure 6-87 on page 565). 564 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 6-87 Bind sales persons to menu After binding employeeNumber, go to the Attributes section and select customerBean.accountOwner as the value for the menu item. 9. Add the Delete button next to the Save button. Select Command - Button from the Palette and click to the right of Save button. Go to the Format tab in Attributes and enter Delete as the label. 10.Add a back-link below the two buttons. Select Link from the Palette and click below the Save button. Enter /SalesTrackingJSFView.jsp as the URL and Back as the label. 11.Save the file and test the application. You should see the window shown in Figure 6-88 on page 566. Chapter 6. Portlet development using Java: Integration examples 565 Figure 6-88 CustomerDetails.jsp with navigation buttons MessageBean 1. Create a new JavaBean. Name the class salestrackingjsf.MessageBean. The Bean should be one field, with the type as String and name as message. Actions for buttons The JSF application is almost ready. Next, we add actions for the Save and Delete buttons. 1. Add the following code for the Save action (Example 6-43). Example 6-43 Code for save customer action if (DominoAccessProxy.addCustomer((CustomerBean) getSessionScope().get("customerBean"))) { getSessionScope().remove("customers"); MessageBean message = new MessageBean(); message.setMessage("Save successful."); getRequestScope().put("messageBean", message); return "success"; } 566 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 else { MessageBean message = new MessageBean(); message.setMessage("Save failed."); getRequestScope().put("message", message); return "failure"; } 2. Add the following code for the Delete action (Example 6-44). Example 6-44 Code for delete customer action if(DominoAccessProxy.deleteCustomer((CustomerBean)getSessionScope().get("custom erBean"))) { getSessionScope().remove("customers"); MessageBean message=new MessageBean(); message.setMessage("Delete successful."); getRequestScope().put("messageBean",message); return "success"; } else { MessageBean message=new MessageBean(); message.setMessage("Delete failed."); getRequestScope().put("message",message); return "failure"; } 3. Both Save and Delete actions use the MessageBean to inform the user of the results of the action. Add a new request scope variable for the CustomerDetails.jsp page and the SalesTrackingJSFView.jsp page. – Right-click requestScope in Page Data and select Add Request Scope Variable. – Enter messageBean as the Variable name. – Enter salestrackingjsf.MessageBean as the Type. Click OK. 4. Add an output field for both CustomerDetails.jsp and SalesTrackingJSFView.jsp pages. – Select Output from Palette and drop it below the header. – If output field does not go below the header when using drag and drop, you can modify the source and move it manually to where you want it. 5. In the Attributes section, click the icon next to the value text field and select message as the value for the output text (Figure 6-89 on page 568). Chapter 6. Portlet development using Java: Integration examples 567 Figure 6-89 Add request scope variable to output text 6. Add navigation for the Save and Delete buttons. If the result is “Success”, the SalesTrackingJSFView.jsp page should be displayed, and if the result is “failure”, the CustomerDetails.jsp page is displayed. 7. Test the application. 6.6.5 Deployment descriptors The Faces portlet includes familiar web.xml and portlet.xml deployment descriptors and also a JSF specific faces-config.xml deployment descriptor. Faces-config.xml (Example 6-45) contains managed beans, validators, custom components, navigation rules, and so on. Many resources of the JSF are specified using the configuration file. Example 6-45 faces-config.xml <?xml version="1.0"?> <!-Copyright 2003 Sun Microsystems, Inc. All rights reserved. SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. --> 568 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN" "http://java.sun.com/dtd/web-facesconfig_1_0.dtd"> <!-- =========== FULL CONFIGURATION FILE ================================== --> <faces-config> <lifecycle> <phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener > </lifecycle> <factory> <faces-context-factory>com.ibm.faces.context.WPPortletFacesContextFactoryImpl</ faces-context-factory> </factory> <managed-bean> <managed-bean-name>pc_SalesTrackingJSFView</managed-bean-name> <managed-bean-class>pagecode.SalesTrackingJSFView</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>pc_Index</managed-bean-name> <managed-bean-class>pagecode.Index</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>customers</managed-bean-name> <managed-bean-class>com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanColle ction</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>pc_CustomerDetails</managed-bean-name> <managed-bean-class>pagecode.CustomerDetails</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>customerBean</managed-bean-name> <managed-bean-class>com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean</man aged-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>salesPersons</managed-bean-name> Chapter 6. Portlet development using Java: Integration examples 569 <managed-bean-class>com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCo llection</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <navigation-rule> <navigation-case> <from-outcome>showCustomers</from-outcome> <to-view-id>/SalesTrackingJSFView.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/SalesTrackingJSFView.jsp</from-view-id> <navigation-case> <from-outcome>showCustomerDetails</from-outcome> <to-view-id>/CustomerDetails.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/CustomerDetails.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/SalesTrackingJSFView.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config> Portlet.xml and web.xml are presented as examples (Example 6-46 and Example 6-47 on page 572). Example 6-46 portlet.xml <?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="salestrackingjsf.SalesTrackingJSFPortlet.72be6987ff" major-version="1" minor-version="0"> <portlet-app-name>SalesTrackingJSF application</portlet-app-name> <portlet id="salestrackingjsf.SalesTrackingJSFPortlet" href="WEB-INF/web.xml#Servlet_1097239824360" major-version="1" minor-version="0"> <portlet-name>SalesTrackingJSF portlet</portlet-name> <cache> <expires>0</expires> <shared>no</shared> </cache> <allows> 570 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <maximized /> <minimized /> </allows> <supports> <markup name="html"> <view /> </markup> </supports> </portlet> </portlet-app> <concrete-portlet-app uid="salestrackingjsf.SalesTrackingJSFPortlet.f0f22987ff.1"> <portlet-app-name>SalesTrackingJSF application</portlet-app-name> <context-param> <param-name>domino.host.address</param-name> <param-value>domino651.swic.fi.ibm.com</param-value> </context-param> <context-param> <param-name>use.single.signon</param-name> <param-value>false</param-value> </context-param> <context-param> <param-name>customer.db</param-name> <param-value>redbook/customer.nsf</param-value> </context-param> <context-param> <param-name>sales.db</param-name> <param-value>redbook/sales.nsf</param-value> </context-param> <context-param> <param-name>product.db</param-name> <param-value>redbook/products.nsf</param-value> </context-param> <context-param> <param-name>user.name</param-name> <param-value>test person</param-value> </context-param> <context-param> <param-name>password</param-name> <param-value>password</param-value> </context-param> <concrete-portlet href="#salestrackingjsf.SalesTrackingJSFPortlet"> <portlet-name>SalesTrackingJSF portlet</portlet-name> <default-locale>en</default-locale> <language locale="en"> <title>SalesTrackingJSF portlet</title> <title-short></title-short> <description></description> <keywords></keywords> Chapter 6. Portlet development using Java: Integration examples 571 </language> <config-param> <param-name>com.ibm.faces.portlet.page.view</param-name> <param-value>/index.jsp</param-value> </config-param> </concrete-portlet> </concrete-portlet-app> </portlet-app-def> Example 6-47 web.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <display-name>SalesTrackingJSF</display-name> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> <servlet> <servlet-name>JS Resource Servlet</servlet-name> <servlet-class>com.ibm.faces.webapp.JSResourceServlet</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <servlet id="Servlet_1097239824360"> <servlet-name>salestrackingjsf.SalesTrackingJSFPortlet</servlet-name> <display-name>salestrackingjsf.SalesTrackingJSFPortlet</display-name> <servlet-class>com.ibm.faces.webapp.WPFacesGenericPortlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>JS Resource Servlet</servlet-name> <url-pattern>/.ibmjsfres/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>salestrackingjsf.SalesTrackingJSFPortlet</servlet-name> <url-pattern>/salestrackingjsf.SalesTrackingJSFPortlet/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> </web-app> 572 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.6.6 Deployment 1. Export the SalesTrackingJSF application to the SalesTrackingJSFRedbookSample.war file (Example 6-48). Example 6-48 Contents of the SalesTrackingJSFRedbookSample.war | CustomerDetails.jsp | index.jsp | SalesTrackingJSFView.jsp | tree.txt | +---META-INF | MANIFEST.MF | +---theme | stylesheet.css | \---WEB-INF | faces-config.xml | ibm-web-bnd.xmi | ibm-web-ext.xmi | portlet.xml | web.xml | +---classes | +---pagecode | | CustomerDetails.class | | Index.class | | PageCodeBase.class | | SalesTrackingJSFView.class | | | \---salestrackingjsf | MessageBean.class | \---lib commons-beanutils.jar commons-collections-3.0.jar commons-collections.jar commons-digester.jar commons-pool-1.1.jar DominoAccess.jar jaxen-full.jar jsf-api.jar jsf-ibm.jar jsf-impl.jar jsf-portlet.jar jstl.jar jstl_el.jar Chapter 6. Portlet development using Java: Integration examples 573 NCSO.jar saxpath.jar standard.jar In the classes directory, there is a package pagecode. Classes in this package are managed beans for JSPs. They are subclasses of PageCodeBase.class that has generic methods like getSessionScope(). Classes in the pagecode package are generated automatically when you design your JSP page. Methods are added, modified, and deleted while you drag and drop components to JSP page. You also add code to these classes, all actions, for example, that we did using the QuickEdit window, has methods in the managed bean class corresponding to the JSP page. 2. Install the application on WebSphere Portal, modify the parameters, and test the portlet (Figure 6-90). Figure 6-90 SalesTrackingJSF portlet 574 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.6.7 Summary In this section, we developed a simple portlet using JSF framework and now you have a basic understanding of JSF support for portlets and tools provided by WSAD. Since JSF is designed to be a RAD framework, we developed our application using the JSF tools provided by WSAD, such as JSF components, visually constructing JSP pages, using a quick edit feature that allows us to add code snippets for actions, and so on. WSAD generates a lot of code for us and we write only the code that we need to. JSP and Java sources are visible and accessible so they can be consulted at any time and, of course, if we want to, we can write our JSPs manually using JSF tags. In addition to visual programming, the JSF framework encapsulates session management, object management, navigation, and so on. All these features makes building portlet applications a lot easier than building a portlet application using just the portlet API. At the time of writing, one issue with JSF is that being a relatively new technology for WebSphere Portal, there are some problems. For example, JSF portlets using JSR 168 and error handling using JSF components does not work in the WebSphere Portal. Note: The SalesTrackingJSF_Project.zip file has the SalesTrackingJSF project ready for importing to WSAD. See Appendix C, “Additional material” on page 741 for download instructions. 6.7 Sales Tracking application using JSR 168 In this section, we develop a simple portlet using JSR 168. The portlet does a simple search for a customer. The first page of the portlet has a form for entering a customer name and a second page displays the customer details. This portlet can display an image from a Rich Text field in the Domino form. 6.7.1 Adding functionality to DominoAccess We add functionality to handle images in a Rich Text field to DominoAccess classes. Chapter 6. Portlet development using Java: Integration examples 575 DominoAccess.getFirstPNGImage() Add the following method to DominoAccess.java (Example 6-49). Example 6-49 DominoAccess.getFirstPNGImage() public String getFirstPNGImage(String key, String noteId, String directory) throws Exception { Session session = null; session = (Session) pool.borrowObject(key); Database customerDb = session.getDatabase(null, CUSTOMER_DB); Document doc = customerDb.getDocumentByID(noteId); RichTextItem additionalInformation = (RichTextItem) doc.getFirstItem("Comments"); Vector embeddedObjects = additionalInformation.getEmbeddedObjects(); String imageFileName = null; if (embeddedObjects.size() > 0) { for (int i = 0; i < embeddedObjects.size(); i++) { EmbeddedObject embObject = (EmbeddedObject) embeddedObjects.elementAt(i); if (embObject.getType() == EmbeddedObject.EMBED_ATTACHMENT) { imageFileName = embObject.getSource(); if (imageFileName.toLowerCase().endsWith("png")) { directory = directory.replace('\\', '/'); if (!directory.endsWith("/")) { directory += "/"; } String imageFilePath = directory + imageFileName; File imageFile = new File(imageFilePath); if (imageFile.exists()) { long imageLastModified = imageFile.lastModified(); if (doc .getLastModified() .toJavaDate() .after(new Date(imageLastModified))) { embObject.extractFile(imageFilePath); } } else { embObject.extractFile(imageFilePath); 576 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 } break; } } } } customerDb.recycle(); pool.returnObject(key, session); return imageFileName; } The functionality of the DominoAccess.getFirstPNGImage() method is quite simple. We get all the embedded objects in the Rich Text field, loop through them, and if there is a PNG image, we save it disk. DominoAccessProxy.getFirstPNGImage() Add the following method to DominoAccessProxy.java (Example 6-50). Example 6-50 DominoAccessProxy.getFirstPNGImage() public static String getFirstPNGImage(String noteId, String directory) { try { DominoAccess dominoAccess = DominoAccess.getInstance(); return dominoAccess.getFirstPNGImage(KEY, noteId, directory); } catch (Exception e) { e.printStackTrace(); } return null; } Remember to export DominoAccess.jar and copy it to the SalesTrackingJSR168/Web-inf/lib directory. 6.7.2 SalesTrackingJSR168 project 1. Create a new JSR 168 portlet project. 2. Add the following init parameter to portlet.xml after the <portlet-class> tag (Example 6-51 on page 578). Chapter 6. Portlet development using Java: Integration examples 577 Example 6-51 Adding the init parameter to portlet.xml <init-param> <name>jspView</name> <value>/jsp/view.jsp</value> </init-param> <init-param> <name>jspResult</name> <value>/jsp/result.jsp</value> </init-param> 3. Add the following preferences to portlet.xml after the <portlet-info> tag (Example 6-52). Example 6-52 Portlet preferences <portlet-preferences> <preference> <name>domino.host.address</name> <value>domino651.swic.fi.ibm.com</value> </preference> <preference> <name>user.name</name> <value>test person</value> </preference> <preference> <name>password</name> <value>password</value> </preference> <preference> <name>customer.db</name> <value>redbook/customer.nsf</value> </preference> <preference> <name>sales.db</name> <value>redbook/sales.nsf</value> </preference> <preference> <name>product.db</name> <value>redbook/products.nsf</value> </preference> </portlet-preferences> 578 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6.7.3 SalesTrackingJSR168Portlet 1. Open (or create) the class salestrackingjsr168.SalesTrackingJSR168Portlet and write the portlet code shown in Example 6-53. Example 6-53 SalesTrackingJSR168Portlet.java package salestrackingjsr168; import java.io.IOException; import import import import import import import import import import import javax.portlet.ActionRequest; javax.portlet.ActionResponse; javax.portlet.GenericPortlet; javax.portlet.PortletConfig; javax.portlet.PortletContext; javax.portlet.PortletException; javax.portlet.PortletPreferences; javax.portlet.PortletRequestDispatcher; javax.portlet.PortletSession; javax.portlet.RenderRequest; javax.portlet.RenderResponse; import import import import com.ibm.itso.cam.redbooks.sg246466.domino.BeanUtils; com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBean; com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccess; com.ibm.itso.cam.redbooks.sg246466.domino.DominoAccessProxy; public class SalesTrackingJSR168Portlet extends GenericPortlet { public void init(PortletConfig config) throws PortletException { super.init(config); } public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { response.setContentType("text/html"); String jspName = request.getParameter("showDetails") == null ? getPortletConfig().getInitParameter("jspView") : getPortletConfig().getInitParameter("jspResult"); PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher(jspName); rd.include(request, response); } Chapter 6. Portlet development using Java: Integration examples 579 public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { String customerName = request.getParameter("customerName"); if (customerName != null) { PortletPreferences prefs = request.getPreferences(); String dominoHostAddress = prefs.getValue("domino.host.address", null); String userName = prefs.getValue("user.name", null); String password = prefs.getValue("password", null); DominoAccessProxy.KEY = dominoHostAddress + ":" + userName + ":" + password; DominoAccess.CUSTOMER_DB = prefs.getValue("customer.db", null); DominoAccess.SALES_DB = prefs.getValue("sales.db", null); DominoAccess.PRODUCTS_DB = prefs.getValue("product.db", null); response.setRenderParameter("showDetails", customerName); PortletSession session = request.getPortletSession(); CustomerBean customer = DominoAccessProxy.getCustomerByName(customerName); customer.setAccountOwner( BeanUtils.getAccountOwnerName( customer.getAccountOwner(), DominoAccessProxy.getSalesPersons())); session.setAttribute("customerBean", customer); //check image attachments PortletContext context = getPortletContext(); String directory = context.getRealPath("/"); String fileName = DominoAccessProxy.getFirstPNGImage(customer.getNoteId(), directory); if (fileName != null) { session.setAttribute("fileName", fileName); } else { session.removeAttribute("fileName"); } } } } SalesTrackingJSR168Portlet explained The portlet code is similar to the IBM Portlet API. In JSR 168, we have the processAction() method and its parameters are ActionRequest and ActionResponse. Parameters in doView are RenderRequest and RenderResponse. 580 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The method processAction() receives an action from our search form and it gets DominoAccess parameters from portlet preferences and sets them before using DominoAccessProxy to get CustomerBean. After getting the CustomerBean, we use the DominoAccessProxy.getFirstPNGImage() method to get the image file name of the PNG file in the Rich Text field. The Rich Text field in Domino form is named Comments and if it includes a PNG image, the first image is copied to the portlet directory and displayed in the Web page. 6.7.4 JSP files The following section describes the relevant JSP files you will need to add using the JSR168 method to implement the Sales Tracking application. view.jsp 1. Add view.jsp (Example 6-54) to the /WebContent/jsp directory. Example 6-54 view.jsp <%@ page import="javax.portlet.*, java.util.*" %> <%@ taglib uri="http://java.sun.com/portlet" prefix="portletAPI" %> <portletAPI:defineObjects /> <p> <table cellspacing="1" cellpadding="1"> <form action="<portletAPI:actionURL/>" method="POST"> <tr> <td class="portlet-section-header">Customer name:</td> </tr> <tr> <td><input name="customerName" type="text" class="portlet-form-input-field"></td> </tr> <tr> <td><input type="submit" value="Search" class="portlet-form-button"></td> </tr> </form> </table> </p> This JSP has a form with one text field for entering a customer name and a button to search for a customer in Domino. JSP uses style classes specified in portlet specification. Chapter 6. Portlet development using Java: Integration examples 581 result.jsp 1. Add result.jsp (Example 6-55) to the /WebContent/jsp directory. Example 6-55 result.jsp <%@ page import="javax.portlet.*, java.util.*,com.ibm.itso.cam.redbooks.sg246466.domino.*" %> <%@ taglib uri="http://java.sun.com/portlet" prefix="portletAPI" %> <%@taglib uri="/WEB-INF/tld/people.tld" prefix="pa"%> <portletAPI:defineObjects /> <div class="portlet-font"><%CustomerBean customerBean = (CustomerBean) renderRequest.getPortletSession().getAttribute("customerBean"); String imageFileName = (String) renderRequest.getPortletSession().getAttribute("fileName"); if (customerBean == null) { customerBean = new CustomerBean(); customerBean.setName( "Name: " + request.getParameter("showDetails") + " not found."); } %></div> <p></p> <table border="0" cellpadding="1" cellspacing="1"> <tbody> <tr> <td class="portlet-section-header">Customer details</td> </tr> <tr> <td class="portlet-section-subheader">Name</td> <td class="portlet-section-text"><%=customerBean.getName()%></td> </tr> <tr> <td class="portlet-section-subheader">Customer number</td> <td class="portlet-section-text"><%=customerBean.getCustomerNumber()%></td> </tr> <tr> <td class="portlet-section-subheader">Account owner</td> <td class="portlet-section-text"><pa:person><%=customerBean.getAccountOwner()%></pa :person></td> </tr> <tr> <td class="portlet-section-subheader">Total employees</td> 582 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <td class="portlet-section-text"><%=String.valueOf(customerBean.getEmployeeTotal()) %></td> </tr> <tr> <td class="portlet-section-subheader">Address</td> <td class="portlet-section-text"><%=customerBean.getAddress()%></td> </tr> <tr> <td class="portlet-section-subheader">Additional information</td> <td class="portlet-section-text"><%=customerBean.getAdditionalInformation()%> <%if (imageFileName != null) {%> <br /> <img src="<%=renderResponse.encodeURL(renderRequest.getContextPath() + "/" + imageFileName)%>" border="0" /> <%}%></td> </tr> <tr> <td class="portlet-section-subheader">Note ID</td> <td class="portlet-section-text"><%=customerBean.getNoteId()%></td> </tr> </tbody> </table> <p></p> <div class="portlet-font"><a href="<portletAPI:renderURL/>">Back</a></div> This displays customer details. The image is saved in the portlet context directory and the encodeURL() method is used to encode the URL so that the server finds the image from the portlet directory. 6.7.5 Test the application 1. Run the portlet in the test environment (Figure 6-91 on page 584). Customer details are shown in the portlet and it includes an image if there is an image in the Domino form. Chapter 6. Portlet development using Java: Integration examples 583 Figure 6-91 Testing SalesTrackingJSR168: search result 6.7.6 Deployment descriptors JSR 168 portlets are a part of Web applications. There can be many servlets, portlets, EJBs, and JSPs in one Web application war file. JSR 168 portlets do not have any reference to web.xml, but it must still be included in the war file since J2EE requires that it be specified. WSAD creates a default web.xml and we can use it as is. Example 6-56 shows the portlet.xml of the JSR 168 portlet. All portlet specific configuration is in this file. Example 6-56 portlet.xml <?xml version="1.0" encoding="UTF-8"?> <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> <portlet> <portlet-name>SalesTrackingJSR168</portlet-name> 584 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 <display-name>SalesTrackingJSR168 portlet</display-name> <display-name xml:lang="en">SalesTrackingJSR168 portlet</display-name> <portlet-class>salestrackingjsr168.SalesTrackingJSR168Portlet</portlet-class> <init-param> <name>jspView</name> <value>/jsp/view.jsp</value> </init-param> <init-param> <name>jspResult</name> <value>/jsp/result.jsp</value> </init-param> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <supported-locale>en</supported-locale> <resource-bundle>salestrackingjsr168.nl.SalesTrackingJSR168PortletResource</res ource-bundle> <portlet-info> <title>SalesTrackingJSR168 portlet</title> </portlet-info> <portlet-preferences> <preference> <name>domino.host.address</name> <value>domino651.swic.fi.ibm.com</value> </preference> <preference> <name>user.name</name> <value>test person</value> </preference> <preference> <name>password</name> <value>password</value> </preference> <preference> <name>customer.db</name> <value>redbook/customer.nsf</value> </preference> <preference> <name>sales.db</name> <value>redbook/sales.nsf</value> </preference> <preference> <name>product.db</name> <value>redbook/products.nsf</value> </preference> Chapter 6. Portlet development using Java: Integration examples 585 </portlet-preferences> </portlet> </portlet-app> 6.7.7 Deployment 1. Export the application, install it to the server, modify the parameters, and add the portlet to a page (Figure 6-92). Figure 6-92 SalesTrackingJSR168 portlet in the server 6.7.8 Summary In this section, we developed a simple portlet with JSR 168. The programming model of the JSR 168 portlets is clearer and cleaner than using IBM Portlet API and that simplifies the development. We also developed a simple way to view images in Domino Rich Text field in a portlet. 586 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Note: The SalesTrackingJSR168_Project.zip file has the SalesTrackingJSR168 project ready for importing to WSAD. See Appendix C, “Additional material” on page 741 for download instructions. 6.8 Summary In this chapter, we developed portlets using four different methods: IBM Portlet API, Struts framework, JSF framework, and JSR 168. The functionality of the portlets and requirements of the portalization project will be the same regardless of the development method and it is mostly up to the developer which method to choose and why. So which method is the best? As always, the answer is: it depends. IBM Portlet API IBM Portlet API is the API for WebSphere Portal. It offers many features and there is no doubt that portlets developed against IBM API will work. In order to successfully implement a portlet with this method, the developer needs to learn the API and familiarity with servlet helps a lot. Because a portlet runs inside a portlet container and one portlet is only a part of the Web page, the developer needs to be familiar with portlet concepts and its strengths and weaknesses. Although IBM Portlet API extends from the Servlet API, it is a proprietary API that is used only in WebSphere Portal and other products based on it, like Lotus Workplace or WebSphere Everyplace Access. This may or may not be an issue depending on the project, product development, or both. WSAD is the preferred IDE to develop portlets but developing with IBM Portlet API does not require WSAD. All we need is a Java compiler, portlet classes from WPS in class path, and any IDE or text editor. JSR 168 JSR 168 is a standard API for portlets. As a standard, it will be supported in WebSphere Portal Server and other portals. At the time of the writing of this redbook, the current Version 1.0 of the API offers the basic functionality of portlets. JSR 168 is not based on servlets, but it offers a cleaner programming model without overhead from the servlet API. As we saw in 6.7, “Sales Tracking application using JSR 168” on page 575, the development, portlet classes, and deployment descriptors are clearer than in IBM Portlet API. Chapter 6. Portlet development using Java: Integration examples 587 Because JSR 168 is, at the time of the writing of this redbook, in its first version, its functionality is not yet as mature as the functionality of the IBM Portlet API, for example, portlet messaging is not yet in the standard. Other features, such as Credential Vault, offered by WebSphere Portal, are not supported in JSR 168 portlets. If a portlet application’s requirements can be met using JSR 168, it is recommended to use it. If not, IBM Portlet API can be used, but it may lead to migration in the future. Developing JSR 168 portlets requires, at minimum, a Java compiler, text editor, and javax.portlet classes in class path. Struts The Struts framework is an extension to Web application development and it is supported in WebSphere Portal. Struts portlet development can be done without necessarily knowing about IBM Portlet API. Developers who have used Struts in Web applications will find the Struts portlet framework easy enough and Struts Web applications can be ported to a portlet application with relatively few changes (see 5.5, “Struts framework” on page 364). Even if Struts is not familiar, it is quickly learned and using the example in this chapter will give you a starting point for developing portlets based on Struts. Successful portlet development with Struts requires familiarity with such Java technologies as JSP, and it is very helpful to be familiar with IBM Portlet API. At the time of writing, Struts support in WPS is based on IBM Portlet API. As we saw in 6.5, “Sales Tracking application using Struts” on page 498, WSAD offers very helpful tools for Struts portlet development and it simplifies portlet development. However, WSAD is not required to do Struts portlet development. As long as portal is kept in mind, the deployment war file includes necessary classes, and deployment descriptors include necessary information for Struts portal framework, any development environment can be used to develop portlets with Struts. JSF JSF framework is a new standard for Web application development. As we saw in 6.6, “Sales Tracking application using JSF” on page 546, it brings Rapid Application Development (RAD) to Web applications and portlets. RAD makes it easier for developers with limited Java knowledge to develop portlets and it can be used to quickly develop working prototypes and applications. It is possible to develop portlets without knowing portlet APIs, but it 588 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 is helpful to be familiar with the portlet API. JSF portlet can use JSR 168 or IBM Portlet API. JSF tools generate a lot of code and that saves time since the developer does not have to type all the necessary code. The more the developer knows about JSF, the easier the development. Using the examples in this chapter as a starting point makes possible to develop portlets without understanding JSF. However, if understanding of JSF is limited, it may lead to “fighting the framework” where a developer tries to do a simple thing using traditional methods and the framework does not allow it or it circumvents the framework, and that would come back to haunt you later. This is also relevant when using the Struts framework. WSAD offers helpful tools for JSF development and since JSF is a RAD framework, it is recommended to use an IDE to visually design portlet pages. It is possible to use other JSF tools than WSAD and before deployment to WebSphere Portal, deployment descriptors and contents of the war file must be modified so that WPS can run the portlet application. Summary of the summary If and when you start to develop portlet applications, start by developing simple portlets using IBM Portlet API or JSR 168. This will give you an understanding of portlet concepts and portlet API features that you can use to your own advantage when developing portlet applications using a framework. When you are familiar with portlet API, start using a framework. You will find that while it is easy to develop portlets using API, it can be time consuming and maintaining the portlet code and JSP pages can lead to sleepless nights. You can choose from two frameworks, JSF or Struts, and either of them can be chosen based on developer or project preferences. In general, as JSF is an actual standard from Java Community Process, it is the recommended framework. Chapter 6. Portlet development using Java: Integration examples 589 590 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 7 Chapter 7. Portlet builders Portlet building technologies, including the IBM WebSphere Portal Application Integrator and those of various IBM Business Partners, promise to provide the capability to rapidly create portlets that can access and manipulate Domino applications without requiring in-depth J2EE programming knowledge. In this chapter we take a look at portlet building tools that are currently available. We present detailed information about: IBM WebSphere Portal Application Integrator Bowstreet Portlet Factory for WebSphere Conet Knowledge Director 3.0 for WebSphere Portal This chapter outlines the technologies available in the marketplace that bridge the gap between the use of existing portlets and custom Java development options. It focuses on the technology offerings from five vendors, including IBM, Bowstreet and Conet. All offer solutions that simplify the building of custom portlets to expose Domino applications on the WebSphere Portal platform. These builders utilize your Domino applications by querying and aggregating Domino data and displaying that content within a portlet context. Finally, this chapter differentiates these various offerings, as well as providing key information about each portlet builder, including features, pricing information, and advantages as well as disadvantages. © Copyright IBM Corp. 2005. All rights reserved. 591 Why choose this option While using existing portlets to expose Domino data is by far the most expedient option, it is only feasible when your portlet requirements match the functionality provided by an existing portlet. Custom portlet development using Java and JSPs provides a much richer set of development options. There is no limit to what can be developed using the tools and techniques available from these options. If your team has the right development skills and enough time, custom portlet development is the way to go. However, there are often situations where the skill set of the development team or the time allotted for development can prevent custom portlet development using Java and JSP tags from being a viable option. Portlet builder technologies offer a middle-ground approach to portlet development. They offer significantly more development capabilities than the use of existing portlets. In addition, they promise a shorter development time and require less in-depth knowledge about custom portlet development than the more advanced Java and JSP-based options. Skills and degree of customization - Portlet Builders Figure 7-1 on page 593 gives an overview of this integration option relative all available options to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. 592 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 Bowstreet Portlet Factory / Conet Knowledge Director 2 1 IBM Portlet Builder for Domino limited Existing Portlets 4 Lotus Workplace Builder low Level of customization high Figure 7-1 Integration options The main message to take from this graphic is that using Portlet Builders represents an intermediate to high option for a high degree of customization, while only requiring minimal Java knowledge. 7.1 IBM Portlet Builder for Domino The following section provides a high level description of the IBM Portlet for Domino, highlighting the functionality and benefits, as well as known implementation and performance considerations. Details for implementing the IBM Portlet Builder for Domino are discussed in 7.2, “Bowstreet Portlet Factory for WebSphere” on page 619. Overview IBM WebSphere Portal Application Integrator is available for use with WebSphere Portal for no additional charge. The IBM WebSphere Portal Application Integrator package includes IBM Portlet Builder for Domino and is available for download from the WebSphere Portlet Catalog. Chapter 7. Portlet builders 593 IBM Portlet Builder for Domino provides developers, administrators, and power users with the ability to easily create a portlet-based interface into an existing Domino application. No Java or other development skills are required. Note: In addition to Domino, IBM WebSphere Portal Application Integrator provides configurable portlets used to access many other back-end systems, including: PeopleSoft SAP Siebel JDBC to relational databases And others IBM Portlet Builder for Domino provides a highly configured interface with a much richer set of capabilities than the Domino portlets available out-of-the-box with WebSphere Portal. The capabilities of IBM Portlet Builder for Domino include: Connects to any Domino database. No changes to existing Domino databases required. Click-to-Action enabled. Presence awareness (using Sametime). Offline browsing support. Mobile support for browsers and devices capable of rendering HTML and WML markup. Attachment support. Sortable columns. View search. Output WAR files are immediately available for re-deployment on another WebSphere Portal server. Select multiple views and forms in a Domino database to customize via portlet builder. Domino views are customized by selecting what columns to display. Domino forms are customized by selecting what fields to display. Domino views are selected by the users from a list at runtime. View columns are resizable. Documents selected from a view are either rendered within the same portlet (take over portlet, or render beside view) or through a separate document viewer portlet. 594 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The Document viewer portlet can render the document either as customized (through its associated form) or through an IFRAME (as the original document from Domino). Documents can be updated and new ones created through either the iFrame viewer or the “data” viewer. The advantages and disadvantages of using IBM Portlet Builder for Domino are similar to those of our first option, using existing portlets. Specifically, if this tool meets your application’s needs, it is much cheaper and faster than a custom development effort. However, if your application has requirements not available from IBM Portlet Builder for Domino, there is no way to extend this tool with customized functionality. IBM Portlet Builder for Domino uses IIOP over the HTTP transport to communicate with each Domino server. Implementation issues Applicable Portlet patterns IBM Portlet Builder for Domino is well suited for the Display pattern. It is also capable of implementing a simple Integrated pattern. Development time Very little development time is required. Developer skill set Basic portal configuration skills. No familiarity with Java or Portlet development is required. Range of applications The IBM Portlet Builder portlet is highly configured, and provides many more options that the Domino portlets currently shipping with WebSphere portal. However, its range of applications is limited by the fixed set of functionality and interface options. If these options do not meet your application’s needs, there is currently no way to extend this interface. Rich text handling If the form is integrated into the portlet content, rich text fields are rendered as plain text. Note that it is possible to configure an IBM Portal Builder portlet to open documents using an IFRAME. Using this option, documents will be rendered using Domino server’s HTTP engine and can therefore leverage all of the Web-based rich text functionality provided by Domino. Chapter 7. Portlet builders 595 Performance Session management IBM Portlet Builder does not currently support session pooling. Clustering IBM Portlet Builder does not natively support server failover in a clustered Domino environment. Scalability No data is currently available for IBM Portlet Builder scalability. Single sign-on support Single sign-on is supported, but not required for IBM Portlet Builder for Domino. Many authentication options are available, including: – LTPA – Credentials Vault – Prompt for a user ID and password – Use an administrator-specified ID and password Required software versions IBM/Lotus Domino V5 or V6.x WebSphere Portal V4.x or V5.x 7.1.1 Implementation details This section provides detailed instructions on the installation process. Once installed and configured, we then provide an implementation example on how to use the IBM Portlet Builder for Domino to build and deploy the portlets for the Sales Tracking application. Installing IBM Portlet Builder for Domino Note: The installation instructions may change from version to version. For the most accurate installation instructions, use the documentation provided with your version of Portlet Builder. The IBM WebSphere Portal Application Integrator set of applications is installed by default with WebSphere Portal V5.x; however, it is strongly recommended that you update to the very latest application war files. 596 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Download the installation package from the WebSphere Portlet Catalog and expand the zip file to a temporary folder. The folder now contains the files needed for installation. Use the following steps to install the Portlet Builder. 1. To install Portlet Builder for Domino, simply update the three WAR product files: – WPAIDefaultTemplate50.war This war file was previously called BusinessObjectFrameworkStruts.war. – WPAIDominoTemplate50.war This war file was previously called DominoStruts.war. – WPAIPortletBuilders50.war This war file was previously called BOBuilderPortlet.war. To update the war files from the Administration area of WebSphere Portal select Portlets → Manage Applications. Then highlight BusinessObjectFrameworkStruts.war and click Update (see Figure 7-2). Figure 7-2 Update the BusinessObjectFrameworkStruts.war for IBM Portlet Builder 2. After selecting Update, browse and find the file WPAIdefaultTemplate50.war and select Next (see Figure 7-3 on page 598). Chapter 7. Portlet builders 597 Figure 7-3 Selecting the new WPAIDefaultTemplate50.war for IBM Portlet Builder to complete the update 3. Finally, click Install to complete the update (see Figure 7-4). Figure 7-4 Completing the update of the WAR file 4. Repeat the above steps until all three war files are updated. 5. After updating the WAR files, create a new page and add the Portlet Builder for Domino Portlet to this page. Figure 7-5 on page 599 illustrates this. For detailed instructions on creating a page and adding a portlet to the page, see 2.4.4, “Adding portlets to a page” on page 89. Note: By default in WebSphere Portal V5.x, the Portlet Builder for Domino is already installed and can be found under My Work → Developers Area → Lotus Domino Builder. 598 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-5 Adding the Portlet Builder for Domino portlet to a page Creating a new Portlet with Portlet Builder for Domino Follow these steps to create and configure a portlet using IBM Portlet Builder for Domino. 1. From within your portal, click the MyWork tab and select Developers Area, then select the Lotus Domino Builder option on the left (See Figure 7-6) Figure 7-6 Accessing the Portlet Builder for Domino 2. Open the page containing the Portlet Builder for Domino portlet, as shown in Figure 7-7 on page 600. Click the New portlet button. Chapter 7. Portlet builders 599 Figure 7-7 Accessing the Portlet Builder for Domino portlet 3. Enter a Portlet name and specify your Domino server name, as shown in Figure 7-8. When finished, click the Connect to server button. Figure 7-8 Configuring the Portlet Builder for Domino: Enter portlet name and server name 4. Enter a valid Domino user name and password with access rights to the server and database you wish to access, as shown in Figure 7-9 on page 601. When finished, click OK. If you have SSO configured with your 600 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Domino server, you will not be presented with this screen as you are already authenticated. Figure 7-9 Configuring the Portlet Builder for Domino: Enter user name and password 5. Select the file name of the Domino database you wish to access, as shown in Figure 7-10. When finished, click Retrieve forms and views. Figure 7-10 Configuring the Portlet Builder for Domino: Select a database Chapter 7. Portlet builders 601 6. Select the forms and views you would like to make available in this portlet, as shown in Figure 7-11. If there are a large number of views and forms, you can browse through the list, page by page, using the navigation buttons. When finished, click Next. Figure 7-11 Configuring the Portlet Builder for Domino: Select the forms and views 7. You will be taken to the form and view options configuration page shown in Figure 7-12 on page 603. From here you are able to: – Configure the portlet settings for each form and view to be displayed. – Specify the portlet authentication options. – Specify the form display options. – Set Click-to-Action. 602 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Edit Click-to-Action Figure 7-12 Configuring Portlet Builder for Domino: Form and view options configuration page 8. From the form and view options configuration page, click the Customers\By Customer Name view edit icon. You will be taken to the view configuration page, as shown in Figure 7-13 on page 604. Here, you are able to control what columns are displayed, the column labels, if they should be Sametime aware, and the column width. There are other options, such as Image and Link Options that are available from the Edit Icon. Now, configure the view to your liking and click Next. Chapter 7. Portlet builders 603 Figure 7-13 Configuring the Portlet Builder for Domino: Configuring the Customers\By Name view 9. You can now control the order in which the columns are displayed within the portlet, using the interface shown in Figure 7-14 on page 605. The buttons with up or down triangles change the column order accordingly. You can also adjust the number of rows to appear for each page of data. Adjust the column order to your liking and click Finish. 604 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-14 Configuring the Portlet Builder for Domino: Ordering the Customers\By Name columns 10.You are taken back to the form and view options configuration page. You can configure another form or view by repeating steps seven and eight. You can also expand the Authentication Options and Form Display Options sections, as shown in Figure 7-15 on page 606. The options available are as follows: – Authentication options • Use single sign-on: The portlet will use the user’s LTPA token to authenticate with Domino. • Prompt for user ID and password: The portlet will prompt the user for their Domino ID and password. • Use this user ID and password: The portlet will always use the ID and password specified here. • Use existing credential vault slot: The portlet will authenticate using the ID and password in the specified slot of the authenticated user’s credential vault. – Form display options • Use data form: The portlet will display forms using the Portlet Builder’s simple data form interface, as configured for each form using steps Chapter 7. Portlet builders 605 seven and eight. While these forms will be embedded seamlessly inside the portlet, they have very limited functionality and display capabilities. • Use Inline frame: The portlet will display forms within an IFrame, using Domino server’s native HTML rendering capabilities. If IFrames are acceptable within your portlet, this will provide the quickest and easiest way to implement full form functionality within your portlet. For some functionality, such as for displaying rich text, using IFrames is the only option. Once you have finished configuring the portlet options, click OK. Figure 7-15 Configuring the Portlet Builder for Domino: Authentication and form display options 11.You should now see your newly created portlet listed within the Portlet Builder for Domino portlet, as shown in Figure 7-16 on page 607. You can reconfigure this portlet at any time. 606 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-16 Configuring the Portlet Builder for Domino: Completed portlet configuration At this step, you have created a portlet. This portlet will be deployed to a paged, moved, and managed like any other portlet that is available on your WebSphere Portal Server. 12.Add the newly created portlet to one of your pages, as shown in Figure 7-17. Steps describing how to add a portlet into a page are detailed in 2.4.4, “Adding portlets to a page” on page 89. Figure 7-17 Configuring the Portlet Builder for Domino: Adding the newly created portlet to a page Chapter 7. Portlet builders 607 7.1.2 Implementation example Following steps 1 through 11 in the previous section. Figure 7-18 shows the Cutomers\By Name view from our Case Study application, as rendered by IBM Portlet builder for Domino. Figure 7-18 The Customers/By Name view as rendered by IBM Portlet Builder for Domino 7.1.3 Adding People Awareness We have seen above that we can very easily surface a Domino application using the IBM Portlet Builder. We can now take advantage of some of the WebSphere Portal infrastructure to bring more value to our application. If Sametime is configured, its just a few clicks to add real-time people awareness to our application. 1. Return to the IBM Portlet builder for Domino portlet and select the Detail icon to edit the configuration of the portlet that we previously created, in our case, Customer List Builder (see Figure 7-19 on page 609). 608 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-19 Editing the Customer List Builder portlet 2. To add people awareness to one of the view columns, click the Edit icon of the view (see Figure 7-20 on page 610). Chapter 7. Portlet builders 609 Figure 7-20 Selecting a View to Edit 3. Tick the Person check box and then click OK (see Figure 7-20). 610 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-21 Enabling People Awareness from the Portlet Builder 4. Click Next and then Finish to return to the View and Form edit page. Then click OK to save the changes. Open the page where you have deployed your portlet to see people awareness enabled (Figure 7-22 on page 612). Note: WebSphere Portal has a very good cache mechanism, so it may take some time for your changes to be reflected in the portlet. One solution to overcome the cache is to redeploy the portlet. Chapter 7. Portlet builders 611 Figure 7-22 People Awareness Enabled on the Account Owner Column 7.1.4 Enhancing further with Click-to-Action It may be easier for your users to be able to see the information about a form right beside the view data. This is where Click-to-Action is particularly useful. In this example, we will add Click-to-Action to our existing portlet to allow the user to launch the Domino Form in an IFrame next to the view data. There are two portlets designed to work with Click-to-Action with IBM Portlet Builder for Domino. These are “Domino Data Form Viewer” and the “Domino IFrame Document Viewer”. With the “Domino Data form Viewer” portlet, you can view Domino documents in the data form using Click-to-Action. With the “Domino IFrame Document Viewer”, you can view Domino documents in IFrame using Click-to-Action. These two portlets do not need any configuration. In order to enable Click-to-Action with the data form, add the “Domino Data Form Viewer” portlet to the same page where the portlet containing data resides. Then enable Click-to-Action in the sending portlet. 1. To add Click-to-Action, return to the IBM Portlet builder for Domino portlet and select the Detail icon to edit the configuration of the portlet that we previously created, in our case, Customer List Builder (see Figure 7-18 on page 608). 612 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 2. Click on the Click-to-Action edit icon, as shown in Figure 7-23, which allows us to set the parameter to send. Figure 7-23 Setting the Click-to-Action parameters 3. Click Add (Figure 7-24). Figure 7-24 Adding a Click-to-Action Parameter 4. On the following screen, enter a type, namespace, and select the field you wish to pass. This screen allows you to pass multiple values in the same action but we will just pass the Customer Name (see Figure 7-25 on page 614). The fields are: Type This value can be any text you like and represents the variable being sent. Chapter 7. Portlet builders 613 Namespace This value again can be any value, but it must be unique to this Click-to-Action interaction. It is possible to have two lots of Click-to-Action on the same page, so to ensure that the messages get to the correct portlet, it is important to define a namespace. The standard convention is to use a URI, in this case, we have used itso-dom.cam.itso.ibm.com.pb. Value This is the value that will be passed and was defined earlier; in this way, it is possible to define multiple values. Figure 7-25 Adding a Click-to-Action parameter 5. Click OK. You will now see a confirmation of the Click-To-Action added (Figure 7-26). Figure 7-26 Confirmation of the Click-to-Action added 614 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 6. Next confirm you action and click OK. This will return you to the View and Form edit screen. The next step is to edit the view and make one of columns enabled for Click-to-Action. Click the edit icon on the Customer\By Customer Name view. Refer to Figure 7-23 on page 613 for clicking the edit icon. 7. Select the field to add the Click-to-Action to. In our case we will add it to the Customer Name field. See Figure 7-27. Figure 7-27 Selecting the column to add Click-to-Action to 8. Expand the Click-to-Action and complete the type and namespace (ensure the namespace is exactly the same as you entered when configuring the parameter). Also, select the customerName as the value. This will be the value passed to the receiving portlet (see Figure 7-28 on page 616). Chapter 7. Portlet builders 615 Figure 7-28 Setting the Click-to-Action Parameters on the Column 9. Click OK, Next, and Finished, which will return to the View and Form editor screen. Click OK to save. 10.Deploy the Domino IFrame Viewer to the same page as the Customer List Builder Portlet (see Figure 7-29 on page 617). For detailed instructions on creating a page and adding a portlet to the page, see 2.4.4, “Adding portlets to a page” on page 89. 616 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-29 Selecting the Domino IFrame Portlet to Deploy 11.Once you have added the iFrame viewer, you will see it also listed as one of the portlets listed within “edit layout options” of the page (Figure 7-30 on page 618). Chapter 7. Portlet builders 617 Figure 7-30 Editing the layout of the page to add the iFrame viewer 12.Open the page in portal and there will now be a Click-to-Action icon just to the left of the Customer Name field. Clicking on this will now give the users an option to display the customer profile document (Figure 7-31 on page 619). 618 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Click-to-Action options Figure 7-31 Using Click-to-Action to display the customer profile 7.2 Bowstreet Portlet Factory for WebSphere Bowstreet Portlet Factory for WebSphere is a framework and set of tools for rapidly creating and maintaining customized portlets for the WebSphere Portal environment. With Portlet Factory, developers build portlets by pulling together a sequence of reusable software components called Builders. Developers assemble Builders into models. These models are then executed at runtime to dynamically generate application code. The code generated includes JSPs, Java classes, XML documents, and all of the low-level artifacts required to create a portlet application. Thus, developers can capture and automate the process of building portlets instead of explicitly coding each portlet. Bowstreet Portlet Factory for WebSphere comes with the Lotus Collaboration Extension. This is a set of Builders (that is, tools) that assist the developer in building portlets to access Domino applications. Bowstreet Portlet Factory is not targeted exclusively to Domino developers. In addition to the Lotus Collaboration extension, it includes a large number of tools Chapter 7. Portlet builders 619 for accessing relational databases, building stand-alone applications, and so forth. Note: In addition to Domino, Bowstreet provides Builders for many other back-end systems, including: PeopleSoft SAP Siebel JDBC to relational databases Stand-alone applications And others A key strength of this tool is that it does not completely insulate a developer from the J2EE framework. If a specific task is not possible with the tools provided, a Java developer can code a method or class in Java and include this code in the Bowstreet development environment. A detailed knowledge of Java and J2EE is not a requirement. However, Bowstreet Portlet Factory is very J2EE-centric. A basic understanding of Java and J2EE technologies will greatly increase a developer’s productivity with these tools. Bowstreet provides developers with: Ability to leverage existing Domino applications Ability to more easily create custom portlets Robust personalization and customization capabilities Simplified portlet-to-portlet communication (including C2A) Categorization and search Many single sign-on options People awareness Bowstreet development tool Bowstreet Portlet Factory has a WebSphere Studio plug-in, Bowstreet Designer, used for creating, viewing, and running portlets. Bowstreet Designer plugs into the Eclipse and WebSphere Workbench IDEs. Portlets created with the Bowstreet Portlet Factory follow a standard J2EE model-view-controller design. In order to simplify the task of writing custom portlet Java and JSP code, Bowstreet introduces the developer to a few key objects used to create a portlet application. 620 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Builder A Builder is the core building block that automates design and development tasks performed by developers. Simply put, a Builder is a collection of Java classes and XML documents that represent a specific pattern or high-level component of a Web application. A Builder provides a wizard-like UI for gathering configuration information from the developer, as well as the code for rendering the pattern or context-aware elements within the Web application. A simple Builder might add a button to a JSP page, while another might render a Domino view. Builders can analyze the application and perform tasks in the context of what previous Builders have created. For example, a “page navigation control” Builder could reference a set of JSP pages and create a set of navigational controls relevant to the context of those pages. If a page changes, then the navigational controls update automatically in a ripple effect that can cascade through the entire application. Model A model is a sequenced collection of Builders that generate the application components representing the behavior, structure, data, and presentation of the portlet application. Underneath the covers, a model is simply an XML file containing a series of calls to Builders. Each model can be turned into a portlet, or can be run as a stand-alone J2EE application. Profile A profile contains a set of inputs that vary the way a portlet behaves. Profile settings can be edited after a portlet is deployed by clicking the configuration icon for the portlet. A profile feeds values into Builders based on user identity or other contextual information (such as day of the week). Using profiles, you can automatically generate different variations of a generic portlet (from the same model) for different users or situations. Configured profiles are very easy to implement with Bowstreet Portlet Factory. Regeneration When a model is regenerated, each Builder in the model executes in sequence and creates pieces of your portlet, such as JSP pages or Java methods. During regeneration, profiles can feed different inputs to Builders based on the user or situation, automatically creating custom portlets “on the fly.” There is a negligible performance hit associated with regeneration; less than 1% of the total processing resources in a typical “regen-enabled” execution environment are spent performing regeneration. This is because generated objects are cached at optimal levels of granularity, as are sessions. Furthermore, Chapter 7. Portlet builders 621 it is possible to break a model into a hierarchy of components, whereby models are selectively regenerated. WebApp The WebApp is a profile-specific instance of a portlet application that is dynamically created by the factory regeneration engine. Each Builder, when called during regeneration, creates objects that get woven into the portlet application, such as pages, buttons, variables, or methods. The regeneration engine creates the WebApp by combining the regeneration of a model with a unique instance of profile data. The WebApp objects are then processed by the factory's execution engine to instantiate the executable J2EE application sessions. Bowstreet server components Portlets created with the Bowstreet Designer plug in to the WebSphere Portal and application server. The Portlet Factory's Automation Engine leverages WebSphere’s HTTP stack as well as all of the services from WebSphere Application Server and WebSphere Portal, such as clustering, failover, J2EE security, and session management. Bowstreet Portlet Factory integrates with the WebSphere Portal via the Bowstreet Portlet Adapter WAR. This is a standard WPS portlet WAR that includes the portlet factory classes (JAR files). When a request comes in from the portal, the Bowstreet Adapter Portlet class calls in to the portlet factory code at the layer below the servlet layer (the WebAppRunner class). Note that this WAR file is deployed into WebSphere Portal only once, eliminating the need to re-deploy a WAR with every iteration or variation. Figure 7-32 on page 623 illustrates the code execution architecture. 622 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 WebSphere App Server Request for Portal Page WebSphere Portal Bowstreet Portlet Adapter WAR Bowstreet Adapter Portlet Model XML Files, imported HTML, other files Profile Data Main Factory Controller (WebAppRunner) Factory Builders & Generation (First time only) Factory WebApp Execution Engine Generated WebApp objects, classes and JSPs Application objects Factory-supplied execution libraries (XML, Web services, etc.) J2EE Components: JDBC, EJB, JCA, JMS, JSP tag libraries, commerce components, etc. Figure 7-32 Bowstreet Portlet Factory for WebSphere code execution architecture Implementation issues Applicable portlet patterns Bowstreet Portlet Factory is capable of implementing all four portlet patterns: – Link – Display – Integrated – Migrated Development time Moderate. Development time can be significantly less than developing an application from scratch using the JSP and Java options, especially once Chapter 7. Portlet builders 623 developers become experienced with the Bowstreet development tools at their disposal. Certain types of portlets require less time to create than others. For example, view navigation, document display (without rich text), and Click-to-Action functionality are significantly easier to develop with Bowstreet Portlet Factory. Other functionality, such as document creation and editing, can be more challenging, especially when input validation, input translation, computed fields, or dynamic keyword values are involved. Developer skill set In addition to learning the Bowstreet development tools and techniques, a developer should have good understanding of Domino, HTML, and JavaScript development. While not required, a solid understanding of Java, JSPs, and portal technologies is very beneficial when using some of the more advanced Builder configuration options, or when implementing a task not easily performed by an available Builder. Range of applications Bowstreet offers a powerful set of Builders for developing a rich portal interface with a high level of functionality. A great number of Builders are available and more are being made available with each release. High-level Builder functionality can be customized using a wide variety of configuration settings and by adding lower-level Builders to your model. In the event that a Builder is not available to provide specific functionality, it is possible to write a custom Builder, or add a Builder that supports custom Java code. Both of these options, of course, require Java development skills and significantly more development time. Rich text handling At the time of the writing of this redbook, rich text fields cannot be viewed or edited using the forms generated by Bowstreet Portlet Factory. Note that it is possible to configure the Bowstreet Domino view Builder to open documents in a new browser window. Using this option, documents will be rendered using Domino’s HTTP engine and can therefore leverage all of the Web-based rich text functionality provided by Domino. Performance Bowstreet has done extensive performance testing on portlets created with the Bowstreet Portlet Factory for WebSphere. The benchmark they made concludes that the Bowstreet Portlet Factory provides all the benefits of rapid creation of portlets without sacrificing performance. The portlets that the portlet factory generates exhibit performance characteristics (throughput, response time, and 624 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 CPU utilization) that are highly comparable to traditional hand-coded portlets. Contact Bowstreet to obtain detailed information about performance. Currently, no metrics are available on performance related to portlets accessing Domino data. As with all integration techniques, performance testing is recommended before deploying a portal application using Bowstreet Portlet Factory. Session management Bowstreet Portlet Factory can implement session pooling for connecting to Domino servers. This will significantly increase the scalability of Domino portal applications. Note that the session pooling option can be used only when “Use regen credentials” is specified as the runtime credentials for connecting to Domino. Clustering Bowstreet Portlet Factory does not natively support server failover in a clustered Domino environment. Requires single sign-on Bowstreet supports a wide range of single sign-on options. It can be configured to use LTPA or the Credential Vault in WebSphere Portal. Also, by configuring a Bowstreet portlet with a valid Domino user name and password, it can allow users to connect to Domino servers that do not support SSO. Required software versions Lotus Domino V5.0.10 or later or V6.0 or later WebSphere Portal V4.x or V5.x Bowstreet Portlet Factory for WebSphere V5.8.4+ Bowstreet Portlet Factory Lotus Collaboration Extension Note: People Awareness requires WebSphere Portal Extend. 7.2.1 Implementation details At a high level, development consists of three main steps: 1. Develop the model. 2. Test the model. 3. Deploy and test the model as a portlet. Chapter 7. Portlet builders 625 Developing the model primarily involves adding and configuring Builders. It may also involve the development of custom Builders, or the insertion of custom Java code into a Builder supporting this action. Using the Bowstreet Designer client After installing and configuring a Bowstreet development environment, all development is performed within the Bowstreet Designer. The Bowstreet Designer client is contained within the IBM Rational® IDEs (WebSphere Studio Application Developer) client. Bowstreet has its own perspective within IBM Rational Application Developer (WebSphere Studio Application Developer). To open the perspective select Window → Open Perspective → Other, and then select Bowstreet Models (Figure 7-33). Figure 7-33 Launching the Bowstreet Designer from WebSphere Studio Once you have Bowstreet installed, there is also an integrated documentation within the help system. This documentation gives you detailed information about using each of the Builders. To get to the help system, click Help → Help Contents (Figure 7-34 on page 627). 626 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-34 Integrated Help System Creating a new project and model There are several ways to configure the Bowstreet tool to interact with various WebSphere Portal Server installations. In the following scenario we will look at using the automatic deployment option with a locally installed WebSphere Portal server. This is a great way of developing applications using Bowstreet and immediately seeing changes reflected on the portal server in a very responsive manner. Use the following steps to create a new project and model. 1. Switch to the Bowstreet perspective (see Figure 7-32 on page 623). Select File → New → Bowstreet WebApp Project (see Figure 7-35 on page 628), then give your project a name. Chapter 7. Portlet builders 627 Figure 7-35 Creating a new Bowstreet Web Application 2. The next screen allows you to select the features of the Bowstreet product you wish to use. For our example, we will simply select the Lotus Collaboration Extensions (see Figure 7-36 on page 629). The samples provide very good examples of how different Builders can fit together and are well worth a look. 628 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-36 Selecting the Bowstreet Features 3. Next, select WebSphere 5 as the server type. For rapid application development, Bowstreet allows changes to immediately be seen on the application server. To allow that to be possible, set the following fields – In the Factory Deployment WAR Location section • Installed Applications Directory This is the directory on the WebSphere Application Server where applications get deployed to. • Automatically Deploy Project to WAS Server Check this check box to have the changes automatically deploy to the WebSphere Application Server. • WAS Server to Deploy To This is the server where the applications will automatically deploy. Chapter 7. Portlet builders 629 – In the other section: • Server Host The name of the host you wish to deploy to. • Server Port The port of the server to deploy to; this must be the port of the server that was specified in the WAS Server to Deploy configuration. • J2EE Version The J2EE version you wish to use; the default is recommended. See Figure 7-37 for example settings. Figure 7-37 Selecting the Embedded Test Server 4. The next screen will prompt for Java settings; accept the defaults and select the Next button. 630 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 5. The next screen has two sections. The first section allows us to export the war file for deployment to a WebSphere Portal Server. Tick the box next to Create WebSphere Portlet WAR. Complete the following fields: – WP Root This is the root directory of the WebSphere Portal Server. – Portlet WAR Name This is the name of the WAR that will be created to deploy to a WebSphere Portal Server. The default is usually OK. – Portlet WAR Location This is the location where the created WAR file will be exported to. This folder must exist. The next section allows changes that are made to automatically be deployed to the WebSphere Portal server. – Admin URL This is the URL to the portal servers config. The default is usually fine, but adjust as necessary. – Admin User The Admin user of the server specified above. For the embedded test server, it should always be wpsadmin. – Admin Password The Admin password of the server specified above. For the embedded test server, it should always be wpsadmin. Refer to Figure 7-38 on page 632 for example settings. Chapter 7. Portlet builders 631 Figure 7-38 Example Bowstreet settings 6. If you want to create portlets that conform to the open portlet standard (JSR168), then select Create JSR 168 Portlet WAR and complete the appropriate fields. In this example, we have elected not to create JSR168 compliant WARs (see Figure 7-39 on page 633). 632 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-39 Bowstreet JSR168 settings 7. Next, you will see the Summary and Important Details screen. Review the information and click Finish. During the process, you will be asked to overwrite existing files; it is important to answer Yes to all these prompts. Creating a new model Use the following steps to create a new model: 1. After selecting File → New → Bowstreet Model, you are prompted to select the project. Select the Web project you are working with; in this case, it is Bowstreet Web, and click Next (see Figure 7-40 on page 634). Chapter 7. Portlet builders 633 Figure 7-40 Selecting the Web Project 2. Next, you are prompted for the model type to start with. For Domino portlets, it is generally best to start with an empty model (Figure 7-41 on page 635). 634 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-41 Creating a new Bowstreet model: Selecting model type 3. Give the model a Name (Figure 7-42 on page 636). Then select Finish. Chapter 7. Portlet builders 635 Figure 7-42 Bowstreet Model name Adding the Domino View & Form Builder Bowstreet provides a great number of Builders, each with a very wide range of available configuration options. When building a Domino portlet, you will generally start by adding the Domino View & Form Builder and then refine this Builder’s functionality with other Builders. 1. To add the Domino View & Form Builder from the outline view (ensure you are in the Bowstreet perspective), click the Add a Builder Icon (Figure 7-43 on page 637). 636 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-43 Selecting the Add Builder Icon in the outline view 2. From the Bowstreet Builder Palette window, select All → Domino View & Form (Figure 7-44 on page 638). Chapter 7. Portlet builders 637 Figure 7-44 Bowstreet Builder Palette window 3. After clicking OK, you will be given the Domino View & Form Builder configuration interface (Figure 7-45 on page 639 and Figure 7-46 on page 640). 638 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-45 Bowstreet Domino View & Form Builder: Configuration window part 1 Chapter 7. Portlet builders 639 Figure 7-46 Bowstreet Domino View & Form Builder: Configuration window part 2 Note: It is important to verify that the HTTP browsing and DIIOP tasks are running on the targeted Domino Server. You should also verify that the user ID and password used has permissions to run Java agents on this server (see the server document in the server’s Domino Directory (names.nsf)), and that the ID has the appropriate access level to the database being accessed. 4. All settings for the Domino View & Form Builder are controlled from this window. The configuration options available include: – Domino server, database, view, and form to use with this model – Authentication method (passed ID and password, LTPA, credentials vault) 640 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 – Interface options: • View options (search, category selection, and so forth) • Document link method (no link, new window, and create integrated form) • Document viewing, creation, edit, and deletion options – Many other options 5. Once configuration is complete, click OK. You will be taken back to the model and should notice that Java code has been generated based on the Builder you have configured (Figure 7-47). Figure 7-47 Java code generated from the Bowstreet Domino View & Form Builder It is possible to change the settings in the Domino View & Form Builder configuration window (or any other Builder’s configuration window) at any time simply by double-clicking the Builder name listed in the outline panel. Click the save icon on the toolbar to save any changes. Chapter 7. Portlet builders 641 Testing a Bowstreet Model It is possible to easily test this model directly from the Bowstreet Designer client. 1. To test a model, select Run → Run. The Create, Manage, and Run configurations screen is displayed. Highlight the Bowstreet Model option and click New. Accept the defaults and select Run (Figure 7-48). Note: Creating the run configuration is only required the first time. Figure 7-48 Bowstreet Run configuration 2. The model will then run as a stand alone application on the configured WebSphere Application server. The next time you wish to run the model, just click the Run icon (see Figure 7-49 on page 643 for an example). 642 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-49 Running the Bowstreet model on WebSphere Application Server Running a model from the Bowstreet Designer makes it very easy to iteratively add or configure a Builder, and then quickly test the changes to confirm the change had the intended effect. This action will test most aspects of the application with a few exceptions, such as Click-to-Action or Lotus Instant Messaging (Sametime) awareness, which must be tested from within WebSphere Portal. Deploying a Bowstreet Model as a portlet Turning a Bowstreet Model into a portlet is a fairly straightforward task. 1. Simply add and configure the WPS Portlet Adapter Builder to your model. For instructions on adding a Builder to a model, see “Adding the Domino View & Form Builder” on page 636. The Portlet Adapter Builder can easily be found by selecting Portlet Integration as the Category Name within the Builder Palette dialog and then selecting Portlet Adapter. Note: If you cannot find your model in the project, it will be located under the webapp/webContent/WEB-INF/models directory. Double-click the model to open it. Figure 7-50 on page 644 lists the configuration options for the WPS portlet adapter Builder. Chapter 7. Portlet builders 643 Figure 7-50 Bowstreet WPS Portlet Adapter Builder configuration window Once you have added this Builder, you are ready to deploy your model as a WebSphere Portlet. You should find this to be quite simple. All Bowstreet portlets are actually concrete portlets referencing a single abstract portlet. The difference between portlets is simply the model the concrete portlet references. 2. Once you have saved your model, the next step is to rebuild the WAR. This will become the WAR that will be deployed and is the WAR that was defined earlier (refer to Figure 7-38 on page 632). To rebuild the portlet WAR, right-click the Web project (in our case, it is called BowstreetWeb) and select Rebuild WAR → Rebuild Portlet WARs (see Figure 7-51 on page 645). This will update the WAR file on the file system in the specified path. 644 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-51 Rebuild Bowstreet Portlet WARs 3. Using the browser, open the home page for the IBM WebSphere Portal. This should be a URL similar to http://hostname:9081/wps/portal. 4. Log in to the portal as a portal administrator. 5. Select the portal Administration tab. 6. If you specified automatic deployment for your WebSphere Portlet WAR, the rebuild process automatically updates the deployed portlet WAR for you. This means that your Orders portlet has already been exposed within WebSphere Portal, and all that remains for you to do is add it to a page (see Figure 7-52 on page 646). Chapter 7. Portlet builders 645 Figure 7-52 Adding the automatically Deployed Portlet to a page 7. It will look and function in much the same way as it did in your test environment (see Figure 7-54 on page 647). Figure 7-53 The Bowstreet Portlet deployed to WebSphere Portal Now every time you make a change to your model, simply rebuild the WAR and the portlet will automatically be updated for you. If you then want to deploy your application to another server, look in the installableApps directory of the Portal Server (<wpsroot>/installableApps) and you will find a WAR file as specified when configuring Bowstreet. This WAR file can then be deployed to any other WebSphere Portal server. Adding people awareness It is a simple task to add people awareness to our portlet. It is just a matter of adding a people awareness Builder to our model. 646 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 1. From the outline pane of the Bowstreet perspective, add the Builder type called People Awareness and fill in the required fields (see Figure 7-54). Figure 7-54 Bowstreet People Awareness Builder 2. Save the model. To view the people awareness, you will need to ensure that you deploy the portlet to a WebSphere Portal server that has Sametime configured (see Figure 7-55). Figure 7-55 Deployed Portlet showing people awareness Chapter 7. Portlet builders 647 Implementing communication between Bowstreet models When implementing Click-to-Action, one portlet (for example, model) is the event listener and another portlet triggers this event. Note: Because Bowstreet uses the standard WebSphere Portal Messaging API (including Click-to-Action), it is possible to implement a non-Bowstreet portlet that triggers a Bowstreet event listener. It is also possible to trigger an event in a non-Bowstreet portlet. This means it is possible to have portlet communication between portlets developed with Bowstreet, and those developed with other tools. The general procedure for creating models to be the source and target for Click-to-Action events is as follows: 1. Create a C2A target model. 2. Create a C2A source model. 3. Generate a deployment WAR and deploy it on the WebSphere Portal. 4. View the C2A portlet. More information about these steps is provided in the following sections. Generating a C2A target model A target portlet accepts data from a source portlet by receiving a C2A event from the source portlet. To C2A-enable the target portlet, add the C2A Event Declaration Builder and provide the C2A event information (see Figure 7-56 on page 649). You also need to add a Event Handler Builder for the C2A event (see Figure 7-57 on page 650). In our example, we also wanted to launch a Domino document by UNID, so we added an Action List (See Figure 7-58 on page 651). Because you will expose the target model as a WebSphere Portal portlet, you must add the Portlet Adapter Builder to the model. 648 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-56 Bowstreet C2A Event Declaration Builder configuration window Chapter 7. Portlet builders 649 Figure 7-57 Bowstreet Event Handler Builder configuration window 650 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-58 Bowstreet Action List configuration Implementing a Click-to-Action menu To trigger a Click-to-Action event from a Bowstreet portlet, add and configure the C2A Builder in the source Model. Refer to the help documentation for a detailed explanation of the parameters (see Figure 7-59 on page 652). Chapter 7. Portlet builders 651 Figure 7-59 Bowstreet C2A menu configuration 7.2.2 Implementation example With the assistance of a Bowstreet expert, we implemented the Sales Tracking application case study introduced earlier. Within a day, we had developed a fully functional portal workspace, complete with a Click-to-Action interface between portlets (Figure 7-60 on page 653). 652 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 . Figure 7-60 Bowstreet implementation of Sales Tracking case study We created four models to implement this portal workspace, one for each portlet: 1. Customers view 2. Customer profile 3. Customer contacts 4. Sales activities With each model, we started with the Domino View and Form Builder, which generated a simple Notes view and form interface. We then configured the Domino View and Form Builder and added additional Builders to refine the interface and add functionality, such as Click-to-Action. Bowstreet’s model-Builder development technique requires some time to get used to. However, with a little bit of effort, it ultimately proved very effective in developing our desired portal application. The ease with which we implemented the challenging functionality of Click-to-Action across multiple portlets was impressive. Chapter 7. Portlet builders 653 There were a few spots where we added straight Java code. For example, we used a custom Java method to grab values from the product view for use in selection fields. The following four tables (Table 7-1 through Table 7-4 on page 656) summarize the Builders used to generate our portal application. Some of these Builders required detailed configuration that has not been captured in these tables. Table 7-1 Customer profile Builder Used Description Domino View & Form Creates the base Domino form & view model: Customers\by Customer number, Customer form. WPS Event Declaration Defines a Click-to-Action event within this portlet for triggering the action to open a customer profile document. Event Handler Maps the event to the action, opens a customer profile document based on UNID. WPS Portlet Adapter Turns this model into a portlet. Action List Opens the “blank” startup page. Data Field Modifier Hides the $$return field. Variable Declares a “customer Selected” variable and sets to false. Visibility Setter Hides the Domino view for this portlet. Action List Creates the action of opening a page by UNID. Page Declares the “blank” startup page. Visibility Setter Hides the “back” button from customer documents, preventing the view from opening in this portlet. Domino View Declares the sales people\by employee number view. Data Field Modifier Modified employee_number field behavior in edit mode. Table 7-2 Customers 654 Builder used Description Domino View & Form Creates the base Domino form & view model: Customers by Name view, Customer form. WPS Event Declaration Defines a Click-to-Action event within this portlet for triggering the action to open a profile document by UNID. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Builder used Description Link Called when user selects a customer, triggers the action list, which triggers three Click-to-Action events. WPS Portlet Adapter Turns this model into a portlet. Data Column Modifier Sales Activity Name view: Adjust the tables, alignment, order, ordering, and visibility of the view columns created by initial port of the Domino view. WPS Event Declaration Declares a Click-to-Action event to handle when a customer name is selected. Action List Triggers three Click-to-Action events, one in each of the other three portlets. Account Owner Adds People Awareness to the Account Owner field. Table 7-3 Customer contacts Builder used Description Domino View & Form Creates the base Domino form & view model: Customer Contacts\by Customer Name, Customer Contact form. WPS Portlet Adapter Turns this model into a portlet. Data Column Modifier Customer Contact form page: Adjust the labels, alignment, order, sorting, and visibility of fields created by the initial port of the form. Visibility Setter Hide Employer column in view when employer category is selected. Visibility Setter Hide system-generated edit button in the view interface. Visibility Setter Hide system-generated delete Button in the view interface. Data Column Modifier Customer Contacts\by Customer Name view: Adjust the labels, alignment, order, ordering, and visibility of the view columns crated by initial port of the Domino view. Action List Set up an action instructing the portlet how to filter documents by a customer number. WPS Event Declaration Defines a Click-to-Action event within this portlet for triggering the action to filter documents by customer name. Event Handler Maps the event to the action, the event is triggered, the action is executed. Chapter 7. Portlet builders 655 Table 7-4 Sales activities 656 Builder used Description Domino View & Form Creates the base Domino form & view model: Sales Activity\by Customer view, Sales Activity form. WPS Portlet Adapter Turns this model into a portlet. Data Column Modifier Sales Activity Name view: Adjust the labels, alignment, order, ordering, and visibility of the view columns created by initial port of the Domino view. Data Column Modifier Sales Activity form: Adjust the labels, alignment, order, ordering, and visibility of the view columns created by the initial port of the form. Domino View Products by Name View: Used to look up product name values from the products database. Method Writes a custom Java method to access the product name values. Data Field Modifier Creates drop-down list entries product selection fields. Variable Creates a Java variable. Action List Set up an action instructing the portlet how to filter documents by a customer number. WPS Event Declaration Defines an Click-to-Action event within this portlet for triggering the action to filter documents by customer name. Event Handler Maps the event to the action; when the event is triggered, the action is executed. Data Page Formatter Formats the date created field. Sales Person Awareness Adds people awareness to the Sales Person Field. Hide $$ Return Hides the $$Return Field when editing the form. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 7.2.3 Installing the sample application Bowstreet also comes with a packaging tool. This tool allows you to create and install models and other Bowstreet artifacts. It can also be used to create versions of your application, allowing you to revert to a previous version if required. The application above is available for download as an additional material from the IBM Redbooks Webs ite. Please refer to Appendix C, “Additional material” on page 741 for instructions on downloading the sample. To install and use the example supplied, the following assumptions have been made: Bowstreet is installed with a valid license. The sample Domino databases have been deployed to a Domino server. DIIOP is running on the Domino Server and HTTP browsing is enabled. A valid Bowstreet project has been created. To install the sample application package: 1. Download the packaged called BowstreetRedbook.pkg to your local hard drive. 2. Open your IDE and switch to the Bowstreet perspective. 3. Locate the Bowstreet Web project, right-click the project, and select Bowstreet Packaging → Install (see Figure 7-61 on page 658). Chapter 7. Portlet builders 657 Figure 7-61 Installing Bowstreet Package 4. The Package application will then prompt for the location of the.pkg file. Using the dialog, navigate to the BowstreetRedbook.pkg file and click Open. 5. You will then see that there are models available for installation. Click on the Install button and click OK to all the prompts (see Figure 7-62 on page 659). After a successful install, close the packaging tool. 658 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-62 Installing Bowstreet Models 6. The models will now be available in your IDE to use. The first modification you may wish to make is to adjust the Host Server Name and runtime credentials for each of the models (see Figure 7-63 on page 660). Chapter 7. Portlet builders 659 Figure 7-63 Adjusting the host server for the installed model 7.3 CONET Knowledge Director 3.0 for WebSphere Portal CONET's Knowledge Director 3.0, formerly called Portlet Factory, is a portlet generator for WebSphere Portal. It allows you to easily portalize existing Domino applications. The development model follows the Domino rapid application development approach. This means that portlets are created similar to the way that Domino applications are built. Domino developers are enabled to build portlets without the need to know either Java or the portal server APIs. The key differentiator between CONET Knowledge Director and all other Domino integration techniques is Knowledge Director's performance and scalability. This is achieved through its multi-tier, distributed and server-centric architecture. It implements advanced data caching strategies using a RDBMS - DB2, SQL-Server, or Oracle as options - as its back end. This guarantees high performance and scalability that is independent from the Domino back-end servers 660 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The Knowledge Director tool is especially interesting if you have: Many custom Domino applications that you need to portalize To combine data from several Notes Databases within one portlet The need for write access to the Notes Databases from the portal Domino development expertise on staff The need for highly scalable portlets The desire to use a rapid application development model that allows prototyping 7.3.1 Knowledge Director components CONET's Knowledge Director is a true J2EE application implemented in a multi-tier architecture. The Knowledge Director consists of five distinct components, which together form the key functionality. These are: Connector Repository Generic Portlet KD Service Integrated Cache The relationship and underlying architecture between the components is illustrated in Figure 7-64. Figure 7-64 CONET Knowledge Director architecture Chapter 7. Portlet builders 661 Knowledge Director Repository The Repository ((1) in Figure 7-64 on page 661) is a Notes configuration and developing application for the definition of portlets. It controls the data selection (queries, selections, and databases), determines the presentation of the portlet, and defines the interaction of the portlets with each other in the scope of Business Packages. With the aid of the Repository's definitions, the individual applications to be later deployed into the WebSphere Portal server are created by the so-called Generic Portlet component (see Figure 7-65). Figure 7-65 Portlet definition repository Portlet creation is done in a five step process that involves the definition of elements similar to the ones used to build Domino applications. Elements used are, for example, selection formulas, views, and form layouts. All these elements are defined by using the Notes @formula language in combination with HTML. Wizards (for basic portlets and category portlets) help with the creation process and there are various templates (that is, e-mail portlet) for standard portlets shipped with Knowledge Director. This is explained in more detail later in this section. 662 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Portlets The so-called Generic Portlet ((5) in Figure 7-64 on page 661) is deployed into the portal server. This Generic Portlet represents the information objects being described in the KD Service in their final form as an integral part of the WebSphere Portal. Connector The Connector ((3) in Figure 7-64 on page 661) is needed for the extraction of data from the Notes source databases at runtime. The Connector is a Java application that has to be installed on each Domino server that is involved in the portalizing process. The connector does not need to reside on the Domino server it extracts the data from. In the case of remote access the Connector communicates via CORBA with the Domino sever. Knowledge Director Service The KD Service ((2) in Figure 7-64 on page 661) is a J2EE application and constitutes the central element of the Knowledge Director. It is responsible for a number of functions, for example, processing the configuration data from the Repository ("Portlet Definitions") using the so-called Repository Import and thus affecting the data selection. Furthermore, the central KD Service also controls the cache management. The Knowledge Director Service is responsible for handling all portlet requests for data and application transactions. The Knowledge Director Service gathers information from the Portlet Definition repository and then utilizes one or more Domino Connectors to interact with a Domino application. There are many tasks associated with processing and answering a request from a portlet. The Knowledge Director Service facilitates the entire process of gathering, organizing, caching, and rendering the output for the portlet, as well as the transactions with the underlying Domino application. Transactions can involve write access to Domino databases, portlet cooperation, and agent execution on the back-end Domino server. Cache To improve performance, the Knowledge Director Service implements caching. Caching provides a significant performance increase in most situations. The Portal Factory Service can cache results in memory or persistent to a DB/2, SQL Server, or Oracle database. Caching respects the Domino Security Model. Depending on the configuration, the edited data can either be stored in memory or in a separate, relational Cache Database ((4) in Figure 7-64 on page 661). The main objective of caching is to ensure optimal data availability anytime and Chapter 7. Portlet builders 663 independent of the Domino server's status. Cache control is handled automatically by the KD Service and can be tuned in the repository. Component communication The KD is using Standard Web Communication Methods. Figure 7-66 gives an overview of the interaction of the different Knowledge Director components. Figure 7-66 CONET Knowledge Director component architecture The portlet communicates with the Knowledge Director Service and the Reverse Proxy via HTTP. The KD Service connects with the KD connector using a Standard IP Socket Connection. CONET implemented a Domino Connector written in Java, which uses the Notes Object Services locally to perform the requests on behalf of the KD Service. In this figure, you see that Knowledge Director Service is not using HTTP or DIIOP to remotely access Domino. The architecture was chosen to minimize the number of calls necessary to transact with a Domino server. Knowledge Director's remote connectors provide a coarse-grained interface. It receives a detailed task description, performs this task on the local server, and returns a result. Instead of dozens or hundreds of remote DIIOP calls, there is just one call on the local toolkit. This improves performance and minimizes network traffic. It is important to point out that the Domino connector is based on WebSphere and Domino standards. It builds on the Domino Java Toolkit and implements a high-level bridge for the specific transaction needs of the Knowledge Director service. 664 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Communication between the KD Service and the RDBMS Caching is handled through Standard JDBC Connections. Configuration options The Knowledge Director was developed by CONET completely based on separate components (using the Model View Controller concept). This modular structure allows configuration of infrastructures of all kinds and sizes, from individual project solutions all the way up to extensive enterprise infrastructures. When setting up the Knowledge Director, all the different components can either be installed centrally on one machine or in a distributed system spread over a number of machines. To illustrate the Knowledge Director's range of possible architectures, we have listed some exemplary options in the following list. (Table 7-5 through Table 7-8 on page 667 illustrates deployment options.) Table 7-5 Single server configuration Portal projects frequently originate in individual divisional or project solutions with a small number of users. All the portal's different components are in this case installed centrally on one computer. The Knowledge Director fully supports such a starting configuration. You can install it on the same application server that the portal runs on. Domino data can then either be accessed via the KD Connectors, or you can replicate the desired Domino databases directly onto the portal installation's Domino server. As an option to heighten the system's performance, we recommend the use of the Knowledge Director's memory-based caching. Chapter 7. Portlet builders 665 Table 7-6 Domino Hub configuration In practice you often want to separate the installation of your IBM WebSphere Portal from all related back-end systems and therefore also from the Domino server providing the source data for the portal. This approach facilitates an easier administration of the portal and enables you to deliberately exchange individual components. The Knowledge Director is in this case installed on the same server as your portal software. Data is either accessed via a Domino Hub or by direct requests to the Domino back-end servers. When using this configuration, we recommend database-supported caching. The database server (SQL, Oracle, and so on) responsible for caching can also be installed on the same machine with the portal software and the Knowledge Director. Table 7-7 Distributed Services configuration If you expect approximately 1000 users to access the portal simultaneously, we do recommend to go for a distributed services configuration. In this case, the WebSphere Portal, the KD Service, the relational KD Cache as well as an optional Domino Replication Hub are all installed on separate machines. This kind of configuration allows for the creation of a highly scalable overall system and the individual definition of every single component's performance features. 666 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Table 7-8 Extended Distributed Services configuration In a variation of example No. 4, all components involved are again installed on separate machines, but in addition to that, they are all provided redundantly in order to make clustering possible. The Knowledge Director is suitable to be run in a cluster, too. This means that several KD Services can be combined to form a single logical system. The KD Cache can either be used centrally or be clustered as well. 7.3.2 Implementation issues This section summarizes the functionality of the CONET Knowledge Director. Applicable portlet patterns Knowledge Director portlets can be used to implement the entire range of portlet patterns that were outlined in Chapter 1, “Introduction to portalizing Domino applications” on page 1 (link, display, integrated, and migrated). Knowledge director portlets are able to link to native applications (they can display and recombine information from Domino databases). With Knowledge Director's write access, it is possible to develop portlets for an integrated scenario, that is, letting the user perform tasks in other applications inside the portlet, rather than having to launch the other application. Finally, a migrated portlet - one that is used to replace an application and transform entire business processes into portlets can be achieved. The Knowledge Director provides you with a whole number of possibilities to define layout and presentation of the portal's display. Even quite ambitious user requirements can be realized. For example: Flexibly definable layout, fully compatible with IBM Portal layout elements. Reverse Proxy for the display of Notes Rich Text directly on the portal interface (includes automated link and JavaScript filtering). Chapter 7. Portlet builders 667 Portlet Caching. Search function with freely definable layout for the presentation of results. n-level categorization as well as support of non-balanced information hierarchies. Support of Portlet Messaging for the display of complete Workplaces. Integrated form generator not depending on Notes ("forms"). Development time Portlet development with Knowledge Director is a very efficient process. The ease of use of the Domino @formula language makes portlet development as fast as building Domino applications. Knowledge Director implements a true rapid application development model, including comfortable portlet preview abilities. Wizards for basic list portlets and category portlets make the development even faster. Demo portlet definitions (that is, search portlet) shipped with Knowledge Director make developers quickly grasp the building principles. The preview lets developers simulate various settings of the portal present in the end user scenario (locale, method of access, searchstrings, and so on) and preview the portlet under these conditions (Figure 7-67). Figure 7-67 Portlet Preview: Settings page 668 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Debugging A code checker for Knowledge Director formula language helps you avoid bugs on the syntax-level. To identify problems, the amount of information feeding the Knowledge Director log files can be finely tuned. Six levels from 'errors' to 'full trace' are possible. Various statistics are recorded to monitor the time usage, traffic, and storage situation on the Knowledge Director modules. Developer skill set Portlet development can be done with basic Domino development skills. Even junior Domino developers who know the @formula language and HTML can build portlets. Range of applications Knowledge Director can be used to build any kind of Domino portlets. It supports read and write access to Domino applications as well as the execution of agents. Portlet messaging is easy to implement. The options for advanced database aggregation create a completely new way to work with Domino databases. Knowledge Director allows you to: Combine data from multiple Domino databases, possibly from different servers – Append data sets – Merge data sets Relate queries through primary/foreign key relationships: – One to One: One row in Query X matches one row in Query Y – One to Many: One row in Query X matches 0+ rows in Query Y Data views can be n-level categorized One drawback is that in the development process you are limited to the functionality provided by the @formula language. Currently the use of JSP tag libraries or customized Java code is not supported. Rich text handling Knowledge Director portlets can display and edit Domino rich text. Rich text can be embedded in portlets, that is, the KD e-mail portlet with all embedded elements, for example, images and links, is still working correctly. Therefore, the Knowledge Director service implements a reverse proxy and handles URL rewriting. We found that Knowledge Director is currently the only tool that Chapter 7. Portlet builders 669 handles Domino rich text properly. Furthermore, Knowledge Director ships with its own HTML editor. Internationalization Multilingual text definitions can be deposited in the Repository. These text definitions are interpreted during runtime depending on the user language specified in the portal or on the respective browser setting. The necessary translation charts (resource bundles) can be maintained centrally. Staging Knowledge Director supports the typical tri-section of WebSphere portal settings, that is, specific Portlet Definition Repositories reflect development, staging, and production systems. Interaction of these repositories is handled automatically, so that portlet definitions are moved from one level to the next one after being released by a developer. Also, the necessary administration tasks for versioning portlet definitions are handled automatically. Performance Knowledge Director’s performance is very good. Through its multi-tier architecture and the use of memory and DB2 caching, it can handle high volume Domino databases with high concurrent user access with good response times. Session management Knowledge Director implements session management. Portlets can use either the active user or a broker that acts on behalf of a group of users to authenticate against the Domino backend. Clustering The Knowledge Director connector can access clustered Domino servers. In high availability and performance scenarios, the Knowledge Director service can be clustered as well. The Knowledge Director Service can be installed in a distributed way on many application servers. These instances of the server use a single caching database. Scalability The Knowledge Director has been tested for databases with more than 100,000 documents and 1000 concurrent users. 670 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Single sign-on Knowledge Director supports the following SSO configurations: Credential vault LTPA Token Required software versions Knowledge Director is currently available in Version 3.0 and requires the following software: WebSphere Portal V5.0 and higher WebSphere Application Server V5.0 and higher Domino V6.5 and higher in the back end (Domino V5.0.10 and higher is supported too, but due to a less powerful Domino API in Domino 5, the full functionality of KD 3.0 cannot be provided.) 7.3.3 Portlet creation methodology CONET’s Portlet creation methodology is completely Domino-centric. Portlets are created in a way similar to that used to build a Domino application. Building blocks The elements that define a portlet are called “building blocks.” To better understand the building block concept, let us draw an analogy and imagine a Notes view, for example, your “All Documents” view in your mailbox. You can ask yourself the question: What elements define this Notes view? The answer is that the Notes view: Lives in a Domino database Has a selection formula Has layout information Usually, a Notes view is created in the Domino Designer by defining these three elements inside of a view design element. Let us compare this to a portlet definition in Knowledge Director. Knowledge Director uses portlet building blocks. Portlet building blocks deal with information, for example, about the database, selection formula, and the layout. So it uses the same three basic elements that we would use to build a Notes view. Figure 7-68 on page 672 shows a comparison of a Portlet and Notes view. Chapter 7. Portlet builders 671 Figure 7-68 Portlet to Notes view comparison To build a portlet out of building blocks, Knowledge Director allows you to combine basic elements like databases and selections into higher level elements called 'Queries' and 'Portlet Definitions.' Figure 7-69 on page 673 shows the containment hierarchy of the different building block elements. 672 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-69 Element containment hierarchy The Query element is essentially used to build views by summarizing one database, one selection, and layout information. The top-most element is the Portlet Definition. It can contain one or multiple Queries. This way, data from multiple Domino databases can be mixed, merged, or categorized. Once you have created a Portlet Definition, Knowledge Director is able to automatically create a WebSphere Portal portlet for you. With one click in the Knowledge Director UI, the tool creates a portlet war file for you that can be deployed in WebSphere Portal. In addition to being able to define views, Knowledge Director also allows you to create forms with read and write access, implement portlet cooperation, and a lot more. The key concept The key concept to implement layouts and functionality with Knowledge Director is the use of the @formula language. The Knowledge Director @formula language is an aggregation of the Notes @formula language we all know from Domino development with specific KD @formulas. The Portlet layout is defined by using HTML with embedded @formula language, as illustrated in Example 7-1. Example 7-1 HTML with embedded @formula language <table border=0 cellspacing=0 cellpadding=0 width=100%> <tr><td> <@ fldTitle @> <@ @if(@Date(@modified)=@today;‘<img src=/images/newicon.gif> ';'') @> <br> <@ fldAbstract @> </td> <td><@ @Date(@Modified) @><td> Chapter 7. Portlet builders 673 </tr></table> You see that Knowledge Director uses the @formula language in the same way you would use Java on a JSP page. As opening and closing tags for @formulas, you have to use <@ and @>. @Formulas can be as simple as single fields or can be more complex, for example, @if conditional constructs. Figure 7-70 is the Portlet output for the previous code example. Figure 7-70 The output result for the previous code example Knowledge Director allows you to use most of the Notes @formulas to build portlets. It also gives you additional @formulas that make sense in the portlet context. 7.4 Implementing the Sales Workplace example In this section, we walk you through the seven step process to build a set of portlets with Knowledge Director. We highlight a few functional components that we used to implement searching and portlet cooperation for our Sales Workplace portlets. In Figure 7-71 on page 675, you see one page of the Sales Workplace, where customer and sales information are combined. 674 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-71 The Sales Workplace The Sales Workplace is based on data from two Notes Databases: Customers (customer.nsf) Sales Reporting (sales.nsf) The databases are independent of each other. To combine their information in the Sales Workplace, we take advantage of the common customer key. The upper left portlet shows the list of customers. Finding a specific entry is supported by a search field and by a clickable alphabetical index. The list can be browsed by a 'following-pages'-mechanism. Clicking on one of the entries causes the upper middle and upper right portlets to show details of this specific customer. The portlet "Customer Profile" shows basic information about the customer. This portlet gives you the chance to edit the customer information (or set up a new customer record). The 'Customer Contacts' portlet lists contact persons at the specific customer and provides information about them. The Chapter 7. Portlet builders 675 'Sales' portlet (lower left) is also triggered by the selected customer in the 'Customer' portlet. It shows the list of activities concerned with the customer. Clicking, in turn, on one of the activities shows its details (including attachments, that is, profile.pdf), which appear in the lower right portlet (the 'Activity Details' portlet). Basics 1. Start the process by identifying your data source (the customer database) (Figure 7-72). Figure 7-72 Database definition This is done by creating a database document that contains a reference to the database that you want to portalize. Knowledge Director allows us to specify either the path or the replica ID to a Domino database. In most cases, the replica ID will be used. 2. You need to select the information that is relevant from this database, so do a select statement. Knowledge Director allows you to build selections based on @formula statements or full-text selections. Remember: you are building a definition similar to a Notes view. If you have access to the design of the Domino database, you can go ahead and copy and paste a view selection formula from a view. 676 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-73 Selection definition 3. This step is used to define a layout. As mentioned previously, the layout is a mixture of HTML and the @formula language. Knowledge Director layouts are made up of different layout components. You find layouts for the overall portlet layout (this is called the Definition Template) as well as layout components for the individual result set row. In this example, you are going to focus on the layout of the individual result set row. In Knowledge Director, this is called a Line Template (Figure 7-74). Figure 7-74 Layout definition The layout also includes an option for sorting. As in a Domino view, you can specify multiple sorted columns. Columns in the portlet context refer to columns of the table layout. 4. In this step, you summarize all the previous steps. You take your database, selection, and layout and put them into a query—the analogy of a Domino view (Figure 7-75 on page 678). Chapter 7. Portlet builders 677 Figure 7-75 Query definition Basics tab On the Basic tab of the Query, select the database and selection definition for the Query (Figure 7-76). These are the elements defined in the previous steps. Figure 7-76 Query definition Layout tab On the layout tab, choose the template for the data display of the individual result set row as well as the Form template that is used to open the customer profile once the user clicks on a customer name inside of the Portlet. 5. Finally, the query becomes formalized as a Portlet definition. Portlet definitions can contain more than one query. This is relevant if you want to merge data from multiple Domino databases. In this example, we just have one query. 678 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-77 Portlet definition 6. This was the final step in the definition process. The Portlet is now ready for creation. This is done by an automatic process that takes the Portlet definition and renders a portlet out of it (Figure 7-78). Figure 7-78 Automatic portlet creation (create button) 7. Once this process is finished you can deploy the Portlet to your Portal and place it on the Sales Workplace. The result should look similar to Figure 7-79. Figure 7-79 The resulting customer portlet Search In the last section, we showed you how to define the basic portlet for the customer list. In this section, we highlight how we implemented the search, including the alphabetic index and portlet cooperation. Chapter 7. Portlet builders 679 To enable the search in the customer portlet, we added the code in Example 7-2 to the Portlet Definition Template. Example 7-2 Customer search <form "Search" action="<@@ViewAction@>" method="post"> <input name="<@@ContentSearchName@>" size="40"> <input type="submit" name="Search" value="Search"> </form> In the layout definition, we created a basic HTML form with a search field. The trick is to give the search field the special name <@@ContentSearchName@> and use the @formula <@@ViewAction@> to create an Action URI to submit the form to the portlets action listener. In the query definition, we can define which fields Knowledge Director should include in the search. Alphabetic Index For the alphabetic index, we defined the following two functions in the definition template (Example 7-3). Example 7-3 Alphabetic Index functions <script> Function WriteSearchField(letter) { {document.forms['Customer_list'].<@@ContentSearchName@>.value = letter; {document.forms['Customer_list'].submit(); } function WriteAlphabeth() var letter = ""; var hStr; For ( i = 0; i = 25, i++){ ….. letter =String.fromCharCode(i+65) hStr = 'javascript:WriteSearchField(" ' + letter + "*" + ' ")'; document.write(" <a href=' " + hStr + " '>"+letter+"</a> "); …… } </script> These JavaScript functions produce a clickable link (href) for each letter that is shown. When the link is clicked, for example, the letter "D", the search field is filled with "D*" and the HTML form is submitted. As a result the user sees the list of customers beginning with the letter "D" (Figure 7-80 on page 681). 680 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-80 Customer Portlet with search field and alphabetical index Portlet cooperation Enabling Portlet cooperation is as straightforward as implementing searches. In our example, we want to implement the following Portlet cooperation: We search in the customer Portlet. Once we select a customer, the customer detail Portlet displays the customer details information (Figure 7-81). Figure 7-81 Customer Profile portlet For defining the Customer Profile portlet, we can rely mostly on the Customer portlet that we have defined in the previous section. We add a Form Template and a Definition Template that contain the HTML code for the Customer Profile portlet, resulting in the following definition structure (Figure 7-82 on page 682). Chapter 7. Portlet builders 681 Figure 7-82 Component structure for a "Detail Message" The communication between the two portlets is achieved by a KD-Messaging formula inserted in the code of the Line Template of the sending portlet (Customer) (Example 7-4). Example 7-4 Portlet cooperation <a href='<@ @Message( <@ @CreateDetailMessage(Customer_Profile) @> ) @>'><@customerName@></a> We build an HTML link around the customerName that embeds the @Message formula. This allows us to send multiple specific messages to other portlets and have them respond to it. In this case, we have included only one message, the @CreateDetailMessage. It tells the receiving portlet (Customer_Profile) to show the data of the current list entry as specified in the From Template. At runtime, KD Service generates a link of the following form from the message formulas. It makes use of the mechanisms of WebSphere Portal messaging: <a href= '/wps/myportal/…..?v=list&kd_broadcast0=v%5Eform%7Ekd_to%5ECustomer_Profile%7Ed %5ECustomer.Q%7C18185526EBF1240C85256F120068FD71%7E'>Adhoc</a> After a user clicks on a customer name link, the other portlet will respond according to the defined behavior (Figure 7-83 on page 683). 682 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 7-83 Customer portlet and Customer Profile portlet connected by messaging The following behavior can be achieved in a similar way: The customer contacts show only the contact personnel of the selected customer. The customer activity portlet displays a view with the latest activities with that customer (Example 7-5). Example 7-5 Using the function @CreateSearchMessage <a href='<@ @Message( <@ @CreateDetailMessage(Customer_Profile) @> <@ @CreateSearchMessage(Customer_Contacts;<@customerNumber@>) <@ @CreateSearchMessage(Sales_Activities;<@customerNumber@>) ) @>'><@customerName@></a> We use the function @CreateSearchMessage, when the sending portlet specifies a search string and the receiving portlet has a search expression (see Figure 7-75 on page 678) to compare this string to. The layout of the search result is specified in the Line Template of the receiving portlet. A third way to define messages is the formula @CreateFormMessage. This formula allows to define the Query (and by that the Form Template) and the uniqueID of the Notes document to be shown. 7.4.1 Write Access In this section, we want show how we implemented the write access in a Knowledge Director portlet. To modify or create a Notes document, Knowledge Director provides an Edit Template. The KD Edit Template corresponds to the KD Form Template for read access. Additionally, it contains the name of the Notes form to write into. The HTML code of the Edit Template contains special Knowledge Director @Edit formulas. Let us look at the Edit Template for the Customer Profile portlet (Figure 7-84 on page 684). Chapter 7. Portlet builders 683 Figure 7-84 Edit Template for editable Customer Profile portlet To make the customerName editable, it is enclosed in the KD formula @EditText. This creates an editable field in the portlet. The KD formulas @EditNumber, @EditTextArea, and @EditTextList work in a corresponding way for other datatypes. These formulas have a couple of optional parameters: Default values, additional HTML text to integrate into the <input> tag, and user roles can be specified. The use of the expression @EditValidate( <@customerNumber@>; NUMBER; 'Please, enter a number') makes sure the user enters a number in the 'Customer Number' Field. In general, the KD Formula @EditValidate enables additional validations to the ones possibly contained in the underlying Notes application. The validation rules are regular expressions or predefined rules. A failure text can be supplied. In the corresponding Form Template of the Customer Profile portlet, we have included the following line of code to create the 'edit' and 'new' links: <a href='<@@LinkToEdit()@>'>Edit</a> <a href='<@@LinkToCreate()@>'>New</a> 684 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Clicking on the Edit button, then, results in the following editable portlet (Figure 7-85). Figure 7-85 Editable Customer profile The following line of code implements the 'save' and 'cancel' links: <a href='@@EditSubmit()@>'>Save</a> <a href='@@LinkToList()@>'>Cancel</a> @EditSubmit and @LinkToList are KD-formulas. @EditSubmit submits the HTML-Form and @LinkToList links back to the Customer portlet. Security It is important to point out that the security mechanisms of Notes Databases are obeyed. The ACLs and Reader Fields are strictly observed. No writing is possible without the correct access rights. Additional roles can be specified in the @Edit formulas that can further restrict the write access rights. 7.4.2 Summary Building portlets with CONET's Knowledge Director is easy for Domino developers who know the @formula language. The building process is straightforward and similar to building forms and views with the Domino designer. Results can be achieved fast and with minimal learning effort. We were especially impressed by the good performance and scalable architecture of the tool. Chapter 7. Portlet builders 685 686 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 8 Chapter 8. Integration with Lotus Workplace Lotus Workplace can be a powerful platform for building new collaborative applications. Just like Lotus Domino, the real value of the platform will be the ability of developers to build applications that leverage and extend the collaborative abilities offered by the platform. In this chapter, we look at some possible ways of integrating and extending a Domino portlet or application to leverage some of the features of Lotus Workplace. As with other techniques for integrating Domino applications with Portal, there are several ways to approach integration. We start by looking at some simple ways to deploy a portlet into Workplace. We also discuss how to use Lotus Workplace Builder to customize an application. We then move on to some more advanced integration techniques utilizing the Lotus Workplace Products API Toolkit. Attention: At the time of the writing of this redbook, the Lotus Workplace API and other development techniques are still very much in their infancy. Some of the technical specifications and delivery timings are subject to change. Always check the latest documentation available on the Web at the Lotus Documentation site: http://www-10.lotus.com/ldd/doc © Copyright IBM Corp. 2005. All rights reserved. 687 8.1 Introduction Lotus Workplace is built on top of WebSphere Portal, so from an integration development point of view, anything that you have constructed for WebSphere Portal will be able to be integrated into Lotus Workplace without change. Any of the techniques and methods we have covered for WebSphere Portal are valid and can be used in exactly the same way in Lotus Workplace. This makes Lotus Workplace a powerful environment to integrate Domino Applications with. We not only can leverage the infrastructure provided by WebSphere Portal, but now also integrate and leverage the components that Lotus Workplace makes available. If we take a quick look at Lotus Workplace structurally (See Figure 8-1 on page 689), we can see that there are layers of services which we can exploit. So with Lotus Workplace, not only can our Domino applications use services at the portal level, but they can be extended to the Workplace level. Alternatively, we can choose to just use the portal level and know that our applications will work perfectly well on Lotus Workplace. Important: The important point to note is that as a general rule, if a portlet works on WebSphere Portal, it will work on Lotus Workplace. Note: Note that the Lotus Workplace V2.0.1 Products server is the foundation for an enterprise-level collaborative environment. Installing and configuring the Lotus Workplace V2.0.1 Products server is a task that requires a certain degree of planning and configuration. While the details for installing this product are beyond the scope of this book, you can review a detailed instruction guide within the redbook Lotus Workplace 2.0.1 Products: Deployment Guide, SG24-6378, found at: http://www.redbooks.ibm.com/redpieces/abstracts/sg246378.html 688 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Workplace Layer Portal and J2EE Layer Figure 8-1 Structural representation of workplace 8.1.1 Skills and degree of customization - Workplace Builder Figure 8-2 on page 690 gives an overview of this integration option relative to all the options available to the user/developer for portalizing Domino applications. Note that the horizontal axis illustrates an increasing range of customization for integrating your application, while the vertical axis illustrates the degree of J2EE skills required for each approach. Chapter 8. Integration with Lotus Workplace 689 high 6 Domino Java API IBM Portlet API JSR 168 Portlet API JSF Portlet Framework Struts Portlet Framework Lotus Workplace API J2EE Knowledge 5 Domino JSP tags 3 2 1 IBM Portlet Builder for Domino limited Existing Portlets Bowstreet Portlet Factory / Conet Knowledge Director 4 Lotus Workplace Builder low Level of customization high Figure 8-2 Integration options The main message to take from this graphic is that using the Lotus Workplace Builder, or simply adding existing Workplace portlets, requires only minimal Java knowledge, while giving the developer, administrator, or power user some flexibility in terms of customization. 8.2 Adding Workplace portlets to Domino portlets Perhaps the simplest and easiest way to get integration between Domino and Lotus Workplace is to use the existing Lotus Workplace portlets with your Domino portlets to create and integrate the application. There are portlets within Lotus Workplace that can add value to a Domino application. It may be useful to have the user’s Lotus Workplace calender beside a custom Domino meetings minutes database so the user can simply switch portlets and pencil a meeting into their calender. Using our Struts example from 6.5, “Sales Tracking application using Struts” on page 498, we could build upon this application to add greater value. More 690 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 specifically, we will enhance the application by putting a chat room in the page so users can talk about the sales strategies and challenges. It might also be beneficial to add the Team Task list so that users can assign related tasks to people. This utilizes the Domino application, and for very little effort, adds a great deal of business benefit and value. In this example, we went into the Administrative GUI of Lotus Workplace and added a Sales tab. Within that Sales tab, we added the Domino Application (see Figure 8-3). Then, beside the application, we added the team task portlet so that users can assign tasks to each other. Underneath those portlets, we added a chat room so multiple users can get together in this page and talk about the sales figures and performance. Figure 8-3 Adding Domino and workplace portlets together For relatively little effort, we added a great deal of functionality to our Domino portlet. In Figure 8-4 on page 692, you can see the users now have a Sales tab where they can view the sales information. This is a simplistic example of what is possible, but it would be very easy to deploy Domino portlets to Lotus Workplace and build many such pages and applications. Again, the important point here is that if it works on WebSphere Portal, it will work on Lotus Workplace. Chapter 8. Integration with Lotus Workplace 691 Figure 8-4 Workplace portlets and Domino portlets together 8.3 Adding Domino Portlets to Workplace Applications Using the Workplace Builder, we can take the example in the previous section one step further and create Workplace Applications. These applications become very easy for a power user to deploy and build upon an existing application. Workplace Applications also add more power when they are packaged together to take advantage of attributes such as roles and parameters. 8.3.1 Applications and templates A Workplace Application is a collection of pages and portlets that address a business need for a particular group of users (refer to Figure 8-5 on page 693). Examples of Workplace Applications could include: Team Spaces Communities of Practice Project Rooms Sales Strategy Planning Customer Rapid Response Team 692 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-5 A Workplace Application page Workplace Applications are built from Templates. These Workplace Applications can be distributed and managed by business users and administrators to provide targeted functionality to specific groups of users. Templates A Workplace Application is made up of business components. A business component is an encapsulation of a business concept or process. Workplace includes many business components like Discussion, Team Calendar, Team Task List, Contact List, Forms, Document Library, Search, and People Finder. We can also add our own business components to an application; these may include a Domino Portlet or Portlets. We could just deploy the portlets to a page and have a Workplace Application; however, with Lotus Workplace, we now have the ability to make our applications into templates. A template defines the Workplace Application, its pages, and the application components deployed on each page (see Figure 8-6). In this way, we can provide a pre-configured set of portlets and pages targeted at a specific business task. These applications have the distinct advantage of being able to be modified by an end user and administrators, who can also control the deployment utilizing user roles and other administrative features. Figure 8-6 Workplace template construction Chapter 8. Integration with Lotus Workplace 693 To work with a template, you must have access to Workplace Builder, which is the toolkit for viewing and editing templates. To see the Workplace Builder link, the user must be granted the user policy Allow users to create Workplace Templates in the Administrative console for the workplace Server. Note: To work with templates, you will need to be granted the specific administrative user policy “Allow users to create Workplace Templates” in the Administrative console to see the Workplace Builder link. For details on setting this administrative user policy, please refer to the Lotus Workplace Infocenter, found at: http://workplaceid.notesdev.ibm.com/lwp20_infocenter/index.html Additionally, you can refer to Chapter 5, “Team Collaboration administration“, in the Redpaper IBM Lotus Workplace Team Collaboration 2.0.1, REDP-3929, found at: http://www.redbooks.ibm.com/redpieces/abstracts/redp3929.html Applications All Workplace Applications are based on a template. When customizing an application, you can choose to either modify the existing application or choose to modify the template on which that application is based. An example of modifying an existing application is you may choose to add your own component to an existing Team Space. However, if you wanted to have that modification to appear for all future Team Spaces, you would modify the template and add your component to the template. It is also possible to save an existing application as a template. This is a concept that is very similar to Lotus Team Workplaces (QuickPlace). Roles Each workplace has members, individuals, and groups who are assigned roles that determine their access to the application. The names of workplace members appear in the Members portlet that is displayed in every application. Generally, application managers are Moderators; application users are Contributors or any other defined role as desired. Application access is determined first by the roles defined in the template, and then by the level of access that each role permits for Workplace objects. The Workplace objects include the template or application, its pages, and the application components deployed on each page. Permission to work with Workplace templates and applications is determined by user policies, assigned template roles, and workplace membership roles. 694 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 User policies Provide permission at the most fundamental level for users to work with templates and applications. Workplace Administrators set user policies. Template roles Provide permission to edit or use templates. Template roles are assigned to users by template owners. Membership roles Provide permission to work with a Workplace Application. Application owners assign member roles in a Workplace Application. Required components for templates and applications Workplace information and membership are essential components of every Workplace Application. These components are displayed as the information portlet and the Members portlet. As these portlets must be available in every Template or Application, the delete icon is not available. The information portlet is used to describe what the application is and also acts as a home portlet for the application. It also contains the rename button so a user with the correct privileges can change the name of the application. The Membership portlet is used to store specific access rights to this application. The size limit of a Workplace Application is set by the Workplace Application policy in the Administrative console for the Workplace Server; by default, the size is set at 60 MB, and there is also a setting within the policy to allow a warning message to be displayed if the size of the application approaches that limit. 8.3.2 Workplace Builder Workplace Builder is an application assembly tool for business analysts, application managers, and designers. It is intended for the business unit of the enterprise that understands the business model and business processes. Workplace Builder is designed to help the business user rapidly assemble components into applications that revolve around a business process. The user who creates an application becomes the default moderator and can specify additional moderators. The application moderator performs most of the administration tasks. The moderator specifies whether an application is open to all authenticated users or to application members only. In addition to specifying membership of the application, moderators edit the names and descriptions of applications, and the layout of pages within applications. Chapter 8. Integration with Lotus Workplace 695 Application moderators can create applications from templates and, when appropriate, save new applications as templates for reuse by other users. In this way, we can add value to the Lotus Workplace platform by extending an application to display Domino related Data. 8.3.3 Using the Workplace Builder As an example, we are going to create a Workplace Application for managers to get together and discuss sales of the fictitious widget company. To do this, we will base the application on the Team Space Template, but add our own application as part of it; in this case, we will use Domino data, but it could be any component you like. If you have all the required roles and policies, the Workplace Builder icon will be available at the top of the screen next to My Favorites. Click on this button to launch the Workplace Builder (see Figure 8-7). Figure 8-7 Workplace Builder We will now create a new Workplace Application Template by clicking on the New button. Several fields are presented to be completed (Figure 8-8 on page 697): Template Name This is a name that will represent the application. We used Widget Sales Discussion. Category This is the area within Workplace that the application will be available from. We wanted this application to be available from the applications area of Workplace, so in this case we selected Application. 696 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Description An optional description of the application. Starting Point This is probably the most powerful parameter on this page. It allows a user to base an application on a previous template. In our case, we based it on the Team Project template. This not only saves a great amount of work, as we do not have to start from scratch, but also allows applications to be built upon a previous application to create the next application. Figure 8-8 Creating a new application template The application is then created and opened. Down the left side is a list of all Builder Tabs where configuration of the application can be performed. The first tab is the Properties tab (see Figure 8-9 on page 698). This is the information that was entered when the application was created. In this case, there is nothing to change, so we are going to click the Pages and Layouts tab. Chapter 8. Integration with Lotus Workplace 697 Figure 8-9 Workplace Builder Properties The next tab represents Pages and Layouts and is an interface that you may be familiar with from the Administration Area of WebSphere Portal and Lotus Workplace. Here we can add new pages, change the order of pages, and set the security of pages as well as other features. We can also drill into each page and place the portlets or components where we want on those pages. In this case, we are going to create two new pages: one to hold some sales information from Domino, and the other to surface some contact information about our customers. As well as those additions, all the components we would get as part of the Team Project template are visible (see Figure 8-10). In this case, we decided this business function did not require the team calender or the chat room, so they were removed by selecting the trash can icon beside those pages. Figure 8-10 Workplace Pages and Layout screen 698 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 From the Pages and Layout screen, it is possible to add components to pages. For the Sales page, we are adding a pre-configured Domino Application Portlet and the instant contact list (see Figure 8-11). Figure 8-11 Adding the Domino Portlet and the Instant Contacts age After setting up the pages with the components that are required and laying them out as you like, select the Parameters Page. Each component of the application can expose parameters, which allows the Business user who is setting up a new application to customize the application or further refine the application to suit that business’ needs. It is up to the component developers to expose which parts of the component will be able to be refined when developing that component. Figure 8-12 on page 700 shows the parameters that are configured for this application. Chapter 8. Integration with Lotus Workplace 699 Figure 8-12 Workplace Builder parameters This example shows that, in this application, we can choose to modify some information about the portlet and also some settings surrounding the team task portlet. At the moment, the Description attribute is set and cannot be edited by a user. If we wanted to change that, it is just a matter of opening that parameter for editing and changing it to the required value (see Figure 8-13). Figure 8-13 Editing a workplace parameter Once the parameter has been edited, we can see that it is now editable by the users when a new application is created from this template (see Figure 8-14 700 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 on page 701). This method can give the business user a great deal of power in varying the application to suit different needs without the need to change any underlying code. When developing components intended to be used with Workplace Builder, this should always be a consideration. Figure 8-14 After editing a workplace parameter After editing the Parameters, click the Roles Tab. Roles allow the designer to add application specific roles to an application. In this way, it is possible to create granular roles that make logical business sense to this application. For example, in this application, we may want to add a role called Contact Manager and have that person as someone who performs the maintainence on the contacts and tasks within this application. After clicking New to create a new role, set the access as required (see Figure 8-15 on page 702). In this case, we are giving members of this role Administration access over the team task so they can edit tasks as deemed appropriate. Chapter 8. Integration with Lotus Workplace 701 Figure 8-15 Editing a workplace role At this point, it is possible to preview the template. At the top of the screen, you will find the Preview button. This Preview button allows the person building the application to iteratively see what the application will look like when it is completed. Another subtle but powerful feature here is that data can be pre-populated into the application. An example is that in the team task there may be a task that will occur every time that this application is deployed. When the application is in preview mode, simply enter the task and that data will be saved as part of the template. When you have completed previewing the application, click Done and then save the template. You are then returned to the list of templates and you should now see the new template listed. Now a template has been defined, it is ready to become a working application. Click back to My Workplace and then the application page (remember, we set the category to application so it would be listed as a new application here). Next, click the New button and our template should be available. Complete the fields that represent the name of the application and add a description. Ensure that you select the newly created template in the template field (see Figure 8-16 on page 703). 702 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-16 Creating a new application based on our template After clicking OK, you will then be presented with a screen where you can set any application specific parameters. These are the parameters that we made editable and are now being displayed to the application creator to further refine the template. Below you can see the parameters associated with the team task portlet (see Figure 8-17 on page 704). Chapter 8. Integration with Lotus Workplace 703 Figure 8-17 Setting the parameters Once the parameters are set, click OK and the application is ready to use and will be available to the users (see Figure 8-18). At this point, if it was not done as part of the template, it may be necessary to add users to their appropriate roles. Figure 8-18 The application ready to use When the application is opened, we can see our Domino data integrated with existing workplace components (see Figure 8-19 on page 705). 704 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-19 Domino Data in Workplace application Editing the application While using the application, the users of the application may decide that they want some components in the application changed. In our example, it may be useful to see a PDF beside the sales information. To achieve this, click the Edit button at the top of the screen (see Figure 8-20 on page 706). Only people in the moderator role will be able to perform this task. Chapter 8. Integration with Lotus Workplace 705 Figure 8-20 Editing the application Once the application is in edit mode, the tab layout should be familiar. In this case, we are going to remove the instant contact portlet and replace it with a PDF viewer. To do this, click the Page and Layouts tab and then click the pencil icon to add the new portlet to the page (see Figure 8-21). Figure 8-21 Editing the layout of the sales page 706 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Once you are happy with the new layout and settings, click Done. The edit of the application should be available immediately to users of the application (see Figure 8-22). Figure 8-22 Edited application with new portlet Reusing the application to create new applications The users of the application may find the changes incredibly useful, so next time an application template is created, it is possible to base that application on the one we have running here. In this manner, it is possible to build upon this application to create new applications (see Figure 8-23 on page 708). Chapter 8. Integration with Lotus Workplace 707 Figure 8-23 Creating a new template based on previous application Conclusion The Workplace Builder provides an easy to use interface for business users to assemble applications. By using the Workplace Builder, it is simple to add great business functionality to the base Workplace product. 8.4 Working with the Workplace API The Workplace API provides Java developers with tools to build custom applications that can leverage the Workplace Platform. With the toolkit it is possible to create applications that take advantage of the frameworks created by workplace. The API includes APIs, SPIs, and JSP tags to help a developer to achieve this. Architecture As with the WebSphere Portal API, the Lotus Workplace API has a clearly defined services layer. We can use these services to interact with Lotus Workplace components (refer to Figure 8-24 on page 709). 708 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-24 Lotus Workplace platform architecture Timeline At the moment, there is only a small set of APIs and SPIs available. The toolkit is a separate release with the current release being 1.0. The Lotus Workplace APIs will be delivered in the IBM Lotus Workplace Products API Toolkit. Table 8-1 summarizes the expected availability and contents for upcoming API Toolkit releases. Table 8-1 API availability API Toolkit Contents Release 1.0 (Workplace V 2.0) Release 2.5/Q4 2004 (Workplace V2.5) Release 2.5.x/Q1 2005 (Workplace V2.5) Collaboration Application Component Interfaces Available Enhancement for Workplace V2.5 Enhancement if needed Component Services API API Reference Javadoc only Available Additional services, other enhancements if needed Application Infrastructure Services API not available Available Additional services, other enhancements if needed Workplace Mail Messaging SPI Available Enhancements if needed Enhancements if needed Chapter 8. Integration with Lotus Workplace 709 API Toolkit Contents Release 1.0 (Workplace V 2.0) Release 2.5/Q4 2004 (Workplace V2.5) Release 2.5.x/Q1 2005 (Workplace V2.5) Workplace Instant Messaging SPI Available Enhancements if needed Enhancements if needed JSP Tags Available Enhancements if needed Enhancements if needed Workplace Client APIs Not available Available Enhancements if needed Application development prerequisite In order to create an application using Lotus Workplace Products API, the following software is required: Lotus Workplace API Toolkit V1.0 Java Editor (although WSAD V5.1.2 + Portal Toolkit 5022 is highly recommended) The Lotus Workplace API Toolkit V1.0 can be download from http://www.lotus.com/ldd/lwpapi. API help documentation installation The Lotus Workplace API Toolkit Information center is shipped with an Eclipse Web-based interface. 1. To install the info center, download the following two files from http://www.lotus.com/ldd/lwpapi: – lwpapi10.zip – lwpapi10_hs_win.zip 2. Unzip lwpapi10.zip first and then unzip lwpapi10_hs_win.zip to the same location. The file structure should appear like Figure 8-25. Figure 8-25 Infocenter file structure 3. Navigate to the Doc directory and launch help_start.bat. 710 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-26 The installed infocenter The API toolkit information center should be the first place to look for in depth details on the API toolkit. 8.4.1 Using the JSP Tag Library to enhance a Domino Portlet At the time of the writing of this redbook, the JSP tags provide the most practical way of integrating Domino and Workplace using the API. With the 1.0 release of the API, it is possible to make use of the collaborative components within Lotus Workplace to bring people awareness to a Domino portlet and give a user control of their online status. Person Tag The Person Tag displays a list of actions that can be performed when integrated with the Lotus Workplace collaboration feature set. This tag will automatically render all the HTML required for a user to perform those actions. Some examples of the actions that can be performed are: Send E-mail Chat Chapter 8. Integration with Lotus Workplace 711 Add to a Contact List Show Profile Find Documents Authored By Tag attributes The tag supports the following attributes: value: Specifies the person name in the syntax supported by the type specified in valueType. For example, if the valueType is specified as "EMAIL", than the value attribute would specify the person’s valid e-mail address. This attribute is required. valueType: Specifies the technology from which the specified person information will be retrieved. The supported values are LDAPDN (LDAP Distinguished Name), EMAIL, WMMID, and MEMBERDN (Member Distinguished Name). This attribute is required. displayName: Specifies the name that you want displayed that is associated with the Person tag. The value of this attribute overrides any display name found in the lookup of the specified person. This attribute is optional. skin: Specifies the name of the JSP used for the Person tag "skin". This attribute is optional. Note: For JSPs created prior to Lotus Workplace 2.0 and with the WebSphere Portal API, the format of "<pa:person>John Doe</pa:person>" (that is, with no attributes) is still supported but not recommended for further usage. Example In this example, we took the Struts JSP example we developed in Chapter 6, “Portlet development using Java: Integration examples” on page 391 and have changed the people awareness tag to be a Workplace compliant tag. We had to make a small modification to the Domino database to pass the uid of the user instead of the short name to the portlet for input as the attribute. To do this, we changed the Customers.jsp to add the Workplace Compliant tag. First, we changed the tag library to reference the new Workplace tld (see Example 8-1 on page 713). Tip: We used WSAD to build this example; to get the project to build without error in WSAD, it was necessary to put two jar files on the build path. These two jars were awarenesstags.jar and people.jar. These two jars can be found on the Lotus Workplace server in the path <installroot>\PortalServer\shared\app\lotusworkplacelib. These files should be added to the WEB-INF\lib\ directory. Also, the people.td and the awarenesstags.tld will need to be imported. 712 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Example 8-1 Adding the people awareness tag library <%@taglib uri="/WEB-INF/people.tld" prefix="pa"%> Next, we changed the actual format of the jsp tag to reflect the required parameters for the Workplace Tag With the required attributes (see Example 8-2). Example 8-2 Workplace people awareness tag example <%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%> <%@taglib uri="/WEB-INF/personTag.tld" prefix="pa"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <jsp:useBean id="customersPageIndex" class="salestrackingstruts.PageIndex" scope="session"></jsp:useBean> <jsp:useBean id="salesPersons" class="com.ibm.itso.cam.redbooks.sg246466.domino.SalesPersonBeanCollection" scope="session"></jsp:useBean> <jsp:useBean id="messageBean" scope="request" class="salestrackingstruts.MessageBean"></jsp:useBean> <jsp:useBean id="customers" class="com.ibm.itso.cam.redbooks.sg246466.domino.CustomerBeanCollection "scope="session"></jsp:useBean> <portletAPI:init /> <h3>Customers</h3> <c:if test="${not empty messageBean.message}"> <bean:write name="messageBean" property="message" scope="request" /> </c:if> <table> <thead> <tr> <th>Name</th> <th>CustomerNumber</th> <th>AccountOwner</th> </tr> </thead> <tbody> <c:forEach var="varCustomerBeans" items="${customers.customerBeans} "begin="${customersPageIndex.startPageIndex}" end="${customersPageIndex.endPageIndex}" step="1" varStatus="status"> <tr> Chapter 8. Integration with Lotus Workplace 713 <td><html:link action="/showCustomerDetails" paramId="noteId "paramName="varCustomerBeans" paramProperty="noteId"> <c:out value="${varCustomerBeans.name}" /> </html:link></td> <td><c:out value="${varCustomerBeans.customerNumber}" /></td> <td><c:forEach var="varSalesPerson "items="${salesPersons.salesPersonBeans}"> <c:if test="${varCustomerBeans.accountOwner == varSalesPerson.employeeNumber}"> <pa:person value="${varSalesPerson.uid} valueType=”LDAPDN”" displayName="${varSalesPerson.name}"/> </c:if> </c:forEach></td> </tr> </c:forEach> <tr> <td>Total: <%=String.valueOf(customers.getCustomerBeans().length)%></td> <td><html:link action="/previousPage">Previous</html:link></td> <td><html:link action="/nextPage">Next</html:link></td><tr> </tbody> </table> <br /> <html:link action="/showCustomerDetails">Add new customer</html:link> <br /> <html:link forward="/main">Main</html:link> The result is that the people awareness is now visible in Lotus Workplace (see Figure 8-27 on page 715). 714 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-27 People awareness inside workplace OnlineCenter tag This tag gives the developer the ability to put the presence awareness controls anywhere on a page that is convenient. These controls allow the user to modify their online status, for example, a user may wish to mark themselves as ‘I am away’ (see Example 8-28). Figure 8-28 Online center tag This facility already exists on most workplace pages, but if we create a Workplace Application with a custom theme that does not include this functionality, it is possible to add this awareness control to a page. Chapter 8. Integration with Lotus Workplace 715 Tag attributes The tag supports the following attributes: objectScopeId: A unique ID required for this tag to function properly when it exists more than once on a page. This can be any text value as long as it is unique for this page. JSRootURL: Defines the place where the JavaScript files exist in the portlet. This is needed for the tag to load the onlinecenter.js file. Since the location of the JavaScript files within the portlet's.WAR file can differ from developer to developer, this attribute lets you specify the correct location. Example For the sake of simplicity, and to show an example, we added an onlineCenter tag to the top of our Customers.jsp of the Struts application we developed in Chapter 6, “Portlet development using Java: Integration examples” on page 391. The first thing to do was to add the reference to the tag library for people awareness (see Example 8-3). Example 8-3 Adding the awareness tag library reference <%@ taglib uri = "/WEB-INF/tld/awarenesstags.tld" prefix = "awarenesstags" %> Next, we added the code to the bottom of our JSP (Example 8-4). Example 8-4 Adding the awareness tag ID in the JSP <tr> <lotus:OnlineCenter objectScopeId="YOUR_TAG_ID"JSRootURL="javascript"/> </tr> Below is an example of what the tag may look like (Figure 8-29 on page 717). 716 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Figure 8-29 Online center tag in our application 8.5 Workplace API and SRI The Lotus Workplace API allows a developer using Java programming skills to extend the Lotus Workplace platform to develop portlets and other applications. There is a set of APIs (Application Programming Interfaces) and SPIs (Service Provider Interfaces) to use to achieve this. At the time of the writing of this redbook, the set of components that are exposed as APIs and SPIs are limited. The current API toolkit does not directly help integrate Domino applications, so strictly speaking, they are out of the scope of this book. However, we cover what you can do with the API toolkit, as there may be other ways you wish to use this functionality now. Version 2.5 will offer a lot more functionality to help with the development of Domino applications. Version 2.5 will allow Domino portlets to integrate with Workplace by: Inserting Calender Entries Interacting with Discussion Forums Interacting with Portal Document Manager Creating Workplace Emails Querying Collaboration Features Interacting with the Workplace Builder Chapter 8. Integration with Lotus Workplace 717 Once you have the API toolkit installed, there is a preview of what might be included in the toolkit for Version 2.5 in the Java Doc. The Java Doc is located in <apitoolkit>\lwpapi\javadoc\lwpapi25_preview\index.html. The components that are included in API Toolkit V1.0 are: Collaborative Application Component Interfaces Workplace Mail Messaging SPI Workplace Instant Messaging SPI The Toolkit API has an excellent Information Center. It also has some documented examples to help you get started with using the API. 8.5.1 Collaborative Application Component Interface This part of the API allows you to: Access application and template catalogs Create and modify applications and templates Manage application instances Access community membership Access collaborative context There are several parts of this interface, but one example that could be developed would be a way for an application to know when a discussion forum is rapidly consuming hard drive space.The application could then warn an administrator of the impending problem. To make use of these features, it is necessary to create a collaborative component. This component is essentially a stateless session EJB that implements one of the Collaborative Application Component Interfaces (see the Info Center for more detail). The Collaborative Application Component Interface methods are essentially callbacks from Lotus Workplace to your component. They make it possible for your component to describe itself to Lotus Workplace so that it can be intelligently managed by the environment, configured by the user, and used in a template with other components. To make your component collaborative, you implement any or all of the following interfaces in your component’s collaborative component EJB. If you implement any of these interfaces, you must implement the Lifecycle interface. 718 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Lifecycle The Lifecycle interface is used to tell your component that a collaborative component has either been created or destroyed. This happens whenever, for example, one of your components is added to a Workplace Application template. You can use this information in your component to create or initialize resources when needed. Membership Whenever members are added or removed from a community associated with the application, Lotus Workplace will notify your component. This can allow you to perform tasks when these events take place. For example, this would allow you to build your own audit log of activities in the applications to which your component belongs. You can also use this information to grant or deny permissions to other resources you may be managing from your application. In addition, the Membership interface allows the component to provide Workplace with a list of component-specific roles, which can be mapped to community roles using Workplace Builder. Sensor The Sensor interface is used by Lotus Workplace to get information about resources managed by the component, so that policies regarding resource usage (for example, disk space quotas) can be enforced. Templatable The Templatable interface is used by Lotus Workplace to incorporate the application component in an application template. This interface allows the component to save information about itself when the template is saved in XML format. Transactional This interface is used by Workplace to work out if your component can participate in global transactions, therefore determining if the component supports the ability to undo changes if a roll back occurs. For details on using these interfaces, refer to the Collaborative Application Component Interfaces Javadoc shipped with this toolkit and the Info Center. 8.5.2 Workplace Mail Messaging SPI The Mail Messaging SPI lets a developer create components that can interact with the messaging system of Workplace. For example, this SPI will allow the developer to build applications that can redirect mail as it is routed. A typical application that may be built using this SPI is a spam filter that lets you block e-mail before it gets to the recipients inbox. Also, a virus scanner for incoming e-mail could be developed using this SPI. Chapter 8. Integration with Lotus Workplace 719 There are two specific interfaces a Java developer can work with: a handler and delivery interface. A handler looks at the message as it passes through the mail services. Your component can then make decisions based on the content of that e-mail, a handler can then choose to either delete or move that e-mail to another part of the system before that e-mail reaches the users inbox. A handler can also reject e-mail so it will not be delivered. There are numerous interfaces to work with; the Info Center has more information about these interfaces. To build a component that uses these interfaces, use the following steps as a guideline: 1. Set the correct classpath so that your code can use the required Mail Messaging SPI.jar files. 2. Write the extension code. 3. Register the mail processing extension. 4. Configure the mail processing extension. 5. Run the mail processing extension. 8.5.3 Workplace Instant Messaging SPI The Workplace Instant Messaging API allows the developer to create components that intercept Instant Messages before they are delivered to the recipient. An example of using this SPI would be to build a component that logged all instant message conversations. Another example would be an application that stopped messages that contained certain words or phrases from being delivered based on a set of rules. The Instant Messaging SPI is part of the presence and instant messaging services of Lotus Workplace V2.0.1. The SPI is reachable via a servlet installed on the WebSphere Portal server. The Instant Messaging SPI includes the following classes: MessagingListener This interface receives events for each message going through the SIP server. MessagingService This interface is used to manage all MessagingListener instances. MessagingServiceFactory This class is used to get an instance of a MessagingService object. Contact 720 This class represents a SIP contact. It is used to examine the contacts to whom messages are being sent. For an example, see ChatLoggingApp.java, the sample program Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 included in this toolkit (in lwpapi10\imspi\samples\chatlogging). 8.5.4 Conclusion At the time of the writing of this redbook, the Lotus Workplace API is very much in its early implementation phase. At the present time, the API is not a great aide in surfacing Domino portal applications in Lotus Workplace. However, in the not too distant future, it will provide a lot of functionality that can be included in a Domino portlet. For example, it would be great to add some functionality to a portlet that could easily add the contents of a Domino discussion database to a related discussion that may be occurring in a Team Space. It is greatly encouraged to explore the API now and become familiar with it. Also, have a look at the Javadoc for the 2.5 release that is included in this release. This API will allow a developer to build on top of the platform and, just like Lotus Domino, it will possible to provide custom Domino based portlets that use the Lotus Workplace platform to build components that add great value to a business process. Chapter 8. Integration with Lotus Workplace 721 722 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 A Appendix A. General portlet development guidelines The following general portlet performance thoughts have been taken directly from the Portlet Developer’s Best Practice and Coding Guidelines, contained within the Portal Application Design and Development Guidelines, REDP-3829, found at http://www.redbooks.ibm.com/abstracts/redp3829.html. We consider performance crucial to any production portlet, so we have included a copy of this information here. © Copyright IBM Corp. 2005. All rights reserved. 723 Portlet coding guidelines These guidelines are intended to help you produce best-of-breed portlets for the WebSphere Portal environment. Refrain from using instance variables The most important rule of thumb is to limit the use of instance or class variables in a portlet. Within WebSphere Portal Server, only a single instance of the Portlet class is instantiated. Even if different users have the same portlet on their pages, it is the same portlet object instance that generates the markup. Therefore, each portlet instance has to be treated like a singleton. The implication is that you should not use instance or class variables to store any state or other information between calls to the portlet. Being a singleton, each instance variable of a portlet effectively becomes a class variable with similar scope and the potential for problems when the variable is accessed many times in each user's context of the portlet. It is better to avoid these problems by limiting the use of instance or class variables to read-only values. Otherwise, reentrance or thread safety may be compromised. There is an exception to this rule in which you can use instance variables. Variables whose values do not change can be stored safely in instance variables. For example, on initialization of the portlet, its configuration is set within the portlet. Because the configuration does not change for different users or between calls, you can store it in an instance variable. Use try/catch blocks. Get in the habit of adding try/catch blocks around significant code in JSPs to enable debugging. This will greatly improve your portlet development experience. Minimize dependencies on JavaScript. Since JavaScript implementations and behavior differ widely between browser types and versions, the more your portlet depends on JavaScript, the more browser-dependent your portlet becomes. Additionally, the more of the page that is rendered using JavaScript, the more difficult it is to maintain and to extend to other markups besides HTML. Also, it is more difficult to namespace-encode JavaScript resources and nearly impossible to properly encode (response.encodeUrl()) URLs built using JavaScript. Use taglibs whenever possible. Encapsulating Java code within taglibs not only allows common view functions to be easily reused, it keeps the JSPs clean and makes them more like normal HTML pages, which allows the page designer to concentrate on layout and decoration and reduces the possibility of breaking the embedded Java code. 724 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Pass data to the view (JSP) as a bean in the request object Use the PortletRequest object to pass data to the view for rendering. This way, when the request is complete, the data falls out of scope and is cleaned up. Passing it as a bean allows the JSP to simply refer to the data as properties on the bean using intrinsic functions in the JSP syntax. Use the portlet logging facility Using the PortletTraceLogger installed with WebSphere Portal for tracing and logging allows your portlet’s debug and trace output to be stored with other portlet output in the portal log files. It also takes care of the infrastructure around logging and tracing. The PortletLog object that is the interface to the logging mechanism can be obtained from the portlet context: PortletLog log = getPortletConfig().getContext().getLog(); You should also verify that logging is enabled for attempting to log data, especially if that requires additional logic or storage to build the log message. Example A-1 illustrates code verifying that logging has debug enabled and how the logic might be written. Example: A-1 Using a log from portlet if (log.isDebugEnabled()) { String logMsg = new String("Time to retrieve data: " + elapsedTime); log.debug(logMsg); } Adopt good code documentation habits While commenting of code is not required for the functionality of the portlet, it is essential for its maintenance. In addition to the fact that the responsibility for a portlet’s maintenance can change hands over time, well-written portlets serve as models for other portlets, which means that someone else must understand what you wrote. Well documented code implies more than simply inserting comments; it implies good naming practices for Java resources as well. The following are examples of guidelines to follow: Insert JavaDoc-compliant prologues for all public classes, variables, and methods. Be sure to document inputs and outputs. Include inline comments, but do not include them on the same line as a Java source. It is difficult to align and follow comments that are on the same line as a Java source. Use meaningful names for variables and methods. Variables x, y, z, while easy to type, are not easy to follow through code. Capitalization conventions and the use Appendix A. General portlet development guidelines 725 of underscores (‘_’) within resource names is a matter of personal choice, but be consistent once your choice is made. Use the ContentAccessService to fetch external content if necessary If it is necessary to fetch external content using an HTTP request, use the ContentAccessService as it is intended to perform that function as expediently as possible. It also prevents you from having to rewrite the same function and introduce another maintenance point. Cache portlet settings or portlet data If portlet settings or data is complicated and requires complex parsing to digest, it may be a good idea to cache the data for quick retrieval later. Avoid using the PortletSession to store this data as it causes “session bloat”. Alternatively, consider using the Application Server’s Dynacache CommandCache to store this data. PortletSettings can be stored keyed off the portlet’s name. PortletData will have to be stored keyed off the portlet name and user name. When updates to the cache are necessary, based on updates to PortletData or PortletSettings, devise a means of communicating updates to the data, such as through implementing the PortletSettingsAttributesListener interface, or by using a “dirty bit” that can be interrogated to see if updates have been made to the configuration, in which case the cache can be invalidated and updated. Note that the CommandCache is not currently cluster-aware, meaning that cached content is not shared across horizontal nodes in a cluster. So, portlets must be able to create the cache entry from scratch if the cache entry does not exist. Follow design guidelines for Struts portlets If you are developing portlets based on Struts, use the following additional guidelines to ensure your implementation is the best it can be: Be sure to use the sample portlet applications that accompany the Struts Portal Framework package to ensure Struts is working properly in your environment before testing Struts support in your portlet. 726 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Make sure to review the documentation on the Struts Portal Framework for application requirements and any restrictions (see The Struts User and Developer Guide, found at http://struts.apache.org/userGuide/index.html). For existing Struts applications, refer to the section in the same document titled “Migrating an Existing Struts Application”, found at: http://www-106.ibm.com/developerworks/websphere/techjournal/0403_yu/0403_yu .html Portlet packaging guidelines Here we discuss the portlet packaging guidelines. Make common functions available externally to portlets If the portlet contains common functions that are replicated across several portlets, consider isolating them, making them externally accessible by the portlets. The easiest way to do this is build another JAR file of the common classes and place the JAR file in a location that is in each portlet’s classpath, such as the AppServer/lib/app directory. Another approach is to build a Portlet Service from the common functions, which can then be accessed using the common PortletService interface, and retrieved using the PortletContext.getService() method. Combine portlets with similar functions into a single portlet with multiple configuration settings If you find yourself developing several similar portlets, such as a mortgage calculator portlet, car loan calculator portlet, and a home equity loan calculator, it might make sense to actually develop a single portlet that can behave differently based on configuration settings. The common portlet code is specified as part of the portlet application’s abstract portlet definition. The application’s various concrete portlet definitions have unique configuration parameters (PortletSettings) that can be used to customize the behavior of the common portlet code. Data management There are three primary areas where portlet configuration information is stored and can be maintained: portlet settings, portlet data, and servlet configuration. Appendix A. General portlet development guidelines 727 Use portlet settings to store user-independent configuration data This data represents configuration parameters from the portlet’s portlet.xml file (<config-param> elements under the concrete portlet definitions). It is only writable in the portlet’s configure mode (doConfigure() method), but is readable through the getPortletSettings() method on the portlet. Use portlet data to store user-dependent configuration data This data often represents personalized overrides to the portlet settings and is thus stored according to user and portlet instance. This data is only writable from a portlet’s edit mode (doEdit() method), but is readable through the getPortletData() method on the PortletRequest object. Use a servlet configuration for storing the static initialization information for a portlet Examples of this information include the install directory or path information. This data, taken from the portlet’s web.xml file, is read only and accessible using the getServletConfig() method on the portlet. General session management guidelines Here we discuss some general session management guidelines. Limit the use of the portlet session for storing portlet state information The Portlet Session is a convenient place to store global data that is user and portlet specific and that spans portlet requests. However, there is considerable overhead in managing the session, both in CPU cycles as well as heap consumption. Since sessions may not expire for quite some time, the data contained in the sessions will remain resident in active memory even after the user is done with the portlet. Be very judicious about what is stored in the Portlet Session. Tip: A good rule of thumb to use when determining if data should be stored in the Portlet Session is if the data is user-specific and cannot be recreated by any other means, such as portlet state information. 728 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 For example, parsed configuration data (from PortletSettings) should not be stored in the Portlet Session since it can be recreated from the database at any time. Do not rely on portlet sessions if the portlet allows anonymous access If your portlet is to be used by unauthenticated users, such as on the Welcome page, then the portlet should not rely on the portlet session at all. Portlet sessions are bound to a user context. By default, for unauthenticated users, a portlet session can be requested by a portlet, but it is a temporary session that only lasts for the duration of the current request. Public session support exists, where sessions are issued to unauthenticated users, but because there is no log out action for an unauthenticated user, the session will not be invalidated until it times out, which can lead to severe memory consumption issues. There are other ways to preserve global data for anonymous access, such as: Storing data in a collection whose key is communicated back to the client using a cookie. Storing data in the WebSphere Application Server’s dynacache facility, again using a unique key which is communicated to the browser using a cookie. Storing the state information as a cookie itself. Storing non-sensitive data as hidden field elements within FORMs so that it gets passed back on subsequent form submission. This has the added advantage of binding state-aware data to the page requiring it. Alternatively, consider limiting the function of the portlet for anonymous access. You can check for the presence of a user object (PortletRequest.getUser()) to see if a user has logged into the portal, in which case a portlet session should be available. Always request an existing portlet session Always request a portlet session using either PortletRequest.getPortletSession() or PortletRequest.getPortletSession(false), which will only return a session if one does not already exist. The portal server will establish a portlet session for a portlet before it is invoked. This helps prevent the case where a temporary session is generated for a portlet during anonymous (unauthenticated) access. Prevent temporary sessions from being generated in the JSP Add the JSP page directive <%@ page session=”false” %> to the JSP to prevent temporary sessions from being created by the JSP compiler if none already exist. Appendix A. General portlet development guidelines 729 This will help guard against attempting to use the session to store global data if the session will not exist past the current request. You will need to be sure the portletSession exists before trying to use it. Other general development guidelines There are potentially many different types of browsers, or user agents, which access WebSphere Portal besides a typical desktop browser, such as hand-held devices (PDAs, or personal data assistants) and wireless phones. The capabilities of these devices vary widely, as do their users’ attention spans and interaction models. Therefore, the portlet’s design needs to take these facts into consideration. Information priority is different, depending on the device it is viewed on. Capabilities of desktop browsers are limitless. Users can download almost anything quickly and randomly navigate through it. For handheld devices, however, screen real estate and device memory is at a premium, not to mention the relatively slow speed of a wireless connection versus a LAN connection. Also, users of mobile and handheld devices need quick access to concise information and cannot afford the time or effort it takes to navigate through several screens to get to the desired information. Here are some more general guidelines for portlet development: All portlet strings should be fetched from resource bundles All displayable strings should be stored in resource bundles and fetched using the ResourceBundle Class. The resource bundles should be organized by language under the portlet’s WEB-INF/classes directory. For example, if a portlet supports the English and Finnish languages, it would have three resource bundles (default, English, and Finnish) and might be organized under WEB-INF/classes as follows: WEB-INF/classes/nls/mystrings.properties WEB-INF/classes/nls/mystrings_en.properties WEB-INF/classes/nls/mystrings_fi.properties Using the ResourceBundle class, you would refer to the properties file as “nls.mystrings”. Java will automatically look for the appropriate properties file based on the current locale. 730 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Organize portlet help files by language As opposed to typical JSPs in the portlet’s view, the portlet’s help JSP files can, and should be, language dependent. Since little else in the JSP will exist but help content, there is not much need in extracting strings from resource bundles. Translate the JSPs instead, and organize them by language. When using the include() method on the portlet context to dispatch a JSP, the method will search the directory structure for locale-specific subdirectories first. For example, if you include the JSP “/WEB-INF/helpjsps/html/myHelp.jsp”, and the current request locale is en_US, then the method will look for the myView.jsp in the following directories, in order: /WEB-INF/helpjsps/html/en_US/myHelp.jsp /WEB-INF/helpjsps/html/en/myHelp.jsp /WEB-INF/helpjsps/html/myHelp.jsp /WEB-INF/helpjsps/myHelp.jsp Note that the include() method will also look for a default myHelp.jsp if one does not exist in the HTML subdirectory. Use portlet messaging to communicate (send messages) to other portlets on the same page It is possible to send messages to a specific portlet or to all portlets on a page. The message body may contain data that the receiving portlets require. The message is sent from a portlet’s actionPerformed() method and received by other portlet’s messageReceived() methods, before those portlet’s doView() is called as a result of the action, so there is an opportunity to set data or state information before the receiving portlets are invoked. Go to the WebSphere Portal Infocenter and select Developing portlets → Writing portlets → Portlet messaging for more details. Avoid the use the HttpSession to share data with other portlets/servlets The HttpSession is not common between nodes in a cluster, so any data store in the HttpSession is only visible by J2EE resources in the same Application Server instance. The PortletSession is derived from the HttpSession, and besides only having visibility of the portlet instance, is also bound by the same restriction. Persistent sessions can be turned on in the application server, which will serialize the session to a database that can be shared across nodes in a cluster, but that can cause performance issues for very large sessions. See “General session management guidelines” on page 728 for other ideas. Appendix A. General portlet development guidelines 731 Avoid the use of HttpSession to share data with other portlets/servlets The HttpSession is not common between nodes in a cluster, so any data stored in the HttpSession is only visible by J2EE resources in the same Application Server instance. The PortletSession is derived from the HttpSession, and besides only having visibility of the portlet instance, is also bound by the same restriction. Persistent sessions can be turned on in the application server, which will serialize the session to a database that can be shared across nodes in a cluster, but that can cause performance issues for very large sessions. See “General session management guidelines” on page 728 for other ideas. Performance consideration guidelines Here we discuss performance consideration guidelines. Do not spawn threads Since portlets are multi-threaded to begin with, spawning child threads can create problems with synchronization or multi-threaded access to the spawned threads. Threads should be used with extreme caution, and when necessary, should be used briefly (no long running threads, especially any that outlast a request). Do not use threads to access J2EE resources In certain Java Virtual Machine (JVM) implementations, such as on z/OS, there are a limited number of threads in the process thread pool that are allocated for accessing J2EE resources, such as JCA connectors. All such resources should be manipulated on the calling thread to minimize the possibility of starving the thread pool. Limit temporary storage Temporary storage includes temporary variables created within a block of code that are used then discarded. Temporary variables are typically utilitarian in nature, such as strings, integers, Booleans, vectors, and such. However simple in nature, temporary variables take CPU cycles to create and destroy and occupy space on the heap, which must be maintained by the garbage collector. The following is a list of simple guidelines for reducing or optimizing temporary storage: Reuse temporary variables as much as possible. 732 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Declare temporary variables outside loops. Instead of String, use StringBuffers, which are optimized for parsing and string assembly. Declare collection classes (Vectors, Arrays) with an initial size that is the average maximum size, to prevent growth and reallocation of space on the heap. Avoid synchronized methods Synchronization causes a bottleneck through your portlet, or a path that only allows one thread at a time to pass through. Besides slowing the entire portal system, the possibility of a deadlock occurring is also high, which could hang the portlet, or portal, for all users. Avoid long-running loops Simply put, portlets need to be fast. Long running loops consume a large number of CPU cycles and cause the portal page to wait for this one portlet to finish. If a long-running loop seems necessary, re-inspect the design to see if it can be accomplished by some other means, such as through block/notification logic, or breaking the large loop up into several shorter ones. Use JSPs instead of XML/XSLT JSPs are more efficient than XML/XSLT in general. Since JSPs are compiled into servlets, they run much faster than having to parse XML and apply XSL stylesheets on every request. Also, the portal infrastructure is optimized around JSPs, allowing for easy expansion into other markups, languages, and even browser support by simply adding new directory structures of JSPs. In general, XML parsing and XSLT processing is expensive. XSL processing, for example, causes hundreds of transient String objects to be created and destroyed, which is expensive in CPU cycles and heap management. If XML/XSLT is a requirement, then make use of caching as much as possible to reduce the amount of parsing and XSLT processing which must take place. Use caching as much as possible If portlet output is static in nature or is valid for some period of time before it is updated, the portlet should enable the “display cache” by setting appropriate values for the <cache> elements in the portlet’s portlet.xml file (note that caching must be enabled in a portlet before it is installed or updated). A portlet’s caching settings can be set such that the output is never cached (<expires> value of 0, the default), cached for some period of time (<expires> value greater than 0, in Appendix A. General portlet development guidelines 733 seconds), or cached indefinitely (<expires> value of –1). The cached entries can also be shared across all users of the same portlet (<shared> value of YES) if the output is valid for any user. Important: Using the cache vastly improves the performance of the portlet, and thus of the page in general. The portlet can also implement the getLastModified() method to control the invalidation of the cached content, informing the portal that it should call the portlet’s doView() method to refresh the output. Refer to the portlet development section of the WebSphere Portal InfoCenter for examples of how to use the getLastModified() method. 734 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 B Appendix B. Data dictionary for case study This appendix contains the specific field names, field labels, and data types for each document type in our fictional Sales Tracking application. © Copyright IBM Corp. 2005. All rights reserved. 735 Product form Table B-1 Product form Field name Label Data type Description Text “Product” Form ProductName Name Text Required ProductNumber Number Number Identifier unique to this product No white space in value Required ProductPrice Price Number Required Not negative Currency format ProductDescription Description Text Comments Additional Information Rich text Sales person form Table B-2 Sales person form Field name Label Form Data type Description Text “Sales Person” SName Name Authors Required SNameFormat Hidden Text <Last Name>, <First Name> SNumber Employee # Text Identifier unique to this employee Required No white space in value SPhone Phone # Text SRegion Region Text Drop-down list Keywords hard coded STitle Job Position Text Drop-down list Keywords hard coded Comments Additional Information Rich text Owner Owner Authors Authorized to edit DateCreated Date Created Date computed 736 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 DateModified Last Modified $$Return Hidden Date computed Save success message on Web Customer form Table B-3 Customer form Field Name Label Form Data type Description Text “Customer”. CustomerName Customer Name Text Required. CustomerNumber Customer Number Text Identifier unique to this customer. No white space in value. Required. OwnerNumber Account Owner Text Drop-down list. Uses Sales People to populate keyword values. Stores EmployeeNumber, displays EmployeeName (EmployeeNumber). Required. OwnerNameFormat hidden Text Computed <Last Name>, <First Name> Formatted name value for OwnerNumber. CustomerAddress Address Text Multi-line, multi-value. Use TEXTAREA on Web. EmployeeTotal # of Employees Number Not negative. Integer only. Comments Additional Information Rich text Owner Owner Authors Authorized to edit. DateCreated Date Created Date Computed. DateModified Last Modified Date Computed. $$Return Hidden Save success message on Web. Appendix B. Data dictionary for case study 737 Customer contact form Table B-4 Customer contact form Field name Label Form Data type Description Text “Customer Contact”. ContactName Contact Name Text Required. ContactNameFormat Hidden Text Computed. <Last Name>, <First Name>. CustomerNumber Employer Text – drop down list Uses Customers to populate keyword values. Stores CustomerNumber, displays. CustomerName (CustomerNumber) Required. CustomerName Hidden Text computed Value from CustomerName field in Customer Record. ContactPhone Contact Phone Text ContactAddress Contact Address Text – multiline ContactJobTitle Contact JobTitle Text Comments Additional Information Rich Text Owner Owner Authors Authorized to edit. DateCreated Date Created Date Computed. DateModified Last Modified Date Computed. $$Return Hidden 738 Use TEXTAREA on Web. Save success message on Web. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Sales activity form Table B-5 Sales activity form Field name Label Form Data type Description Text “Sales Activity”. AType Activity Type Text Drop-down list. Hard coded keyword values. Required. ADate Activity Date Date/Time Defaults to today. CustomerNumber Customer Text Drop-down list. Uses Customers to populate keyword values. Stores CustomerNumber, displays Customer Name (CustomerNumber). Required. CustomerName hidden Text Computed. ContactName Customer Contact Text Drop-down list. Uses Customer Contacts to populate keyword values. ContactNameFormat Hidden Text Computed. Uses ContactName. <Last Name>, <First Name>. SNumber Sales Person Text Drop-down list. Uses Sales People to populate keyword values. Stores EmployeeNumber, displays Employee Name (EmployeeNumber). Required. SNameFormat Hidden Text Computed. Uses SNumber to lookup Sales Person name. <Last Name>, <First Name>. MadeSale Made a Sale? Text Radio button. Hard coded keyword values: Yes / No. Product1 Product Text – Drop down list Uses Products to populate keyword values. Stores ProductName (ProductNumber). Product2 Appendix B. Data dictionary for case study 739 Product3 Product1Q Quantity Number Comments Additional Information Rich text Owner Owner Authors Authorized to edit. DateCreated Date Created Date Computed. DateModified Last Modified Date Computed. $$Return Hidden Product2Q Product3Q 740 Save success message on Web. Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 C Appendix C. Additional material This redbook refers to additional material that can be downloaded from the Internet as described below. Locating the Web material The Web material associated with this redbook is available in softcopy on the Internet from the IBM Redbooks Web server. Point your Web browser to: ftp://www.redbooks.ibm.com/redbooks/SG246466 Alternatively, you can go to the IBM Redbooks Web site at: ibm.com/redbooks Select the Additional materials and open the directory that corresponds with the redbook form number, SG246466 © Copyright IBM Corp. 2005. All rights reserved. 741 Using the Web material The additional Web material that accompanies this redbook includes the following files (Table C-1). Table C-1 Description of additional materials files File name Description SampleNotesdbs.zip Contains the sample Notes Databases used throughout this book. (Databases are SALES,NSF, CUSTOMER,NSF, and PRODUCTS.NSF. See 2.3.1, “Case study overview” on page 78 for details of each database and how to deploy them. DominoAccess_Project.zip DominoAccess project for WSAD. SalesTrackingIBMAPI_Project.zip SalesTrackingIBMAPI portlet project for WSAD. SalesTrackingStruts_Project.zip SalesTrackingStruts portlet project for WSAD. SalesTrackingJSF_Project.zip SalesTrackingJSF portlet project for WSAD. SalesTrackingJSR168_Project.zip SalesTrackingJSR168 portlet project for WSAD. ep651int.pdf Domino V6.5.1 Extended Products Integration Guide (Official Lotus Documentation) How to use the Web material Here we discuss the use of the Web material. Importing project to WebSphere Studio ApplicationDeveloper You can use the Import Wizard in WSAD to copy a project into the Workbench. 1. From the main menu bar, select File -> Import. The Import wizard opens. 2. Select Project Interchange and click Next. 3. Click the Browse button to select the zip file which you would like to import. 4. Click Finish to start the import. 5. Create a subdirectory (folder) on your workstation, and unzip the contents of the Web material zip file into this folder. 742 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Related publications The publications listed in this section are considered particularly suitable for a more detailed discussion of the topics covered in this redbook. IBM Redbooks For information about ordering these publications, see “How to get IBM Redbooks” on page 748. Note that some of the documents referenced here may be available in softcopy only. Access Integration Patterns using IBM WebSphere Portal, SG24-6267 Domino Designer 6: A Developer’s Handbook, SG24-6854 Domino and WebSphere Together Second Edition, SG24-5955 IBM Lotus Domino Application Portlet: Configuration and Tips, REDP-3917 IBM Lotus Workplace Team Collaboration 2.0.1, REDP-3929 IBM WebSphere Portal for Multiplatforms V5 Handbook, SG24-6098 IBM WebSphere Portal V5 A Guide for Portlet Application Development, SG24-6076 Lotus Workplace 2.0.1 Products: Deployment Guide, SG24-6378 Portal Application Design and Development Guidelines, REDP-3829 A Portal Composite Pattern Using WebSphere Portal V5, SG24-6087 Portalizing Domino Applications for WebSphere Portal, SG24-7004 Using the Domino JSP Custom Tags: An Approach to Portalizing Domino Applications, REDP-3902 WebSphere Portal 4.12 Collaboration Services, REDP-0319 WebSphere Studio 5.1.2 JavaServer Faces and Service Data Objects, SG24-6361 WebSphere Studio Application Developer Programming Guide, SG24-6585 WebSphere Studio Application Developer Version 5 Programming Guide, SG24-6957 © Copyright IBM Corp. 2005. All rights reserved. 743 Other publications These publications are also relevant as further information sources: Gamma, et al, Design Patterns: Elements of Reusable Object-Oriented Software, Addison-Wesley, 2000, 0201485370 Lotus Domino and Extended Products 6.5.1 Integration Guide, G210-1747 Building a Portlet within the Model-View-Controller Paradigm using WebSphere Portal, found at: http://www-128.ibm.com/developerworks/websphere/library/techarticles/0210_k wong/kwong.html Guide to WebSphere Portal 4.2, found at: ftp://ftp.software.ibm.com/software/websphere/portal/pdf/Guide-to-Websphere -Portal.pdf Guide to WebSphere Portal 5.0, found at: ftp://ftp.software.ibm.com/software/websphere/portal/pdf/Guide_to_WebSphere _PortalV5.pdf IBM WebSphere Developer Technical Journal: Migrating a Struts application to WebSphere Portal, found at: http://www-106.ibm.com/developerworks/websphere/techjournal/0403_yu/0403_yu .html IBM WebSphere Developer Technical Journal: WebSphere Portal Programming, found at: http://www7b.software.ibm.com/wsdd/techjournal/0207_wanderski/wanderski.htm l Introduction to JavaServer Pages, found at: http://www-105.ibm.com/developerworks/education.nsf/java-onlinecourse-bytit le/882707E838C672A185256770004BDE72?OpenDocument Lotus Collaborative Services JavaDoc, found at: http://www7b.software.ibm.com/wsdd/zones/portal/portlet/4.2api/collaborativ e/ Portlet Development Best Practices and Coding Guidelines, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/portlet/portle tcodingguidelines.html Portlet Development Guide: Second Edition, found at: http://www-106.ibm.com/developerworks/websphere/zones/portal/portlet/portle tdevelopmentguide.html 744 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 The Struts User Guide, found at: http://struts.apache.org/userGuide/index.html Struts in WebSphere Portal 4.1, found at: http://www.ibm.com/support/docview.wss?rs=0&org=SW&doc=7002247 Using Click-to-Action to Provide User-Controlled Integration of Portlets, found at: http://www7b.software.ibm.com/wsdd/library/techarticles/0212_roy/roy.html Online resources These Web sites and URLs are also relevant as further information sources: AdHoc http://www.adhoc.cz Apache Jakarta Project: Pool http://jakarta.apache.org/commons/pool/ Apache Logging Services Project http://logging.apache.org Apache: Struts http://struts.apache.org Bowstreet http://www.bowstreet.com Conet AG http://www.conet.de CORBA http://www.omg.org IBM developerWorks: Lotus http://www-136.ibm.com/developerworks/lotus IBM developerWorks: SOA and Web services http://www-106.ibm.com/developerworks/webservices/newto/websvc.html IBM developerWorks: WebSphere http://www.ibm.com/developerworks/websphere IBM Lotus Domino Developer Domain http://www.lotus.com/ldd Related publications 745 IBM Lotus Workplace Information center http://workplaceid.notesdev.ibm.com/lwp20_infocenter/index.html IBM Portal Toolkit http://www.ibm.com/websphere/portal/toolkit IBM WebSphere http://www.ibm.com/websphere IBM WebSphere Developer Domain - Portal Zone http://www-128.ibm.com/developerworks/websphere/zones/portal/ IBM WebSphere Portal for Multiplatforms Version 5.0.2 Information Center http://publib.boulder.ibm.com/pvc/wp/502/index.html IBM Workplace Products API Toolkit http://www.lotus.com/ldd/lwpapi Introduction to JavaServer Pages http://www-106.ibm.com/developerworks/edu/j-dw-jsp-i.html Introduction to log4j http://logging.apache.org/log4j JavaServer Pages Technology http://java.sun.com/products/jsp Java Technology http://java.sun.com JSR 52: A Standard Tag Library for JavaServer Pages http://www.jcp.org/en/jsr/detail?id=52 JSR 127: JavaServer Faces http://www.jcp.org/en/jsr/detail?id=127 JSR 168: Portlet Specification http://www.jcp.org/en/jsr/detail?id=168 Log4j http://jakarta.apache.org/log4j/docs/ Lotus Documentation http://www-10.lotus.com/ldd/notesua.nsf/find/designer http://www-10.lotus.com/ldd/doc The Lotus Domino Toolkit for Java/CORBA / Domino Java API http://www-10.lotus.com/ldd/toolkits 746 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 New to WebSphere Portal http://www-106.ibm.com/developerworks/websphere/zones/portal/newto OASIS Web Services for Remote Portlets (WSRP) TC http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wsrp Object pooling http://jakarta.apache.org/commons/pools Portal Struts support http://jakarta.apache.org/struts/index.html Portal Zone http://www7b.software.ibm.com/wsdd/zones/portal/ Portlet API Javadoc for WebSphere Portal http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html#d evguide5 Portlet JSP Tag Library Syntax http://www7b.software.ibm.com/wsdd/zones/portal/portlet/V41jsptaglib.html StrutsSolutions - Apache Struts Wiki http://wiki.apache.org/struts/StrutsSolutions Sun Microsystems J2EE Web site http://java.sun.com/j2ee/ Sun Microsystems JSP Web site http://java.sun.com/jsp Using Click-to-Action to Provide User-Controlled Integration of Portlets http://www-106.ibm.com/developerworks/websphere/library/techarticles/0212_r oy/roy.html WebSphere Application Server Library http://www-306.ibm.com/software/webservers/appserv/infocenter.html WebSphere EveryPlace Access InfoCenter http://publib.boulder.ibm.com/infocenter/weahelp/index.jsp?topic=/com.ibm.w ebsphere.start.doc/welcome.html WebSphere Portal InfoCenter http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html WebSphere Portal and Lotus Workplace Catalog http://catalog.lotus.com/wps/portal/portalworkplace Related publications 747 WebSphere Portal for Multiplatforms Library http://www-306.ibm.com/software/genservers/portal/library WebSphere Portal Product Documentation http://www7b.software.ibm.com/wsdd/zones/portal/proddoc.html http://www-106.ibm.com/developerworks/websphere/zones/portal/proddoc.html#i c5 WP Experts http://www.wpexperts.com JSF API Specifications http://java.sun.com/j2ee/javaserverfaces/reference/api/ How to get IBM Redbooks You can search for, view, or download Redbooks, Redpapers, Hints and Tips, draft publications and Additional materials, as well as order hardcopy Redbooks or CD-ROMs, at this Web site: ibm.com/redbooks Help from IBM IBM Support and downloads ibm.com/support IBM Global Services ibm.com/services 748 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Index Symbols $$Return field 82 @DbLookup 82 @Functions 82 A A sample Customer database in the Domino Application portlet 120 A Workplace Application Page 693 Abstract Factory 384 Accessing databases 323 Accessing documents 324 Accessing Domino 322 Accessing Domino data 400 Accessing Domino sessions 322 Accessing items and rich text items 325 Accessing views 324 Action events 346 Action interaction in the Customer Details portlet 255 Actions for buttons 566 Add deluxe pager 557 Add Global Forwards 532 Add libraries to web.xml 241 Add library to Java build path 498 Add link to table 559 Add navigation to index.jsp 551 Add new action mapping 521 Add new customer action and show details action 558 Add new JavaBean 552 Add parameter to link 561 Add Person or Group 153 Add portlets to a page 495 Add request scope variable to output text 568 Adding a SessionBean 227 Adding additional views to the Domino Databases portlet 121 Adding classes to DominoAccess 498 Adding Domino Portlets to Workplace Applications 692 Adding functionality to DominoAccess 575 Adding global forwards 531 © Copyright IBM Corp. 2005. All rights reserved. Adding Lotus Domino JSP tags to our portlets 239 Adding People Awareness 608, 646 Adding portlets to a page 89 Adding Session Sharing attributes 226 Adding support for Domino JSP custom tags 200 Adding the automatically Deployed Portlet to a page 646 Adding the Customer List portlet to the page 252 Adding the Customers/Customer By Name view to View.jsp 246 Adding the Domino View & Form Builder 636 Adding Workplace Portlets to Domino Portlets 690 Additional application functionality 82 Additional information 388 Additional thoughts on J2EE 180 Adjusting the Host Server for the Installed Model 660 Advanced Search 168 Aggregating informaion from multiple databases 46 Alphabetic Index 680 API Help Documentation Installation 710 Applicable portlet patterns 75, 667 Application Development prerequisite 710 Applications 694 Applications and Templates 692 Architecture 708 Authentication 54, 125 Authentication UI 126 Automatic portlet creation (create button) 679 Available options for Portalizing Domino Applications 61 B Basic elements of Struts 365 Basic portlet 223 Basics 676 BeanUtils 414 Benefits of Collaborative Services 380 Benefits of Domino and Portal together 22 Between components of a single web application 216 Between multiple web applications 217 Bind sales persons to menu 565 749 Bowstreet Action List Configuration 651 Bowstreet Builder Palette window 638 Bowstreet C2A Event Declaration Builder configuration window 649 Bowstreet C2A Menu Configuration 652 Bowstreet Designer 620 Bowstreet development tool 620 Bowstreet Domino View & Form Builder 639 Configuration window part 2 640 Bowstreet Event Handler Builder configuration window 650 Bowstreet implementation of Sales Tracking case study 653 Bowstreet JSR168 Settings 633 Bowstreet Model Name 636 Bowstreet People Awareness Builder 647 Bowstreet Portlet Factory benefits 620 builder 621 Click-to-Action 648 code execution architecture 622 considerations 623 deploying 643 development environment 620 Domino form builder 636 Domino view builder 636 implementation example 652 Lotus Collaboration extension 619 model 621 opening the developer 626 overview 619 performance 624 profile 621 rich text 624 sample portlets 654 server components 622 skillset 620, 624 testing a model 642 Bowstreet Portlet Factory for WebSphere 77, 619 Bowstreet Portlet Factory for WebSphere code execution architecture 623 Bowstreet Run Configuration 642 Bowstreet server components 622 Bowstreet WPS Portlet Adapter Builder configuration window 644 Builder 621 Builders 60 Building Blocks 671 Building the portlet project with WebSphere Studio 750 222 Business Card 164 C Cache 663 Caching 126 Caching UI 127 Calendar Portlet 143 Calendar portlet 111 Case Study application details 80 application functionality 82 databases 78 document types 79 overview 78 relationships 80 sales workplace 80 use cases 81 user roles 80 Case study 77 A simple sales tracking application 77 Application details 80 Case study objective Sales Workplace 80 Case study overview 78 Changing the table to include headers 247 Changing values for the Team Spaces portlet 113 Chat 153 Choose form fields 519 Choosing an integration technique 70 Click-to-Action 287 287 architecture 290 broadcasting 287 broker 288 chained propagation 287 concepts 288 enabling source portlets 292 encodeProperty 294 event broker 290 features 287 functionality 287 implementation 291 model 287 namespace 303 operating diagram 289 request-response flow 291 source 288 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 source portlets 288 target 288 target portlets 288 Click-to-Action chained propagation 288 Click-to-Action sequence diagram 290 Client tier 180 Clustering 670 Collaboration Center portlets 99 Collaborative Application Component Interface 718 Collaborative Components 305 Collaborative Services API 379 Column container 34 Command 385 Command button and hyperlink actions 373 Common pitfalls 303 Commonly used Domino Java classes 327 Comparing common portlet API concepts 354 Comparing elements of the API 357 Comparing portlet packaging and descriptors 356 Completed SalesTrackingStruts application 533 Component Communication 664 Component structure for a "Detail Message" 682 Concepts and design of Click-to-Action 288 Concepts unique to JSR 168 360 Concepts unique to the IBM portlet API 363 Conclusion 708, 721 Conclusions to the custom Domino tags integration technique 286 Concrete portlet application 341 Conet Knowledge Director 3.0 @formulas 673 benefits 661 components 661 considerations 667 creating portlets 671 data source 676 defining the layout 677 implementation example 674 Knowledge Director connector 663 overview 660 portlet cooperation 681 scalability 661, 670 search 679 selection 676 CONET Knowledge Director 3.0 for WebSphere Portal 660 Conet Knowledge Director 3.0 for WebSphere Portal 77, 660 CONET Knowledge Director architecture 661 Configuration Basics 162 Configuration Options 124, 665 Configuration options 161 Configuration parameters 443 Configure SalesTrackingIBMAPI portal application 496 Configure URL 556 Configuring a portlets’ properties 162 Configuring authentication in the Domino Application portlet 119 Configuring Team Workplace (Team Spaces) portlet 111 Configuring the 6.5.1 Extended Products portlets 109 Configuring the Document Manager (Domino.Doc) portlet 117 Configuring the Document Manager portlet 117 Configuring the Domino Application portlet 118–119 Configuring the Domino Databases (Notes View) portlet 120 Configuring the Domino Web Access portlet 110, 141 Configuring the Domino Web Access portlet - Manually 143 Configuring the Extended Products portlets 109 Configuring the Instant Messaging Contact List 116 Configuring the Instant Messaging Contact List for WebSphere Portal 116 Configuring the Notes View in the Domino Databases portlet 121 Configuring the Portlet Builder for Domino Enter username and password 601 Select the forms and views 602 Configuring the Team Spaces portlet 111 Configuring the Web Conferences portlet 114 Connecting to a Domino database 243, 594 Connecting to Domino databases through Domino toolkit 243 Connecting to the Domino database 242–243 Connections between index.jsp and Customers.jsp 508 Connector 663 Considerations 123, 131, 155, 160, 291 Considerations for deploying the Domino Web Access Portlet 139 Considerations for the Domino Extended Products Portlets 105 Contacts Portlet 144 Index 751 Contacts portlet 111 container-specific variables 218 containment model 202 containment relationships 202 Cooperative portlets 27 CORBA 214, 316 accessing Domino 318 architecture 318 functionality 318 stub objects 318 Core tags 203 Create DominoSessionFactory class 405 Create fields for form bean 520 Create folder hierarchy 239 Create new class in WSAD 404 Create page SalesTrackingIBMAPI 494 Create Redbook samples label 493 Create Struts portlet project 504 Creating a label 85 Creating a new Bowstreet model Selecting model type 635 Creating a new Bowstreet Web Application 628 Creating a new model 633 Creating a new Portlet with Portlet Builder for Domino 599 Creating a new project and model 627 Creating a page 87 Creating a Portlet Project 222 Creating a WSDL file 298 Credential vault 55 CredentialVaultManager 431 CredentialVaultManager explained 434 CredentialVaultService 349 CSEnvironment.properties file 116 Custom Domino JSP session tag 214 custom JSP tags 199 Customer Contacts initial portlet 274 Customer Contacts portlet 197, 263 Customer Contacts portlet Enable Click-to-Action Target Parameters 299 Customer Contacts Servlet 273 Customer Detail portlet 263 Customer Details portlet 196 Customer Details portlet Enable Click-to-Action Target 296 Customer Details portlet Enable Click-to-Action Target Parameters 297 Customer details portlet Java code 253 Customer Details Servlet 262 752 Customer List portlet 196 Customer portlet and Customer Profile portlet connected by messaging 683 Customer Portlet with search field and alphabetical index 681 Customer Profile Portlet 681 Customer Sales Activities initial portlet 286 Customer Sales Activities portlet 198, 274 Customer Sales Activities portlet Enable Click-to-Action Target Parameters 301 Customer Sales Activities Servlet 285 CustomerBean 408 CustomerBeanCollection and SalesPersonBeanCollection in Web diagram 509 CustomerContactBean 410 CustomerContacts.java file 264 CustomerContactsEntry.jsp file 271 CustomerContactsPortlet 472 CustomerContactsPortlet with Click-to-Action 482 CustomerContactsPortlet, contact listing 477 CustomerContactsPortlet, editing customer 484 CustomerContactsPortlet, testing Click-to-Action 483 CustomerContactsPortletView.jsp 475 CustomerDetails.jsp 562 CustomerDetails.jsp with navigation buttons 566 CustomerDetails.jsp, updating CustomerBean 564 CustomerDetailsEntry.jsp 259 CustomerDetailsPortlet 456 CustomerDetailsPortlet explained 465 CustomerDetailsPortlet in the test environment 469 CustomerDetailsPortlet JSP files 466 CustomerDetailsPortlet portlet settings 459 CustomerDetailsPortlet, add new customer 470 CustomerDetailsPortlet, edit a customer 472 CustomerDetailsPortlet, new customer added 471 CustomerDetailsPortletAddCustomerView.jsp 466 CustomerDetailsPortletView.jsp 466 CustomerSalesActivities.java 274 CustomerSalesActivitiesEntry.jsp file 281 CustomersPortlet 434 CustomersPortlet and a list of five customers 456 CustomersPortlet explained 441 CustomersPortlet JSP files 445 CustomersPortletConfig.jsp 451 CustomersPortletEdit.jsp 449 CustomersPortletView.jsp 447 Customization 33 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 D DAP - Access to configuration menu 124 DAP - Edit UI 129 Data Access Tags 202 Data access tags 205 Data aggregation 51 Data dictionary 82 Data Input Tags 202 Data input tags 207 Database 329 Database definition 676 Database tier 179 Debug 128 Debug UI 128 Debugging 669 Declarations 182 Decorator 384 Definition of a JSP 181 Deploy the portlet 263, 273, 285, 302 Deployed Portlet Showing People Awareness 647 Deploying a Bowstreet Model as a Portlet 643 Deploying our initial application 249 Deploying the case study portlets 83 Deployment 489, 540, 573, 586 Deployment descriptors 262, 351, 484, 535, 568, 584 Design principles 387 Designing the integration portlet 45 Details view 158 Developer Skill Set 669 Developing Domino portlets using Java 76 Developing using Java 60 Development Environment - Local debug configuration 191 Development Environment - Remote debug configuration 192 Development environment configurations 191 Development environments 59 Development Options 58 Development Time 668 Development tools 59 DIIOP 200, 214, 317 Directives 181 Discussion portlet 139 Display Details menu 157 Display pattern 43 Display pattern example 44 Distributed Domino scenario 53 Document 332 Document Manager (Domino.Doc) portlet 117 Document properties 397 DocumentCollection 331 dojkey attribute 221 Domino infrastructure bottlenecks 54 integration techniques 69 Workplace 20 Domino application choosing a design pattern 47 Domino Application Portlet 123 Domino Application portlet 118 Domino applications 37 characteristics 37 example 77 features 71 integration into the Portal 57 migrating into the Portal 45 portalizing challenges 36 transforming into the Portal 45 type of use 37 types 37 Domino custom JSP tag libraries 199 Domino Databases (Notes View) portlet 120 Domino Designer 186, 396 Domino hub scenario 52–53 Domino Internet Inter-ORB Protocol 200 Domino Java API 315 Domino Java classes 321 Domino JSP custom tags adding support 200 Domino JSP tag libraries 60, 74, 175 overview 198 taglib 198 Domino JSP tags adding to a portlet 239 customer contacts portlet 197 customer detail portlet 196 customer list portlet 195 customer sales activities portlet 197 data access 205 data input 207 database 206 docloop 207 document 206 ftsearch 206, 272 ifcategoryentry 208 ifdbrole 209 ifdocauthor 209 Index 753 ifdocumententry 208, 272 implementation example 222 integration techniques 195 item 206 making a connection to a Domino database 243 nodocument 209 process control 208 runagent 209 sample applications 195 session 205 support 175 technologies 177 types 203 unid 206 utility tags 210 view 206, 272 viewitem 206 viewloop 207, 284 Domino Object Model 320 Domino objects architecture 319 Domino Session 213 Domino Tags 245 Domino view tag 272 Domino viewloop tag 258, 284 Domino Web Access - Instance 142 Domino Web Access portlet 110 Domino XML 376 Domino.Doc (Document Manager) Portlet 170 Domino.Doc sources form 172 DominoAccess 417 DominoAccess explained 424 DominoAccess project 400 DominoAccess project in WSAD workspace 402 DominoAccess.getFirstPNGImage() 576 DominoAccessProxy.getFirstPNGImage() 577 DominoSessionFactory 403 DominoSessionFactory class template 406 DominoSessionFactory explained 407 DominoSessionManager 215 domtags.jar 199 Drawing a Struts application 505 E Eclipse 620 Edit Domino Source Server 129 Edit icon 171 Edit Options 129 Edit options 140 754 Edit Page Layout 89 Edit page layout 494 Edit parameters 156, 171 Edit Template for editable Customer Profile portlet 684 Editable Customer Profile 685 Editing a portlets’ properties 132, 140, 145, 156 Editing and Configuration parameters 152 Editing options 132 Editing parameters 145 Editing the Application 705 EJB container tier 179 Element containment hierarchy 673 Elements of a JSP 181 Elements of the IBM Portlet API 342 EmbeddedObject 335 Enable Click-to-Action source 478 Enable Click-to-Action target 480 Enabling Click-to-Action 477 Enabling our CustomerSalesActivities portlet 309 Enabling the Customer Contacts portlet 298 Enabling the Customer Details portlet 295 Enabling the Customer Sales Activities portlet 300 Enabling the CustomerContacts portlet 309 Enabling the CustomerDetails portlet 308 Enabling the CustomerList portlet 308 Enabling the source portlet (Customer List) 292 Enabling the target portlets 295 Enhancements 75 Enhancing Further with Click-to-Action 612 Evolution of Lotus Domino Toolkit for WebSphere Studio 194 Example 712, 716 Example “shadow” skin 33 Example Bowstreet Settings 632 Example of a place with portlet cooperation 28 Example portlet “Employee Directory” 39 Existing portlets 59 overview 93 QuickLinks 122 skillset 94 Web clipping portlet 122 Web page portlet 139 Export JAR 427 Export project 426 Export SalesTrackingIBMAPI portlet application 490 Exporting DominoAccess 426 Expressions 183 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Extending the PortletAdapter class 230 External jars in Java build path 403 F Facade 385 Factors and dependencies 36 Factory 383 Features of the Click-to-Action model 287 Forwards and redirects 369 G Generating a C2A target model 648 Getting Domino data in a high-performance way 40 Granting access to the DominoJspTags application 251 H Hide-when formulas 82 How it fits in to the Lotus technology strategy 193 HttpServletRequest 184 HttpServletResponse 184 HttpSession 184 I IBM Portal Builder Presence Awareness 594 IBM Portlet API 336, 397, 587 IBM Portlet API and the servlet API 337 IBM Portlet API portlets basic and simplified functionality 398 IBM Portlet Builder authentication options 605 Click-to-Action 594 configuring a portlet 599 connecting to a Domino server 601 considerations 595 creating a new portlet 599 features 594 form display options 605 implementation details 596 implementation example 608 installing 596 performance 596 rich text 595 scalability 596 secleting views and forms 602 skill set 595 view configuration 603 IBM Portlet Builder for Domino 77, 593 features 594 IBM Portlet Wiring Tool 28 IBM WebSphere Portal Application Integrator 593 connectivity 594 features 594, 620 IBM WebSphere Portal overall architecture 23 IBM Workplace Client Technology and its role within IBM Workplace 18 Identify project requirements 71 IFrame 606 Implementation details 161, 596, 625 Implementation details for Extended Products Portlets 107 Implementation details for the Document Manager Portlet 170 Implementation details for the Domino Application Portlet 123 Implementation details for the Domino Web Access Portlet 140 Implementation details for the Instant Messaging Contact List 151 Implementation details for the Lotus Web Conferencing Portlet 144 Implementation details for the Notes View Portlet 131 Implementation details for the Team Workplaces portlet 155 Implementation example 222, 608, 652 Implementation issues 595, 623, 667 Implementation of the technique 291, 307 Implementing a Click-to-Action Menu 651 Implementing communication between Bowstreet models 648 Implementing the Sales Workplace example 674 Implicit objects in JSP files 184 Import jar files 240 Important configuration prerequisites 105 index.jsp 548 Index.jsp attributes 548 Infocenter file structure 710 Initial portlet JSP in Design mode 249 Initial portlet with Domino functionality accessed through JSP tags 252 Initial setup 124, 132, 140, 145, 152, 156, 161, 170 Input translation formulas 82 Input validation 82 Insert Click-to-Action Output Property 293 Index 755 Insert Click-to-Action Output Property control 293 Insert JavaBean dialog 553 Insert JavaBean for updating fields 563 Insert Tag Libraries to the new CustomerDetails.jsp file 259 Inserting Domino custom tag libraries 241 Install portlet I 492 Install portlet II 493 Install portlets 83 Installing Bowstreet Models 659 Installing Bowstreet Package 658 Installing IBM Portlet Builder for Domino 596 Installing the Customer List portlet 250 Installing the Extended Products Portlets 107 Installing the Sample Application 657 Instant Messaging Contact List 116 Integrate using Lotus Notes View Portlet 130 Integrate using the Domino Web Access (iNotes) portlet 139 Integrated Help System 627 Integrated pattern 44 Integrating Domino applications 35 Integration of the Domino 6.5.2 products with a common Portal interface 101 Integration Option 1 - Using the Domino 6.5.1 and Extended Products Portlets Collaboration the easy way 100 Integration Option 2 - The Domino Application Portlet 122 Integration Option 3 - using specific Portlets 130 Integration options 61–62, 95, 177, 315, 593, 690 Integration project considerations 73 functional requirements 71 identifying requirements 71 portlet pattern 71 preparation 70 selecting the integration technique 72 steps 70 training 70 using existing portlets 74 Integration technique selecting 72 Integration techniques 69, 195 described 74 Integration techniques and development options 73 Integration techniques and overview of portlets 97 Integration using Domino custom JSP Tag libraries 198 756 Integration via Click-to-Action 287 Integration via people awareness 303 Integration with Lotus Workplace 77, 687 Internationalization 670 Internet links 388 Introduction 688 Introduction to IBM Workplace 6 Introduction to object-oriented design patterns 382 Introduction to portalizing Domino applications 1 Introduction to portlets 24 Item 334 J J2EE 178 application server 180 Client tier 180 database tier 179 described 178 EJB container tier 179 portlets 178 technologies included 178 Web container tier 180 J2EE overview 178 Jakarta 186 Java 76 Java 2 Enterprise Edition See J2EE Java archive files 199 Java code generated from the Bowstreet Domino View & Form Builder 641 JavaServer Pages 180 See JSP JDBC 594, 620 JSF 399, 588 JSF application concept 372 JSF application structure 372 JSF framework 371 JSF support in WPS 373 JSP 180 adding a Domino view 249 adding tag library definitions 248 declarations 182 described 181 directives 181 expressions 183 limitations 185 objects 184 request 184 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 response 184 scriptlets 183 session 184 stateful interaction 184 tags 181 JSP files 581 JSP limitations 185 JSP tags 353 JspWriter 184 JSR 168 399, 587 JSR 168 Java Portlet Specification 354 JSR 168 portlet, basic and simplified functionality 400 JSTL 374 K Knowledge Director components 661 Knowledge Director Repository 662 Knowledge Director Service 663 L Launching the Bowstreet Designer from WebSphere Studio 626 Layout and functional aspects 46 Layout definition 46, 677 Layout of the portal page 33 Lightweight Third-Party AuthenticationToken 55 Limitations and Considerations 212 Link pattern 42 Link pattern example 43 Link to main page 555 Linking the servlet, portlet, and concrete portlet 352 List of Portlets 91 Listeners 347 Load balancing 54 Local access to Domino data 41 Local debug configuration 191 local session 214 Local/remote access to Domino 317 Logging 376 Logging in on WebSphere Portal as an administrator 112 Logical representation of portlets in JSR 168 355–356 Logical representation of portlets in the IBM portlet API 354–355 Lotus Discovery Server 307 Lotus Domino and Extended Products 6.5.1 Integration Guide 106 Lotus Domino Document Manager (Domino.Doc) 97 Lotus Domino Toolkit for WebSphere Studio 192 Lotus Domino Toolkit for WebSphere Studio 1.3 192–193 Lotus Instant Messaging and Web Conferencing (Sametime) 97 Lotus Instant Messaging Contact List (Sametime Contact List) 151 Lotus Notes and Domino and its role within IBM Workplace 11 Lotus Notes Portlets before configuration 132 Lotus Notes View portlet edit mode 134 Lotus Notes View portlet edit Style 135 Lotus Notes/Domino 20 Lotus Notes/Domino and Extended Products Portlets 101 Lotus Team Workplace (QuickPlace) 97 Lotus technology strategy 193 Lotus Web Conferencing (Sametime) 144 Lotus Workplace 15, 21 Lotus Workplace and its role within IBM Workplace 14 Lotus Workplace Builder 63 Lotus Workplace Platform Architecture 709 Lotus Workplace products and features 15 M Manage Portlets 112 Manage SalesTrackingStruts application 543 Manage SalesTrackingStruts application parameters 544 Mechanism of CORBA 319 Mechanism of the CORBA sessions for Domino 318 Message events 346 MessageBean 566 Migrated pattern 45 Mobile support 594 Model 621 Model-View-Controller 385 Modifying the Customer List portlet java source 235 Modifying the Customer List portlet JSP file 244 Modifying the Team Spaces portlet 113 Multidevice portlets 32 Multi-server session-based authentication 54 Index 757 My Contacts 151 My Contacts - New Group 154 My Contacts - Options 155 My Lotus Team Workplaces (QuickPlace) 155 N Navigation 373 NCSO.jar 199 Nested tag warning in SalesTrackingJSFView.jsp 559 New Documents portlet 49 New Form Bean 518 New JSP file NoCredentials.jsp 446 New Label 87 New Page 89 New portlet 458 New portlet project 429 New portlet project wizard 428 New project wizard 401 New Struts portlet project 505 New Web Conferences 151 New workplace 159 News portlet 48 No response object 368 NoCredentials.jsp 445 Notes and Domino 96 Notes view portlet 131 considerations 131 Notes.jar 199 NotesException and NotesError 336 NotesFactory 327 O Object Pooling 220 supported objects 220 Object pooling 375 object pooling error handling 221 MVC architecture 221 validation 221 Object Pooling and Domino JSP custom tags 220 Object Pooling and MVC architecture 221 object sharing 220 Object validation and error handling 221 Offline browsing support 594 Online Center Tag 715 Online Center Tag in Our Application 717 758 Online presence 305 Options 154 Options for line of business and power users 65 Options for mid-level script developers 65–66 Options for professional Domino/J2EE developers 66 Other technologies 374 Overview 3, 94, 176, 198, 213, 314–315, 336, 593 Overview of Domino - WebSphere Portal integration 316 Overview of Lotus Workplace Builder 63 P Page adding a portlet 251 Page content aggregation 31–32 Page customization 33 Page layout example 34 PageData with CustomerBeanCollection 553 Pages containers 34 layout example 34 Pagination 46 Paging 556 Parameters for creating the portlet project 223 parse tree 216 people 306 People Awareness 303 chat 304 finding documents 304 implementing 306–307 online presence 305 online status 304 people links 304 People awareness 304 People Awareness Inside Workplace 715 People finder - Basic Configuration 163 People finder - Business Card 164 People finder - Configuration Overview 162 People Finder - Detail Person Record 169 People Finder - Organization 170 People finder - Quick Search 167 People Finder - sections 165 People Finder Portlet 160 People links 304 peopleinit 307 PeopleService tags 306 PeopleSoft 594, 620 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 Performance 596, 624, 670 Performance considerations 38 Person Tag 711 Personalization 46 Places example 28 Pointing Domino Web Access to a source mail database 142 Pointing to view in Notes database 133 Portal 5 architecture 23 architecture considerations 23 benefits 6 Click-to-Action 290 dedicated server for Domino 54 description 6 developing portlets using Java 76 functionality 6 integration techniques 69 page aggregation 23 page customization 33 people awareness 303, 308 search 46 Portal and Domino within the context of the IBM Workplace 3 Portal application design guidelines 381 Portal application functionality 397 Portal architecture 23 Portal engine components 30 Portal Toolkit provides the following 190 Portalization project 395 Portlet 342 login() method 219, 238 logout() method 219 Portlet API 26 Portlet applications 24, 341 Portlet Builders 76–77, 591 Conet Knowledge Director for WebSphere Portal 660 Portlet builders 76, 591 Bowstreet Portlet Factory for WebSphere 619 IBM Portlet Builder for Domino 593 Portlet builders option advantages 592 benefits 592 disadvantages 592 overview 591 skillset 592 Portlet class instance 338 Portlet communications 26 Portlet concept 340 Portlet concepts 339 Portlet configuration 344 Portlet cooperation 681 Portlet creation methodology 671 Portlet definition 679 Portlet definition repository 662 Portlet deployment descriptor 338 Portlet deployment descriptor, portlet.xml 352 Portlet development using Java Integration examples 391 Technology review 313 Portlet events 345 Portlet inheritance 337 Portlet life cycle 342 Portlet menu 351 Portlet modes 25 Portlet modes and JSF 374 Portlet patterns 42 advantages 72 disadvantages 72 selecting 71 Portlet patterns examples 48 Portlet patterns used in designing the integration 47 Portlet perspective 222 Portlet Preview Settings Page 668 Portlet running in test environment. 455 Portlet to Notes view comparison 672 portlet.xml 263, 273, 285 PortletApplicationSettings 345 PortletApplicationSettingsAttributesListener 349 PortletConfig 344 PortletData 345 PortletMenu 350 PortletPageListener 347 PortletRequest 343 PortletResponse 343 Portlets 663 actions 255 adding Domino JSP tags 239 adding to a page 251 application integration 51 basic 223 choosing the desing pattern 47 Click-to-Action 287 communicating 287 Index 759 design patterns 42 display 43 displaying information 43 enabling people awareness 308 granting access 250 installing 249 integrated 44 integrating the application logic 44 interportlet communication 287 J2EE development 178 link 42 migrated 45 opening an application 43 packaging guidelines 727 performance considerations 732 portlet.xml 262, 273, 285 previewing 252 Toolkit for WebSphere Studio 189 transmitting information 287 UI components 46 use cases 42 web.xml 262 Portlets which make up Extended Products Portlets 103 PortletService 349 PortletSession 344 PortletSessionListener 347 PortletSettings 345 PortletSettingsAttributesListener 349 PortletTitleListener 348 Presentation services 29 Process Control Tags 203 Process control tags 208 Product and component matrix WebSphere Portal 5.0.2 13 Profile 621 Programmatic access to underlying Domino Java Objects 211 Project considerations 70 Project Navigator view 224 Providing a stateful interaction through a stateless protocol 184 Proxy 384 R Q S Query definition Basics tab 678 Query definition Layout tab 678 Sales Report - Sametime Detail 138 Sales Tracking application 77 Sales Tracking application using IBM Portlet API 760 Range of Applications 669 Realizing actions 520 Realizing JSPs and JavaBeans 511 Rebuild Bowstreet Portlet WARs 645 Recycling Domino objects 320 Redbooks 389 Redbooks Web site 748 Contact us xvii Redpaper 389 Reference Material 310 Reference material 174 Referencing concrete portlet to portlet 353 Referencing portlet to servlet 352 Regeneration 621 Relationship to servlet API 354 Relationships 80 Remote access to Domino data 40 Remote debug configuration 192 remote session 214 Required software versions 596, 625, 671 resource limitations 220 Result of clicking the first highlighted link in the Lotus Notes View portlet 138 Result of modifying the Lotus Notes View Portlet 137 result.jsp 582 Results 129 Results of configuring the Notes View Portlet 136 Results of using the Document Manager portlet 173 Reusing the Application to Create New Applications 707 Review - Meeting Detail 150 Reviewing the Customer database 244 Rich text 595 Rich Text Handling 669 RichTextItem 335 Roles 694 Roles support 370 Row container 34 Rules 127 Running the Bowstreet model on WAS 643 Portalizing Domino Applications: Integration with Portal 5.02 and Lotus Workplace 2.0.1 428 Sales Tracking application using JSF 546 Sales Tracking application using JSR 168 575 Sales Tracking application using Struts 498 Sales Tracking Domino application 395 Sales Tracking portal app